For complex requirements—such as managing certificates differently based on their name—you must implement a custom Cache and Config.
In this pattern:
- Create a
certmagic.Cache with a GetConfigForCert callback. - Inside the callback, use
certmagic.New(cache, ...) to create a Config that is correctly associated with that cache. - Use
magic.ManageSync() to trigger certificate acquisition/renewal. - Use
magic.TLSConfig() or magic.GetCertificate to integrate with your existing TLS listeners. - If using the HTTP-01 challenge, wrap your HTTP multiplexer with
myACME.HTTPChallengeHandler(httpMux).
// First make a pointer to a Cache as we need to reference the same Cache in
// GetConfigForCert below.
var cache *certmagic.Cache
cache = certmagic.NewCache(certmagic.CacheOptions{
GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
// Here we use New to get a valid Config associated with the same cache.
// The provided Config is used as a template and is completed with
// any defaults that are set in the Default config.
return certmagic.New(cache, certmagic.Config{
// ...
}), nil
},
...
})
magic := certmagic.New(cache, certmagic.Config{
// any customizations you need go here
})
myACME := certmagic.NewACMEIssuer(magic, certmagic.ACMEIssuer{
CA: certmagic.LetsEncryptStagingCA,
Email: "you@yours.com",
Agreed: true,
// plus any other customizations you need
})
magic.Issuers = []certmagic.Issuer{myACME}
// this obtains certificates or renews them if necessary
err := magic.ManageSync(context.TODO(), []string{"example.com", "sub.example.com"})
if err != nil {
return err
}
// to use its certificates and solve the TLS-ALPN challenge,
// you can get a TLS config to use in a TLS listener!
tlsConfig := magic.TLSConfig()
// be sure to customize NextProtos if serving a specific
// application protocol after the TLS handshake, for example:
tlsConfig.NextProtos = append([]string{"h2", "http/1.1"}, tlsConfig.NextProtos...)
//// OR ////
// if you already have a TLS config you don't want to replace,
// we can simply set its GetCertificate field and append the
// TLS-ALPN challenge protocol to the NextProtos
myTLSConfig.GetCertificate = magic.GetCertificate
myTLSConfig.NextProtos = append(myTLSConfig.NextProtos, acmez.ACMETLS1Protocol)
// the HTTP challenge has to be handled by your HTTP server;
// if you don't have one, you should have disabled it earlier
// when you made the certmagic.Config
httpMux = myACME.HTTPChallengeHandler(httpMux)