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/web_letsencrypt.go | |
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/web_letsencrypt.go')
-rw-r--r-- | cmd/web_letsencrypt.go | 69 |
1 files changed, 69 insertions, 0 deletions
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) +} |