-
Notifications
You must be signed in to change notification settings - Fork 132
feat(crypto): enabled the use of certificate/key pairs from disk vs. … #66
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
3b9ba76
f6fabaf
a9bd8d0
20d267b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -36,6 +36,10 @@ var ( | |||||
// The version is set by the build command. | ||||||
version string | ||||||
|
||||||
// The TLS Certificate/Key pair | ||||||
tlsCertificate string | ||||||
tlsKey string | ||||||
|
||||||
// httpd | ||||||
httpAddr string | ||||||
httpHost string | ||||||
|
@@ -90,6 +94,8 @@ func init() { | |||||
cli.StringVar(&backlink, "backlink", "", "backlink (optional)") | ||||||
cli.StringVar(&httpHost, "http-host", "", "HTTP host") | ||||||
cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") | ||||||
cli.StringVar(&tlsCertificate, "certificate", "", "enable TLS using a custom certificate/key pair") | ||||||
cli.StringVar(&tlsKey, "key", "", "enable TLS using a custom certificate/key pair") | ||||||
cli.BoolVar(&httpInsecure, "http-insecure", false, "enable sessions cookies for http (no https) not recommended") | ||||||
cli.BoolVar(&letsencrypt, "letsencrypt", true, "enable TLS using Let's Encrypt on port 443") | ||||||
cli.BoolVar(&showVersion, "version", false, "display version and exit") | ||||||
|
@@ -199,12 +205,16 @@ func main() { | |||||
// | ||||||
// Server | ||||||
// | ||||||
|
||||||
httpTimeout := 10 * time.Minute | ||||||
maxHeaderBytes := 10 * (1024 * 1024) | ||||||
|
||||||
if tlsCertificate != "" && tlsKey != "" { | ||||||
ArchiMoebius marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
logger.Info("Unable to leverage both Let's Encrypt and certificate/key flags at the same time - using the certificate/key pair...") | ||||||
letsencrypt = false | ||||||
} | ||||||
ArchiMoebius marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
// Plain text web server for use behind a reverse proxy. | ||||||
if !letsencrypt { | ||||||
if !letsencrypt && tlsCertificate == "" || tlsKey == "" { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
So it should stay a && and not be changed to a || - or am I missing it? |
||||||
httpd := &http.Server{ | ||||||
Handler: r, | ||||||
Addr: net.JoinHostPort(httpIP, httpPort), | ||||||
|
@@ -213,6 +223,7 @@ func main() { | |||||
MaxHeaderBytes: maxHeaderBytes, | ||||||
} | ||||||
hostport := net.JoinHostPort(httpHost, httpPort) | ||||||
|
||||||
if httpPort == "80" { | ||||||
hostport = httpHost | ||||||
} | ||||||
|
@@ -224,48 +235,8 @@ func main() { | |||||
logger.Fatal(httpd.ListenAndServe()) | ||||||
} | ||||||
|
||||||
// Let's Encrypt TLS mode | ||||||
|
||||||
// autocert | ||||||
certmanager := autocert.Manager{ | ||||||
Prompt: autocert.AcceptTOS, | ||||||
Cache: autocert.DirCache(filepath.Join(datadir, "letsencrypt")), | ||||||
HostPolicy: func(_ context.Context, host string) error { | ||||||
host = strings.TrimPrefix(host, "www.") | ||||||
if host == httpHost { | ||||||
return nil | ||||||
} | ||||||
if host == config.FindInfo().Domain { | ||||||
return nil | ||||||
} | ||||||
return fmt.Errorf("autocert: host %q not permitted by HostPolicy", host) | ||||||
}, | ||||||
} | ||||||
|
||||||
// http redirect to https and Let's Encrypt auth | ||||||
go func() { | ||||||
redir := httprouter.New() | ||||||
redir.GET("/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | ||||||
r.URL.Scheme = "https" | ||||||
r.URL.Host = httpHost | ||||||
http.Redirect(w, r, r.URL.String(), http.StatusFound) | ||||||
}) | ||||||
|
||||||
httpd := &http.Server{ | ||||||
Handler: certmanager.HTTPHandler(redir), | ||||||
Addr: net.JoinHostPort(httpIP, "80"), | ||||||
WriteTimeout: httpTimeout, | ||||||
ReadTimeout: httpTimeout, | ||||||
MaxHeaderBytes: maxHeaderBytes, | ||||||
} | ||||||
if err := httpd.ListenAndServe(); err != nil { | ||||||
logger.Fatalf("http server on port 80 failed: %s", err) | ||||||
} | ||||||
}() | ||||||
|
||||||
// TLS | ||||||
tlsConfig := tls.Config{ | ||||||
GetCertificate: certmanager.GetCertificate, | ||||||
NextProtos: []string{"http/1.1"}, | ||||||
Rand: rand.Reader, | ||||||
PreferServerCipherSuites: true, | ||||||
|
@@ -281,29 +252,86 @@ func main() { | |||||
}, | ||||||
} | ||||||
|
||||||
// Let's Encrypt TLS mode | ||||||
if letsencrypt { | ||||||
// autocert | ||||||
certmanager := autocert.Manager{ | ||||||
Prompt: autocert.AcceptTOS, | ||||||
Cache: autocert.DirCache(filepath.Join(datadir, "letsencrypt")), | ||||||
HostPolicy: func(_ context.Context, host string) error { | ||||||
host = strings.TrimPrefix(host, "www.") | ||||||
|
||||||
if host == httpHost { | ||||||
return nil | ||||||
} | ||||||
|
||||||
if host == config.FindInfo().Domain { | ||||||
return nil | ||||||
} | ||||||
return fmt.Errorf("autocert: host %q not permitted by HostPolicy", host) | ||||||
}, | ||||||
} | ||||||
|
||||||
tlsConfig.GetCertificate = certmanager.GetCertificate | ||||||
|
||||||
// http redirect to https and Let's Encrypt auth | ||||||
go func() { | ||||||
redir := httprouter.New() | ||||||
redir.GET("/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | ||||||
r.URL.Scheme = "https" | ||||||
r.URL.Host = httpHost | ||||||
http.Redirect(w, r, r.URL.String(), http.StatusFound) | ||||||
}) | ||||||
|
||||||
httpd := &http.Server{ | ||||||
Handler: certmanager.HTTPHandler(redir), | ||||||
Addr: net.JoinHostPort(httpIP, "80"), | ||||||
WriteTimeout: httpTimeout, | ||||||
ReadTimeout: httpTimeout, | ||||||
MaxHeaderBytes: maxHeaderBytes, | ||||||
} | ||||||
|
||||||
if err := httpd.ListenAndServe(); err != nil { | ||||||
logger.Fatalf("http server on port 80 failed: %s", err) | ||||||
} | ||||||
}() | ||||||
} | ||||||
|
||||||
// Using a certificate/key pair from disk | ||||||
if tlsCertificate != "" && tlsKey != "" { | ||||||
var certificates []tls.Certificate | ||||||
cert, err := tls.LoadX509KeyPair(tlsCertificate, tlsKey) | ||||||
|
||||||
if err != nil { | ||||||
logger.Fatal(err.Error()) | ||||||
os.Exit(20) | ||||||
ArchiMoebius marked this conversation as resolved.
Show resolved
Hide resolved
ArchiMoebius marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
|
||||||
certificates = append(certificates, cert) | ||||||
|
||||||
tlsConfig.Certificates = certificates | ||||||
} else if tlsCertificate != "" || tlsKey != "" { | ||||||
logger.Fatal("You must define both a certificate and a key") | ||||||
os.Exit(30) | ||||||
ArchiMoebius marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
|
||||||
// Override default for TLS. | ||||||
if httpPort == "80" { | ||||||
httpPort = "443" | ||||||
httpAddr = net.JoinHostPort(httpIP, httpPort) | ||||||
} | ||||||
|
||||||
httpsd := &http.Server{ | ||||||
Handler: r, | ||||||
Addr: httpAddr, | ||||||
WriteTimeout: httpTimeout, | ||||||
ReadTimeout: httpTimeout, | ||||||
MaxHeaderBytes: maxHeaderBytes, | ||||||
} | ||||||
|
||||||
// Enable TCP keep alives on the TLS connection. | ||||||
tcpListener, err := net.Listen("tcp", httpAddr) | ||||||
|
||||||
if err != nil { | ||||||
logger.Fatalf("listen failed: %s", err) | ||||||
return | ||||||
} | ||||||
tlsListener := tls.NewListener(tcpKeepAliveListener{tcpListener.(*net.TCPListener)}, &tlsConfig) | ||||||
|
||||||
hostport := net.JoinHostPort(httpHost, httpPort) | ||||||
|
||||||
if httpPort == "443" { | ||||||
hostport = httpHost | ||||||
} | ||||||
|
@@ -312,6 +340,15 @@ func main() { | |||||
Host: hostport, | ||||||
Path: "/", | ||||||
}) | ||||||
|
||||||
httpsd := &http.Server{ | ||||||
Handler: r, | ||||||
Addr: httpAddr, | ||||||
WriteTimeout: httpTimeout, | ||||||
ReadTimeout: httpTimeout, | ||||||
MaxHeaderBytes: maxHeaderBytes, | ||||||
} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to check out the PR on my own machine but this looks like it's in the wrong place. |
||||||
logger.Fatal(httpsd.Serve(tlsListener)) | ||||||
} | ||||||
|
||||||
|
@@ -397,6 +434,7 @@ func configureSAML() error { | |||||
return nil | ||||||
} | ||||||
|
||||||
// BestDomain will attempt to isloate the domain this binary is running from | ||||||
jack1902 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
func BestDomain() string { | ||||||
domain := config.FindInfo().Domain | ||||||
if domain != "" { | ||||||
|
Uh oh!
There was an error while loading. Please reload this page.