diff options
author | techknowlogick <techknowlogick@gitea.io> | 2021-01-24 18:37:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-25 01:37:35 +0200 |
commit | d2ea21d0d8103986b2ce53c17b7b99b1ce6828b0 (patch) | |
tree | 802ea1a787b1f6ef08b18524d3818115a750f0eb /cmd | |
parent | bc05ddc0ebd6fdc826ef2beec99304bac60ddd8a (diff) | |
download | gitea-d2ea21d0d8103986b2ce53c17b7b99b1ce6828b0.tar.gz gitea-d2ea21d0d8103986b2ce53c17b7b99b1ce6828b0.zip |
Use caddy's certmagic library for extensible/robust ACME handling (#14177)
* use certmagic for more extensible/robust ACME cert handling
* accept TOS based on config option
Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/web.go | 31 | ||||
-rw-r--r-- | cmd/web_letsencrypt.go | 69 |
2 files changed, 69 insertions, 31 deletions
diff --git a/cmd/web.go b/cmd/web.go index 063e41c946..2e8c45a76e 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -22,7 +22,6 @@ import ( context2 "github.com/gorilla/context" "github.com/urfave/cli" - "golang.org/x/crypto/acme/autocert" ini "gopkg.in/ini.v1" ) @@ -72,36 +71,6 @@ func runHTTPRedirector() { } } -func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error { - certManager := autocert.Manager{ - Prompt: autocert.AcceptTOS, - HostPolicy: autocert.HostWhitelist(domain), - Cache: autocert.DirCache(directory), - Email: email, - } - go func() { - log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) - // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here) - var err = runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) - if err != nil { - log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err) - } - }() - return runHTTPSWithTLSConfig("tcp", listenAddr, certManager.TLSConfig(), context2.ClearHandler(m)) -} - -func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" && r.Method != "HEAD" { - http.Error(w, "Use HTTPS", http.StatusBadRequest) - return - } - // Remove the trailing slash at the end of setting.AppURL, the request - // URI always contains a leading slash, which would result in a double - // slash - target := strings.TrimSuffix(setting.AppURL, "/") + r.URL.RequestURI() - http.Redirect(w, r, target, http.StatusFound) -} - func runWeb(ctx *cli.Context) error { managerCtx, cancel := context.WithCancel(context.Background()) graceful.InitManager(managerCtx) diff --git a/cmd/web_letsencrypt.go b/cmd/web_letsencrypt.go new file mode 100644 index 0000000000..cded53a49d --- /dev/null +++ b/cmd/web_letsencrypt.go @@ -0,0 +1,69 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package cmd + +import ( + "net/http" + "strings" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "github.com/caddyserver/certmagic" + context2 "github.com/gorilla/context" +) + +func runLetsEncrypt(listenAddr, domain, directory, email 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 programatically + // TODO: these are placeholders until we add options for each in settings with appropriate warning + enableHTTPChallenge := true + enableTLSALPNChallenge := true + + magic := certmagic.NewDefault() + magic.Storage = &certmagic.FileStorage{Path: directory} + myACME := certmagic.NewACMEManager(magic, certmagic.ACMEManager{ + Email: email, + Agreed: setting.LetsEncryptTOS, + DisableHTTPChallenge: !enableHTTPChallenge, + DisableTLSALPNChallenge: !enableTLSALPNChallenge, + }) + + magic.Issuer = myACME + + // this obtains certificates or renews them if necessary + err := magic.ManageSync([]string{domain}) + if err != nil { + return err + } + + tlsConfig := magic.TLSConfig() + + if enableHTTPChallenge { + go func() { + log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) + // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here) + var err = runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) + if err != nil { + log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err) + } + }() + } + + return runHTTPSWithTLSConfig("tcp", listenAddr, tlsConfig, context2.ClearHandler(m)) +} + +func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" && r.Method != "HEAD" { + http.Error(w, "Use HTTPS", http.StatusBadRequest) + return + } + // Remove the trailing slash at the end of setting.AppURL, the request + // URI always contains a leading slash, which would result in a double + // slash + target := strings.TrimSuffix(setting.AppURL, "/") + r.URL.RequestURI() + http.Redirect(w, r, target, http.StatusFound) +} |