英文:
How to specify custom SSL roots with Go on Linux
问题
假设我正在使用一个第三方网络库,我不想修改它。该库使用标准的http.Request
接口来进行一些HTTPS请求。
我正在在一个嵌入式Linux实例上运行它,该实例没有安装证书根,并且我只能访问/data
目录。这意味着你会得到以下错误:
Get https://example.com/: x509: failed to load system roots and no roots provided
有没有办法实际上“提供”根证书?据我所知,Go在这些目录中查找X509证书根(参见):
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo等
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
}
var certDirectories = []string{
"/system/etc/security/cacerts", // Android
}
正如我所说,我无法访问这些目录,并且根证书池似乎是私有的,所以你无法追加它:
var (
once sync.Once
systemRoots *CertPool
)
func systemRootsPool() *CertPool {
once.Do(initSystemRoots)
return systemRoots
}
在Go中是否完全不可能实现这一点?
英文:
Suppose I'm using a third party network library that I don't want to modify. It uses the standard http.Request
interface to make some HTTPS requests.
I'm running it on an embedded Linux instance that doesn't have a certificate roots installed, and the only directory I can access is /data
. This means you get the error:
Get https://example.com/: x509: failed to load system roots and no roots provided
Is there any way to actually provide roots? As far as I can tell Go looks in these directories for X509 certificate roots (see also):
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
}
var certDirectories = []string{
"/system/etc/security/cacerts", // Android
}
As I said, I don't have access to those, and the root pool seems to be private so you can't append to it:
var (
once sync.Once
systemRoots *CertPool
)
func systemRootsPool() *CertPool {
once.Do(initSystemRoots)
return systemRoots
}
Is this just impossible with Go?
答案1
得分: 1
这样的代码似乎可以工作(实际上我只需要一个证书链,你可以通过在Firefox上点击SSL锁图标,选择更多信息,查看证书,详细信息,导出,将类型更改为“X509证书与链(PEM)”来获取)。
func initCerts() error {
certs := x509.NewCertPool()
pemData, err := ioutil.ReadFile("api.example.crt")
if err != nil {
return err
}
certs.AppendCertsFromPEM(pemData)
newTlsConfig := &tls.Config{}
newTlsConfig.RootCAs = certs
defaultTransport := http.DefaultTransport.(*http.Transport)
defaultTransport.TLSClientConfig = newTlsConfig
return nil
}
我不确定,但文档建议在使用任何TLS函数之前必须这样做,所以我将其放在了main()
的开头。
英文:
Something like this seems to work (I actually only need one certificate chain, which you can get from Firefox easily by clicking on the SSL lock icon, More Information, View Certificate, Details, Export, Change type to "X509 certificate with chain (PEM)".
func initCerts() error {
certs := x509.NewCertPool()
pemData, err := ioutil.ReadFile("api.example.crt")
if err != nil {
return err
}
certs.AppendCertsFromPEM(pemData)
newTlsConfig := &tls.Config{}
newTlsConfig.RootCAs = certs
defaultTransport := http.DefaultTransport.(*http.Transport)
defaultTransport.TLSClientConfig = newTlsConfig
return nil
}
I'm not certain, but the docs suggest that you must do that before using any TLS functions, so I put it at the start of my main()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论