tls_acme.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //go:build with_acme
  2. package inbound
  3. import (
  4. "context"
  5. "crypto/tls"
  6. "strings"
  7. "github.com/sagernet/certmagic"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/option"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. )
  12. type acmeWrapper struct {
  13. ctx context.Context
  14. cfg *certmagic.Config
  15. domain []string
  16. }
  17. func (w *acmeWrapper) Start() error {
  18. return w.cfg.ManageSync(w.ctx, w.domain)
  19. }
  20. func (w *acmeWrapper) Close() error {
  21. w.cfg.Unmanage(w.domain)
  22. return nil
  23. }
  24. func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Config, adapter.Service, error) {
  25. var acmeServer string
  26. switch options.Provider {
  27. case "", "letsencrypt":
  28. acmeServer = certmagic.LetsEncryptProductionCA
  29. case "zerossl":
  30. acmeServer = certmagic.ZeroSSLProductionCA
  31. default:
  32. if !strings.HasPrefix(options.Provider, "https://") {
  33. return nil, nil, E.New("unsupported acme provider: " + options.Provider)
  34. }
  35. acmeServer = options.Provider
  36. }
  37. var storage certmagic.Storage
  38. if options.DataDirectory != "" {
  39. storage = &certmagic.FileStorage{
  40. Path: options.DataDirectory,
  41. }
  42. } else {
  43. storage = certmagic.Default.Storage
  44. }
  45. config := &certmagic.Config{
  46. DefaultServerName: options.DefaultServerName,
  47. Storage: storage,
  48. }
  49. config.Issuers = []certmagic.Issuer{
  50. certmagic.NewACMEIssuer(config, certmagic.ACMEIssuer{
  51. CA: acmeServer,
  52. Email: options.Email,
  53. Agreed: true,
  54. DisableHTTPChallenge: options.DisableHTTPChallenge,
  55. DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
  56. AltHTTPPort: int(options.AlternativeHTTPPort),
  57. AltTLSALPNPort: int(options.AlternativeTLSPort),
  58. }),
  59. }
  60. config = certmagic.New(certmagic.NewCache(certmagic.CacheOptions{
  61. GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
  62. return config, nil
  63. },
  64. }), *config)
  65. return config.TLSConfig(), &acmeWrapper{ctx, config, options.Domain}, nil
  66. }