aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorCristian Le <github@lecris.me>2022-02-08 14:45:35 +0900
committerGitHub <noreply@github.com>2022-02-08 13:45:35 +0800
commit60f203385e6f27fae47f3cc8c5d71309f4fd88dc (patch)
tree3be2a41b96ab7ab0419e0e63676a5fc16e20cd7d /cmd
parenta60e8be8d15e90a44f2a746a4e8d81a81e03d2db (diff)
downloadgitea-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.go19
-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
}