summaryrefslogtreecommitdiffhomepage
path: root/cmd/tailtlsproxy
diff options
context:
space:
mode:
authorXe <xe@tailscale.com>2021-11-19 10:11:27 -0500
committerXe <xe@tailscale.com>2021-11-19 10:50:28 -0500
commit4d5386001abb52f31e6d20109834251265ed0ab1 (patch)
tree4e18162b0811c4624adc015a117c5dc97bddc0a6 /cmd/tailtlsproxy
parent758c37b83d8fa2abd0ac461b4d6d1be41447b25b (diff)
downloadtailscale-Xe/tailtlsproxy.tar.xz
tailscale-Xe/tailtlsproxy.zip
cmd/tailtlsproxy: introduce HTTPS proxy bridgeXe/tailtlsproxy
This allows you to bridge existing HTTP/S services into your tailnet using the Let's Encrypt[1] functionality. This will allow you to run multiple services on the same computer and still have them point at different target HTTP services. This also includes an example systemd template unit that lets you easily set up multiple instances of tailtlsproxy on the same machine. [1]: https://tailscale.com/blog/tls-certs/ Signed-off-by: Xe <xe@tailscale.com>
Diffstat (limited to 'cmd/tailtlsproxy')
-rw-r--r--cmd/tailtlsproxy/main.go86
-rw-r--r--cmd/tailtlsproxy/tailtlsproxy-test.defaults2
-rw-r--r--cmd/tailtlsproxy/tailtlsproxy@.service19
3 files changed, 107 insertions, 0 deletions
diff --git a/cmd/tailtlsproxy/main.go b/cmd/tailtlsproxy/main.go
new file mode 100644
index 000000000..b5fe35a48
--- /dev/null
+++ b/cmd/tailtlsproxy/main.go
@@ -0,0 +1,86 @@
+// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "crypto/tls"
+ "flag"
+ "log"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "os"
+ "time"
+
+ "tailscale.com/client/tailscale"
+ "tailscale.com/tsnet"
+)
+
+func envOr(name, def string) string {
+ if val, ok := os.LookupEnv(name); ok {
+ return val
+ }
+
+ return def
+}
+
+var (
+ bind = flag.String("bind", ":443", "TCP hostport to bind to for TLS http traffic")
+ hostname = flag.String("hostname", envOr("HOSTNAME", "toolname"), "hostname to register on tailnet (can be set with $HOSTNAME)")
+ auth = flag.Bool("auth", false, "if set, authenticate with tailscale (enables verbose logging)")
+ v = flag.Bool("v", false, "if set, enable verbose tailscale logs")
+ to = flag.String("to", envOr("TO", "http://127.0.0.1:3030"), "HTTP/S url to reverse proxy to (can be set with $TO)")
+)
+
+func main() {
+ os.Setenv("TAILSCALE_USE_WIP_CODE", "true")
+ flag.Parse()
+
+ srv := tsnet.Server{
+ Hostname: *hostname,
+ }
+
+ if *auth || *v {
+ srv.Logf = log.Printf
+ } else {
+ srv.Logf = func(string, ...interface{}) {}
+ }
+
+ if *auth {
+ os.Setenv("TS_LOGIN", "1")
+ }
+
+ ln, err := srv.Listen("tcp", *bind)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ u, err := url.Parse(*to)
+ if err != nil {
+ log.Fatalf("%s wasn't a valid URL: %v", *to, err)
+ }
+
+ h := httputil.NewSingleHostReverseProxy(u)
+
+ ln = tls.NewListener(ln, &tls.Config{
+ GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ c, err := tailscale.GetCertificate(chi)
+ if err != nil {
+ log.Println(err)
+ }
+ return c, err
+ },
+ })
+
+ s := &http.Server{
+ IdleTimeout: 5 * time.Minute,
+ Addr: *bind,
+ Handler: h,
+ }
+
+ log.Printf("listening for https on https://%s.your.tailcert.domain and forwarding to %s", *hostname, *to)
+
+ log.Fatal(s.Serve(ln))
+}
diff --git a/cmd/tailtlsproxy/tailtlsproxy-test.defaults b/cmd/tailtlsproxy/tailtlsproxy-test.defaults
new file mode 100644
index 000000000..9a5e3991d
--- /dev/null
+++ b/cmd/tailtlsproxy/tailtlsproxy-test.defaults
@@ -0,0 +1,2 @@
+HOSTNAME=test
+TO=http://127.0.0.1:3030
diff --git a/cmd/tailtlsproxy/tailtlsproxy@.service b/cmd/tailtlsproxy/tailtlsproxy@.service
new file mode 100644
index 000000000..78505da39
--- /dev/null
+++ b/cmd/tailtlsproxy/tailtlsproxy@.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=Tailscale TLS Proxy bridge for %i
+After=network.target
+
+[Service]
+Environment=HOME=/var/lib/private/tailtlsproxy-%i
+EnvironmentFile=/etc/default/tailtlsproxy-%i
+ExecStart=/usr/bin/tailtlsproxy
+Restart=on-failure
+RuntimeDirectory=tailtlsproxy-%i
+RuntimeDirectoryMode=0755
+StateDirectory=tailtlsproxy-%i
+StateDirectoryMode=0700
+CacheDirectory=tailtlsproxy-%i
+CacheDirectoryMode=0750
+DynamicUser=yes
+
+[Install]
+WantedBy=multi-user.target \ No newline at end of file