Cache certificates across program restarts.

So far, we request a certificate each time we start the broker.  Let's
Encrypt maintains several rate limiters and if we exceed one of them, we
won't get a certificate.  Worse, since we don't store certificates, we
won't even be able to use an old one.

This patch uses autocert's DirCache structure to cache certificates on
disk.

This patch fixes <https://bugs.torproject.org/30512>.
This commit is contained in:
Philipp Winter 2019-05-14 14:25:57 -07:00
parent cd650fa009
commit 11efa42e4c
No known key found for this signature in database
GPG key ID: 0FD95F1D3A597A48

View file

@ -251,6 +251,7 @@ func robotsTxtHandler(w http.ResponseWriter, r *http.Request) {
func main() { func main() {
var acmeEmail string var acmeEmail string
var acmeHostnamesCommas string var acmeHostnamesCommas string
var acmeCertCacheDir string
var addr string var addr string
var geoipDatabase string var geoipDatabase string
var geoip6Database string var geoip6Database string
@ -263,6 +264,7 @@ func main() {
flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate") flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate")
flag.StringVar(&certFilename, "cert", "", "TLS certificate file") flag.StringVar(&certFilename, "cert", "", "TLS certificate file")
flag.StringVar(&keyFilename, "key", "", "TLS private key file") flag.StringVar(&keyFilename, "key", "", "TLS private key file")
flag.StringVar(&acmeCertCacheDir, "acme-cert-cache", "acme-cert-cache", "directory in which certificates should be cached")
flag.StringVar(&addr, "addr", ":443", "address to listen on") flag.StringVar(&addr, "addr", ":443", "address to listen on")
flag.StringVar(&geoipDatabase, "geoipdb", "/usr/share/tor/geoip", "path to correctly formatted geoip database mapping IPv4 address ranges to country codes") flag.StringVar(&geoipDatabase, "geoipdb", "/usr/share/tor/geoip", "path to correctly formatted geoip database mapping IPv4 address ranges to country codes")
flag.StringVar(&geoip6Database, "geoip6db", "/usr/share/tor/geoip6", "path to correctly formatted geoip database mapping IPv6 address ranges to country codes") flag.StringVar(&geoip6Database, "geoip6db", "/usr/share/tor/geoip6", "path to correctly formatted geoip database mapping IPv6 address ranges to country codes")
@ -329,7 +331,7 @@ func main() {
// Handle the various ways of setting up TLS. The legal configurations // Handle the various ways of setting up TLS. The legal configurations
// are: // are:
// --acme-hostnames (with optional --acme-email) // --acme-hostnames (with optional --acme-email and/or --acme-cert-cache)
// --cert and --key together // --cert and --key together
// --disable-tls // --disable-tls
// The outputs of this block of code are the disableTLS, // The outputs of this block of code are the disableTLS,
@ -338,7 +340,15 @@ func main() {
acmeHostnames := strings.Split(acmeHostnamesCommas, ",") acmeHostnames := strings.Split(acmeHostnamesCommas, ",")
log.Printf("ACME hostnames: %q", acmeHostnames) log.Printf("ACME hostnames: %q", acmeHostnames)
var cache autocert.Cache
if err = os.MkdirAll(acmeCertCacheDir, 0700); err != nil {
log.Printf("Warning: Couldn't create cache directory %q (reason: %s) so we're *not* using our certificate cache.", acmeCertCacheDir, err)
} else {
cache = autocert.DirCache(acmeCertCacheDir)
}
certManager := autocert.Manager{ certManager := autocert.Manager{
Cache: cache,
Prompt: autocert.AcceptTOS, Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(acmeHostnames...), HostPolicy: autocert.HostWhitelist(acmeHostnames...),
Email: acmeEmail, Email: acmeEmail,