Administrator
Administrator
Published on 2025-01-14 / 23 Visits
0
0

记一次HTTP请求403的解决办法

情况总结

情况A:全部请求都是403

情况B:程序刚运行的开头几次请求是403,然后大部分是正常(穿插一些403)

情况C:全部正常

前言

昨天遇到一个问题,用Go写的程序访问HTTPS,在请求头、COOKIES都是正确的情况下,返回403代码。于是开始研究TLS(SSL的版本)、证书、加密套件、密钥交换(椭圆曲线).......,最终在密钥交换问题这里解决了

过程

openssl安装

最早是情况A,用openssl执行:

openssl s_client -connect 域名:443

看到TLS版本是1.3,加密套件是TLS_AES_256_GCM_SHA384,就先配置了tls:

    cert, err := x509.SystemCertPool() //加载系统根证书
	tlsConfig := &tls.Config{
		RootCAs:            cert,
		InsecureSkipVerify: false,
		MinVersion:         tls.VersionTLS13,
		MaxVersion:         tls.VersionTLS13,
		CipherSuites: []uint16{
			tls.TLS_AES_256_GCM_SHA384,
		},
	}

这样改之后,在我本机是情况C。于是放到服务器(Windows Server2022)运行时出现情况B

看到浏览器里密钥交换是X25519MLKEM768,Golang的tls中没有这个,只有X25519,在github上找到了有X25519MLKEM768选项的tls包:Github地址

将中src/crypto下的所有文件解压替换到go SDK的crypto标准库里面

服务器签名是ECDSA with SHA-256,于是tls配置变成了:

    cert, err := x509.SystemCertPool() //加载系统根证书
	tlsConfig := &tls.Config{
		RootCAs:            cert,
		InsecureSkipVerify: false,
		MinVersion:         tls.VersionTLS13,
		MaxVersion:         tls.VersionTLS13,
		CipherSuites: []uint16{
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		},
        CurvePreferences: []tls.CurveID{
			tls.X25519MLKEM768,
		},
	}

替换了标准库后第一次运行会报错缺少依赖,打印多条go get命令,依次执行即可)依然不行,就连本地都出403了,既然是这样那说明就是curve导致的,然后又把crypto标准库还原。

在go中tls的CurvePerferences属性默认是这样的:

var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}

后面三个分别对应名称:SecP256r1、SecP384r1、SecP521r1

在本地运行时每次只写一个,依次尝试只有CurveP256完全正常运行,其它的都会403,到此就齐活了。

后面发现把加密套件参数CipherSuites去掉不写,也可以正常运行。

番外

用wireshark查看握手信息,左上角过滤IP(对方服务器IP),不然请求太多,ClientHello就是握手


Comment