mirror of
https://github.com/foxcpp/maddy.git
synced 2025-04-05 05:57:39 +03:00
Support for a subset of libdns providers is added. Some are enabled by default (assuming they are popular ones). AWS and Google Cloud SDKs take up extra 10 MiB of executable size. Only filesystem storage is supported as of now. Closes #3.
159 lines
3.7 KiB
Go
159 lines
3.7 KiB
Go
package acme
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/caddyserver/certmagic"
|
|
"github.com/foxcpp/maddy/framework/config"
|
|
modconfig "github.com/foxcpp/maddy/framework/config/module"
|
|
"github.com/foxcpp/maddy/framework/hooks"
|
|
"github.com/foxcpp/maddy/framework/log"
|
|
"github.com/foxcpp/maddy/framework/module"
|
|
)
|
|
|
|
const modName = "tls.loader.acme"
|
|
|
|
type Loader struct {
|
|
instName string
|
|
|
|
store certmagic.Storage
|
|
cache *certmagic.Cache
|
|
cfg *certmagic.Config
|
|
cancelManage context.CancelFunc
|
|
|
|
log log.Logger
|
|
}
|
|
|
|
func New(_, instName string, _, inlineArgs []string) (module.Module, error) {
|
|
if len(inlineArgs) != 0 {
|
|
return nil, fmt.Errorf("%s: no inline args expected", modName)
|
|
}
|
|
return &Loader{
|
|
instName: instName,
|
|
log: log.Logger{Name: modName},
|
|
}, nil
|
|
}
|
|
|
|
func (l *Loader) Init(cfg *config.Map) error {
|
|
var (
|
|
hostname string
|
|
extraNames []string
|
|
storePath string
|
|
caPath string
|
|
testCAPath string
|
|
email string
|
|
agreed bool
|
|
challenge string
|
|
provider certmagic.ACMEDNSProvider
|
|
)
|
|
cfg.Bool("debug", true, false, &l.log.Debug)
|
|
cfg.String("hostname", true, true, "", &hostname)
|
|
cfg.StringList("extra_names", false, false, nil, &extraNames)
|
|
cfg.String("store_path", false, false,
|
|
filepath.Join(config.StateDirectory, "acme"), &storePath)
|
|
cfg.String("ca", false, false,
|
|
certmagic.LetsEncryptStagingCA, &caPath)
|
|
cfg.String("test_ca", false, false,
|
|
certmagic.LetsEncryptStagingCA, &testCAPath)
|
|
cfg.String("email", false, false,
|
|
"", &email)
|
|
cfg.Bool("agreed", false, false, &agreed)
|
|
cfg.Enum("challenge", false, true,
|
|
[]string{"dns-01"}, "dns-01", &challenge)
|
|
cfg.Custom("dns", false, false, func() (interface{}, error) {
|
|
return nil, nil
|
|
}, func(m *config.Map, node config.Node) (interface{}, error) {
|
|
var p certmagic.ACMEDNSProvider
|
|
err := modconfig.ModuleFromNode("libdns", node.Args, node, m.Globals, &p)
|
|
return p, err
|
|
}, &provider)
|
|
if _, err := cfg.Process(); err != nil {
|
|
return err
|
|
}
|
|
|
|
cmLog := l.log.Zap()
|
|
|
|
l.store = &certmagic.FileStorage{Path: storePath}
|
|
l.cache = certmagic.NewCache(certmagic.CacheOptions{
|
|
Logger: cmLog,
|
|
GetConfigForCert: func(c certmagic.Certificate) (*certmagic.Config, error) {
|
|
return &certmagic.Config{
|
|
Storage: l.store,
|
|
Logger: cmLog,
|
|
}, nil
|
|
},
|
|
})
|
|
|
|
l.cfg = certmagic.New(l.cache, certmagic.Config{
|
|
Storage: l.store, // not sure if it is necessary to set these twice
|
|
Logger: cmLog,
|
|
})
|
|
mngr := certmagic.NewACMEManager(l.cfg, certmagic.ACMEManager{
|
|
Logger: cmLog,
|
|
CA: caPath,
|
|
Email: email,
|
|
Agreed: agreed,
|
|
})
|
|
|
|
switch challenge {
|
|
case "dns-01":
|
|
mngr.DisableTLSALPNChallenge = true
|
|
mngr.DisableHTTPChallenge = true
|
|
if provider == nil {
|
|
return fmt.Errorf("tls.loader.acme: dns-01 challenge requires a configured DNS provider")
|
|
}
|
|
mngr.DNS01Solver = &certmagic.DNS01Solver{
|
|
DNSProvider: provider,
|
|
}
|
|
default:
|
|
return fmt.Errorf("tls.loader.acme: challenge not supported")
|
|
}
|
|
l.cfg.Issuers = []certmagic.Issuer{mngr}
|
|
|
|
if module.NoRun {
|
|
return nil
|
|
}
|
|
|
|
manageCtx, cancelManage := context.WithCancel(context.Background())
|
|
err := l.cfg.ManageAsync(manageCtx, append([]string{hostname}, extraNames...))
|
|
if err != nil {
|
|
cancelManage()
|
|
return err
|
|
}
|
|
l.cancelManage = cancelManage
|
|
|
|
return nil
|
|
}
|
|
|
|
func (l *Loader) ConfigureTLS(c *tls.Config) error {
|
|
c.GetCertificate = l.cfg.GetCertificate
|
|
return nil
|
|
}
|
|
|
|
func (l *Loader) Close() error {
|
|
l.cancelManage()
|
|
l.cache.Stop()
|
|
return nil
|
|
}
|
|
|
|
func (l *Loader) Name() string {
|
|
return modName
|
|
}
|
|
|
|
func (l *Loader) InstanceName() string {
|
|
return l.instName
|
|
}
|
|
|
|
func init() {
|
|
hooks.AddHook(hooks.EventShutdown, func() {
|
|
certmagic.CleanUpOwnLocks(nil)
|
|
})
|
|
}
|
|
|
|
func init() {
|
|
var _ module.TLSLoader = &Loader{}
|
|
module.Register(modName, New)
|
|
}
|