caddy-tailscale icon indicating copy to clipboard operation
caddy-tailscale copied to clipboard

Ready to use Dockerfile

Open falknerdominik opened this issue 1 year ago • 9 comments

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?

falknerdominik avatar Jul 27 '23 09:07 falknerdominik

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

mholt avatar Jul 27 '23 21:07 mholt

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?

falknerdominik avatar Jul 27 '23 22:07 falknerdominik

That's good progress...

but the command does not seem to be successful.

What is the error?

mholt avatar Jul 28 '23 01:07 mholt

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

falknerdominik avatar Jul 28 '23 09:07 falknerdominik

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

mholt avatar Jul 28 '23 16:07 mholt

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?

falknerdominik avatar Jul 28 '23 17:07 falknerdominik

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.

clly avatar Aug 04 '23 01:08 clly

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

falknerdominik avatar Sep 12 '23 11:09 falknerdominik

@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.?

codethief avatar May 15 '24 20:05 codethief