From a51e86f4c435fae3c26fbbd9ff60a2d8bc76b0c8 Mon Sep 17 00:00:00 2001 From: mleku Date: Mon, 18 Aug 2025 20:13:14 +0100 Subject: [PATCH] update: reorganize imports, add URL rewriting support, and minor refactoring - cmd/lerproxy/reverse/proxy.go - Reorganized imports for logical grouping. - cmd/lerproxy/main.go - Added URL rewriting capability and updated command-line usage documentation. - Reorganized imports for consistency. - Replaced `context.T` with `context.Context` for standardization. - Updated timeout handling logic to use `context.WithTimeout`. - pkg/protocol/ws/connection.go - Replaced `fmt.Errorf` with `errorf.E` for error formatting. - cmd/lerproxy/util/util.go - Renamed file for better clarity. - Removed unnecessary package documentation. - cmd/lerproxy/hsts/proxy.go - Removed redundant package comments. - cmd/lerproxy/tcpkeepalive/listener.go - Removed redundant package comments. - Adjusted import order. - cmd/lerproxy/buf/bufpool.go - Removed unnecessary package comments. - cmd/lerproxy/README.md - Updated package usage examples and installation instructions. - Removed outdated and unnecessary instructions. --- cmd/lerproxy/LICENSE | 0 cmd/lerproxy/README.md | 21 +++-------- cmd/lerproxy/buf/bufpool.go | 1 - cmd/lerproxy/hsts/proxy.go | 1 - cmd/lerproxy/main.go | 54 +++++++++++++-------------- cmd/lerproxy/reverse/proxy.go | 5 +-- cmd/lerproxy/tcpkeepalive/listener.go | 5 +-- cmd/lerproxy/timeout/conn.go | 2 - cmd/lerproxy/util/{u.go => util.go} | 3 -- pkg/protocol/ws/connection.go | 8 ++-- 10 files changed, 40 insertions(+), 60 deletions(-) mode change 100644 => 100755 cmd/lerproxy/LICENSE mode change 100644 => 100755 cmd/lerproxy/README.md rename cmd/lerproxy/util/{u.go => util.go} (72%) diff --git a/cmd/lerproxy/LICENSE b/cmd/lerproxy/LICENSE old mode 100644 new mode 100755 diff --git a/cmd/lerproxy/README.md b/cmd/lerproxy/README.md old mode 100644 new mode 100755 index cce1ceb..7d06122 --- a/cmd/lerproxy/README.md +++ b/cmd/lerproxy/README.md @@ -6,12 +6,12 @@ DNS verification [NIP-05](https://github.com/nostr-protocol/nips/blob/master/05. ## Install - go install lerproxy.mleku.dev@latest + go install mleku.dev/lerproxy@latest ## Run ``` -Usage: lerproxy.mleku.dev [--listen LISTEN] [--map MAP] [--rewrites REWRITES] [--cachedir CACHEDIR] [--hsts] [--email EMAIL] [--http HTTP] [--rto RTO] [--wto WTO] [--idle IDLE] [--cert CERT] +Usage: mleku.dev/lerproxy [--listen LISTEN] [--map MAP] [--rewrites REWRITES] [--cachedir CACHEDIR] [--hsts] [--email EMAIL] [--http HTTP] [--rto RTO] [--wto WTO] [--idle IDLE] [--cert CERT] Options: --listen LISTEN, -l LISTEN @@ -49,7 +49,7 @@ as: * in the launch parameters for `lerproxy` you can now add any number of `--cert` parameters with the domain (including for wildcards), and the path to the `.crt`/`.key` files: - lerproxy.mleku.dev --cert :/path/to/TLS_cert + mleku.dev/lerproxy --cert :/path/to/TLS_cert this will then, if found, load and parse the TLS certificate and secret key if the suffix of the domain matches. The certificate path is expanded to two files with the above filename @@ -58,17 +58,6 @@ as: > Note that the match is greedy, so you can explicitly separately give a subdomain certificate and it will be selected even if there is a wildcard that also matches. -# IMPORTANT - -With Comodo SSL (sectigo RSA) certificates you also need to append the intermediate certificate -to the `.crt` file in order to get it to work properly with openssl library based tools like -wget, curl and the go tool, which is quite important if you want to do subdomains on a wildcard -certificate. - -Probably the same applies to some of the other certificate authorities. If you sometimes get -issues with CLI tools refusing to accept these certificates on your web server or other, this -may be the problem. - ## example mapping.txt nostr.example.com: /path/to/nostr.json @@ -96,7 +85,7 @@ Description=lerproxy [Service] Type=simple User=username -ExecStart=/usr/local/bin/lerproxy.mleku.dev -m /path/to/mapping.txt -l xxx.xxx.xxx.xxx:443 --http xxx.xxx.xxx.6:80 -m /path/to/mapping.txt -e email@example.com -c /path/to/letsencrypt/cache --cert example.com:/path/to/tls/certs +ExecStart=/usr/local/bin/mleku.dev/lerproxy -m /path/to/mapping.txt -l xxx.xxx.xxx.xxx:443 --http xxx.xxx.xxx.6:80 -m /path/to/mapping.txt -e email@example.com -c /path/to/letsencrypt/cache --cert example.com:/path/to/tls/certs Restart=on-failure Wants=network-online.target After=network.target network-online.target wg-quick@wg0.service @@ -114,7 +103,7 @@ a tunnel, such as your dev machine (something I do for nostr relay development) The simplest way to allow `lerproxy` to bind to port 80 and 443 is as follows: - setcap 'cap_net_bind_service=+ep' /path/to/lerproxy.mleku.dev + setcap 'cap_net_bind_service=+ep' /path/to/mleku.dev/lerproxy ## todo diff --git a/cmd/lerproxy/buf/bufpool.go b/cmd/lerproxy/buf/bufpool.go index 95abf42..81a0dae 100644 --- a/cmd/lerproxy/buf/bufpool.go +++ b/cmd/lerproxy/buf/bufpool.go @@ -1,4 +1,3 @@ -// Package buf implements a simple concurrent safe buffer pool for raw bytes. package buf import "sync" diff --git a/cmd/lerproxy/hsts/proxy.go b/cmd/lerproxy/hsts/proxy.go index e26f9f9..133788a 100644 --- a/cmd/lerproxy/hsts/proxy.go +++ b/cmd/lerproxy/hsts/proxy.go @@ -1,4 +1,3 @@ -// Package hsts implements a HTTP handler that enforces HSTS. package hsts import "net/http" diff --git a/cmd/lerproxy/main.go b/cmd/lerproxy/main.go index 180d5d0..fe1b409 100644 --- a/cmd/lerproxy/main.go +++ b/cmd/lerproxy/main.go @@ -1,10 +1,10 @@ // Command lerproxy implements https reverse proxy with automatic LetsEncrypt -// usage for multiple hostnames/backends,your own SSL certificates, nostr NIP-05 -// DNS verification hosting and Go vanity redirects. +// usage for multiple hostnames/backends, and URL rewriting capability. package main import ( "bufio" + "context" "crypto/tls" _ "embed" "encoding/json" @@ -15,14 +15,6 @@ import ( "net/http" "net/http/httputil" "net/url" - "orly.dev/cmd/lerproxy/buf" - "orly.dev/cmd/lerproxy/hsts" - "orly.dev/cmd/lerproxy/reverse" - "orly.dev/cmd/lerproxy/tcpkeepalive" - "orly.dev/cmd/lerproxy/util" - "orly.dev/pkg/utils/chk" - "orly.dev/pkg/utils/context" - "orly.dev/pkg/utils/log" "os" "os/signal" "path/filepath" @@ -34,14 +26,22 @@ import ( "github.com/alexflint/go-arg" "golang.org/x/crypto/acme/autocert" "golang.org/x/sync/errgroup" + "orly.dev/cmd/lerproxy/buf" + "orly.dev/cmd/lerproxy/hsts" + "orly.dev/cmd/lerproxy/reverse" + "orly.dev/cmd/lerproxy/tcpkeepalive" + "orly.dev/cmd/lerproxy/util" + "orly.dev/pkg/utils/chk" + "orly.dev/pkg/utils/log" ) //go:embed favicon.ico var defaultFavicon []byte type runArgs struct { - Addr string `arg:"-l,--listen" default:":https" help:"address to listen at"` - Conf string `arg:"-m,--map" default:"mapping.txt" help:"file with host/backend mapping"` + Addr string `arg:"-l,--listen" default:":https" help:"address to listen at"` + Conf string `arg:"-m,--map" default:"mapping.txt" help:"file with host/backend mapping"` + // Rewrites string `arg:"-r,--rewrites" default:"rewrites.txt"` Cache string `arg:"-c,--cachedir" default:"/var/cache/letsencrypt" help:"path to directory to cache key and certificates"` HSTS bool `arg:"-h,--hsts" help:"add Strict-Transport-Security header"` Email string `arg:"-e,--email" help:"contact email address presented to letsencrypt CA"` @@ -49,22 +49,21 @@ type runArgs struct { RTO time.Duration `arg:"-r,--rto" default:"1m" help:"maximum duration before timing out read of the request"` WTO time.Duration `arg:"-w,--wto" default:"5m" help:"maximum duration before timing out write of the response"` Idle time.Duration `arg:"-i,--idle" help:"how long idle connection is kept before closing (set rto, wto to 0 to use this)"` - Certs []string `arg:"--cert,separate" help:"certificates and the domain they match: eg: orly.dev:/path/to/cert - this will indicate to load two, one with extension .key and one with .crt, each expected to be PEM encoded TLS private and public keys, respectively"` - // Rewrites string `arg:"-r,--rewrites" default:"rewrites.txt"` + Certs []string `arg:"--cert,separate" help:"certificates and the domain they match: eg: mleku.dev:/path/to/cert - this will indicate to load two, one with extension .key and one with .crt, each expected to be PEM encoded TLS private and public keys, respectively"` } var args runArgs func main() { arg.MustParse(&args) - ctx, cancel := signal.NotifyContext(context.Bg(), os.Interrupt) + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() - if err := run(ctx, args); chk.T(err) { + if err := run(ctx, args); err != nil { log.F.Ln(err) } } -func run(c context.T, args runArgs) (err error) { +func run(ctx context.Context, args runArgs) (err error) { if args.Cache == "" { err = log.E.Err("no cache specified") @@ -83,7 +82,7 @@ func run(c context.T, args runArgs) (err error) { if args.WTO > 0 { srv.WriteTimeout = args.WTO } - group, ctx := errgroup.WithContext(c) + group, ctx := errgroup.WithContext(ctx) if args.HTTP != "" { httpServer := http.Server{ Addr: args.HTTP, @@ -100,8 +99,8 @@ func run(c context.T, args runArgs) (err error) { group.Go( func() error { <-ctx.Done() - ctx, cancel := context.Timeout( - context.Bg(), + ctx, cancel := context.WithTimeout( + context.Background(), time.Second, ) defer cancel() @@ -137,7 +136,9 @@ func run(c context.T, args runArgs) (err error) { group.Go( func() error { <-ctx.Done() - ctx, cancel := context.Timeout(context.Bg(), time.Second) + ctx, cancel := context.WithTimeout( + context.Background(), time.Second, + ) defer cancel() return srv.Shutdown(ctx) }, @@ -328,13 +329,12 @@ func setProxy(mapping map[string]string) (h http.Handler, err error) { ) fin := hn + "/favicon.ico" var fi []byte - if fi, err = os.ReadFile(fin); chk.E(err) { + if fi, err = os.ReadFile(fin); !chk.E(err) { fi = defaultFavicon } mux.HandleFunc( hn+"/favicon.ico", func(writer http.ResponseWriter, request *http.Request) { - log.T.F("serving favicon to %s", hn) if _, err = writer.Write(fi); chk.E(err) { return } @@ -376,12 +376,12 @@ func setProxy(mapping map[string]string) (h http.Handler, err error) { ) // req.Header.Set("Access-Control-Allow-Credentials", "true") req.Header.Set("Access-Control-Allow-Origin", "*") - log.I.Ln(req.URL, req.RemoteAddr) + log.D.Ln(req.URL, req.RemoteAddr) }, Transport: &http.Transport{ - DialContext: func(c context.T, n, addr string) ( - net.Conn, error, - ) { + DialContext: func( + ctx context.Context, n, addr string, + ) (net.Conn, error) { return net.DialTimeout(network, ba, 5*time.Second) }, }, diff --git a/cmd/lerproxy/reverse/proxy.go b/cmd/lerproxy/reverse/proxy.go index f991d18..89b00b8 100644 --- a/cmd/lerproxy/reverse/proxy.go +++ b/cmd/lerproxy/reverse/proxy.go @@ -1,13 +1,12 @@ -// Package reverse is a copy of httputil.NewSingleHostReverseProxy with addition -// of "X-Forwarded-Proto" header. package reverse import ( "net/http" "net/http/httputil" "net/url" - "orly.dev/cmd/lerproxy/util" "orly.dev/pkg/utils/log" + + "orly.dev/cmd/lerproxy/util" ) // NewSingleHostReverseProxy is a copy of httputil.NewSingleHostReverseProxy diff --git a/cmd/lerproxy/tcpkeepalive/listener.go b/cmd/lerproxy/tcpkeepalive/listener.go index c701e7d..46233ea 100644 --- a/cmd/lerproxy/tcpkeepalive/listener.go +++ b/cmd/lerproxy/tcpkeepalive/listener.go @@ -1,12 +1,11 @@ -// Package tcpkeepalive implements a net.TCPListener with a singleton set period -// for a default 3 minute keep-aline. package tcpkeepalive import ( "net" - "orly.dev/cmd/lerproxy/timeout" "orly.dev/pkg/utils/chk" "time" + + "orly.dev/cmd/lerproxy/timeout" ) // Period can be changed prior to opening a Listener to alter its' diff --git a/cmd/lerproxy/timeout/conn.go b/cmd/lerproxy/timeout/conn.go index fc8be7a..244eabc 100644 --- a/cmd/lerproxy/timeout/conn.go +++ b/cmd/lerproxy/timeout/conn.go @@ -1,5 +1,3 @@ -// Package timeout provides a simple extension of a net.TCPConn with a -// configurable read/write deadline. package timeout import ( diff --git a/cmd/lerproxy/util/u.go b/cmd/lerproxy/util/util.go similarity index 72% rename from cmd/lerproxy/util/u.go rename to cmd/lerproxy/util/util.go index 9a333ce..04a47de 100644 --- a/cmd/lerproxy/util/u.go +++ b/cmd/lerproxy/util/util.go @@ -1,6 +1,3 @@ -// Package util provides some helpers for lerproxy, a tool to convert maps of -// strings to slices of the same strings, and a helper to avoid putting two / in -// a URL. package util import "strings" diff --git a/pkg/protocol/ws/connection.go b/pkg/protocol/ws/connection.go index 86410bd..2415785 100644 --- a/pkg/protocol/ws/connection.go +++ b/pkg/protocol/ws/connection.go @@ -3,10 +3,10 @@ package ws import ( "crypto/tls" "errors" - "fmt" "io" "net/http" "orly.dev/pkg/utils/context" + "orly.dev/pkg/utils/errorf" "orly.dev/pkg/utils/units" "time" @@ -40,7 +40,7 @@ func (c *Connection) WriteMessage( ctx context.T, data []byte, ) (err error) { if err = c.conn.Write(ctx, ws.MessageText, data); err != nil { - err = fmt.Errorf("failed to write message: %w", err) + err = errorf.E("failed to write message: %w", err) return } return nil @@ -52,11 +52,11 @@ func (c *Connection) ReadMessage( ) (err error) { var reader io.Reader if _, reader, err = c.conn.Reader(ctx); err != nil { - err = fmt.Errorf("failed to get reader: %w", err) + err = errorf.E("failed to get reader: %w", err) return } if _, err = io.Copy(buf, reader); err != nil { - err = fmt.Errorf("failed to read message: %w", err) + err = errorf.E("failed to read message: %w", err) return } return