Why an exposed Jellyfin server needs a watchdog
If your Jellyfin server answers on a public address, it is being scanned every day. Bots probe for /.env, wp-login and path traversal tricks, try passwords in bursts, spray a list of accounts from one address, and sometimes succeed after a long run of failures. Others look for a way in through a new administrator, an API key or a changed setting.
Reading logs after the fact is slow. Security Notifications watches the server's events and log and turns those signals into alerts on the channel you already look at — Telegram, e-mail, a webhook (Discord, Slack, ntfy, Gotify or plain JSON) or the Jellyfin activity log. This tutorial sets it up for jellyfin security work: getting the right alert, with enough context to act, and without a flood of noise.
fail2ban is still useful and complementary: it blocks repeat offenders at the network level. Security Notifications tells you what is happening and who is doing it, including things fail2ban cannot see, like a new admin or a mass deletion.
Prerequisites
- Jellyfin Server 12.2 or newer, on Linux, Windows or Docker.
- A MediaLab Works account with a license that covers the plugin: an active subscription, a lifetime license within its update window, the Jellyfin bundle, or the free 30-day trial.
- For Telegram: a bot. For e-mail: an SMTP server (port 587 with STARTTLS is recommended). For a webhook: the address of your Discord, Slack, ntfy or Gotify endpoint, or any URL that accepts JSON.
- Optional but recommended: fail2ban already running in front of the server.
Step 1 — Install the plugin
The cleanest route is your private plugin repository, so Jellyfin installs and updates the plugin itself:
- In your MediaLab Works account open Licenses → Jellyfin plugin repository, click Create address and copy it. It is private (it contains a token), so do not share it; you can regenerate or revoke it at any time.
- In Jellyfin open Dashboard → Plugins → Repositories, click +, name it (for example MediaLab Works), paste the address and save.
- In Dashboard → Plugins → Catalog find Security Notifications by MediaLab, click Install, then restart Jellyfin.
You can also install from the public catalog (https://medialab.works/jellyfin/manifest.json) or manually from a zip file into the plugins folder (/var/lib/jellyfin/plugins/ on a Linux package install, /config/plugins/ in the Docker config volume, %ProgramData%\Jellyfin\Server\plugins\ on Windows). The guide has the exact steps for each.
Step 2 — Activate the license
Open Dashboard → Plugins → Security Notifications by MediaLab and click Open License page. Paste your license key and click Activate with key: the plugin binds the key to this server and shows the license as Active. No key yet? Enter your e-mail on the same page to start the 30-day trial.
The license is checked once a day and at every Jellyfin start; without internet the plugin keeps working for 7 days after the last successful check. Background tasks run only with a valid license and the plugin enabled.
Step 3 — Connect a channel and send a test
Open Security Notifications in the dashboard menu and go to the Channels tab. Every channel is off by default; turn on what you want and set a minimum severity for each.
- Telegram: enter the bot token, send
/startto the bot (or add it to a group), then click Find to fill in the chat. - E-mail: add recipients and your SMTP server. Port 587 with STARTTLS is recommended; port 465 with implicit TLS is not supported. If Registration by MediaLab is installed, you can reuse its SMTP server.
- Webhook: choose Discord, Slack, ntfy, Gotify or JSON and paste the address. The address contains the token and is stored apart from the settings. For Gotify, add
?token=…to the/messageaddress. - Jellyfin activity log: alerts also appear in the dashboard's activity list.
Click Send a test on each channel before you rely on it. Then open Settings and pick a Location source: DB-IP Lite (free, no account) or MaxMind GeoLite2 (your account id and license key). Geolocation happens locally; IP addresses are never sent anywhere. Without location, the new-country, impossible-travel and new-network rules cannot work.
Step 4 — Tell the plugin about your network
Still in Settings, add your trusted networks (CIDR) — your own VPN, for example. Private networks and those in Jellyfin's network settings are included automatically. If Jellyfin sits behind nginx, Caddy, Traefik or similar, turn on The server is behind its own proxy so forwarded headers are expected; Cloudflare is recognized by itself. This keeps the spoofed-proxy-header rule meaningful.
Leave the Bad IP lists on: Tor exit nodes are refreshed hourly and Spamhaus DROP daily. Both are downloads only.
Step 5 — Tune the 20 rules
Open the Rules tab. Each rule has its own switch, a severity and, where it applies, thresholds. The rules cover four groups:
- Attacks on accounts: bursts of wrong passwords from one address, many accounts tried from the same address (password spraying), a successful sign-in after many failures, a locked account.
- Unusual sign-ins: a new country or impossible travel; an administrator signing in from a new device, a new network, from outside the local network or at an unusual hour; sign-ins from a Tor exit or a known bad network.
- Sensitive changes and damage: a new administrator, a password change, an account deleted, an API key created or deleted, a plugin installed or removed, critical settings changed (remote access, HTTPS, trusted proxies, ports, UPnP), mass deletion from a library, one account used from too many places at once.
- Signs of compromise: scans and probes (
/.env,wp-login, path traversal), spoofed proxy headers, "Forgot password" used, backdoor files in the plugins folder, a server version with published vulnerabilities.
Start with the defaults, then adjust. Set the wrong-password threshold to how many failures in how many minutes you consider normal for your users, and set the administrator's usual hours so out-of-hours admin sign-ins stand out. Raise severity for rules you would always act on, such as a new administrator or a successful sign-in after many failures.
Step 6 — Cut the noise
On the Channels tab, the No spam settings decide how often you hear from the plugin: how often the same alert may repeat, bursts grouped into one message, quiet hours (only critical alerts go out at once, the rest arrive in a summary when they end) and an optional daily digest for medium and informational alerts. If Telegram gets busy, raise the minimum severity for that channel and keep the activity log for everything else.
Daily use and troubleshooting
- Overview shows recent alerts and the plugin's status; History lists every alert with filters and CSV export. Alert history keeps up to 5000 entries (configurable).
- No test message arrives? Check the minimum severity for that channel and use Send a test again. For e-mail, switch to port 587 with STARTTLS if you used 465.
- No Telegram chat found? Send
/startto the bot first, then click Find. - Too many sign-in alerts? Add your trusted networks and confirm the proxy setting; without location data the new-country and impossible-travel rules stay silent by design.
- Unknown users do not trigger failures? Failed sign-ins are detected from 401/403 responses, because Jellyfin emits no event for unknown users.
- After an update something breaks? On the License page, Roll back to x.y.z returns to the previous version; restart Jellyfin afterward. Note that automatic updates are then off for this plugin until you use Install update.
- Keep fail2ban running. Let it ban the noisy scanners; let Security Notifications tell you what happened, from where, and what to check.
Conclusion
A public Jellyfin server will be probed. With Security Notifications installed, the signals that matter — password spraying, impossible travel, /.env probes, a new admin — arrive as alerts with the account, address, country, device and a hint of what to check. Set up one channel, send a test, tune the rules for a week, and you will have a quiet watchdog instead of a log you never read.
More details are in the user guide, the changelog and our knowledge base. Questions? Contact us.
Product page: /products/jf-securitynotifications