Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make SSL cipher suite configurable #17440

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions cmd/web_graceful.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package cmd

import (
"crypto/tls"
"net"
"net/http"
"net/http/fcgi"
Expand All @@ -20,14 +19,6 @@ func runHTTP(network, listenAddr, name string, m http.Handler) error {
return graceful.HTTPListenAndServe(network, listenAddr, name, m)
}

func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
return graceful.HTTPListenAndServeTLS(network, listenAddr, name, certFile, keyFile, m)
}

func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}

// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
func NoHTTPRedirector() {
graceful.GetManager().InformCleanup()
Expand Down
191 changes: 191 additions & 0 deletions cmd/web_https.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// Copyright 2021 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 (
"crypto/tls"
"net/http"
"os"
"strings"

"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/klauspost/cpuid/v2"
)

var tlsVersionStringMap = map[string]uint16{
"": tls.VersionTLS12, // Default to tls.VersionTLS12
"tlsv1.0": tls.VersionTLS10,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not allow v1.0 and v1.1 since they are not secure any more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In real world, some users still need these legacy protocols.

In my company, one of our customers are still using TLSv1.1 😭

So, I think we just provide the options, whatever is used is the end user's choice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whatever is used is the end user's choice.

Should we at least advise on not recommending using the TLSv1.0 and TLSv1.1? Having as a option is fine, but it shouldn't be prominent that a user could think that's a good choice to choose it if they don't have a specific reason for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we can write something about "not recommended to use xxx"

However, the default values of setting options are generally fine tuned, so if a user have to edit the setting to change the TLS protocols, they must be familiar the TLS system already and know what they are doing, our warning doesn't seem to help much, because everyone on internet will tell you that "only TLS>=1.2 is secure"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our warning doesn't seem to help much, because everyone on internet will tell you that "only TLS>=1.2 is secure"

At least we did warn, better safe than sorry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a good example would be to look at the documentation for nginx, Apache and Tomcat

nginx's documentation:

http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols

Apache's documentation:

https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslprotocol

Tomcat appears to be completely silent too.


The point of this PR is to make Gitea configurable and provide the guns for people to shoot themselves should they want to do so or rather need to do so. It also updates our defaults to match a better standard.

It very deliberately does not provide security advice. We do not have the expertise, time and patience to keep this up-to-date and if we start doing so we're absolutely going to have to keep it up-to-date.

Are we really going to get into the habit of providing this level of security advice in Gitea? Do you want to be responsible for keeping this advice up-to-date and dealing with the negative comments from people who determine that we've done this wrong or not to their standards?

Feel free to write the documentation for this and add the warnings you feel necessary but honestly I think we would be better to be silent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well - then I will say the magic words.
"Let it be", I do personally have a hard time with providing options to the user that seriously weaken the security. I do get that their are legitimate reasons for using TLSv1.0 and TLSv1.1 - Given that the option is only be done after you explicitly typed the version, I think that should be fine (but it's for me personally on the edge).

The security advice that can be given possibly is widely accepted within the security community - In theoretical sense something like this could be given: "Changing this setting can have impact on the security of gitea, please read about what the TLS versions means over at: link". Making the user aware shouldn't do any harm(while like you say, people can and will disagree).

If in the future such issue or discussion come up, feel free, better I will insist that someone ping's me. I gladly will take part into such discussion.

The configuring of the SSL chipher suite is good - The question if we should warn users can possibly be done on another PR. Let's get this PR rolled into master.

"tlsv1.1": tls.VersionTLS11,
"tlsv1.2": tls.VersionTLS12,
"tlsv1.3": tls.VersionTLS13,
}

func toTLSVersion(version string) uint16 {
tlsVersion, ok := tlsVersionStringMap[strings.TrimSpace(strings.ToLower(version))]
if !ok {
log.Warn("Unknown tls version: %s", version)
return 0
}
return tlsVersion
}

var curveStringMap = map[string]tls.CurveID{
"x25519": tls.X25519,
"p256": tls.CurveP256,
"p384": tls.CurveP384,
"p521": tls.CurveP521,
}

func toCurvePreferences(preferences []string) []tls.CurveID {
ids := make([]tls.CurveID, 0, len(preferences))
for _, pref := range preferences {
id, ok := curveStringMap[strings.TrimSpace(strings.ToLower(pref))]
if !ok {
log.Warn("Unknown curve: %s", pref)
}
if id != 0 {
ids = append(ids, id)
}
}
return ids
}

var cipherStringMap = map[string]uint16{
"rsa_with_rc4_128_sha": tls.TLS_RSA_WITH_RC4_128_SHA,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, we should not list all possible cipher here but only those proved secure currently.

Copy link
Contributor

@Gusted Gusted Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree on this one - we should only provide a option to those we can somewhat guarantee security. The best thing to do is to re-use the list that golang uses(they have a awesome crypto packages and will hold them up to date as time goes on) the tls.CipherSuites. + We could get the tls.InsecureCipherSuites

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, the insecure protocols are disabled by default.

If a user insist to use it, then that's their choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please look at the documentation for nginx, apache or tomcat.

They say nothing.

Honestly I think saying nothing is the only correct way.

"rsa_with_3des_ede_cbc_sha": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
"rsa_with_aes_128_cbc_sha": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
"rsa_with_aes_256_cbc_sha": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
"rsa_with_aes_128_cbc_sha256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
"rsa_with_aes_128_gcm_sha256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
"rsa_with_aes_256_gcm_sha384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
"ecdhe_ecdsa_with_rc4_128_sha": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
"ecdhe_ecdsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
"ecdhe_ecdsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
"ecdhe_rsa_with_rc4_128_sha": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
"ecdhe_rsa_with_3des_ede_cbc_sha": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
"ecdhe_rsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
"ecdhe_rsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
"ecdhe_ecdsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
"ecdhe_rsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
"ecdhe_rsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
"ecdhe_ecdsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
"ecdhe_rsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"ecdhe_ecdsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"ecdhe_rsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
"ecdhe_ecdsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
"ecdhe_rsa_with_chacha20_poly1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
"ecdhe_ecdsa_with_chacha20_poly1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
"aes_128_gcm_sha256": tls.TLS_AES_128_GCM_SHA256,
"aes_256_gcm_sha384": tls.TLS_AES_256_GCM_SHA384,
"chacha20_poly1305_sha256": tls.TLS_CHACHA20_POLY1305_SHA256,
}

func toTLSCiphers(cipherStrings []string) []uint16 {
ciphers := make([]uint16, 0, len(cipherStrings))
for _, cipherString := range cipherStrings {
cipher, ok := cipherStringMap[strings.TrimSpace(strings.ToLower(cipherString))]
if !ok {
log.Warn("Unknown cipher: %s", cipherString)
}
if cipher != 0 {
ciphers = append(ciphers, cipher)
}
}

return ciphers
}

// defaultCiphers uses hardware support to check if AES is specifically
// supported by the CPU.
//
// If AES is supported AES ciphers will be preferred over ChaCha based ciphers
// (This code is directly inspired by the certmagic code.)
func defaultCiphers() []uint16 {
if cpuid.CPU.Supports(cpuid.AESNI) {
return defaultCiphersAESfirst
}
return defaultCiphersChaChaFirst
}

var (
defaultCiphersAES = []uint16{
Copy link
Contributor

@Gusted Gusted Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to note that these default ciphers are recommended for TLS v1.0-v.1.2

TLS v1.3 has another default cipher recommendation IIRC.

IIRC(please check it up) AES support:
AES-128 GCM with SHA256
AES-256 GCM with SHA384

No-AES support:
ChaCha20-Poly1305 with SHA256

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To give another note on TLS v1.3 - all chiper suites are secure enough that TLS v1.3 supports, thus golang currently will disregard custom cipher suites when TLS v1.3 is used - Might be worth noting somewhere to avoid confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have copied these defaults from

https://github.com/caddyserver/certmagic/blob/f83201861a3710cd9e062ea86954928854a0b57b/crypto.go#L289-L318

They represent a reasonable choice of default of ciphers when we default to MinTLSVersion 1.2. If users want to change their TLS version they need to know how to set things themselves.

tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
}

defaultCiphersChaCha = []uint16{
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
}

defaultCiphersAESfirst = append(defaultCiphersAES, defaultCiphersChaCha...)
defaultCiphersChaChaFirst = append(defaultCiphersChaCha, defaultCiphersAES...)
Comment on lines +127 to +128
Copy link
Contributor

@Gusted Gusted Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to add the whole list as well which golang uses as well. https://github.com/golang/go/blob/master/src/crypto/tls/cipher_suites.go#L271 (Skip the first 6 as they are "defaultCiphersChaCha" and "defaultCiphersAES")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have copied these defaults from

https://github.com/caddyserver/certmagic/blob/f83201861a3710cd9e062ea86954928854a0b57b/crypto.go#L289-L318

They represent a reasonable choice of default of ciphers when we default to MinTLSVersion 1.2.

)

// runHTTPs listens on the provided network address and then calls
// Serve to handle requests on incoming TLS connections.
//
// Filenames containing a certificate and matching private key for the server must
// be provided. If the certificate is signed by a certificate authority, the
// certFile should be the concatenation of the server's certificate followed by the
// CA's certificate.
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
tlsConfig := &tls.Config{}
if tlsConfig.NextProtos == nil {
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
}

if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
tlsConfig.MinVersion = version
}
zeripath marked this conversation as resolved.
Show resolved Hide resolved
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
tlsConfig.MaxVersion = version
}

// Set curve preferences
tlsConfig.CurvePreferences = []tls.CurveID{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Golang will by default set a good curvePreference which is bit less restrictive than this one, not sure if it would make sense to set our own then:
https://github.com/golang/go/blob/e8cda0a6c925668972ada40602ada08468fa90dc/src/crypto/tls/common.go#L1025-L1032

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have copied these defaults from

https://github.com/caddyserver/certmagic/blob/f83201861a3710cd9e062ea86954928854a0b57b/crypto.go#L289-L318

They represent a reasonable choice of default of ciphers when we default to MinTLSVersion 1.2. If users want to change their TLS version they need to know how to set things themselves.

tls.X25519,
tls.CurveP256,
}
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
tlsConfig.CurvePreferences = curves
}

// Set cipher suites
tlsConfig.CipherSuites = defaultCiphers()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The less we say the better.

if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
tlsConfig.CipherSuites = ciphers
}

tlsConfig.Certificates = make([]tls.Certificate, 1)

certPEMBlock, err := os.ReadFile(certFile)
if err != nil {
log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, network, listenAddr, err)
return err
}

keyPEMBlock, err := os.ReadFile(keyFile)
if err != nil {
log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, network, listenAddr, err)
return err
}

tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
log.Error("Failed to create certificate from cert file %s and key file %s for %s:%s: %v", certFile, keyFile, network, listenAddr, err)
return err
}

return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}

func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
}
17 changes: 17 additions & 0 deletions cmd/web_letsencrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
tlsConfig := magic.TLSConfig()
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")

if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
tlsConfig.MinVersion = version
}
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
tlsConfig.MaxVersion = version
}

// Set curve preferences
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
tlsConfig.CurvePreferences = curves
}

// Set cipher suites
if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
tlsConfig.CipherSuites = ciphers
}

if enableHTTPChallenge {
go func() {
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
Expand Down
10 changes: 10 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ RUN_MODE = ; prod
;REDIRECT_OTHER_PORT = false
;PORT_TO_REDIRECT = 80
;;
;; Minimum and maximum supported TLS versions
;SSL_MIN_VERSION=TLSv1.2
;SSL_MAX_VERSION=
;;
;; SSL Curve Preferences
;SSL_CURVE_PREFERENCES=X25519,P256
;;
;; SSL Cipher Suites
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be noted here about TLSv1.3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. The less we say the better.

;SSL_CIPHER_SUITES=; Will default to "ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305" if aes is supported by hardware, otherwise chacha will be first.
;;
;; Timeout for any write to the connection. (Set to 0 to disable all timeouts.)
;PER_WRITE_TIMEOUT = 30s
;;
Expand Down
36 changes: 36 additions & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,42 @@ The following configuration set `Content-Type: application/vnd.android.package-a

- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, allows redirecting http requests on `PORT_TO_REDIRECT` to the https port Gitea listens on.
- `PORT_TO_REDIRECT`: **80**: Port for the http redirection service to listen on. Used when `REDIRECT_OTHER_PORT` is true.
- `SSL_MIN_VERSION`: **TLSv1.2**: Set the minimum version of ssl support.
- `SSL_MAX_VERSION`: **\<empty\>**: Set the maximum version of ssl support.
- `SSL_CURVE_PREFERENCES`: **X25519,P256**: Set the prefered curves,
- `SSL_CIPHER_SUITES`: **ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305**: Set the preferred cipher suites.
- If there is not hardware support for AES suites by default the cha cha suites will be preferred over the AES suites
- supported suites as of go 1.17 are:
- TLS 1.0 - 1.2 cipher suites
- "rsa_with_rc4_128_sha"
- "rsa_with_3des_ede_cbc_sha"
- "rsa_with_aes_128_cbc_sha"
- "rsa_with_aes_256_cbc_sha"
- "rsa_with_aes_128_cbc_sha256"
- "rsa_with_aes_128_gcm_sha256"
- "rsa_with_aes_256_gcm_sha384"
- "ecdhe_ecdsa_with_rc4_128_sha"
- "ecdhe_ecdsa_with_aes_128_cbc_sha"
- "ecdhe_ecdsa_with_aes_256_cbc_sha"
- "ecdhe_rsa_with_rc4_128_sha"
- "ecdhe_rsa_with_3des_ede_cbc_sha"
- "ecdhe_rsa_with_aes_128_cbc_sha"
- "ecdhe_rsa_with_aes_256_cbc_sha"
- "ecdhe_ecdsa_with_aes_128_cbc_sha256"
- "ecdhe_rsa_with_aes_128_cbc_sha256"
- "ecdhe_rsa_with_aes_128_gcm_sha256"
- "ecdhe_ecdsa_with_aes_128_gcm_sha256"
- "ecdhe_rsa_with_aes_256_gcm_sha384"
- "ecdhe_ecdsa_with_aes_256_gcm_sha384"
- "ecdhe_rsa_with_chacha20_poly1305_sha256"
- "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
- TLS 1.3 cipher suites
- "aes_128_gcm_sha256"
- "aes_256_gcm_sha384"
- "chacha20_poly1305_sha256"
- Aliased names
- "ecdhe_rsa_with_chacha20_poly1305" is an alias for "ecdhe_rsa_with_chacha20_poly1305_sha256"
- "ecdhe_ecdsa_with_chacha20_poly1305" is alias for "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
- `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).
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ require (
github.com/kevinburke/ssh_config v1.1.0 // indirect
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/klauspost/compress v1.13.1
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/klauspost/cpuid/v2 v2.0.9
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/lafriks/xormstore v1.4.0
github.com/lib/pq v1.10.2
Expand Down
40 changes: 3 additions & 37 deletions modules/graceful/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,48 +95,14 @@ func (srv *Server) ListenAndServe(serve ServeFunction) error {
return srv.Serve(serve)
}

// ListenAndServeTLS listens on the provided network address and then calls
// Serve to handle requests on incoming TLS connections.
//
// Filenames containing a certificate and matching private key for the server must
// be provided. If the certificate is signed by a certificate authority, the
// certFile should be the concatenation of the server's certificate followed by the
// CA's certificate.
func (srv *Server) ListenAndServeTLS(certFile, keyFile string, serve ServeFunction) error {
config := &tls.Config{}
if config.NextProtos == nil {
config.NextProtos = []string{"h2", "http/1.1"}
}

config.Certificates = make([]tls.Certificate, 1)

certPEMBlock, err := os.ReadFile(certFile)
if err != nil {
log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, srv.network, srv.address, err)
return err
}

keyPEMBlock, err := os.ReadFile(keyFile)
if err != nil {
log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, srv.network, srv.address, err)
return err
}

config.Certificates[0], err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
log.Error("Failed to create certificate from cert file %s and key file %s for %s:%s: %v", certFile, keyFile, srv.network, srv.address, err)
return err
}

return srv.ListenAndServeTLSConfig(config, serve)
}

// ListenAndServeTLSConfig listens on the provided network address and then calls
// Serve to handle requests on incoming TLS connections.
func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFunction) error {
go srv.awaitShutdown()

tlsConfig.MinVersion = tls.VersionTLS12
if tlsConfig.MinVersion == 0 {
tlsConfig.MinVersion = tls.VersionTLS12
}

l, err := GetListener(srv.network, srv.address)
if err != nil {
Expand Down
7 changes: 0 additions & 7 deletions modules/graceful/server_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ func HTTPListenAndServe(network, address, name string, handler http.Handler) err
return server.ListenAndServe(lHandler)
}

// HTTPListenAndServeTLS listens on the provided network address and then calls Serve
// to handle requests on incoming connections.
func HTTPListenAndServeTLS(network, address, name, certFile, keyFile string, handler http.Handler) error {
server, lHandler := newHTTPServer(network, address, name, handler)
return server.ListenAndServeTLS(certFile, keyFile, lHandler)
}

// HTTPListenAndServeTLSConfig listens on the provided network address and then calls Serve
// to handle requests on incoming connections.
func HTTPListenAndServeTLSConfig(network, address, name string, tlsConfig *tls.Config, handler http.Handler) error {
Expand Down
8 changes: 8 additions & 0 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ var (
LetsEncryptTOS bool
LetsEncryptDirectory string
LetsEncryptEmail string
SSLMinimumVersion string
SSLMaximumVersion string
SSLCurvePreferences []string
SSLCipherSuites []string
GracefulRestartable bool
GracefulHammerTime time.Duration
StartupTimeout time.Duration
Expand Down Expand Up @@ -618,6 +622,10 @@ func NewContext() {
}
LetsEncryptDirectory = sec.Key("LETSENCRYPT_DIRECTORY").MustString("https")
LetsEncryptEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("")
SSLMinimumVersion = sec.Key("SSL_MIN_VERSION").MustString("")
SSLMaximumVersion = sec.Key("SSL_MAX_VERSION").MustString("")
SSLCurvePreferences = sec.Key("SSL_CURVE_PREFERENCES").Strings(",")
SSLCipherSuites = sec.Key("SSL_CIPHER_SUITES").Strings(",")
Domain = sec.Key("DOMAIN").MustString("localhost")
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HTTPPort = sec.Key("HTTP_PORT").MustString("3000")
Expand Down