diff options
Diffstat (limited to 'test/cmd/relayd/main.go')
| -rw-r--r-- | test/cmd/relayd/main.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/test/cmd/relayd/main.go b/test/cmd/relayd/main.go new file mode 100644 index 0000000..26700d7 --- /dev/null +++ b/test/cmd/relayd/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "context" + "flag" + "log" + "log/slog" + "net" + "net/http" + "net/http/httputil" + "net/url" + "os" + "path/filepath" + "strings" + "time" + + "github.com/TecharoHQ/anubis/internal" + "github.com/facebookgo/flagenv" + "github.com/google/uuid" +) + +var ( + bind = flag.String("bind", ":3004", "port to listen on") + certDir = flag.String("cert-dir", "/xe/pki", "where to read mounted certificates from") + certFname = flag.String("cert-fname", "cert.pem", "certificate filename") + keyFname = flag.String("key-fname", "key.pem", "key filename") + proxyTo = flag.String("proxy-to", "http://localhost:5000", "where to reverse proxy to") + slogLevel = flag.String("slog-level", "info", "logging level") +) + +func main() { + flagenv.Parse() + flag.Parse() + + internal.InitSlog(*slogLevel) + + slog.Info("starting", + "bind", *bind, + "cert-dir", *certDir, + "cert-fname", *certFname, + "key-fname", *keyFname, + "proxy-to", *proxyTo, + ) + + cert := filepath.Join(*certDir, *certFname) + key := filepath.Join(*certDir, *keyFname) + + st, err := os.Stat(cert) + + if err != nil { + slog.Error("can't stat cert file", "certFname", cert) + os.Exit(1) + } + + lastModified := st.ModTime() + + go func(lm time.Time) { + t := time.NewTicker(time.Hour) + defer t.Stop() + + for range t.C { + st, err := os.Stat(cert) + if err != nil { + slog.Error("can't stat file", "fname", cert, "err", err) + continue + } + + if st.ModTime().After(lm) { + slog.Info("new cert detected", "oldTime", lm.Format(time.RFC3339), "newTime", st.ModTime().Format(time.RFC3339)) + os.Exit(0) + } + } + }(lastModified) + + u, err := url.Parse(*proxyTo) + if err != nil { + log.Fatal(err) + } + + h := httputil.NewSingleHostReverseProxy(u) + + if u.Scheme == "unix" { + slog.Info("using unix socket proxy") + + h = &httputil.ReverseProxy{ + Director: func(r *http.Request) { + r.URL.Scheme = "http" + r.URL.Host = r.Host + + r.Header.Set("X-Forwarded-Proto", "https") + r.Header.Set("X-Forwarded-Scheme", "https") + r.Header.Set("X-Request-Id", uuid.NewString()) + r.Header.Set("X-Scheme", "https") + + remoteHost, remotePort, err := net.SplitHostPort(r.Host) + if err == nil { + r.Header.Set("X-Forwarded-Host", remoteHost) + r.Header.Set("X-Forwarded-Port", remotePort) + } else { + r.Header.Set("X-Forwarded-Host", r.Host) + } + + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err == nil { + r.Header.Set("X-Real-Ip", host) + } + }, + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", strings.TrimPrefix(*proxyTo, "unix://")) + }, + }, + } + } + + log.Fatal( + http.ListenAndServeTLS( + *bind, + cert, + key, + h, + ), + ) +} |
