cmd/pomerium: redirect http and add hsts headers (#92)

This commit is contained in:
Bobby DeSimone 2019-04-24 13:29:11 -07:00 committed by GitHub
parent fbe1cae482
commit 857b9e5773
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 29 deletions

View file

@ -16,11 +16,13 @@ import (
"github.com/pomerium/pomerium/internal/version"
)
// securityHeaders corresponds to HTTP response headers that help to protect against protocol
// downgrade attacks and cookie hijacking.
// securityHeaders corresponds to HTTP response headers that help to protect
// against protocol downgrade attacks and cookie hijacking.
//
// https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Headers
// https://https.cio.gov/hsts/
var securityHeaders = map[string]string{
"Strict-Transport-Security": "max-age=31536000",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",

View file

@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"os"
"time"
"google.golang.org/grpc"
@ -102,6 +103,7 @@ func main() {
if proxyService != nil {
topMux.Handle("/", proxyService.Handler())
}
httpOpts := &https.Options{
Addr: mainOpts.Addr,
Cert: mainOpts.Cert,
@ -110,6 +112,18 @@ func main() {
KeyFile: mainOpts.KeyFile,
}
log.Fatal().Err(https.ListenAndServeTLS(httpOpts, topMux, grpcServer)).Msg("cmd/pomerium: https serve failure")
// redirect http to https
srv := &http.Server{
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Connection", "close")
url := fmt.Sprintf("https://%s%s", r.Host, r.URL.String())
http.Redirect(w, r, url, http.StatusMovedPermanently)
}),
}
go func() { log.Fatal().Err(srv.ListenAndServe()).Msg("cmd/pomerium: http server") }()
log.Fatal().Err(https.ListenAndServeTLS(httpOpts, topMux, grpcServer)).Msg("cmd/pomerium: https server")
}

View file

@ -129,27 +129,6 @@ func ValidateHost(mux map[string]http.Handler) func(next http.Handler) http.Hand
}
}
// RequireHTTPS reroutes a HTTP request to HTTPS
// todo(bdd) : this is unreliable unless behind another reverser proxy
// todo(bdd) : header age seems extreme
func RequireHTTPS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
// todo(bdd) : scheme and x-forwarded-proto cannot be trusted if not behind another load balancer
if (r.URL.Scheme == "http" && r.Header.Get("X-Forwarded-Proto") == "http") || &r.TLS == nil {
dest := &url.URL{
Scheme: "https",
Host: r.Host,
Path: r.URL.Path,
RawQuery: r.URL.RawQuery,
}
http.Redirect(w, r, dest.String(), http.StatusMovedPermanently)
return
}
next.ServeHTTP(w, r)
})
}
// Healthcheck endpoint middleware useful to setting up a path like
// `/ping` that load balancers or uptime testing external services
// can make a request before hitting any routes. It's also convenient

View file

@ -24,9 +24,10 @@ var (
)
var securityHeaders = map[string]string{
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "SAMEORIGIN",
"X-XSS-Protection": "1; mode=block",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "SAMEORIGIN",
"X-XSS-Protection": "1; mode=block",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", // 1 year
}
// StateParameter holds the redirect id along with the session id.
@ -62,7 +63,6 @@ func (p *Proxy) Handler() http.Handler {
Msg("proxy: request")
}))
c = c.Append(middleware.SetHeaders(securityHeaders))
c = c.Append(middleware.RequireHTTPS)
c = c.Append(middleware.ForwardedAddrHandler("fwd_ip"))
c = c.Append(middleware.RemoteAddrHandler("ip"))
c = c.Append(middleware.UserAgentHandler("user_agent"))