浏览代码

Optionally require basic authentication for http interface

Ask Bjørn Hansen 10 年之前
父节点
当前提交
49f140c8bb
共有 3 个文件被更改,包括 46 次插入1 次删除
  1. 4 0
      config.go
  2. 5 0
      dns/geodns.conf.sample
  3. 37 1
      monitor.go

+ 4 - 0
config.go

@@ -21,6 +21,10 @@ type AppConfig struct {
 	GeoIP struct {
 	GeoIP struct {
 		Directory string
 		Directory string
 	}
 	}
+	HTTP struct {
+		User     string
+		Password string
+	}
 }
 }
 
 
 var Config = new(AppConfig)
 var Config = new(AppConfig)

+ 5 - 0
dns/geodns.conf.sample

@@ -10,3 +10,8 @@
 [stathat]
 [stathat]
 ;; Add an API key to send query counts and other metrics to stathat
 ;; Add an API key to send query counts and other metrics to stathat
 ;apikey=abc123
 ;apikey=abc123
+
+[http]
+; require basic HTTP authentication; not encrypted or safe over the public internet
+; user = stats
+; password = Aeteereun8eoth4

+ 37 - 1
monitor.go

@@ -380,6 +380,42 @@ func StatusHandler(zones Zones) func(http.ResponseWriter, *http.Request) {
 	}
 	}
 }
 }
 
 
+type basicauth struct {
+	h http.Handler
+}
+
+func (b *basicauth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+
+	// don't request passwords for the websocket interface (for now)
+	// because 'wscat' doesn't support that.
+	if r.RequestURI == "/monitor" {
+		b.h.ServeHTTP(w, r)
+		return
+	}
+
+	cfgMutex.RLock()
+	user := Config.HTTP.User
+	password := Config.HTTP.Password
+	cfgMutex.RUnlock()
+
+	if len(user) == 0 {
+		b.h.ServeHTTP(w, r)
+		return
+	}
+
+	ruser, rpass, ok := r.BasicAuth()
+	if ok {
+		if ruser == user && rpass == password {
+			b.h.ServeHTTP(w, r)
+			return
+		}
+	}
+
+	w.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm=%q`, "GeoDNS Status"))
+	http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+	return
+}
+
 func httpHandler(zones Zones) {
 func httpHandler(zones Zones) {
 	http.Handle("/monitor", websocket.Handler(wsHandler))
 	http.Handle("/monitor", websocket.Handler(wsHandler))
 	http.HandleFunc("/status", StatusHandler(zones))
 	http.HandleFunc("/status", StatusHandler(zones))
@@ -388,5 +424,5 @@ func httpHandler(zones Zones) {
 
 
 	log.Println("Starting HTTP interface on", *flaghttp)
 	log.Println("Starting HTTP interface on", *flaghttp)
 
 
-	log.Fatal(http.ListenAndServe(*flaghttp, nil))
+	log.Fatal(http.ListenAndServe(*flaghttp, &basicauth{h: http.DefaultServeMux}))
 }
 }