Move backends to cmd args, allow setting private key seed via parameter or ENV var
This commit is contained in:
@@ -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 {
|
||||
|
Reference in New Issue
Block a user