Mutual TLS
Mutual TLS authentication between nodes
Standard TLS provides server authentication - the client verifies the server's certificate. Mutual TLS (mTLS) adds client authentication - both sides present and verify certificates. Only clients with certificates signed by a trusted CA can connect.
Configuration
func startSecureNode(name string) (gen.Node, error) {
// Load node certificate (signed by cluster CA)
cert, err := tls.LoadX509KeyPair(
fmt.Sprintf("%s.pem", name),
fmt.Sprintf("%s-key.pem", name),
)
if err != nil {
return nil, err
}
// Load cluster CA
caCert, err := os.ReadFile("cluster-ca.pem")
if err != nil {
return nil, err
}
caPool := x509.NewCertPool()
caPool.AppendCertsFromPEM(caCert)
certManager := gen.CreateCertAuthManager(cert)
certManager.SetClientCAs(caPool) // verify incoming
certManager.SetClientAuth(tls.RequireAndVerifyClientCert) // require client cert
certManager.SetRootCAs(caPool) // verify outgoing
return ergo.StartNode(gen.Atom(name), gen.NodeOptions{
CertManager: certManager,
})
}NodeOptions.CertManager is used for:
Default acceptor (created automatically on port 15000)
All outgoing connections
To override per-acceptor, use AcceptorOptions.CertManager.
CertAuthManager
gen.CertAuthManager extends CertManager with CA pool and authentication settings:
Server-side settings:
ClientCAs
CA pool to verify client certificates
ClientAuth
How strictly to enforce client certificates
ClientAuth values:
tls.NoClientCert
Don't request client certificate (default)
tls.RequestClientCert
Request but don't require
tls.RequireAnyClientCert
Require certificate, don't verify against CA
tls.VerifyClientCertIfGiven
Verify against CA if provided
tls.RequireAndVerifyClientCert
Require and verify against CA
Client-side settings:
RootCAs
CA pool to verify server certificates
ServerName
Server name for SNI (if different from host)
Runtime Certificate Rotation
Certificates can be rotated without restart:
New connections use the updated certificate. Existing connections keep their original certificate.
CA pools and ClientAuth are fixed at startup. Restart the node to change these settings.
To use different certificates for specific destinations, see Static Routes.
Troubleshooting
Connection rejected with certificate error
Verify the client certificate is signed by a CA in the server's ClientCAs pool. Check certificate expiration dates.
Server certificate verification failed
The server's certificate must be signed by a CA in the client's RootCAs pool. For development, disable verification with NetworkOptions.InsecureSkipVerify: true.
SNI mismatch
Set ServerName on the client's CertAuthManager if the certificate's Common Name doesn't match the connection address.
Certificate rotation not taking effect
Updates apply to new connections only. Close existing connections to force reconnection with new certificate.
CA pool changes not taking effect
CA pools are fixed at startup. Restart the node to apply changes.
Last updated
