cmd/anubis: support ED25519_PRIVATE_KEY_HEX_FILE (#185)

This commit is contained in:
Talya Connor 2025-04-01 11:20:06 +11:00 committed by GitHub
parent b4a2e1a6a0
commit 08bb7f953c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 22 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"context" "context"
"crypto/ed25519" "crypto/ed25519"
"crypto/rand" "crypto/rand"
@ -32,22 +33,23 @@ import (
) )
var ( var (
bind = flag.String("bind", ":8923", "network address to bind HTTP to") bind = flag.String("bind", ":8923", "network address to bind HTTP to")
bindNetwork = flag.String("bind-network", "tcp", "network family to bind HTTP to, e.g. unix, tcp") bindNetwork = flag.String("bind-network", "tcp", "network family to bind HTTP to, e.g. unix, tcp")
challengeDifficulty = flag.Int("difficulty", anubis.DefaultDifficulty, "difficulty of the challenge") challengeDifficulty = flag.Int("difficulty", anubis.DefaultDifficulty, "difficulty of the challenge")
cookieDomain = flag.String("cookie-domain", "", "if set, the top-level domain that the Anubis cookie will be valid for") cookieDomain = flag.String("cookie-domain", "", "if set, the top-level domain that the Anubis cookie will be valid for")
cookiePartitioned = flag.Bool("cookie-partitioned", false, "if true, sets the partitioned flag on Anubis cookies, enabling CHIPS support") cookiePartitioned = flag.Bool("cookie-partitioned", false, "if true, sets the partitioned flag on Anubis cookies, enabling CHIPS support")
ed25519PrivateKeyHex = flag.String("ed25519-private-key-hex", "", "private key used to sign JWTs, if not set a random one will be assigned") ed25519PrivateKeyHex = flag.String("ed25519-private-key-hex", "", "private key used to sign JWTs, if not set a random one will be assigned")
metricsBind = flag.String("metrics-bind", ":9090", "network address to bind metrics to") ed25519PrivateKeyHexFile = flag.String("ed25519-private-key-hex-file", "", "file name containing value for ed25519-private-key-hex")
metricsBindNetwork = flag.String("metrics-bind-network", "tcp", "network family for the metrics server to bind to") metricsBind = flag.String("metrics-bind", ":9090", "network address to bind metrics to")
socketMode = flag.String("socket-mode", "0770", "socket mode (permissions) for unix domain sockets.") metricsBindNetwork = flag.String("metrics-bind-network", "tcp", "network family for the metrics server to bind to")
robotsTxt = flag.Bool("serve-robots-txt", false, "serve a robots.txt file that disallows all robots") socketMode = flag.String("socket-mode", "0770", "socket mode (permissions) for unix domain sockets.")
policyFname = flag.String("policy-fname", "", "full path to anubis policy document (defaults to a sensible built-in policy)") robotsTxt = flag.Bool("serve-robots-txt", false, "serve a robots.txt file that disallows all robots")
slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)") policyFname = flag.String("policy-fname", "", "full path to anubis policy document (defaults to a sensible built-in policy)")
target = flag.String("target", "http://localhost:3923", "target to reverse proxy to") slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)")
healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis") target = flag.String("target", "http://localhost:3923", "target to reverse proxy to")
useRemoteAddress = flag.Bool("use-remote-address", false, "read the client's IP address from the network request, useful for debugging and running Anubis on bare metal") healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis")
debugBenchmarkJS = flag.Bool("debug-benchmark-js", false, "respond to every request with a challenge for benchmarking hashrate") useRemoteAddress = flag.Bool("use-remote-address", false, "read the client's IP address from the network request, useful for debugging and running Anubis on bare metal")
debugBenchmarkJS = flag.Bool("debug-benchmark-js", false, "respond to every request with a challenge for benchmarking hashrate")
) )
func keyFromHex(value string) (ed25519.PrivateKey, error) { func keyFromHex(value string) (ed25519.PrivateKey, error) {
@ -206,18 +208,30 @@ func main() {
} }
var priv ed25519.PrivateKey var priv ed25519.PrivateKey
if *ed25519PrivateKeyHex == "" { if *ed25519PrivateKeyHex != "" && *ed25519PrivateKeyHexFile != "" {
log.Fatal("do not specify both ED25519_PRIVATE_KEY_HEX and ED25519_PRIVATE_KEY_HEX_FILE")
} else if *ed25519PrivateKeyHex != "" {
priv, err = keyFromHex(*ed25519PrivateKeyHex)
if err != nil {
log.Fatalf("failed to parse and validate ED25519_PRIVATE_KEY_HEX: %v", err)
}
} else if *ed25519PrivateKeyHexFile != "" {
hex, err := os.ReadFile(*ed25519PrivateKeyHexFile)
if err != nil {
log.Fatalf("failed to read ED25519_PRIVATE_KEY_HEX_FILE %s: %v", *ed25519PrivateKeyHexFile, err)
}
priv, err = keyFromHex(string(bytes.TrimSpace(hex)))
if err != nil {
log.Fatalf("failed to parse and validate content of ED25519_PRIVATE_KEY_HEX_FILE: %v", err)
}
} else {
_, priv, err = ed25519.GenerateKey(rand.Reader) _, priv, err = ed25519.GenerateKey(rand.Reader)
if err != nil { if err != nil {
log.Fatalf("failed to generate ed25519 key: %v", err) log.Fatalf("failed to generate ed25519 key: %v", err)
} }
slog.Warn("generating random key, Anubis will have strange behavior when multiple instances are behind the same load balancer target, for more information: see https://anubis.techaro.lol/docs/admin/installation#key-generation") slog.Warn("generating random key, Anubis will have strange behavior when multiple instances are behind the same load balancer target, for more information: see https://anubis.techaro.lol/docs/admin/installation#key-generation")
} else {
priv, err = keyFromHex(*ed25519PrivateKeyHex)
if err != nil {
log.Fatalf("failed to parse and validate ED25519_PRIVATE_KEY_HEX: %v", err)
}
} }
s, err := libanubis.New(libanubis.Options{ s, err := libanubis.New(libanubis.Options{

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added a wait with button continue + 30 second auto continue after 30s if you click "Why am I seeing this?" - Added a wait with button continue + 30 second auto continue after 30s if you click "Why am I seeing this?"
- Fixed a typo in the challenge page title. - Fixed a typo in the challenge page title.
- Disabled running integration tests on Windows hosts due to it's reliance on posix features (see [#133](https://github.com/TecharoHQ/anubis/pull/133#issuecomment-2764732309)). - Disabled running integration tests on Windows hosts due to it's reliance on posix features (see [#133](https://github.com/TecharoHQ/anubis/pull/133#issuecomment-2764732309)).
- Added support for passing the ed25519 signing key in a file with `-ed25519-private-key-hex-file` or `ED25519_PRIVATE_KEY_HEX_FILE`.
## v1.15.1 ## v1.15.1