Documentation
¶
Overview ¶
Package tlsconfig builds tls.Config values from PEM files and keeps the certificate fresh with a file-polling reloader.
Entry points:
- NewServerTLSFromFiles / NewClientTLSFromFiles build a tls.Config with MinVersion TLS 1.2 and ALPN "h2","http/1.1" from cert, key and optional CA bundle files. An optional "<cert basename>.ocsp" file next to the certificate is loaded as an OCSP staple if it is valid and not expired.
- KeypairReloader polls the cert/key files' modification times on a ticker and reloads them (also forced once per hour). Use GetKeypairFunc as tls.Config.GetCertificate on servers and GetClientCertificateFunc as tls.Config.GetClientCertificate on clients.
- NewHTTPTransportWithReloader returns an http.RoundTripper whose client certificate is swapped in on reload.
- UpdateCipherSuites maps cipher suite names to tls.Config.CipherSuites. The names come from tls.CipherSuites; suites in tls.InsecureCipherSuites and TLS 1.3 suites (not configurable in Go) are rejected.
Server example:
cfg, err := tlsconfig.NewServerTLSFromFiles(certFile, keyFile, trustedCAFile, clientCAFile, tls.VerifyClientCertIfGiven)
if err != nil {
return err
}
reloader, err := tlsconfig.NewKeypairReloader("", certFile, keyFile, 5*time.Minute)
if err != nil {
return err
}
defer reloader.Close()
cfg.GetCertificate = reloader.GetKeypairFunc()
cfg.Certificates = nil // use the callback even when a client omits SNI
Client example:
cfg, reloader, err := tlsconfig.NewClientTLSWithReloader(certFile, keyFile, rootsFile, 5*time.Minute)
if err != nil {
return err
}
defer reloader.Close()
client := &http.Client{Transport: &http.Transport{TLSClientConfig: cfg}}
An expired certificate is rejected during reload. If the current certificate later expires, the GetCertificate and GetClientCertificate callbacks return an error instead of serving it.
Index ¶
- func GetCipherSuite(s string) (uint16, bool)
- func LoadX509KeyPairWithOCSP(certFile, keyFile string) (*tls.Certificate, error)
- func NewClientTLSFromFiles(certFile, keyFile, rootsFile string) (*tls.Config, error)
- func NewServerTLSFromFiles(certFile, keyFile, rootsFile, caFile string, clientauthType tls.ClientAuthType) (*tls.Config, error)
- func UpdateCipherSuites(cfg *tls.Config, ss []string) error
- func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (*tls.Certificate, error)
- func X509KeyPairWithOCSP(certPEMBlock, keyPEMBlock, ocspStaple []byte) (*tls.Certificate, error)
- type HTTPTransport
- type KeypairReloader
- func (k *KeypairReloader) CertAndKeyFiles() (string, string)
- func (k *KeypairReloader) Close() error
- func (k *KeypairReloader) GetClientCertificateFunc() func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
- func (k *KeypairReloader) GetKeypairFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error)
- func (k *KeypairReloader) Keypair() *tls.Certificate
- func (k *KeypairReloader) LoadedAt() time.Time
- func (k *KeypairReloader) LoadedCount() uint32
- func (k *KeypairReloader) OnReload(f OnReloadFunc) *KeypairReloader
- func (k *KeypairReloader) Reload() error
- type OnReloadFunc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetCipherSuite ¶
GetCipherSuite returns the ID for a cipher suite name such as "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" and whether UpdateCipherSuites accepts it: the name must be a TLS 1.0-1.2 suite that crypto/tls implements and does not list in tls.InsecureCipherSuites.
func LoadX509KeyPairWithOCSP ¶
func LoadX509KeyPairWithOCSP(certFile, keyFile string) (*tls.Certificate, error)
LoadX509KeyPairWithOCSP reads a PEM certificate chain and private key from files and, if a file named "<certFile without extension>.ocsp" exists, uses its content as the OCSP staple (see X509KeyPairWithOCSP). A missing OCSP file is not an error. The certificate file may contain intermediates after the leaf.
func NewClientTLSFromFiles ¶
NewClientTLSFromFiles builds a client tls.Config (MinVersion TLS 1.2, ALPN h2/http1.1) from PEM files. rootsFile (optional) sets RootCAs; when empty the OS roots are used. certFile/keyFile (optional) set the client certificate for mutual TLS. The certificate is loaded once; use NewClientTLSWithReloader for rotation.
func NewServerTLSFromFiles ¶
func NewServerTLSFromFiles(certFile, keyFile, rootsFile, caFile string, clientauthType tls.ClientAuthType) (*tls.Config, error)
NewServerTLSFromFiles builds a server tls.Config (MinVersion TLS 1.2, ALPN h2/http1.1) from PEM files. certFile and keyFile are required; an OCSP staple is loaded from "<cert basename>.ocsp" if present. rootsFile (optional) is used as both RootCAs and ClientCAs; caFile (optional) overrides ClientCAs. When both are empty the OS roots are used and client certificates cannot be verified. clientauthType is applied as-is. CA files must contain at least one valid certificate. The returned config has no GetCertificate; pair it with KeypairReloader for rotation.
func UpdateCipherSuites ¶
UpdateCipherSuites sets cfg.CipherSuites, the enabled TLS 1.0-1.2 suites, from names. It restricts which suites can be negotiated, not their preference: Go ignores the order of tls.Config.CipherSuites, and PreferServerCipherSuites has no effect. An empty list is a no-op. Names are checked like GetCipherSuite; it returns an error, leaving cfg unchanged, if CipherSuites is already set or a name is unknown, insecure or a TLS 1.3 suite (TLS 1.3 suites are not configurable in Go).
func X509KeyPair ¶
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (*tls.Certificate, error)
X509KeyPair is X509KeyPairWithOCSP without an OCSP staple. Unlike tls.X509KeyPair it always populates Certificate.Leaf.
func X509KeyPairWithOCSP ¶
func X509KeyPairWithOCSP(certPEMBlock, keyPEMBlock, ocspStaple []byte) (*tls.Certificate, error)
X509KeyPairWithOCSP parses a PEM certificate chain and private key (PKCS#1, PKCS#8 or SEC1; RSA, ECDSA or Ed25519), verifies the key matches the leaf, and sets Certificate.Leaf. Expired certificates are accepted. If ocspStaple is given and the chain has an issuer, the staple is validated against the leaf: a Revoked status is an error, an expired or unparsable staple is dropped with a warning, and a good staple is set as Certificate.OCSPStaple.
Types ¶
type HTTPTransport ¶
type HTTPTransport struct {
// contains filtered or unexported fields
}
HTTPTransport is an http.RoundTripper that uses the current client certificate for each new TLS handshake. Create it with NewHTTPTransportWithReloader.
func NewHTTPTransportWithReloader ¶
func NewHTTPTransportWithReloader( certFile, keyFile, rootsFile string, checkInterval time.Duration, HTTPUserTransport *http.Transport) (*HTTPTransport, error)
NewHTTPTransportWithReloader returns an HTTPTransport with a fixed TLS client config that obtains the current certificate for each handshake. Reloads close idle connections so new dials use the new pair. The supplied transport is cloned before use. When HTTPUserTransport is nil a clone of http.DefaultTransport with 100 max idle/per-host connections is used. The caller must Close the returned transport to stop the reloader.
func (*HTTPTransport) Close ¶
func (t *HTTPTransport) Close() error
Close stops the certificate reloader and closes idle connections on the wrapped transport. It returns an error on a second call.
type KeypairReloader ¶
type KeypairReloader struct {
// contains filtered or unexported fields
}
KeypairReloader loads a TLS certificate/key pair from files and reloads it in a background goroutine when either file's modification time changes, or at least once per hour. Obtain the current pair via Keypair, GetKeypairFunc (server) or GetClientCertificateFunc (client). Close stops the goroutine. Expired certificates are rejected; a failed reload keeps the previous pair.
func NewClientTLSWithReloader ¶
func NewClientTLSWithReloader(certFile, keyFile, rootsFile string, checkInterval time.Duration) (*tls.Config, *KeypairReloader, error)
NewClientTLSWithReloader is NewClientTLSFromFiles plus a KeypairReloader wired as GetClientCertificate, polling every checkInterval. certFile and keyFile are required. The caller must Close the returned reloader.
func NewKeypairReloader ¶
func NewKeypairReloader(label, certPath, keyPath string, checkInterval time.Duration) (*KeypairReloader, error)
NewKeypairReloader loads the pair once (returning an error on failure) and starts a goroutine that polls the files every checkInterval. label is used in logs and defaults to the certificate file's base name. The initial load includes a fixed 100ms delay. The caller must call Close.
func (*KeypairReloader) CertAndKeyFiles ¶
func (k *KeypairReloader) CertAndKeyFiles() (string, string)
CertAndKeyFiles returns the certificate and key file paths being watched.
func (*KeypairReloader) Close ¶
func (k *KeypairReloader) Close() error
Close waits for an active reload, then signals the polling goroutine to stop without waiting for that goroutine to exit. It is nil-safe and returns an error on a second call.
func (*KeypairReloader) GetClientCertificateFunc ¶
func (k *KeypairReloader) GetClientCertificateFunc() func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
GetClientCertificateFunc returns a function suitable for tls.Config.GetClientCertificate that serves the current pair. It returns an error if the pair has expired.
func (*KeypairReloader) GetKeypairFunc ¶
func (k *KeypairReloader) GetKeypairFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error)
GetKeypairFunc returns a function suitable for tls.Config.GetCertificate that serves the current pair or returns an error if it has expired.
func (*KeypairReloader) Keypair ¶
func (k *KeypairReloader) Keypair() *tls.Certificate
Keypair returns the current pair, or nil on a nil receiver. It returns nil if the pair has expired.
func (*KeypairReloader) LoadedAt ¶
func (k *KeypairReloader) LoadedAt() time.Time
LoadedAt returns the UTC time of the last successful load.
func (*KeypairReloader) LoadedCount ¶
func (k *KeypairReloader) LoadedCount() uint32
LoadedCount returns the number of successful loads, including the first.
func (*KeypairReloader) OnReload ¶
func (k *KeypairReloader) OnReload(f OnReloadFunc) *KeypairReloader
OnReload registers a handler called after each reload that changed the certificate file's modification time. A nil handler is ignored.
func (*KeypairReloader) Reload ¶
func (k *KeypairReloader) Reload() error
Reload synchronously re-reads the pair from disk, retrying up to three times with a 100ms sleep before each attempt outside the write lock, and notifies OnReload handlers if the certificate's mtime changed. If another Reload is in progress, it waits for that one and then loads again, so a nil return means the pair was read after the call started. On failure the previous pair is kept. Reload returns an error after Close.
type OnReloadFunc ¶
type OnReloadFunc func(pair *tls.Certificate)
OnReloadFunc is invoked, in its own goroutine, with the newly loaded certificate each time the certificate file's modification time changes.