Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为什么用 Go 访问某网站始终会 503 Service Unavailable ? #50

Open
izackwu opened this issue Mar 14, 2021 · 21 comments
Open
Labels

Comments

@izackwu
Copy link
Owner

izackwu commented Mar 14, 2021

https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/#%E5%B0%BE%E5%A3%B0

记一次耗费了我三天精力,但是相当有趣的 Debug 经历

Gitalk_/posts/2021-03-14-why-i-always-get-503-with-golang/

@izackwu izackwu added the Gitalk label Mar 14, 2021
@Xuanwo
Copy link

Xuanwo commented Mar 14, 2021

看标题的时候就在想会是什么原因,没想到居然是 Cipher Suites 导致的,神奇

@holmesian
Copy link

给大佬点赞,之前我有一次爬数据的时候也遇到了类似的问题,因为时间紧,后来直接改用了Python,原来坑在这里

@Zheaoli
Copy link

Zheaoli commented Mar 14, 2021

很有趣的问题

实际上看起来这个网站的活做的很细,某种程度上让人更难排查

@laike9m
Copy link

laike9m commented Mar 14, 2021

这反爬🤣
看来是被 go 搞怕了
所以如果使用第三方的 go HTTP 库会怎样呢,不知道是不是还是同一套 cipher suites

@Allianzcortex
Copy link

大胆假设,小心求证

@izackwu
Copy link
Owner Author

izackwu commented Mar 15, 2021

@laike9m

那得看第三方的 HTTP 库有没有用 Go 的 TLS 库的默认参数了,我感觉应该不太可能自己实现一个 TLS 库

@Wusuluren
Copy link

用go爬微博的个人主页也会被防,换成python就可以

@yihong0618
Copy link

cloudflare 利用了部分 Cipher Suites 的特性做 anti-bot
code

@izackwu
Copy link
Owner Author

izackwu commented May 26, 2021

@yihong0618 学到了

@yihong0618
Copy link

我又来了,哈哈, 之前发现可以强制指定 tls 版本绕过一些例如 anti-bot, 想试试这网站行不行。
但再尝试发现,这网站已经可以用 go 直接访问了不会 503...太奇怪了(可能是服务器升级了。)

@qiankunxienb
Copy link

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

@Zheaoli
Copy link

Zheaoli commented Aug 18, 2021

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

@qiankunxienb
Copy link

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

@Zheaoli
Copy link

Zheaoli commented Aug 19, 2021

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

HTTP2 加上 ForceAttemptHTTP2: true 就行

@qiankunxienb
Copy link

@Zheaoli

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

HTTP2 加上 ForceAttemptHTTP2: true 就行

加上ForceAttemptHTTP2: true 以后,上面使用的tls.VersionTLS12就会失效。于是又不能请求这个网址了。

@Zheaoli
Copy link

Zheaoli commented Aug 19, 2021

@Zheaoli

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

@Zheaoli 这样做,这个网站确实可以了。因为这个网站同时支持http/2和http/1.1两种协议。如果有网站它只支持http/2,那这样做就不能访问网站了。

博主可以试一试这个网站:https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series 即使改了Cipher Suites,用net/http也无法请求成功。但Python的httpx就能轻松成功。

和 Chiper Suite 有关系,Go 很奇葩的在 TLS 1.2 的 Chiper Suite 里加入了三个 TLS 1.3 专属的 Suite TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_256_GCM_SHA384,特征太过于明显了,以及这个站对 UserAgent 对 Go Client 做了拦截

	myClient := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS12,
			},
		},
	}
	request, err := http.NewRequest("GET", "https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series/", nil)

你这样处理下就行

HTTP2 加上 ForceAttemptHTTP2: true 就行

加上ForceAttemptHTTP2: true 以后,上面使用的tls.VersionTLS12就会失效。于是又不能请求这个网址了。

I see, 我大概知道原因了。。这个站实际上 HTTP2 要求必须在 TLS1.3 ,但是 Go 的 TLS1.3 的特征又太过于明显。。。我看看怎么样绕过或者是给 Go 提个 PR。。。

@izackwu
Copy link
Owner Author

izackwu commented Nov 6, 2021

https://go.dev/blog/tls-cipher-suites

才发现 Go 官方最近(两个月前)写了篇文章讲新版本 Go 的 cipher suites 设计逻辑,有兴趣的话大家可以读一下

@yihong0618
Copy link

Cool

@Molin-L
Copy link

Molin-L commented Mar 3, 2022

我遇到的情况和你一模一样,不过原因是python自动走系统代理,go不会

@0fv
Copy link

0fv commented Apr 2, 2022

🤣遇到过类似的问题,爬的亚马逊网站,不过亚马逊更狠,判断了第一位密码套件,第一位是grease位,go都没实现

@saber3188
Copy link

惊呆了,我也碰到了这个问题,完全没往这方面想

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests