Move backends to cmd args, allow setting private key seed via parameter or ENV var

This commit is contained in:
WeebDataHoarder
2025-04-06 03:08:19 +02:00
parent c763a59a4d
commit 411f028f56
7 changed files with 176 additions and 72 deletions

View File

@@ -1,18 +1,24 @@
package main
import (
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"errors"
"flag"
"fmt"
"git.gammaspectra.live/git/go-away/lib"
"git.gammaspectra.live/git/go-away/lib/policy"
"git.gammaspectra.live/git/go-away/utils"
"gopkg.in/yaml.v3"
"log"
"log/slog"
"maps"
"net"
"net/http"
"os"
"strconv"
"strings"
)
func setupListener(network, address, socketMode string) (net.Listener, string) {
@@ -49,6 +55,17 @@ func setupListener(network, address, socketMode string) (net.Listener, string) {
return listener, formattedAddress
}
type MultiVar []string
func (v *MultiVar) String() string {
return fmt.Sprintf("%v", *v)
}
func (v *MultiVar) Set(value string) error {
*v = append(*v, value)
return nil
}
func main() {
bind := flag.String("bind", ":8080", "network address to bind HTTP to")
bindNetwork := flag.String("bind-network", "tcp", "network family to bind HTTP to, e.g. unix, tcp")
@@ -63,11 +80,18 @@ func main() {
packageName := flag.String("package-path", "git.gammaspectra.live/git/go-away/cmd/go-away", "package name to expose in .well-known url path")
jwtPrivateKeySeed := flag.String("jwt-private-key-seed", "", "Seed for the jwt private key, or on JWT_PRIVATE_KEY_SEED env. One be generated by passing \"generate\" as a value, follows RFC 8032 private key definition. Defaults to random")
var backends MultiVar
flag.Var(&backends, "backend", "backend definition in the form of an.example.com=http://backend:1234 (can be specified multiple times)")
flag.Parse()
var err error
{
var programLevel slog.Level
if err := (&programLevel).UnmarshalText([]byte(*slogLevel)); err != nil {
if err = (&programLevel).UnmarshalText([]byte(*slogLevel)); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "invalid log level %s: %v, using info\n", *slogLevel, err)
programLevel = slog.LevelInfo
}
@@ -82,6 +106,36 @@ func main() {
slog.SetDefault(slog.New(h))
}
var seed []byte
var kValue string
if kValue = os.Getenv("JWT_PRIVATE_KEY_SEED"); kValue != "" {
} else if *jwtPrivateKeySeed != "" {
kValue = *jwtPrivateKeySeed
}
if kValue != "" {
if strings.ToLower(kValue) == "generate" {
_, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Fatal(fmt.Errorf("failed to generate private key: %w", err))
}
fmt.Printf("%x\n", priv.Seed())
os.Exit(0)
}
seed, err = hex.DecodeString(kValue)
if err != nil {
log.Fatal(fmt.Errorf("failed to decode seed: %w", err))
}
if len(seed) != ed25519.SeedSize {
log.Fatal(fmt.Errorf("invalid seed length: %d, expected %d", len(seed), ed25519.SeedSize))
}
}
policyData, err := os.ReadFile(*policyFile)
if err != nil {
log.Fatal(fmt.Errorf("failed to read policy file: %w", err))
@@ -93,11 +147,36 @@ func main() {
log.Fatal(fmt.Errorf("failed to parse policy file: %w", err))
}
createdBackends := make(map[string]http.Handler)
parsedBackends := make(map[string]string)
//TODO: deprecate
maps.Copy(parsedBackends, p.Backends)
for _, backend := range backends {
parts := strings.Split(backend, "=")
if len(parts) != 2 {
log.Fatal(fmt.Errorf("invalid backend definition: %s", backend))
}
parsedBackends[parts[0]] = parts[1]
}
for k, v := range parsedBackends {
backend, err := utils.MakeReverseProxy(v)
if err != nil {
log.Fatal(fmt.Errorf("backend %s: failed to make reverse proxy: %w", k, err))
}
backend.ErrorLog = slog.NewLogLogger(slog.With("backend", k).Handler(), slog.LevelError)
createdBackends[k] = backend
}
state, err := lib.NewState(p, lib.StateSettings{
Backends: createdBackends,
Debug: *debug,
PackageName: *packageName,
ChallengeTemplate: *challengeTemplate,
ChallengeTemplateTheme: *challengeTemplateTheme,
PrivateKeySeed: seed,
})
if err != nil {