diff options
author | Cristian Le <github@lecris.me> | 2022-02-08 14:45:35 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-08 13:45:35 +0800 |
commit | 60f203385e6f27fae47f3cc8c5d71309f4fd88dc (patch) | |
tree | 3be2a41b96ab7ab0419e0e63676a5fc16e20cd7d /cmd | |
parent | a60e8be8d15e90a44f2a746a4e8d81a81e03d2db (diff) | |
download | gitea-60f203385e6f27fae47f3cc8c5d71309f4fd88dc.tar.gz gitea-60f203385e6f27fae47f3cc8c5d71309f4fd88dc.zip |
Support custom ACME provider (#18340)
* Added ACMECAURL option to support custom ACME provider. Closes #18306
* Refactor setting.go https settings, renamed options and variables, and documented app.example.ini
* Refactored runLetsEncrypt to runACME
* Improved documentation
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/web.go | 19 | ||||
-rw-r--r-- | cmd/web_acme.go (renamed from cmd/web_letsencrypt.go) | 43 |
2 files changed, 48 insertions, 14 deletions
diff --git a/cmd/web.go b/cmd/web.go index 9a8d9dfa73..710c12775f 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -222,18 +222,19 @@ func listen(m http.Handler, handleRedirector bool) error { } err = runHTTP("tcp", listenAddr, "Web", m) case setting.HTTPS: - if setting.EnableLetsEncrypt { - err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, m) + if setting.EnableAcme { + err = runACME(listenAddr, m) break - } - if handleRedirector { - if setting.RedirectOtherPort { - go runHTTPRedirector() - } else { - NoHTTPRedirector() + } else { + if handleRedirector { + if setting.RedirectOtherPort { + go runHTTPRedirector() + } else { + NoHTTPRedirector() + } } + err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m) } - err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m) case setting.FCGI: if handleRedirector { NoHTTPRedirector() diff --git a/cmd/web_letsencrypt.go b/cmd/web_acme.go index 517d71f017..9a04274db5 100644 --- a/cmd/web_letsencrypt.go +++ b/cmd/web_acme.go @@ -5,7 +5,11 @@ package cmd import ( + "crypto/x509" + "encoding/pem" + "fmt" "net/http" + "os" "strconv" "strings" @@ -16,7 +20,25 @@ import ( "github.com/caddyserver/certmagic" ) -func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error { +func getCARoot(path string) (*x509.CertPool, error) { + r, err := os.ReadFile(path) + if err != nil { + return nil, err + } + block, _ := pem.Decode(r) + if block == nil { + return nil, fmt.Errorf("no PEM found in the file %s", path) + } + caRoot, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + certPool := x509.NewCertPool() + certPool.AddCert(caRoot) + return certPool, nil +} + +func runACME(listenAddr string, m http.Handler) error { // If HTTP Challenge enabled, needs to be serving on port 80. For TLSALPN needs 443. // Due to docker port mapping this can't be checked programmatically // TODO: these are placeholders until we add options for each in settings with appropriate warning @@ -33,10 +55,21 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) } magic := certmagic.NewDefault() - magic.Storage = &certmagic.FileStorage{Path: directory} + magic.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory} + // Try to use private CA root if provided, otherwise defaults to system's trust + var certPool *x509.CertPool + if setting.AcmeCARoot != "" { + var err error + certPool, err = getCARoot(setting.AcmeCARoot) + if err != nil { + log.Warn("Failed to parse CA Root certificate, using default CA trust: %v", err) + } + } myACME := certmagic.NewACMEManager(magic, certmagic.ACMEManager{ - Email: email, - Agreed: setting.LetsEncryptTOS, + CA: setting.AcmeURL, + TrustedRoots: certPool, + Email: setting.AcmeEmail, + Agreed: setting.AcmeTOS, DisableHTTPChallenge: !enableHTTPChallenge, DisableTLSALPNChallenge: !enableTLSALPNChallenge, ListenHost: setting.HTTPAddr, @@ -47,7 +80,7 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) magic.Issuers = []certmagic.Issuer{myACME} // this obtains certificates or renews them if necessary - err := magic.ManageSync(graceful.GetManager().HammerContext(), []string{domain}) + err := magic.ManageSync(graceful.GetManager().HammerContext(), []string{setting.Domain}) if err != nil { return err } |