2020-05-13 22:00:13 +08:00
|
|
|
// Package certmagic is the ACME provider from github.com/caddyserver/certmagic
|
2019-10-11 16:25:15 +01:00
|
|
|
package certmagic
|
|
|
|
|
|
|
|
import (
|
2020-02-15 15:10:26 +00:00
|
|
|
"crypto/tls"
|
2020-09-05 02:43:16 +03:00
|
|
|
"fmt"
|
2019-10-17 16:31:02 +01:00
|
|
|
"math/rand"
|
2019-10-11 16:25:15 +01:00
|
|
|
"net"
|
2019-10-17 16:31:02 +01:00
|
|
|
"time"
|
2019-10-11 16:25:15 +01:00
|
|
|
|
2020-05-13 22:00:13 +08:00
|
|
|
"github.com/caddyserver/certmagic"
|
2020-08-19 17:47:17 +03:00
|
|
|
"github.com/unistack-org/micro/v3/api/server/acme"
|
2019-10-11 16:25:15 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type certmagicProvider struct {
|
2019-10-23 22:15:15 +01:00
|
|
|
opts acme.Options
|
2019-10-11 16:25:15 +01:00
|
|
|
}
|
|
|
|
|
2020-02-15 15:10:26 +00:00
|
|
|
// TODO: set self-contained options
|
|
|
|
func (c *certmagicProvider) setup() {
|
2020-05-13 22:00:13 +08:00
|
|
|
certmagic.DefaultACME.CA = c.opts.CA
|
2019-10-11 16:25:15 +01:00
|
|
|
if c.opts.ChallengeProvider != nil {
|
|
|
|
// Enabling DNS Challenge disables the other challenges
|
2020-05-13 22:00:13 +08:00
|
|
|
certmagic.DefaultACME.DNSProvider = c.opts.ChallengeProvider
|
2019-10-11 16:25:15 +01:00
|
|
|
}
|
|
|
|
if c.opts.OnDemand {
|
|
|
|
certmagic.Default.OnDemand = new(certmagic.OnDemandConfig)
|
|
|
|
}
|
2019-10-17 16:31:02 +01:00
|
|
|
if c.opts.Cache != nil {
|
|
|
|
// already validated by new()
|
|
|
|
certmagic.Default.Storage = c.opts.Cache.(certmagic.Storage)
|
|
|
|
}
|
|
|
|
// If multiple instances of the provider are running, inject some
|
|
|
|
// randomness so they don't collide
|
2020-05-13 22:00:13 +08:00
|
|
|
// RenewalWindowRatio [0.33 - 0.50)
|
2019-10-17 16:31:02 +01:00
|
|
|
rand.Seed(time.Now().UnixNano())
|
2020-05-30 11:00:43 +01:00
|
|
|
randomRatio := float64(rand.Intn(17)+33) * 0.01
|
2020-05-13 22:00:13 +08:00
|
|
|
certmagic.Default.RenewalWindowRatio = randomRatio
|
2020-02-15 15:10:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *certmagicProvider) Listen(hosts ...string) (net.Listener, error) {
|
|
|
|
c.setup()
|
|
|
|
return certmagic.Listen(hosts)
|
|
|
|
}
|
2019-10-17 16:31:02 +01:00
|
|
|
|
2020-02-15 15:10:26 +00:00
|
|
|
func (c *certmagicProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
|
|
|
c.setup()
|
|
|
|
return certmagic.TLS(hosts)
|
2019-10-11 16:25:15 +01:00
|
|
|
}
|
|
|
|
|
2020-09-05 02:43:16 +03:00
|
|
|
func (p *certmagicProvider) Init(opts ...acme.Option) error {
|
|
|
|
if p.opts.Cache != nil {
|
|
|
|
if _, ok := p.opts.Cache.(certmagic.Storage); !ok {
|
|
|
|
return fmt.Errorf("ACME: cache provided doesn't implement certmagic's Storage interface")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-12 13:41:30 +00:00
|
|
|
// NewProvider returns a certmagic provider
|
2020-02-15 15:10:26 +00:00
|
|
|
func NewProvider(options ...acme.Option) acme.Provider {
|
2019-10-23 22:15:15 +01:00
|
|
|
opts := acme.DefaultOptions()
|
|
|
|
|
|
|
|
for _, o := range options {
|
|
|
|
o(&opts)
|
2019-10-11 16:25:15 +01:00
|
|
|
}
|
2019-10-23 22:15:15 +01:00
|
|
|
|
2019-10-11 16:25:15 +01:00
|
|
|
return &certmagicProvider{
|
2019-10-23 22:15:15 +01:00
|
|
|
opts: opts,
|
2019-10-11 16:25:15 +01:00
|
|
|
}
|
|
|
|
}
|