Implementation of certmagic as an ACME provider
This commit is contained in:
parent
9bd96d4cc1
commit
723c17fdd7
@ -4,9 +4,13 @@ package acme
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
"github.com/go-acme/lego/v3/challenge"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrProviderNotImplemented can be returned when attempting to
|
||||
// instantiate an unimplemented provider
|
||||
ErrProviderNotImplemented = errors.New("Provider not implemented")
|
||||
)
|
||||
|
||||
@ -14,3 +18,68 @@ var (
|
||||
type Provider interface {
|
||||
NewListener(...string) (net.Listener, error)
|
||||
}
|
||||
|
||||
// The Let's Encrypt ACME endpoints
|
||||
const (
|
||||
LetsEncryptStagingCA = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
)
|
||||
|
||||
// Option (or Options) are passed to New() to configure providers
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options represents various options you can present to ACME providers
|
||||
type Options struct {
|
||||
// AcceptTLS must be set to true to indicate that you have read your
|
||||
// provider's terms of service.
|
||||
AcceptToS bool
|
||||
// CA is the CA to use
|
||||
CA string
|
||||
// ChallengeProvider is a go-acme/lego challenge provider. Set this if you
|
||||
// want to use DNS Challenges. Otherwise, tls-alpn-01 will be used
|
||||
ChallengeProvider challenge.Provider
|
||||
// Issue certificates for domains on demand. Otherwise, certs will be
|
||||
// retrieved / issued on start-up.
|
||||
OnDemand bool
|
||||
// TODO
|
||||
Cache interface{}
|
||||
}
|
||||
|
||||
// AcceptTLS indicates whether you accept your CA's terms of service
|
||||
func AcceptTLS(b bool) Option {
|
||||
return func(o *Options) {
|
||||
o.AcceptToS = b
|
||||
}
|
||||
}
|
||||
|
||||
// CA sets the CA of an acme.Options
|
||||
func CA(CA string) Option {
|
||||
return func(o *Options) {
|
||||
o.CA = CA
|
||||
}
|
||||
}
|
||||
|
||||
// ChallengeProvider sets the Challenge provider of an acme.Options
|
||||
// if set, it enables the DNS challenge, otherwise tls-alpn-01 will be used.
|
||||
func ChallengeProvider(p challenge.Provider) Option {
|
||||
return func(o *Options) {
|
||||
o.ChallengeProvider = p
|
||||
}
|
||||
}
|
||||
|
||||
// OnDemand enables on-demand certificate issuance. Not recommended for use
|
||||
// with the DNS challenge, as the first connection may be very slow.
|
||||
func OnDemand(b bool) Option {
|
||||
return func(o *Options) {
|
||||
o.OnDemand = b
|
||||
}
|
||||
}
|
||||
|
||||
// Default uses the Let's Encrypt Production CA, with DNS Challenge disabled.
|
||||
func Default() []Option {
|
||||
return []Option{
|
||||
AcceptTLS(true),
|
||||
CA(LetsEncryptProductionCA),
|
||||
OnDemand(true),
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Package autocert is the ACME interpreter from golang.org/x/crypto/acme/autocert
|
||||
// Package autocert is the ACME provider from golang.org/x/crypto/acme/autocert
|
||||
// This provider does not take any config.
|
||||
package autocert
|
||||
|
||||
import (
|
||||
|
42
api/server/acme/certmagic/certmagic.go
Normal file
42
api/server/acme/certmagic/certmagic.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Package certmagic is the ACME provider from github.com/mholt/certmagic
|
||||
package certmagic
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/mholt/certmagic"
|
||||
|
||||
"github.com/micro/go-micro/api/server/acme"
|
||||
)
|
||||
|
||||
type certmagicProvider struct {
|
||||
opts *acme.Options
|
||||
}
|
||||
|
||||
func (c *certmagicProvider) NewListener(ACMEHosts ...string) (net.Listener, error) {
|
||||
if c.opts.ChallengeProvider != nil {
|
||||
// Enabling DNS Challenge disables the other challenges
|
||||
certmagic.Default.DNSProvider = c.opts.ChallengeProvider
|
||||
}
|
||||
if c.opts.OnDemand {
|
||||
certmagic.Default.OnDemand = new(certmagic.OnDemandConfig)
|
||||
}
|
||||
return certmagic.Listen(ACMEHosts)
|
||||
}
|
||||
|
||||
// New returns a certmagic provider
|
||||
func New(options ...acme.Option) acme.Provider {
|
||||
o := &acme.Options{}
|
||||
if len(options) == 0 {
|
||||
for _, op := range acme.Default() {
|
||||
op(o)
|
||||
}
|
||||
} else {
|
||||
for _, op := range options {
|
||||
op(o)
|
||||
}
|
||||
}
|
||||
return &certmagicProvider{
|
||||
opts: o,
|
||||
}
|
||||
}
|
37
api/server/acme/certmagic/certmagic_test.go
Normal file
37
api/server/acme/certmagic/certmagic_test.go
Normal file
@ -0,0 +1,37 @@
|
||||
package certmagic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-acme/lego/v3/providers/dns/cloudflare"
|
||||
"github.com/micro/go-micro/api/server/acme"
|
||||
)
|
||||
|
||||
func TestCertMagic(t *testing.T) {
|
||||
l, err := New().NewListener()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
l.Close()
|
||||
|
||||
c := cloudflare.NewDefaultConfig()
|
||||
c.AuthEmail = ""
|
||||
c.AuthKey = ""
|
||||
c.AuthToken = "test"
|
||||
c.ZoneToken = "test"
|
||||
|
||||
p, err := cloudflare.NewDNSProviderConfig(c)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
l, err = New(acme.AcceptTLS(true),
|
||||
acme.CA(acme.LetsEncryptStagingCA),
|
||||
acme.ChallengeProvider(p),
|
||||
).NewListener()
|
||||
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
l.Close()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user