Skip to content

Commit b82c14b

Browse files
Fluftechknowlogick
Fluf
authored andcommitted
add letsencrypt to Gitea (#4189)
1 parent 6c1a31f commit b82c14b

35 files changed

+4518
-280
lines changed

Gopkg.lock

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ignored = ["google.golang.org/appengine*"]
1515
name = "code.gitea.io/sdk"
1616

1717
[[constraint]]
18-
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
18+
revision = "12dd70caea0268ac0d6c2707d0611ef601e7c64e"
1919
name = "golang.org/x/crypto"
2020

2121
[[constraint]]

cmd/web.go

+33
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package cmd
66

77
import (
8+
"crypto/tls"
89
"fmt"
910
"net"
1011
"net/http"
@@ -22,6 +23,7 @@ import (
2223
"github.com/Unknwon/com"
2324
context2 "github.com/gorilla/context"
2425
"github.com/urfave/cli"
26+
"golang.org/x/crypto/acme/autocert"
2527
ini "gopkg.in/ini.v1"
2628
)
2729

@@ -71,6 +73,33 @@ func runHTTPRedirector() {
7173
}
7274
}
7375

76+
func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
77+
certManager := autocert.Manager{
78+
Prompt: autocert.AcceptTOS,
79+
HostPolicy: autocert.HostWhitelist(domain),
80+
Cache: autocert.DirCache(directory),
81+
Email: email,
82+
}
83+
go http.ListenAndServe(listenAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler))) // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validatio happens here)
84+
server := &http.Server{
85+
Addr: listenAddr,
86+
Handler: m,
87+
TLSConfig: &tls.Config{
88+
GetCertificate: certManager.GetCertificate,
89+
},
90+
}
91+
return server.ListenAndServeTLS("", "")
92+
}
93+
94+
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
95+
if r.Method != "GET" && r.Method != "HEAD" {
96+
http.Error(w, "Use HTTPS", http.StatusBadRequest)
97+
return
98+
}
99+
target := setting.AppURL + r.URL.RequestURI()
100+
http.Redirect(w, r, target, http.StatusFound)
101+
}
102+
74103
func runWeb(ctx *cli.Context) error {
75104
if ctx.IsSet("config") {
76105
setting.CustomConf = ctx.String("config")
@@ -143,6 +172,10 @@ func runWeb(ctx *cli.Context) error {
143172
case setting.HTTP:
144173
err = runHTTP(listenAddr, context2.ClearHandler(m))
145174
case setting.HTTPS:
175+
if setting.EnableLetsEncrypt {
176+
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
177+
break
178+
}
146179
if setting.RedirectOtherPort {
147180
go runHTTPRedirector()
148181
}

docs/content/doc/advanced/config-cheat-sheet.en-us.md

+5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
125125
- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, redirects http requests
126126
on another (https) port.
127127
- `PORT_TO_REDIRECT`: **80**: Port used when `REDIRECT_OTHER_PORT` is true.
128+
- `ENABLE_LETSENCRYPT`: **false**: If enabled you must set `DOMAIN` to valid internet facing domain (ensure DNS is set and port 80 is accessible by letsencrypt validation server).
129+
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
130+
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt
131+
- `LETSENCRYPT_DIRECTORY`: **https**: Directory that Letsencrypt will use to cache information such as certs and private keys
132+
- `LETSENCRYPT_EMAIL`: **[email protected]**: Email used by Letsencrypt to notify about problems with issued certificates. (No default)
128133

129134
## Database (`database`)
130135

docs/content/doc/usage/https-support.md

+18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ KEY_FILE = key.pem
3232
```
3333
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
3434

35+
## Using Let's Encrypt
36+
37+
[Let's Encrypt](https://letsencrypt.org/) is a Certificate Authority that allows you to automatically request and renew SSL/TLS certificates. In addition to starting Gitea on your configured port, to request HTTPS certificates Gitea will also need to listed on port 80, and will set up an autoredirect to HTTPS for you. Let's Encrypt will need to be able to access Gitea via the Internet to verify your ownership of the domain.
38+
39+
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
40+
41+
```ini
42+
[server]
43+
PROTOCOL=https
44+
DOMAIN=git.example.com
45+
ENABLE_LETSENCRYPT=true
46+
LETSENCRYPT_ACCEPTTOS=true
47+
LETSENCRYPT_DIRECTORY=https
48+
LETSENCRYPT_EMAIL[email protected]
49+
```
50+
51+
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
52+
3553
## Using reverse proxy
3654

3755
Setup up your reverse proxy like shown in the [reverse proxy guide](../reverse-proxies).

modules/setting/setting.go

+12
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ var (
112112
UnixSocketPermission uint32
113113
EnablePprof bool
114114
PprofDataPath string
115+
EnableLetsEncrypt bool
116+
LetsEncryptTOS bool
117+
LetsEncryptDirectory string
118+
LetsEncryptEmail string
115119

116120
SSH = struct {
117121
Disabled bool `ini:"DISABLE_SSH"`
@@ -737,6 +741,14 @@ func NewContext() {
737741
}
738742
UnixSocketPermission = uint32(UnixSocketPermissionParsed)
739743
}
744+
EnableLetsEncrypt := sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
745+
LetsEncryptTOS := sec.Key("LETSENCRYPT_ACCEPTTOS").MustBool(false)
746+
if !LetsEncryptTOS && EnableLetsEncrypt {
747+
log.Warn("Failed to enable Let's Encrypt due to Let's Encrypt TOS not being accepted")
748+
EnableLetsEncrypt = false
749+
}
750+
LetsEncryptDirectory = sec.Key("LETSENCRYPT_DIRECTORY").MustString("https")
751+
LetsEncryptEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("")
740752
Domain = sec.Key("DOMAIN").MustString("localhost")
741753
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
742754
HTTPPort = sec.Key("HTTP_PORT").MustString("3000")

0 commit comments

Comments
 (0)