Nginx reverse proxy, vps and vpn to home reddit / selfhosted ---------------------------------------------------------------------- NoctisBE · 2023-11-06 23:54 Heya, I'm in the process of making various services I host at home (mostly Plex-related, like Overseerr) available through a VPS. Basically what I want to do is run a Wireguard VPN to my VPS, and run a reverse proxy there to point specific subdomains to my home server. I currently only have the Plex port opened so my parents and friends can access it, but I would like Overseerr available as well. On my VPS I run Docker, with the nginx-proxy image by jwilder, and the acme companion. I also run a few other things there, and it works great. I tried setting up a Wireguard VPN, and that works, but then my Plex isn't reachable through the internet anymore. My VPS is hosted at Hetzner, and I would like to avoid Plex traffic going through there, just the Overseerr service. Does anyone know the best way to tackle this? Thanks! ---------------------------------------------------------------------- ebb_earl-co · 2023-11-07 00:55 This is very similar to the setup that I have been using; except that I am using Tailscale as the Wireguard VPN connection from home server to VPS, and using [Fly](https://fly.io/) as the VPS because it's so simple to spin up [in coordination with Tailscale](https://tailscale.com/kb/1132/flydotio/). Tailscale isn't the same as your own self-fashioned Wireguard network, but [here is a guide I liked](https://blog.gurucomputing.com.au/Smart% 20VPNS%20with%20Headscale/Configuring%20a%20Reverse%20Proxy/#set-up- your-reverse-proxy) on how to setup your own open-source version of the Tailscale coordination server, as well as how to configure Nginx Proxy Manager. [Here is a very long guide](https://www.qovery.com/blog/build-your- own-network-with-linux-and-wireguard) that seems to be well-written about how to set up your own Wireguard network. In any case, let me outline how simple it was for me to get Tailscale + [Fly.io](https://Fly.io) working (n.b. you'll need to pay the $2 per month to get an (IPv4) IP address for your project, so it's not entirely free). This is following the guide that I linked to above from Tailscale's knowledge base: First is the Dockerfile for your [Fly.io](https://Fly.io) app, which for me is simply the Tailscale daemon running as well as Caddy reverse proxy. Everything with Fly is a container, so it has to be a Dockerfile: `# Dockerfile` `ARG CADDY_VERSION=2.7.5-alpine` `ARG TAILSCALE_VERSION=v1.50.1` `FROM caddy:${CADDY_VERSION}` `WORKDIR /app` `RUN apk update && apk add ca-certificates iptables ip6tables && rm -rf /var/cache/apk/*` `COPY ./start.sh /app/start.sh` `COPY ./Caddyfile /etc/caddy/Caddyfile` `# Copy Tailscale binaries from the tailscale image on Docker Hub to production image.` `COPY --from=docker.io/tailscale/tailscale:v1.50.1 /usr/local/bin/tailscaled /app/tailscaled` `COPY --from=docker.io/tailscale/tailscale:v1.50.1 /usr/local/bin/tailscale /app/tailscale` `RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale` `#caddy should only listen on 80 to redirect to 443; don't expose the admin interface (2019)` `EXPOSE 80` `EXPOSE 443` `EXPOSE 443/udp` `# Run on container startup.` `CMD ["/app/start.sh"]` You'll see that this Dockerfile creates an image that simply runs some script called start.sh in the local directory; here that file is: `# start.sh` `#!/bin/sh` `# https://tailscale.com/kb/1132/flydotio/` `/app/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock &` `/app/tailscale up --authkey=${TAILSCALE_AUTHKEY} --hostname=flyio` `/usr/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile` You'll see from the last line of this script that what \`start.sh\` *does* is to run Tailscale in the background of this container and run Caddy according to its configuration file, \`Caddyfile\`. Here that is: `# Caddyfile` `{` `email admin@example.com` `admin off` `auto_https off` `}` `http://audiobooks.example.com {` `reverse_proxy 100.87.73.17:13378` `reverse_proxy [some:ipv6:address:goes:here:brackets:are:necessary]:13378` `}` Obviously, "[example.com](https://example.com)" isn't the actual website; that's actually a reserved URL for documentation such as this. In any case, a few points: * The first {} block is expressing that the email should be used as the "account" for the Let's Encrypt SSL certificate that *automatically* is generated by Caddy (why I use it in the first place). The \`admin off\` line means that I do **not** want an exposed administration interface for this Caddy server. Lastly, the `auto_https off` line tells Caddy **NOT** to automatically provision an SSL certificate for any site in the file. Why did I set this if I said at the beginning of this paragraph that I use Caddy specifically for this functionality? We'll get to that in a moment * The second stanza documents that, to reach my self-hosted [Audiobookshelf](https://www.audiobookshelf.org/) instance on my home server (which is, crucially, a node on my Tailscale network), Caddy proxies requests to [http://audiobooks.example.com](http://audiobooks.example.com) to either the Tailscale IPv4 or Tailscale IPv6 address of my home server. That's it. * Back to the first point: [Fly.io](https://Fly.io) automatically generates certificates for your projects, so I had to specifically tell Caddy *not* to provision the certificates; say the name of this project is `example-reverse-proxy-tailscsale-project`. Then, Fly automatically creates an SSL certificate for [https://example-reverse- proxy-tailscale-project.fly.dev](https://example-reverse-proxy- tailscale-project.fly.dev). * In order to point [audiobooks.example.com](https://audiobooks.example.com) to this Fly- generated domain name, you just need to add A and AAAA records in your DNS provider for the Fly-provisioned IP addresses, as well as an `_acme-challenge` CNAME record that points https://\*.example.com --> [https://example-reverse-proxy-tailscale- project.fly.dev](https://example-reverse-proxy-tailscale- project.fly.dev) (or whatever subdomains you want, explicitly: wildcard is simpler) * TL;DR of the above is * (Some Client) [https://audiobooks.example.com](https://audiobooks.example.com) [https://example-reverse-proxy-tailscale- project.fly.dev](https://example-reverse-proxy-tailscale- project.fly.dev) [http://100.87.73.17:13378](http://100.100.100.1:13378) (your Web app on your Tailscale host) This seems like a lot of steps, but it really was simple to set up, mostly because no firewall futzing was required; that's the beauty of Tailscale (and, I suppose, a Wireguard network if you can set it up that way). Indeed, I have my default UFW rule on my Docker server where Audiobookshelf and a few other services are to only accept traffic on the `tailscale0` interface and LAN. I hope that this helps somewhat, and that if this isn't actually a secure way to forward HTTPS traffic over Tailscale/Wireguard to self- hosted web apps, that someone pipe up and point it out! ---------------------------------------------------------------------- chucklesduck · 2023-11-07 03:00 I made a write up of how I did mine. https://github.com/chucklessducks/VPS-Wireguard-Nginx- Mailcow/wiki/Prerequisite ---------------------------------------------------------------------- NoctisBE · 2023-11-09 04:50 Awesome writeup, I can definitely use this for inspiration. Thank you! ---------------------------------------------------------------------- NoctisBE · 2023-11-09 04:51 Cheers! Will check it out and (together with the other comment above) use it as a staring point. Thanks!