Edge Shield for Jellyfin

For Jellyfin: set up Cloudflare from the dashboard: DNS and DDNS, SSL Full (strict), a Let's Encrypt certificate, edge rules and failed-login blocking.

Connect once with a Cloudflare API token limited to your zone: it is kept encrypted on the server and never shown again1 of 8

Putting a Jellyfin server behind Cloudflare usually means a dozen manual steps in two places, and an easy mistake: sending video through the Cloudflare CDN, which the Cloudflare terms for Free, Pro and Business plans do not allow. Edge Shield for Cloudflare® does the whole setup from the Jellyfin dashboard, with your own Cloudflare API token, and keeps the video streams going straight to your server.

What it does

  • Connection: an API token restricted to your zone, stored encrypted (AES-256-GCM) on the server and never shown in the browser again; zone choice and a check of every permission the token needs.
  • "Stream offload" (recommended mode): the app host (for example media.example.com) goes through the Cloudflare proxy for the web interface, the API and the sign-in, while video, audio and download requests are redirected (307) to a streaming host (for example direct.example.com) that is "DNS only" and goes straight to your server. A "DNS only" mode is there for anyone who does not want the proxy.
  • DNS: the A / AAAA records of both names, with the public IP detected and kept up to date automatically (DDNS).
  • TLS in Cloudflare: SSL Full (strict), Always Use HTTPS, minimum TLS version, TLS 1.3, optional HSTS.
  • Let's Encrypt certificate for both names through ACME DNS-01 (with the same token, no port 80 needed), renewed automatically 30 days before it expires and set in Jellyfin as a .pfx file.
  • Cloudflare rules that fit the Free plan: the stream redirect, no caching of media paths, the block list, blocking of client-sent IP headers, allowed countries, a login rate limit and the origin port (for example when your router uses 2096 outside). Your own rules stay untouched; Remove the Edge Shield rules deletes only what the plugin created.
  • Real client IP: the Cloudflare IP ranges are written to Jellyfin's known proxies and refreshed daily, so Jellyfin sees the visitor's address and cannot be shown a fake one.
  • The streaming host accepts media paths only: any other request on that name gets 403, and blocked IPs are refused by Jellyfin itself too, also on the direct host.
  • Dynamic protection: an IP with too many failed sign-ins (5 in 10 minutes by default) goes into the Cloudflare list medialab_blocked and is blocked at the edge for 24 hours, ×4 on every repeat (at most 30 days); entries expire by themselves. Allowlist, manual block and unblock, and a timed Under Attack switch that turns itself off.
  • Status and fixes: every point checked, with a Fix button per row and Fix everything; the firewall commands to restrict the port are shown, ready to copy.
  • In English and Romanian.

What it sends where

  • To Cloudflare, through its API and with your own token: the zone settings, the DNS records (with your server's public IP), the rules, and the IP addresses to block. The comment of a block-list entry holds the expiry time and the reason (the number of failed sign-ins, or "manual" with the note you wrote for a manual block). Since 0.1.1 the attempted user name is no longer sent to Cloudflare: it stays on your server only, in the block list and the log of the plugin page.
  • To find your public IP (DDNS), the server reads https://www.cloudflare.com/cdn-cgi/trace; the list of Cloudflare IP ranges is read daily from the public Cloudflare API.
  • To Let's Encrypt: the certificate request for your two host names (and the e-mail address, if you enter one). The private key is created on your server and never leaves it.
  • The token is stored only encrypted on your server and is never sent to the browser.
  • Nothing goes to medialab.works except the license check.

Full details for every product, including what stays on your server: Licensing, privacy and compatibility.

Client compatibility

Edge Shield works at the server and network level, so it applies to every app. What has been verified so far:

  • Jellyfin Web and medialab Server: real playback through "stream offload", with no video bytes through Cloudflare.
  • Jellyfin apps (Android, Android TV, Swiftfin, Findroid, Kodi/JellyCon, Infuse, Streamyfin) and TV browsers: not tested yet. In "stream offload" mode an app must follow the 307 redirect for media; if one does not, use the "DNS only" mode.
  • Edge Shield has been checked against a simulator of the Cloudflare API; the check against the real Cloudflare API is still in progress.

Requirements

  • Jellyfin Server 12.2 or newer.
  • A Cloudflare account with your domain's zone in it; the Free plan is enough.
  • A Cloudflare API token ("Custom token", restricted to your zone) with: Zone · Zone · Read, Zone · DNS · Edit, Zone · Zone Settings · Edit, Zone · SSL and Certificates · Edit, Zone · Zone WAF · Edit, Zone · Single Redirect · Edit, Zone · Cache Rules · Edit, Zone · Origin Rules · Edit, Account · Account Filter Lists · Edit. The plugin page lists them and checks them.
  • For "stream offload": HTTPS ports forwarded from your router to Jellyfin for the app host and for the streaming host.

Limits

  • The streaming host is "DNS only", so your server's public IP is visible to anyone who looks it up. On it, Jellyfin answers only media requests, which still need a valid Jellyfin token.
  • Under Attack asks every visitor for a JavaScript check: native apps (Android TV, Roku, iOS, Kodi…) cannot pass it and will not connect while it is on. Use it only during an attack, briefly.
  • No Cloudflare Tunnel and no Origin CA certificate in this version: both would send video through Cloudflare or need a certificate that browsers do not trust on the direct host.
  • Jellyfin reads its network settings at start-up: the certificate, HTTPS and the Cloudflare ranges in the known proxies take effect after you restart Jellyfin.

Licensing

The plugin is open source (GPL-3.0). The ready-to-install builds are public, like the source code. What you buy is the subscription: the license to use the plugin on one Jellyfin server, the updates your plan includes, and support: every update while the subscription is active, through your private plugin repository, and help when something does not work. The plugin checks the subscription key once a day; without a valid subscription it stops until you renew (nothing is deleted). Monthly, yearly or lifetime (lifetime includes one year of updates), or included in the Jellyfin bundle. 30-day free trial.

Source code. For every release, the complete corresponding source code is public, next to the build, in the changelog, and also in your account (Account → Licenses, Source code); each archive contains the full GPL-3.0 text (LICENSE). If you need the source of a version you can no longer download, ask us and we send it. See section 10 of the EULA.

Our own code, written from scratch by MediaLab Works; it contains no third-party code. Cloudflare is a registered trademark of Cloudflare, Inc.; Edge Shield is not affiliated with or endorsed by Cloudflare.

Works best with medialab Server

This plugin works on official Jellyfin 12.2 or newer. On medialab Server, our Jellyfin-based server with the same data, libraries, users and apps, it works better:

  • Verified – medialab. The server checks the signature of our plugins and shows you that the files are exactly the ones we published. A plugin changed after publishing is flagged.
  • Built into the interface. Plugins can add buttons and links to your users' menu (for example "TV", "Share") with no manual web configuration.
  • Priority by default. medialab plugins come first where it matters: Live TV tuners, guide sources and subtitle providers. The order stays yours: you can change it at any time.
  • The medialab.works catalog included, installing without extra confirmations.
  • Updates from the web UI, no terminal (with Self-Update by MediaLab): check, update and roll back from the dashboard; if a new version fails to start, the server rolls back on its own with your data intact.
  • The same Jellyfin, up to date. medialab Server follows the stable Jellyfin 12.x releases every week; a new version is published only after it passes every test, including the tests of our plugins.

Jellyfin apps (Android, iOS, TV, web) connect exactly as they do to official Jellyfin.

To install it, run the container image (guide) or, on Debian 12, the apt packages, which replace jellyfin-server and jellyfin-web and keep your data in place (guide).

medialab Server is free software (GPL-2.0), based on Jellyfin. The source code is public: medialab-server and medialab-server-web.

Requirements

  • Jellyfin Server 12.2 or newer (Linux, Windows or Docker)
  • A Cloudflare account with your domain's zone (the Free plan is enough)
  • A Cloudflare API token restricted to the zone, with the permissions listed on the plugin page
  • For stream offload: HTTPS ports forwarded to the server for the app host and the streaming host
  • Open source (GPL-3.0): the source code of each version is in your account

Latest version

0.1.5
released Oct 20, 2026
See all changes →