How would you expose Jellyfin securely without a vpn?
from kiol@discuss.online to selfhosted@lemmy.world on 23 May 22:00
https://discuss.online/post/40181742
from kiol@discuss.online to selfhosted@lemmy.world on 23 May 22:00
https://discuss.online/post/40181742
Assuming the user will not be connecting over vpn, but is both remote and non-technical, how would you expose Jellyfin to them securely?
threaded - newest
At the very minimum stick a reverse proxy in front like caddy, nginx, or Traefik. Then have some middleware like crowdsec to inspect what’s going on. Then whitelist the IP or the country IP block.
There is much more but those would be the bare minimum.
I too would like to know more. Jellyfin has been something that I am still heditating to expose online without a VPN.
I have Plex behind a reverse proxy (HAproxy) with Crowdsec and firewall rules all behind Cloudflare. My firewall rules in HAproxy block access a few different ways, like if request are higher then 60 requests a second, or if there is strange path traversal. Used the following guide as a start.
archy.net/building-a-native-fail2ban-with-haproxy…
I agree with reverse proxy + middleware. I’d also suggest something like Jellyswarm as the front end. That way I can connect to other friends’ servers too.
Meh. If someone hacks my server and watches TV then idc, have at it. They earned it
EDIT: the downvotes are warranted but they change nothing
Sure… If someone managed to stream some of my media… They probably earned it… But then they exploit a vulnerability to perform arbitrary code execution, and leverage that to hack everything else on my network…
https://app.opencve.io/cve/CVE-2023-30626
I’m learning a lot of this as I go and have not exposed any services to the internet yet, but would VLANs not contain the damage to a limited portion of the network? Because that’s the plan I’m working toward. Not just for Jellyfin but a handful of other services.
That… might work. Do you have a different physical server for each service though?
The issue is once someone is in, then they can try to jailbreak and move laterally to get to other things. Other devices, into the file system.
Jellyfin might not be your concern, but are there other files on that server? Or services? Secrets passwords etc? If anything else is on that vlan, what security flaws might be there that an attacker could use?
There is no personal information on anything in that proposed VLAN currently, and in the future, the most personal stuff it will include is a chat program to replace Discord. In all, I’m assuming I can run the reverse proxy and most services (not even a dozen) on a mini PC, and then somewhere between 1-4 on a NAS. Two devices total on this VLAN, unless I learn of something that would change this plan.
If Jellyfin gets compromised, you risk everything else on the same server getting compromised, as well as everything that server can reach.
VLANs can certainly reduce what is at risk, but wouldn’t the machine running the Jellyfin client be reachable from the Jellyfin server? And if they manage to move laterally to the client machine, what could they then reach from there?
Again, still learning, but my understanding is that that’s what VLAN rules can protect against.
Didn’t down vote, and I get what you’re saying to a certain extent. I’m not touting my server as hack-proof in the least, but it would take some work. My concern wouldn’t be someone hacking in and listening to my personal music collection I’ve been working on for decades…it goes all the way back to 1937.
I would be more concerned that my compromised server was used as a zombie attack on some other server. The first VPS server got ransacked and used over-nite to (unsuccessfully) DDoS another business site.I got a ton of nasty grams for that boner. I didn’t loose anything but time.
Bitcoin miners are easy to spot. I’ve never really understood why someone would hack into a small server and deploy a nefarious miner. On a huge corporate server farm, sure. But not some small selfhost VPS somebody found on lowendbox.
Because they’re not mining on just one, they’re mining on thousands.
I understand economy of scale, but how much could you actually mine over nite on a little droplet before junior sysadmin notices that there is an influx of nasty grams in his in box and his little 4 banger VPS is maxed out on resources.
Long enough to make it worth it. Most people aren’t paying that much attention.
Remote code execution is a concern. Your server and your network as a whole (including other VLANs) are susceptible to attack if Jellyfin is compromised. If Jellyfin is running on the host, it would be trivial to hack your server (and anything else running/connected to it). If Jellyfin is in a Docker/Podman containers, it doesnt prevent attacks against the host (sandbox escape, kernel privilege escalation, etc), or against your network over some ports. Even if the server is on it’s own VLAN, a vulnerability or weakness in your router could still lead to a compromise, meaning that any devices that is in any way connected to your router (including personal devices) could be attacked.
There is a lot of depth to this topic of course. And at some point you just calculate your risks and weigh your options. There is no such thing as perfect security of course.
Reverse proxy with auth in front of the actual jellyfin login. Like pangolin.
How do you get apps through something like that? Do you have to open your browser and hit the URL periodically to handle auth there and it just remembers your IP?
You can set pangolin to allow access to an entire resource or just certain paths without the front auth, instead relying on the built in auth.
Your random plex/emby/jellyfin server isn’t going to be a huge target and the built in auth is good enough for the limited access your media system should have.
Wait so if you’re gonna allow access without authentication then why bother putting pangolin in front of jellyfin? Does it help in some other kind of way? I don’t really get how it helps without interfering with apps accessing jellyfin.
I am really not comfortable with that. Limited or not.
You don’t.
Gotcha I see, just checking if I missed something since that was the issue last time I tried doing something like that. These days I just yolo it and expose jellyfin to the public Internet.
If there was a Jellyfin app that supported adding a custom header to the server connection, you could set your reverse proxy to just let the connections with that secret key header through, and make everything else go through the extra auth middleware. But as far as I know, none of the Jellyfin apps have that feature, even though it has been requested. Lots of other selfhosted apps do have the feature though, and I use it in a few places as well.
Gotcha yeah, I did this for LunaSea with traefik forward auth for the arrs, but the lack of support in jellyfin clients is annoying. Though personally I’ve been waiting 5 years for Findroid to support transcoded streams / adjusting video quality so personally that’s higher on my list of priorities.
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
11 acronyms in this thread; the most compressed thread commented on today has 14 acronyms.
[Thread #311 for this comm, first seen 23rd May 2026, 22:30] [FAQ] [Full list] [Contact] [Source code]
Good bot.
See if there are any apps that will handle the VPN tunneling transparently, then provide the web interface, all in one.
If you can’t find any that work like you want, I would put an authenticating reverse proxy in front of jellyfin. But last time I tried that, it only half worked. I don’t know if that’s changed.
Worst case, a reverse proxy that only exposes the necessary endpoints. Or a WAF that can block known attacks.
In any case, you should have a firewall rule as narrow as possible to only limit access to them. Static IP address if possible, then subnet, then ASN. Whatever is the most restrictive but still works.
Why no VPN?
VPNs are not trivial to use for normies.
Way easier than reverse proxies IMO
They mean on the client side most likely. A reverse proxy will be transparent to the user.
Yeah, let me just walk my normie friends and parents through setting up a VPN on their TV so they can stream their shows.
Sounds annoying but doable. No need to be offended I’m just asking why VPN is being ruled out.
How much access do you have to their system? I would set up a script on their end to poll ipv4.icanhazip.com and send you their IP. I would then trigger a firewall rule change on your end to that information. This keeps the access to only their IP, with maybe a few minutes between polls where it might be different.
you don’t.
if you’re intent on “spreading your legs” to the world, get a WAF.
edit: don’t get mad about the analogy, it’s apt.
when you open your local network to public access without protection, you’re bound to have a couple “accidents” and “infections”.
protect your local network with at least a proper firewall and segmented network.
a properly configured WAF is better than any reverse proxy you could use.
Does Tailscale count as a VPN for you? It’s how I roll. Well, I run my own headscale server, but the free Tailscale tier is going to be fine for any reasonably sized personal project.
If they could be using web UI (I’m not sure how a client would work with auth like that) then it kind of depends on how much hassle they can live with and how secure you want to be
Simplest would be to use https://doc.traefik.io/traefik/reference/routing-configuration/http/middlewares/basicauth/
You set up username and password and share those with the user. But it can be brute-forced
Something more secure but also a bit more demanding would be some kind of email otp https://docs.goauthentik.io/add-secure-apps/flows-stages/stages/authenticator_email/
Set up authentik to send time-limited link to their email that well let them through. But they would have to authenticate every time they access
Adding onto the other comments, if you have admin access to your network router/firewall you can configure the incoming port forward itself to only allow specific IP addresses while dropping traffic from any other internet WAN IPs. It’s a bit like using the Jellyfin whitelist/blacklist but doing it at the network level. This drops all unwanted internet traffic to that port at the firewall before ever reaching the Jellyfin software. Downside is having to occasionally update the firewall whenever there are IP address changes.
This is probably only feasible if you only have some specific Jellyfin clients in mind to accept connections from, not any random person from any random WAN IP address.
call me crazy but I just use a couldflare tunnel since my domain is already provided through them. They make it really easy to add sub-domains attached to specific ports on the local machine and automatically adds the proper DNS entries. Additionally they have a ton of domain security/anti-bot measures you can set up.
community.cloudflare.com/t/…/855051
I haven’t heard of anyone being kicked off.
I haven’t had any issues like that. It’s been pretty plug and play and I have it set up for some family that are accessing it from out of town. No problems except for the big cloudflare outage that happened a while ago.
Reverse proxy with fail2ban or crowdsec. It’s possible to set up things like Pangolin which ultimately use a VPN between external and internal access points but not at the client, though it takes more setup if you want to use apps over pangolin instead of just the browser.
if theyre close, add them to your tailscale, if not and you have a web serve, use a reverse proxy.
for tailscale, you’d probably have to walk them through setting it up but then its one and done
That’s basically the VPN solution but with a little more flexibility.
If you want to actually expose the service, you can use Tailscale to connect it to a VPS and then expose that port to the web with Nginx, but if you do that, be prepared on the security front because…you know…open internet be full of hazards.
Ask them to use the Jellyfin web, and you expose it to the public via Netbird / Pangolin locked behind SSO
Depends on what you mean by “secure.” My personal setup is Jellyfin LXC on proxmox –> Wireguard to VPS -> Nginx reverse proxy on VPS.
This setup relies somewhat on Jellyfin’s auth, but I’m comfortable with that risk. The LXC is blocked from sending local traffic on my network by firewall rules. Yes, someone could exploit a vulnerability in Jellyfin (though looking through the CVEs I’m not overly worried about that), then escape the LXC and fuck with my server. But that’s a lot of work for no profit.
For more protection (in sense of reducing traffic that even interacts with your server), I’d recommend getting a wildcard cert for the domain so that the actual subdomain jellyfin is on is undisclosed to anyone not using your service.
Security isn’t about making everything impregnable, it’s about making attacks more trouble than they’re worth. Otherwise, we’d all live in fortified bunkers surrounded by landmines. 🙃
How much bandwidth is used via the VPS in this instance? I’ve seen most VPS in the USA have a limit of 1TB of bandwidth.
How many users are you sharing with?
I know Hetzner does 20TB bandwidth, but that is only EU servers as far as I know.
I have a very cheap ($11/yr) us-based vps through racknerd I got via low end box. I’ve got 12 users but only 5 really active ones and I’ve never come close to hitting the 1tb transfer. I serve several services through that one vps (all just reverse proxy to my homelab).
I did just pick up another u.s. based vps through low end box the other day- $12/yr and unmetered Gbps. 1 CPU only, but a reverse proxy doesn’t need a lot of compute. :)
Your vps isn’t doing anything useful security wise… it’s just sending traffic directly to jellyfin.
You’d get the same protection with just port forwarding to a local proxy in front of jellyfin. Or you could even leave out the proxy if you didn’t need it.
I’m aware of this (that’s why I described a potential breach as Jellyfin -> LXC escape). What it does provide me is a static IP to point my domain at that I don’t have to worry about updating via whatever DDNS service and that isn’t tied to my home address. That and the wireguard tunnel gives me plausible deniability should my ISP ever decide to enforce its rules against hosting servers. 😀
I agree with the folks saying reverse proxy of some kind + WAF. That way end users don’t have to deal with the VPN, but your home system is not directly exposed.
I’ve been doing something similar with SSH local port forwarding and a $5/month VPS. Haven’t come anywhere close to my network quotas, and performance has not been an issue for home use with 2-5 concurrent users most of the time. I forward the local caddy ports to unprivileged ports/user on the VPS, then use the firewall on the VPS to forward that port to 443 and lock down the rest.
That said, VPN would be much more manageable if I was trying to really push performance or scale out the network.
best practice states security through obscurity is not to be relied upon, but compare ssh logs after one year on the default port vs a non-standard port and you’ll immediately see why you want to use a non-standard https port for non-professional services. it cuts 99.9% of the noise/attempts.
Secure is relative, you should be aware that jellyfin itself has security issues github.com/jellyfin/jellyfin/issues/5415 most of which are harmless, but at least one is fairly serious and allows people to watch your media without authentication, and adding an extra layer of authentication on the proxy would likely cause issues with clients.
That being said, if you’re okay with those security issues what I would do is have a cheap VPS, connect both machines to tailscale, and have something like Caddy on the VPS to do the forwarding.
Just leaving this here
github.com/jellyfin/jellyfin/issues/5415#issuecom…
Except most people have almost the same structure because of media organizers like radarr/sonarr. At the very least they should hide that behind a setting to not require auth (since the header should be there for most clients) so only people running an old client would be affected. They could also add an extra salt to that hash or something similar.
I agree, it’s not critical, but it shouldn’t be hand waved either. And like I said, security is relative, I would argue for most people this is fine, but I still think this should be taken more seriously.
Yeah not only would a lot of people have the same media name, because of docker mounts, probably a lot of people have the same path to the media inside of the docker container even if the external location is different. I bet you could make a rainbow table of sorts of the most popular movie/TV torrents combined with the most common place in the container for media to be mounted, then use shodan to get a list of hundreds of instances that you could scan for the common hashes.
I’m just seeing the issue for the first time and noticed it was raised 5 years ago - surely that was enough time to at least put forward a changeover date and give clients time to update.
Jokes on them, my paths are a shitshow and I can’t be bothered to organize them properly
Do you not do any renaming? That probably would make it even easier as you can just brute force with a database of filenames scraped from torrents. I already have a proof of concept that generates valid jellyfin IDs from any given file path, it only takes a few more steps before you can plug in a shodan scan of jellyfin instances and just shotgun a bunch of IDs generated from torrents.csv at them and find stuff you can stream without authentication.
People not bothering to rename, using the default radarr naming scheme, or everyone using the same naming pattern from trash guides just makes it easier.
Probably the only way to guarantee nobody can probe your media and stream it without authentication is to make sure to rename everything using a format that only you use or mount all your media under a path inside docker that contains a long randomly generated folder prefix.
It really seems overblown of an issue…
afaik but I’m not sure, Jellyfin lacks support for OIDC AuthN which is a clear sign that you cannot expose this publicly.
There’s a plugin for that.Plugin is archived and will become outdated (and unsafe to use) over time. Don’t use it.says repo is archived
Oops. I tried it in the past and just linked to quickly without taking a close look at the repo. I’ve updated the above posting. Thanks for pointing this out.
*Archived, arrived just means it is here
You don’t say. My autocorrect had a mind of its own again. Fixed it.
If that is the same as oAuth, that can be done with a plugin.
But yes, that’s not native.
I use a Wireguard tunnel to a VPS and fail2ban with geoblocking: codeberg.org/skjalli/jellyfin-vps-setup
I toyed with the idea of exposing ports and decided against it. I don’t understand networking well enough yet. For me specifically, VPN access has been perfectly workable in the US with both speed and ease of access.
Can you use fail2ban on Jellyfin? That might be a wise step.
Tailscale or cloudflare
Not at all, there’s legal risk if you’re hosting your blurays. Cloudflare even explicitly forbids such use. VPN or nothing imo.
Legal risk of bluray rips, as opposed to other media types?
Wow, Cloudflare is against piracy? Every single site I’ve ever seen in my life is registered with Cloudflare and uses their DNS with the exception of PTB I believe.
Not sure about that, I think it’s more just that they don’t want people streaming terabytes of traffic through their edge.
Well, I don’t know. Cloudflare seems to be the standard, again with that one exception, and the only reason PTB has a different situation is because the founders had a connect.
Set up a reverse proxy with https always on. And get a good (physical) firewall, preferably something akin to opnsense, pfsense, openwrt. Exposing is always a risk, and if you do want it, you have to bear the responsibility for your own security. Keep things up to date, set up monitoring and a good logging system (Wazuh) comes to mind.
Exposure means a security risk. How you deal with that security risk is your choice.
Cloudflare and the likes forbid usage of their stuff for these things.
How does a reverse proxy helps for security? I mean, the problem here is that exposing Jellyfin on the internet is dangerous: the only way to improve security via a reverse proxy would be mTLS, but I’m not sure how it would work client side.
You’ve got a couple benefits. If you have a domain name, and aren’t advertising it publicly, then you can use the reverse proxy to point that domain to a non-standard port that Jellyfin runs on.
Security through obscurity is not good security, but it does prevent the majority of port scanning attacks. You can also use fail2ban on the reverse proxy side to try and mitigate some attacks.
By setting up a reverse proxy you redirect the traffic through that specific proxy which means less open ports (basically just 80/443), less monitoring, the ability to easily put a WAF inbetween, etc.
😬
Cf used to have it against the rules, but it’s fine now.
Ah cool, didn’t know!
For a remote and non-technical user I would say IP whitelisting offers a decent tradeoff.
On your end you expose your jellyfin port to internet, but restrict at the router level to your user’s client IP address as soon as you have it. Obviously in practice this works best if the address does not change often.
If anyone has any tips for getting Tailscale running via Docker on my Openmediavault machine, I’m open to it. Everyone lauds it for being dead simple and I cannot for the life of me get it running on the machine it needs to be. Not sure my wife can/will handle anything more complicated.
Just read their actual documentation. You’ll want to either way.
Ask them to visit ipv4.icanhazip.com and give you back the number, then whitelist in your webserver, as well as your LAN/VPN range, deny rest. Explain they can only reach jellyfin from their home internet. Repeat if they get 403 forbidden after they get a new WAN IP.
That or VPN like openziti, wireguard but gets more complicated.
Perhaps (and I know I might be weird) running pangolin on something like hetzner? (Which I do)
Run the jellyfin in a container that only has read privileges to the videos ( make sure you can’t get out to your whole NAS from there), put that behind a Cloudflaired tunnel.
It’s not technically secure, but if they can’t get a foothold in your network and the only thing they can access is your video catalog, that’s a reasonable amount of risk.