Jellyfin Remote Access with Tailscale

Set-up guide for Jellyfin or other local services over Tailscale

January 07, 2021

This is a guide on setting up Jellyfin for remote access by yourself & friends using Tailscale (for free) with a reverse proxy to get easy-to-rembemer URLs like https://jellyfin.ethanmad.com or http://jellyfin. Though this is written about Jellyfin, you can probably follow along for any other local service.

Jellyfin on my phone over LTE, through Tailscale

A few months ago, I set up a Jellyfin media server on my desktop so that I could stream content from my library to my phone in order to watch shows in bed. That was pretty cool, but what if I wasn’t home? I live with some housemates and don’t have access to port forwarding settings on our router and have a dynamic IP address. With exposing the service to the Internet not an easy option, using a VPN was my next thought.

I had previously heard about Tailscale, a mesh VPN network using Wireguard. Since it handles NAT-traversal, is free to use, and BSD-licensed, this seemed like a perfect solution.1

I didn’t see any guides about setting up remote access to Jellyfin using Tailscale or similar, so here’s mine! I’m on Arch Linux, but most steps will be similar regardless of operating system.

This post written with some feedback by the Tailscale team after I participated in a survey, but it is not sponsored by Tailscale.

Jellyfin

  1. If you haven’t installed Jellyfin, follow the Quick Start guide to get going.
    • Don’t worry about step 5 (secure the server); we’ll get to that.
    • In the Networking settings, find Remote Access Settings. Turn on “Allow remote connections to this server”, and set it to work on a Blacklist. Turn off “Enable automatic port mapping”. (This seems to be required as of Jellyfin 10.7.x). 2

Tailscale & DNS

Tailscale is a mesh VPN network, which means you can treat remote devices as if they’re on your local network. Tailscale assigns each device an IP address in the 100.x.y.z range. Only you (or those you give access) can access your device with the given IP address.

  1. Register for Tailscale. A free (“Solo”) account will work fine.
  2. Install the Tailscale app on your server and any clients. Enable the VPN with $ tailscale up on Linux, or by clicking the toggle on other operating systems.
  3. Test your connection as described or pinging one of the IP addresses assigned to you. $ tailscale status will show IP addresses of all of your connected devices.
  4. If you want to access your server via a subdomain like jellyfin.ethanmad.com, create an A record on your domain with name jellyfin and the IP address assigned to your server by Tailscale (e.g., 100.109.161.29).
  5. If you’d rather use Tailscale’s Magic DNS to access your devices by their hostname (e.g., ethanmad-desktop), then enable “Magic DNS"3 in your Tailscale admin panel.
    • You’ll need to add a nameserver to make this work; if you don’t already have one, you can pick a provider. (I use NextDNS so that connecting to Tailscale blocks ads for me. If you don’t know what you’re looking for, you can use Cloudflare’s 1.1.1.1.)
  6. Try accessing your Jellyfin server by entering either http://jellyfin.ethanmad.com:8096 or http://ethanmad-desktop:8096, using your domain or hostname instead of mine. If you can connect, you’re set! In the next step, we’ll add TLS and remove the need for the port number.
  7. If you want to share your device with friends, share access with them4. Your friends will have access to any port unless you set up an access control list (ACL) restricting their access!

Reverse Proxy and HTTPS

We will use Caddy5 to reverse proxy port requests on ports 80 (HTTP) and 443 (HTTPS) to 8096 (Jellyfin) and to set up TLS & HTTPS.

Jellyfin provides a guide for using Caddy as a reverse proxy, but it will not enable HTTPS. Since Tailscale’s underlying protocol, Wireguard, encrypts traffic, TLS doesn’t add much value other than removing the browser nag; you can safely skip TLS use that guide and skip setting up TLS if you’re short on time.

  1. Install Caddy after reading the rest of this section to determine which version you need.
  2. If you’re using your domain name (jellyfin.ethanmad.com) to access Jellyfin, you can use the DNS challenge to set up TLS. Pick whichever method is more convenient for you of the two.
  3. If you’re using Tailscale’s Magic DNS, I don’t think you can get a publicly-trusted TLS certificate at the time of writing. This may change in the future, since Tailscale is considering adding a built-in reverse proxy to make this easier.
  4. Create /var/lib/caddy/Caddyfile and, using mine (below) as a reference, add in your configuration.
    • If you only want access via one of subdomain or Magic DNS, then take add just the relevant section to your Caddyfile. My Caddyfile shows both.
    • The listed Cloudflare API key is an example; it is not really mine. You would use your API key for your DNS provider instead. Do not share API keys with others.
    • Note that the Magic DNS configuration requires specifying port 80 since Caddy tries to automatically set up HTTPS.
  5. If you don’t already have one, set up a systemd service file for Caddy and enable it so it’s always running: $ systemctl enable --now caddy
  6. Try accessing your Jellyfin server, e.g., by entering either https://jellyfin.ethanmad.com or http://ethanmad-desktop, using your domain or hostname instead of mine. If you can connect, you’re done.
# /var/lib/caddy/Caddyfile
{
    email ethan@ethanmad.com
}
jellyfin.ethanmad.com {
    tls {
        dns cloudflare 1484053787dJQB8vP1q0yc5ZEBnH6JGS4d3mBmvIeMrnnxFi3WtJdF # not my real key
    }

    reverse_proxy :8096
}
ethanmad-desktop:80 {
    reverse_proxy :8096
}

Conclusion

Share your services with your friends and family. All they have to do is sign up for Tailscale using the node sharing link you send them and connect. I’ve been using it to share access to Jellyfin with friends and family across the US without problems. If you need help, see the Tailscale forums.

Here’s the message I sent to my dad when sharing with him. You could use something similar:

To access my media library, you need to use A VPN to connect. So first download Tailscale (https://tailscale.com/download) and log in with your Google account. I’ll send you an link which you’ll need to open to gain access to my server.

Then install the Jellyfin app (https://jellyfin.org/clients/) if you want to watch on your phone.

Once both are downloaded, turn on Tailscale then open Jellyfin and enter https://jellyfin.ethanmad.com as the server address. Then you can browse and watch whatever you want! Use AirPlay or Chromecast to get it on the TV.

Bonus ideas


  1. There are some alternatives to Tailscale you might consider as I did, namely plain Wireguard, ZeroTier, and Nebula. I didn’t want to configure Wireguard on each device I wanted to share access with, so that was out. ZeroTier’s website is broken by my adblockers, so I passed on it. Nebula has a great set-up guide by Ars Technica, but it’s slower than Wireguard and not as polished. That’s how I decided on Tailscale, and I’m happy with my choice so far. ↩︎

  2. Added on 2021-04-14 after I upgraded Jellyfin. ↩︎

  3. At the time of writing, Magic DNS is a public beta feature. I don’t think you will be able to use HTTPS just yet, but I think a new Tailscale feature will address this in the near future. Device hostnames will also soon be renamable, in case you’d prefer to access your server another way. ↩︎

  4. At the time of writing, sharing nodes is an opt-in beta feature. I heard from Ross at Tailscale that it’s receiving better control features soon. ↩︎

  5. There are other equally viable reverse-proxy options, like Apache, Nginx, and Traefik. I like Caddy: I use it elsewhere, set-up is easy, and it handles TLS itself. Ross told me Tailscale is adding a built-in reverse proxy, which will eliminate the need for running one locally. ↩︎