2022-08-19 07:42:57 +00:00
|
|
|
//go:build with_acme
|
|
|
|
|
|
|
|
package inbound
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/sagernet/certmagic"
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
|
|
"github.com/sagernet/sing-box/option"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
2022-08-19 10:05:26 +00:00
|
|
|
"github.com/sagernet/sing/common/logger"
|
2022-08-19 07:42:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type acmeWrapper struct {
|
|
|
|
ctx context.Context
|
|
|
|
cfg *certmagic.Config
|
|
|
|
domain []string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *acmeWrapper) Start() error {
|
|
|
|
return w.cfg.ManageSync(w.ctx, w.domain)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *acmeWrapper) Close() error {
|
|
|
|
w.cfg.Unmanage(w.domain)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-08-19 10:05:26 +00:00
|
|
|
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.Service, error) {
|
2022-08-19 07:42:57 +00:00
|
|
|
var acmeServer string
|
|
|
|
switch options.Provider {
|
|
|
|
case "", "letsencrypt":
|
|
|
|
acmeServer = certmagic.LetsEncryptProductionCA
|
|
|
|
case "zerossl":
|
|
|
|
acmeServer = certmagic.ZeroSSLProductionCA
|
|
|
|
default:
|
|
|
|
if !strings.HasPrefix(options.Provider, "https://") {
|
|
|
|
return nil, nil, E.New("unsupported acme provider: " + options.Provider)
|
|
|
|
}
|
|
|
|
acmeServer = options.Provider
|
|
|
|
}
|
|
|
|
var storage certmagic.Storage
|
|
|
|
if options.DataDirectory != "" {
|
|
|
|
storage = &certmagic.FileStorage{
|
|
|
|
Path: options.DataDirectory,
|
|
|
|
}
|
2022-08-19 10:05:26 +00:00
|
|
|
} else {
|
|
|
|
storage = certmagic.Default.Storage
|
2022-08-19 07:42:57 +00:00
|
|
|
}
|
2022-08-19 10:05:26 +00:00
|
|
|
config := &certmagic.Config{
|
2022-08-19 07:42:57 +00:00
|
|
|
DefaultServerName: options.DefaultServerName,
|
2022-08-19 10:05:26 +00:00
|
|
|
Storage: storage,
|
|
|
|
}
|
|
|
|
config.Issuers = []certmagic.Issuer{
|
|
|
|
certmagic.NewACMEIssuer(config, certmagic.ACMEIssuer{
|
|
|
|
CA: acmeServer,
|
|
|
|
Email: options.Email,
|
|
|
|
Agreed: true,
|
|
|
|
DisableHTTPChallenge: options.DisableHTTPChallenge,
|
|
|
|
DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
|
|
|
|
AltHTTPPort: int(options.AlternativeHTTPPort),
|
|
|
|
AltTLSALPNPort: int(options.AlternativeTLSPort),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
config = certmagic.New(certmagic.NewCache(certmagic.CacheOptions{
|
|
|
|
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
|
|
|
|
return config, nil
|
2022-08-19 07:42:57 +00:00
|
|
|
},
|
2022-08-19 10:05:26 +00:00
|
|
|
}), *config)
|
2022-08-19 07:42:57 +00:00
|
|
|
return config.TLSConfig(), &acmeWrapper{ctx, config, options.Domain}, nil
|
|
|
|
}
|