<h1 style="color: #2c3e50; border-left: 4px solid #3498db; padding-left: 15px; margin: 20px 0;">golang操作华为防火墙ACL实现远程启停2---寻找真相</h1>
<h2 style="color: #34495e; margin: 20px 0 15px;">一、摸索</h2>
<p style="line-height: 1.6; margin-bottom: 15px;">上文提到用go开发的程序对接防火墙api时出现<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">remote error: tls: handshake failure</code>,虽然通过调低防火墙api security加密算法强度解决了,但是总感觉怪怪的。因为用python和curl简单测试了下,都能正常访问,难道golang还落后了?</p>
<p style="line-height: 1.6; margin-bottom: 15px;">为了搞清楚原因,先是设置了<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">InsecureSkipVerify</code>,测试没效果;再指定tls版本<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">MaxVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12</code>,也没效果;改写<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">VerifyPeerCertificate</code>,直接return nil,测试还是没效果。</p>
<p style="line-height: 1.6; margin-bottom: 15px;">怀疑go需要手动指定证书,把cer转成pem后<strong>(用openssl可以转)</strong>,加载到RootCAs,测试还是不行。</p>
<pre style="background: #2c3e50; color: #ecf0f1; padding: 15px; border-radius: 5px; overflow-x: auto; font-family: 'Courier New', monospace; margin: 15px 0;">
// certPool := x509.NewCertPool()
//pem文件转换 openssl x509 -inform der -in cer2.cer -out demo2.pem
// bCert, _ := os.ReadFile("demo2.pem")
// bOk := certPool.AppendCertsFromPEM(bCert)
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
MaxVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12
VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
return nil
},
//RootCAs:certPool
},
}
</pre>
<h2 style="color: #34495e; margin: 25px 0 15px;">二、意外的成功</h2>
<p style="line-height: 1.6; margin-bottom: 15px;">正当一愁莫展时,随手打开了fiddler抓包工具,然后抓了python demo程序发起的https请求,数据正常的返回,看不到什么特别的请求参数。随后改了防火墙的一些设置,还有go项目里的代码也不知改了哪里,反正再次run时,竟然成功了!</p>
<div style="background: #d4edda; padding: 15px; border-radius: 5px; border-left: 4px solid #28a745; margin: 15px 0;">
<p style="margin-bottom: 0;"><strong>意外惊喜:</strong>幸福来的太突然了,我都不知咋回事?很好奇是哪一行代码写错了,于是我把代码重写了一遍,只启用了<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">InsecureSkipVerify</code>,其他参数都没加上,测试也成功了。</p>
</div>
<p style="line-height: 1.6; margin-bottom: 15px;">感觉不对劲,干脆把防火墙也重启了<strong>(后面改动的配置没保存)</strong>,此后再测试,请求仍然成功,感觉非常意外,但又找不到具体原因。夜已深,只好先睡。。。</p>
<h2 style="color: #34495e; margin: 25px 0 15px;">三、罪魁祸首竟是它</h2>
<p style="line-height: 1.6; margin-bottom: 15px;">第二天起来再测试,发现仍然能正常访问,心里有点慌,这神操作有点懵啊。于是再重新建一个测试项目,代码又重写了一遍,好家伙,怎么折腾都行了,此前可是怎么折腾都不行呢!正晕乎乎的不知所以时,无意间点开了fiddler,发现fiddler一直开着的,于是随手把它关了。然后继续测试代码,奇迹出现了,这回竟然出现了久违的<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">tls: handshake failure</code>报错。</p>
<div style="background: #fff3cd; padding: 15px; border-radius: 5px; border-left: 4px solid #ffc107; margin: 15px 0;">
<p style="margin-bottom: 0;"><strong>真相大白:</strong>此时终于知道为什么了,使用fiddler抓包,相当于设置了代理,而且fiddler能自动信任证书,所以开启抓包后go的请求能正常访问api接口。</p>
</div>
<p style="line-height: 1.6; margin-bottom: 15px;">排查工作似乎又回到了原点,好在这时我已经深深的怀疑golang的net/http包有问题。</p>
<h2 style="color: #34495e; margin: 25px 0 15px;">四、柳暗花明</h2>
<p style="line-height: 1.6; margin-bottom: 15px;">即然fiddler也分析不了TLS协议握手过程,那就上Wireshark吧。启动抓包,先golang程序发起请求,然后python的程序请求,Wireshark里过滤感兴趣的数据包<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">tcp.port==xxxx && ip.dst=xxxx</code>。对比两者发起的Client hello发现golang的cipher suites比python少了很多算法。</p>
<div style="text-align: center; margin: 20px 0;">
<div style="display: inline-block; margin: 10px;">
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
<div style="font-style: italic; color: #666; margin-bottom: 10px;">Golang Client Hello</div>
<div style="padding: 20px; background: #e9ecef; border-radius: 5px;">
image-20230824004348171
</div>
</div>
</div>
<div style="display: inline-block; margin: 10px;">
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
<div style="font-style: italic; color: #666; margin-bottom: 10px;">Python Client Hello</div>
<div style="padding: 20px; background: #e9ecef; border-radius: 5px;">
image-20230824005435130
</div>
</div>
</div>
</div>
<p style="line-height: 1.6; margin-bottom: 15px;">会不会是某个算法漏了,导致加密方式不一致呢?于是我在<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">tls.Config</code>里加上<code style="background: #f8f9fa; padding: 2px 5px; border-radius: 3px;">CipherSuites</code>,把wireshark里抓取到的加密算法对应的常量值都放进数组里,测试后发现还是老样子的报错。心里很不甘心,用wireshark抓包,发现即使手动加上了28个算法常量,请求时仍然只有16个。</p>
<pre style="background: #2c3e50; color: #ecf0f1; padding: 15px; border-radius: 5px; overflow-x: auto; font-family: 'Courier New', monospace; margin: 15px 0;">
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
MaxVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{ .....}
}
</pre>
<p style="line-height: 1.6; margin-bottom: 15px;">到底少了哪些算法呢?我在tls包找到cipher_suites.go源码,tls加密用到的算法都在里面了,但是仔细数了下,发现确实比python的少了很多。经过一个个对比,发现少的部分算法都是TLS_DHE开头的。百度后了解到DHE算法效率低且比较占用资源,在github上也有人建议增加dhe支持,但是没被官方支持!</p>
<div style="background: #e3f2fd; padding: 15px; border-radius: 5px; margin: 15px 0;">
<p style="margin-bottom: 10px;"><strong>解决方案:</strong>用别人写的<a href="https://github.com/mordyovits/golang-crypto-tls" target="_blank" style="color: #3498db;">https://github.com/mordyovits/golang-crypto-tls</a></p>
<p style="margin-bottom: 0;">具体我没测试,对于我来说,我只是想找出真相而已,不想继续在这小项目上浪费太多时间了。</p>
</div>
<div style="text-align: center; margin: 20px 0;">
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px; display: inline-block;">
<div style="font-style: italic; color: #666; margin-bottom: 10px;">TLS参数对比</div>
<div style="padding: 20px; background: #e9ecef; border-radius: 5px;">
image-20230824010700069
</div>
</div>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 5px; border-left: 4px solid #6c757d; margin: 20px 0;">
<p style="margin-bottom: 5px;"><strong>参考文档:</strong></p>
<p style="margin-bottom: 0;">Transport Layer Security (TLS) Parameters 传输层安全TLS参数</p>
<p style="margin-bottom: 0;"><a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xml" target="_blank" style="color: #3498db;">https://www.iana.org/assignments/tls-parameters/tls-parameters.xml</a></p>
</div>