diff options
| author | Xe Iaso <me@xeiaso.net> | 2025-01-18 18:23:23 -0500 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2025-01-18 18:23:23 -0500 |
| commit | 2309654e616d934b87279c070697c559221717d1 (patch) | |
| tree | 4f5354bf17cdeb0b3e7df634d041f9dea7e94814 | |
| parent | bcc7c0d28e8c225c730b5574718aa7d963c1cdea (diff) | |
| download | x-2309654e616d934b87279c070697c559221717d1.tar.xz x-2309654e616d934b87279c070697c559221717d1.zip | |
cmd/anubis: improve metrics
Signed-off-by: Xe Iaso <me@xeiaso.net>
| -rw-r--r-- | cmd/anubis/.gitignore | 1 | ||||
| -rw-r--r-- | cmd/anubis/anubis.env.default | 5 | ||||
| -rw-r--r-- | cmd/anubis/anubis@.service | 12 | ||||
| -rw-r--r-- | cmd/anubis/main.go | 22 | ||||
| -rw-r--r-- | cmd/anubis/yeetfile.js | 22 |
5 files changed, 60 insertions, 2 deletions
diff --git a/cmd/anubis/.gitignore b/cmd/anubis/.gitignore new file mode 100644 index 0000000..8d5bedc --- /dev/null +++ b/cmd/anubis/.gitignore @@ -0,0 +1 @@ +*.rpm
\ No newline at end of file diff --git a/cmd/anubis/anubis.env.default b/cmd/anubis/anubis.env.default new file mode 100644 index 0000000..b72eddd --- /dev/null +++ b/cmd/anubis/anubis.env.default @@ -0,0 +1,5 @@ +BIND=:8923 +DIFFICULTY=3 +METRICS_BIND=:9090 +SERVE_ROBOTS_TXT=0 +TARGET=http://localhost:3000
\ No newline at end of file diff --git a/cmd/anubis/anubis@.service b/cmd/anubis/anubis@.service new file mode 100644 index 0000000..102775f --- /dev/null +++ b/cmd/anubis/anubis@.service @@ -0,0 +1,12 @@ +[Unit] +Description="Anubis HTTP defense proxy (instance %i)" + +[Service] +ExecStart=/usr/bin/anubis +Restart=always +RestartSec=30s +EnvironmentFile=/etc/anubis/anubis-%i.env +LimitNOFILE=infinity + +[Install] +WantedBy=multi-user.target
\ No newline at end of file diff --git a/cmd/anubis/main.go b/cmd/anubis/main.go index 5c345e3..da4571c 100644 --- a/cmd/anubis/main.go +++ b/cmd/anubis/main.go @@ -12,6 +12,7 @@ import ( "fmt" "log" "log/slog" + "math" mrand "math/rand" "net/http" "net/http/httputil" @@ -24,6 +25,7 @@ import ( "github.com/golang-jwt/jwt/v5" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" "within.website/x/internal" "within.website/x/xess" ) @@ -38,6 +40,11 @@ var ( //go:embed static static embed.FS + bypasses = promauto.NewCounter(prometheus.CounterOpts{ + Name: "anubis_bypasses", + Help: "The total number of requests that bypassed challenge validation", + }) + challengesIssued = promauto.NewCounter(prometheus.CounterOpts{ Name: "anubis_challenges_issued", Help: "The total number of challenges issued", @@ -56,7 +63,7 @@ var ( timeTaken = promauto.NewHistogram(prometheus.HistogramOpts{ Name: "anubis_time_taken", Help: "The time taken for a browser to generate a response (milliseconds)", - Buckets: prometheus.DefBuckets, + Buckets: prometheus.ExponentialBucketsRange(1, math.Pow(2, 18), 19), }) ) @@ -94,12 +101,23 @@ func main() { }) } + if *metricsBind != "" { + go metricsServer() + } + mux.HandleFunc("/", s.maybeReverseProxy) - slog.Info("listening", "url", "http://localhost"+*bind) + slog.Info("listening", "url", "http://localhost"+*bind, "difficulty", *challengeDifficulty, "serveRobotsTXT", *robotsTxt, "target", *target) log.Fatal(http.ListenAndServe(*bind, mux)) } +func metricsServer() { + mux := http.NewServeMux() + mux.Handle("/metrics", promhttp.Handler()) + slog.Debug("listening for metrics", "url", "http://localhost"+*metricsBind) + log.Fatal(http.ListenAndServe(*metricsBind, mux)) +} + func sha256sum(text string) (string, error) { hash := sha256.New() _, err := hash.Write([]byte(text)) diff --git a/cmd/anubis/yeetfile.js b/cmd/anubis/yeetfile.js new file mode 100644 index 0000000..6f4096e --- /dev/null +++ b/cmd/anubis/yeetfile.js @@ -0,0 +1,22 @@ +go.install(); + +["amd64", "arm64"].forEach(goarch => rpm.build({ + name: "anubis", + description: "Anubis weighs the souls of incoming HTTP requests and uses a sha256 proof-of-work challenge in order to protect upstream resources from scraper bots.", + homepage: "https://xeiaso.net/blog/2025/anubis", + license: "CC0", + goarch, + + build: (out) => { + // install Anubis binary + go.build("-o", `${out}/usr/bin/anubis`); + + // install systemd unit + yeet.run("mkdir", "-p", `${out}/usr/lib/systemd/system`); + yeet.run("cp", "anubis@.service", `${out}/usr/lib/systemd/system/anubis@.service`); + + // install default config + yeet.run("mkdir", "-p", `${out}/etc/anubis`); + yeet.run("cp", "anubis.env.default", `${out}/etc/anubis/anubis-default.env`); + }, +}));
\ No newline at end of file |
