ts-reverse-proxy/main.go

89 lines
1.9 KiB
Go
Raw Permalink Normal View History

2023-01-31 09:19:43 -07:00
package main
import (
"crypto/tls"
"flag"
"fmt"
"log"
"net/http"
"net/http/httputil"
2023-04-28 08:24:52 -06:00
_ "net/http/pprof"
2023-01-31 09:19:43 -07:00
"net/url"
2023-02-04 07:11:27 -07:00
"time"
2023-01-31 09:19:43 -07:00
"tailscale.com/client/tailscale"
"tailscale.com/tsnet"
)
2023-02-04 07:11:27 -07:00
func httpLog(r *http.Request) {
n := time.Now()
fmt.Printf("%s (%s) [%s] \"%s %s\" %03d\n",
r.RemoteAddr,
n.Format(time.RFC822Z),
r.Method,
r.URL.Path,
r.Proto,
r.ContentLength,
)
}
2023-01-31 09:19:43 -07:00
func main() {
sName := flag.String("name", "", "server name we will be reverse proxying for")
cIP := flag.String("ip", "127.0.0.1", "ip address to reverse proxy to")
2023-04-28 08:24:52 -06:00
cPort := flag.Int("port", 5000, "port to reverse proxy to")
2024-06-28 07:50:11 -06:00
cHost := flag.String("host-header", "", "manually set the Host header to this value")
2023-04-28 08:24:52 -06:00
prof := flag.Bool("prof", false, fmt.Sprintf("expose pprof on port %d", *cPort+1))
2023-01-31 09:19:43 -07:00
flag.Parse()
tsServer := &tsnet.Server{
Hostname: *sName,
}
tsLocalClient := &tailscale.LocalClient{}
tsLocalClient, err := tsServer.LocalClient()
if err != nil {
log.Fatal("can't get ts local client: ", err)
}
2023-04-28 08:24:52 -06:00
if *prof {
go func() {
log.Println(http.ListenAndServe(fmt.Sprintf("localhost:%d", *cPort+1), nil))
}()
}
2023-01-31 09:19:43 -07:00
ln, err := tsServer.Listen("tcp", ":443")
if err != nil {
log.Fatal("can't listen: ", err)
}
rpURL, err := url.Parse(fmt.Sprintf("http://%s:%d", *cIP, *cPort))
if err != nil {
log.Fatal(err)
}
proxy := &httputil.ReverseProxy{Director: func(req *http.Request) {
req.Header.Add("X-Forwarded-Host", req.Host)
req.Header.Add("X-Origin-Host", rpURL.Host)
req.URL.Scheme = rpURL.Scheme
2024-06-28 07:50:11 -06:00
if *cHost != "" {
req.URL.Host = *cHost
} else {
req.URL.Host = rpURL.Host
}
2023-02-04 07:11:27 -07:00
httpLog(req)
2023-01-31 09:19:43 -07:00
}}
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
proxy.ServeHTTP(w, r)
})
hs := &http.Server{
Handler: mux,
TLSConfig: &tls.Config{
GetCertificate: tsLocalClient.GetCertificate,
},
}
log.Panic(hs.ServeTLS(ln, "", ""))
}