How to specify custom SSL roots with Go on Linux

huangapple go评论81阅读模式
英文:

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().

huangapple
  • 本文由 发表于 2015年9月17日 21:17:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/32631289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定