Skip to content

Commit

Permalink
Enforce HSTS on all endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
fiorix committed Oct 4, 2017
1 parent 3ff4602 commit 989e6d4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 34 deletions.
81 changes: 48 additions & 33 deletions apiserver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,17 @@ func NewHandler(c *Config) (http.Handler, error) {

func (f *apiHandler) config(mc *httpmux.Config) error {
mc.Prefix = f.conf.APIPrefix
if f.conf.PublicDir != "" {
mc.NotFound = f.publicDir()
}
mc.NotFound = newPublicDirHandler(f.conf.PublicDir)
if f.conf.UseXForwardedFor {
mc.UseFunc(httplog.UseXForwardedFor)
}
if !f.conf.Silent {
mc.UseFunc(httplog.ApacheCombinedFormat(f.conf.accessLogger()))
}
mc.UseFunc(f.metrics)
if f.conf.HSTS != "" {
mc.UseFunc(hstsMiddleware(f.conf.HSTS))
}
mc.UseFunc(clientMetricsMiddleware(f.db))
if f.conf.RateLimitLimit > 0 {
rl, err := newRateLimiter(f.conf)
if err != nil {
Expand All @@ -96,40 +97,57 @@ func (f *apiHandler) config(mc *httpmux.Config) error {
return nil
}

func (f *apiHandler) publicDir() http.HandlerFunc {
fs := http.FileServer(http.Dir(f.conf.PublicDir))
return prometheus.InstrumentHandler("frontend", fs)
func newPublicDirHandler(path string) http.HandlerFunc {
handler := http.NotFoundHandler()
if path != "" {
handler = http.FileServer(http.Dir(path))
}
return prometheus.InstrumentHandler("frontend", handler)
}

func (f *apiHandler) metrics(next http.HandlerFunc) http.HandlerFunc {
func hstsMiddleware(policy string) httpmux.MiddlewareFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.TLS == nil {
return
}
w.Header().Set("Strict-Transport-Security", policy)
next(w, r)
}
}
}

func clientMetricsMiddleware(db *freegeoip.DB) httpmux.MiddlewareFunc {
type query struct {
Country struct {
ISOCode string `maxminddb:"iso_code"`
} `maxminddb:"country"`
}
return func(w http.ResponseWriter, r *http.Request) {
next(w, r)
// Collect metrics after serving the request.
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return
}
ip := net.ParseIP(host)
if ip == nil {
return
}
if ip.To4() != nil {
clientIPProtoCounter.WithLabelValues("4").Inc()
} else {
clientIPProtoCounter.WithLabelValues("6").Inc()
}
var q query
err = f.db.Lookup(ip, &q)
if err != nil || q.Country.ISOCode == "" {
clientCountryCounter.WithLabelValues("unknown").Inc()
return
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
next(w, r)
// Collect metrics after serving the request.
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return
}
ip := net.ParseIP(host)
if ip == nil {
return
}
if ip.To4() != nil {
clientIPProtoCounter.WithLabelValues("4").Inc()
} else {
clientIPProtoCounter.WithLabelValues("6").Inc()
}
var q query
err = db.Lookup(ip, &q)
if err != nil || q.Country.ISOCode == "" {
clientCountryCounter.WithLabelValues("unknown").Inc()
return
}
clientCountryCounter.WithLabelValues(q.Country.ISOCode).Inc()
}
clientCountryCounter.WithLabelValues(q.Country.ISOCode).Inc()
}
}

Expand Down Expand Up @@ -169,9 +187,6 @@ func (f *apiHandler) iplookup(writer writerFunc) http.HandlerFunc {
http.Error(w, "Try again later.", http.StatusServiceUnavailable)
return
}
if r.TLS != nil && f.conf.HSTS != "" {
w.Header().Set("Strict-Transport-Security", f.conf.HSTS)
}
w.Header().Set("X-Database-Date", f.db.Date().Format(http.TimeFormat))
resp := q.Record(ip, r.Header.Get("Accept-Language"))
writer(w, r, resp)
Expand Down
2 changes: 1 addition & 1 deletion apiserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

// Version tag.
var Version = "3.4"
var Version = "3.4.1"

// Run is the entrypoint for the freegeoip server.
func Run() {
Expand Down

0 comments on commit 989e6d4

Please sign in to comment.