Last active
November 28, 2024 06:15
-
-
Save pR0Ps/92217e826bdbf7e5e65db5baf0026c23 to your computer and use it in GitHub Desktop.
Nginx config for running a public, read-only, multi-user, account-less Plex instance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Goals: | |
# - Allow access without having to deal with Plex accounts | |
# - Only allow read-only access (no changing tags, fixing matches, etc) | |
# - Don't leak information between users (what has been watched, play progress, etc) | |
# - Prevent users from claiming the server, changing settings, or acessing internal information | |
# - Allow administration of the server for people with SSH access to it | |
# Basic setup instructions: | |
# - Install Nginx on the same server as Plex and load this config file (usually just a matter of | |
# dropping it into `/etc/nginx/conf.d`) | |
# - Configure Plex to accept auth-less access from localhost (through the UI or by setting | |
# `allowedNetworks` in the server settings) | |
# - Block access to Plex for anything except localhost using `iptables` (make sure the rules | |
# persist across reboots!): | |
# ``` | |
# iptables -A INPUT ! -i lo -p tcp --dport 32400 -j DROP | |
# ip6tables -A INPUT ! -i lo -p tcp --dport 32400 -j DROP | |
# ``` | |
# - Visit `http://yourserver` to confirm everything works (also confirm that | |
# `http://yourserver:32400` _doesn't_ work) | |
# - Deploy it to your users (add HTTPS, some sort of access control, forward ports, etc) | |
# Administration | |
# - Forward local port `32400` to the server using SSH | |
# (`ssh -L 127.0.0.1:32400:127.0.0.1:32400 yourserver`) | |
# - Load `http://127.0.0.1:32400` in a browser and administrate away | |
# Should work for all recent versions of the Plex server (API doesn't seem to change much) | |
# Latest confirmed working version: 1.41.2.9200 | |
upstream plex { | |
server 127.0.0.1:32400; | |
} | |
server { | |
listen 80; | |
listen [::]:80; | |
# Make Plex think everything is coming from localhost | |
# This bypasses IP/domain checks and login redirection | |
proxy_set_header Host "127.0.0.1"; | |
proxy_set_header Referer "http://127.0.0.1"; | |
proxy_set_header Origin "http://127.0.0.1"; | |
proxy_set_header X-Real-IP "127.0.0.1"; | |
proxy_set_header X-Forwarded-For "127.0.0.1"; | |
# Prevent Plex from responding to requests with compressed data as this would prevent the | |
# inline modifications to the responses from working. | |
proxy_set_header Accept-Encoding ""; | |
# Use a CSP to prevent the browser from loading any external content (*.plex.tv, analytics, etc.) | |
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: blob:"; | |
# Default to only allowing GET requests to Plex. | |
# (prevents the majority of ways of changing the server's state) | |
location / { | |
if ($request_method != "GET") { | |
return 403; | |
} | |
# Rewrite the bare domain to the web interface (unless it's an API call) | |
set $rewrite 1; | |
if ($arg_X-Plex-Client-Identifier != '') { | |
set $rewrite 0; | |
} | |
if ($http_x_plex_client_identifier != '') { | |
set $rewrite 0; | |
} | |
if ($rewrite = 1){ | |
rewrite ^/$ $scheme://$http_host/web/index.html redirect; | |
} | |
# Rewrite the "myPlexSigninState" key of API responses to tell the frontend that the | |
# server is claimed, preventing the "server is unclaimed and not secure" warning | |
# from showing up. This key is returned in requests to both `/` and | |
# `/media/providers` | |
sub_filter_types application/json text/xml; | |
sub_filter_last_modified off; | |
sub_filter_once on; | |
sub_filter '"myPlexSigninState":"none"' '"myPlexSigninState":"ok"'; # JSON | |
sub_filter 'myPlexSigninState="none"' 'myPlexSigninState="ok"'; # XML | |
proxy_pass http://plex; | |
} | |
# Allow GET/POST/PUT/DELETE requests to the playQueues endpoint. | |
# This allows users full control over their individual play queues. | |
location /playQueues { | |
proxy_pass http://plex; | |
} | |
# Allowing PUT requests to the /library/parts endpoint allows enabling | |
# subtitles. Unfortunately this setting is persisted different sessions | |
# so one user changing the setting affects others. It is therefore | |
# disabled by default. | |
#location /library/parts/ { | |
# proxy_pass http://plex; | |
#} | |
##### | |
# Disable a bunch of endpoints that use GET requests to modify things or return sensitive | |
# information | |
##### | |
# Prevent all websocket traffic as it's not required and can return data like server logs | |
location /:/websockets/ { | |
return 403; | |
} | |
# Disable claiming the server or changing the settings | |
location /myplex { | |
return 403; | |
} | |
# Disable access to server/library preferences | |
location ~* ^/(.+/)?prefs { | |
return 403; | |
} | |
# Disable marking media as played | |
location ~* ^/:/(un)?scrobble { | |
return 403; | |
} | |
# Disable saving of progress in stream | |
location ~* ^/:/(timeline|progress) { | |
return 403; | |
} | |
# Disable emptying the trash or starting a manual rescan | |
location ~* ^/library/sections/.+/(refresh|emptyTrash) { | |
return 403; | |
} | |
# Disable access to the file browser | |
location /services/browse { | |
return 403; | |
} | |
# Disable access to currently-running activities | |
location /activities { | |
return 403; | |
} | |
# Disable access to account information | |
location /accounts { | |
return 403; | |
} | |
# Disable access to device information | |
location /devices { | |
return 403; | |
} | |
# Disable access to client information | |
location /clients { | |
return 403; | |
} | |
# Disable access to server status | |
location /status { | |
return 403; | |
} | |
# Disable access to update information | |
location /updater { | |
return 403; | |
} | |
# Disable generating access tokens for the server | |
location /security { | |
return 403; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment