tailscale / caddy-tailscale

A highly experimental exploration of integrating Tailscale and Caddy.
Apache License 2.0
347 stars 36 forks source link

Ready to use Dockerfile #14

Open falknerdominik opened 11 months ago

falknerdominik commented 11 months ago

Question:

As i understand it a could use this extension to generate a docker image which can be used as a base for a reverse proxy. So starting the image it could create a device in tailscale and setup up https certs. Then the caddy plugin could forward all traffic to an remote host.

How would i accomplish that or did i misunderstand something?

mholt commented 11 months ago

You could try the instructions on our official Docker image for "Building your own Caddy-based image": https://hub.docker.com/_/caddy

falknerdominik commented 11 months ago

Good idea... I came up with this:

# Stage 1: Build the custom Caddy server with Tailscale plugin
FROM docker.io/caddy:builder AS builder

WORKDIR /app

ARG CADDY_VERSION v2.6.4
RUN apk add --no-cache nss-tools ca-certificates iptables iproute2 ip6tables

# Build Caddy with Tailscale plugin
RUN xcaddy build $CADDY_VERSION --with github.com/tailscale/caddy-tailscale

# Stage 2: Create the final minimal Caddy image
FROM docker.io/alpine:latest

# Copy the Caddy binary from the builder stage
COPY --from=builder /app/caddy /usr/bin/caddy

# Set environment variables, if needed (you can modify this as required)
ENV TAILSCALE_FROM="tailscale/mydevice"
ENV TAILSCALE_TO="localhost:80"

# Run Caddy with Tailscale proxy command, this does not work yet
# CMD ["caddy", "tailscale-proxy", "--from", "${TAILSCALE_FROM}", "--to", "${TAILSCALE_TO}"]

minimal docker-compose.yml

version: '3.9'

services:

  nginx:
    image: docker.io/nginx

  tailscale-vpn:
    image: docker.io/dfalkner/tailscale-proxy
    restart: unless-stopped
    env_file: values.env
    entrypoint: "caddy tailscale-proxy --from tailscale/test --to nginx:80"

values.env

TS_AUTHKEY=<AUTH_KEY>
TAILSCALE_FROM="tailscale/test"
TAILSCALE_TO="nginx:80"

but it does not yet work. Tailscale Admin Console shows the device (it also gets an IP) but the command does not seem to be successful. With a lot of tinkering (of TAILSCALE_FROM) i got http to work but never https.

Any help?

mholt commented 11 months ago

That's good progress...

but the command does not seem to be successful.

What is the error?

falknerdominik commented 11 months ago

This error happens when the command is run manually inside the container after starting

cmd

caddy tailscale-proxy --from tailscale/test --to nginx:80

Error during connecting to https://test.tailscaleNNNN.ts.net (with a browser, i expected this to work)

tailscale-vpn_1  | {"level":"info","ts":1690534804.9615376,"msg":"[unexpected] localbackend: got TCP conn w/o serveConfig; from 100.69.137.64:54736 to port 443"}

if i bind differently it does work for HTTP only:

caddy tailscale-proxy --from tailscale/test:80 --to nginx:80

Access via IP or https://test.tailscaleNNNN.ts.net works. However binding to port 443 like this:

caddy tailscale-proxy --from tailscale/test:443 --to nginx:80

Results in:

tailscale-vpn_1  | {"level":"info","ts":1690538696.7273436,"msg":"control: client.Login(false, 2)"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7273552,"logger":"http","msg":"enabling HTTP/3 listener","addr":"test:443"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7274578,"msg":"control: [v1] authRoutine: state:new; wantLoggedIn=true"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.727465,"msg":"control: [v1] direct.TryLogin(token=false, flags=2)"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7274873,"msg":"control: LoginInteractive -> regen=true"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7274914,"msg":"control: doLogin(regen=true, hasUrl=false)"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7279801,"msg":"control: [v1] mapRoutine: state:authenticating"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.728011,"msg":"health(\"overall\"): error: not in map poll"}
tailscale-vpn_1  | {"level":"info","ts":1690538696.7327168,"logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0x4000141570"}
tailscale-vpn_1  | Error: loading new config: http app module: start: listen udp: lookup test on 127.0.0.11:53: no such host
mholt commented 11 months ago

At this point, I'm guessing @willnorris or @Xe would have a better clue...

falknerdominik commented 11 months ago

Running

caddy tailscale-proxy --from tailscale+tls/test:443 --to nginx:80

(which according to the docs) is needed result in a parsing error. Is TLS not supported by the tailscale-proxy command?

clly commented 11 months ago

This is the setup I use and can confirm that it works: https://gist.github.com/clly/567713da815f59b97d50e5f712ad1167

The only suggestion I have is to use a Caddyfile to confirm that works as an experiment.

falknerdominik commented 9 months ago

mhh maybe i should have reported back... I made my own image which works on a local instance. Published on dockerhub and github here: https://github.com/falknerdominik/image-tailscale-proxy

codethief commented 1 month ago

@falknerdominik Very interesting, thank you! As far as I can tell you're not using the Tailscale Caddy plugin but rather start a Tailscale daemon separately and then make use of Caddy's native support for Tailscale to have it connect to Tailscale, obtain TLS certs, etc.?