mirror of
				https://github.com/go-micro/go-micro.git
				synced 2025-10-30 23:27:41 +02:00 
			
		
		
		
	Implementation of certmagic as an ACME provider
This commit is contained in:
		| @@ -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() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user