|
@@ -76,6 +76,8 @@ type Options struct {
|
|
OGPassthrough bool
|
|
OGPassthrough bool
|
|
OGTimeToLive time.Duration
|
|
OGTimeToLive time.Duration
|
|
Target string
|
|
Target string
|
|
|
|
+
|
|
|
|
+ WebmasterEmail string
|
|
}
|
|
}
|
|
|
|
|
|
func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedConfig, error) {
|
|
func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedConfig, error) {
|
|
@@ -193,7 +195,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
|
cr, rule, err := s.check(r)
|
|
cr, rule, err := s.check(r)
|
|
if err != nil {
|
|
if err != nil {
|
|
lg.Error("check failed", "err", err)
|
|
lg.Error("check failed", "err", err)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("Internal Server Error: administrator has misconfigured Anubis. Please contact the administrator and ask them to look for the logs around \"maybeReverseProxy\"")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("Internal Server Error: administrator has misconfigured Anubis. Please contact the administrator and ask them to look for the logs around \"maybeReverseProxy\"", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -218,7 +220,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
if resp != dnsbl.AllGood {
|
|
if resp != dnsbl.AllGood {
|
|
lg.Info("DNSBL hit", "status", resp.String())
|
|
lg.Info("DNSBL hit", "status", resp.String())
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage(fmt.Sprintf("DroneBL reported an entry: %s, see https://dronebl.org/lookup?ip=%s", resp.String(), ip))), templ.WithStatus(http.StatusOK)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage(fmt.Sprintf("DroneBL reported an entry: %s, see https://dronebl.org/lookup?ip=%s", resp.String(), ip), s.opts.WebmasterEmail)), templ.WithStatus(http.StatusOK)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -233,17 +235,17 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
|
lg.Info("explicit deny")
|
|
lg.Info("explicit deny")
|
|
if rule == nil {
|
|
if rule == nil {
|
|
lg.Error("rule is nil, cannot calculate checksum")
|
|
lg.Error("rule is nil, cannot calculate checksum")
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
hash, err := rule.Hash()
|
|
hash, err := rule.Hash()
|
|
if err != nil {
|
|
if err != nil {
|
|
lg.Error("can't calculate checksum of rule", "err", err)
|
|
lg.Error("can't calculate checksum of rule", "err", err)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
lg.Debug("rule hash", "hash", hash)
|
|
lg.Debug("rule hash", "hash", hash)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage(fmt.Sprintf("Access Denied: error code %s", hash))), templ.WithStatus(http.StatusOK)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage(fmt.Sprintf("Access Denied: error code %s", hash), s.opts.WebmasterEmail)), templ.WithStatus(http.StatusOK)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
case config.RuleChallenge:
|
|
case config.RuleChallenge:
|
|
lg.Debug("challenge requested")
|
|
lg.Debug("challenge requested")
|
|
@@ -253,7 +255,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
|
return
|
|
return
|
|
default:
|
|
default:
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -399,7 +401,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
cr, rule, err := s.check(r)
|
|
cr, rule, err := s.check(r)
|
|
if err != nil {
|
|
if err != nil {
|
|
lg.Error("check failed", "err", err)
|
|
lg.Error("check failed", "err", err)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("Internal Server Error: administrator has misconfigured Anubis. Please contact the administrator and ask them to look for the logs around \"passChallenge\".")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("Internal Server Error: administrator has misconfigured Anubis. Please contact the administrator and ask them to look for the logs around \"passChallenge\".", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
lg = lg.With("check_result", cr)
|
|
lg = lg.With("check_result", cr)
|
|
@@ -408,7 +410,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if nonceStr == "" {
|
|
if nonceStr == "" {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("no nonce")
|
|
lg.Debug("no nonce")
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("missing nonce")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("missing nonce", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -416,7 +418,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if elapsedTimeStr == "" {
|
|
if elapsedTimeStr == "" {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("no elapsedTime")
|
|
lg.Debug("no elapsedTime")
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("missing elapsedTime")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("missing elapsedTime", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -424,7 +426,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if err != nil {
|
|
if err != nil {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("elapsedTime doesn't parse", "err", err)
|
|
lg.Debug("elapsedTime doesn't parse", "err", err)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid elapsedTime")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid elapsedTime", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -440,7 +442,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if err != nil {
|
|
if err != nil {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("nonce doesn't parse", "err", err)
|
|
lg.Debug("nonce doesn't parse", "err", err)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid nonce")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid nonce", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -450,7 +452,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if subtle.ConstantTimeCompare([]byte(response), []byte(calculated)) != 1 {
|
|
if subtle.ConstantTimeCompare([]byte(response), []byte(calculated)) != 1 {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("hash does not match", "got", response, "want", calculated)
|
|
lg.Debug("hash does not match", "got", response, "want", calculated)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid response")), templ.WithStatus(http.StatusForbidden)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid response", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusForbidden)).ServeHTTP(w, r)
|
|
failedValidations.Inc()
|
|
failedValidations.Inc()
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -459,7 +461,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if !strings.HasPrefix(response, strings.Repeat("0", rule.Challenge.Difficulty)) {
|
|
if !strings.HasPrefix(response, strings.Repeat("0", rule.Challenge.Difficulty)) {
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
lg.Debug("difficulty check failed", "response", response, "difficulty", rule.Challenge.Difficulty)
|
|
lg.Debug("difficulty check failed", "response", response, "difficulty", rule.Challenge.Difficulty)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid response")), templ.WithStatus(http.StatusForbidden)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("invalid response", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusForbidden)).ServeHTTP(w, r)
|
|
failedValidations.Inc()
|
|
failedValidations.Inc()
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -477,7 +479,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
if err != nil {
|
|
if err != nil {
|
|
lg.Error("failed to sign JWT", "err", err)
|
|
lg.Error("failed to sign JWT", "err", err)
|
|
s.ClearCookie(w)
|
|
s.ClearCookie(w)
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage("failed to sign JWT")), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage("failed to sign JWT", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -498,7 +500,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
func (s *Server) TestError(w http.ResponseWriter, r *http.Request) {
|
|
func (s *Server) TestError(w http.ResponseWriter, r *http.Request) {
|
|
err := r.FormValue("err")
|
|
err := r.FormValue("err")
|
|
- templ.Handler(web.Base("Oh noes!", web.ErrorPage(err)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
|
|
|
|
+ templ.Handler(web.Base("Oh noes!", web.ErrorPage(err, s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
|
}
|
|
}
|
|
|
|
|
|
// Check evaluates the list of rules, and returns the result
|
|
// Check evaluates the list of rules, and returns the result
|