I spend quite some time to figure out how nginx needs to be configured to run a https vhost on port 443 and do a proper reverse proxying to my docker instance bound to localport:32400. Proxy_pass sends the data to http://localhost:32400.
When the container is bound to localhost:32400, even the claim process is not working (which makes sense if the reverse proxy settings are wrong and no network connection can be established).
If I add a Custom Access Url, the containerized Plex intance is not reachable anymore (which makes sense because the server is not claimed?)
Do I need to add the ssl-certificate to Plex? Actualy, I didn’t
Do I need to enforce secure connections, even though ssl terminates at the reverse proxy?
When do i need to add the Custom Access URL?
Finally, i have a solution that seem to work fine.
The nginx configuration is gathered from severall sources. Thank you, who ever created this script initialy
upstream plex_backend {
server localhost:32400;
keepalive 32;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name example.myplexdomain.com;
return 301 example.myplexdomain.com$request_uri;
}
server {
listen 443 ssl http2; #http2 can provide a substantial improvement for streaming: https://blog.cloudflare.com/introducing-http2/
server_name example.myplexdomain.com;
send_timeout 100m; #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause (e.g. Chrome)
#Faster resolving, improves stapling time. Timeout and nameservers may need to be adjusted for your location Google's have been used here.
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
#Use letsencrypt.org to get a free and trusted ssl certificate
ssl_certificate /etc/letsencrypt/live/myplexdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myplexdomain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384.
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
#Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/
ssl_stapling on;
ssl_stapling_verify on;
#For letsencrypt.org you can get your chain like this: https://esham.io/2016/01/ocsp-stapling
ssl_trusted_certificate /etc/letsencrypt/live/myplexdomain.com/chain.pem;
#Reuse ssl sessions, avoids unnecessary handshakes
#Turning this on will increase performance, but at the cost of security. Read below before making a choice.
#https://github.com/mozilla/server-side-tls/issues/135
#https://wiki.mozilla.org/Security/Server_Side_TLS#TLS_tickets_.28RFC_5077.29
#ssl_session_tickets on;
#ssl_session_tickets off;
#Use: openssl dhparam -out dhparam.pem 2048 - 4096 is better but for overhead reasons 2048 is enough for Plex.
ssl_dhparam /config/nginx/dhparams.pem;
#ssl_ecdh_curve secp384r1;
#Will ensure https is always used by supported browsers which prevents any server-side http > https redirects, as the browser will internally correct any request to https.
#Recommended to submit to your domain to https://hstspreload.org as well.
#!WARNING! Only enable this if you intend to only serve Plex over https, until this rule expires in your browser it WONT BE POSSIBLE to access Plex via http, remove 'includeSubDomains;' if you only want it to effect your Plex (sub-)domain.
#This is disabled by default as it could cause issues with some playback devices it's advisable to test it with a small max-age and only enable if you don't encounter issues. (Haven't encountered any yet)
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
#Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off. (Haven't encountered any yet)
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml;
gzip_disable "MSIE [1-6]\.";
#Nginx default client_max_body_size is 1MB, which breaks Camera Upload feature from the phones.
#Increasing the limit fixes the issue. Anyhow, if 4K videos are expected to be uploaded, the size might need to be increased even more
client_max_body_size 100M;
#Forward real ip and host to Plex
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Plex headers
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
proxy_set_header X-Plex-Device $http_x_plex_device;
proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
proxy_set_header X-Plex-Platform $http_x_plex_platform;
proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
proxy_set_header X-Plex-Product $http_x_plex_product;
proxy_set_header X-Plex-Token $http_x_plex_token;
proxy_set_header X-Plex-Version $http_x_plex_version;
proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
proxy_set_header X-Plex-Provides $http_x_plex_provides;
proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
proxy_set_header X-Plex-Model $http_x_plex_model;
proxy_set_header Host $server_addr;
proxy_set_header Referer $server_addr;
proxy_set_header Origin $server_addr;
#Websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#Disables compression between Plex and Nginx, required if using sub_filter below.
#May also improve loading time by a very marginal amount, as nginx will compress anyway.
#proxy_set_header Accept-Encoding "";
#Buffering off send to the client as soon as the data is received from Plex.
proxy_redirect off;
proxy_buffering off;
location / {
#Example of using sub_filter to alter what Plex displays, this disables Plex News.
#sub_filter ',news,' ',';
#sub_filter_once on;
#sub_filter_types text/xml;
proxy_pass http://plex_backend;
}
}
Settings i made:
custom access url: https://example.myplexdomain.com:443
secure connection: prefered
I even added a pcks12 certificate (just to be sure)
network: remote connections enabled, manual port 443
The fun thing is: the remote connection is shown as non functional. But in fact i am able to playback content on a mobile device that is not in the same network.
I am pretty sure, some of the settings Iapplied are unnecessary and i would like to reduce the config to the effective settings.
Seems like everything is working fine so far, even websockets and hsts is enabled and no errors appear in the firebugs network tab while accessing the page with plex web.
Do you allow the local subnet to skip authentication? Does Plex now honor the X-Forwarded-For header to determine that reverse-proxied clients are not local to the network and thus allowed to bypass authentication? Last time I played with this (long ago) the PMS saw the client was the reverse-proxy box (same network) and allowed everything in without authentication first.
my lan settings in the network settings is blank. As a result the machines from the same subnet should be consideren beeing external as well, shouldn’t they?
if I acces my domain with a browser that is not logged in into the sso plex identity, a dialog for sso login appears. Thus, authentification IS required to access the pms instance
Are you aware that plex provides an sso identity provider service?
It means that regardless where you do your first login, as long as you are authorized to accessed that particular instance with your user identity, you don’t need to relogin again… It might seem that no login is required…
Fun fact: you can do a successful login with google or facebook accounts and access plex web. Though, with no visible servers and an endless search for available servers.
List of IP addresses and networks that are allowed without auth
Comma separated list of IP addresses or IP/netmask entries for networks that are allowed to access Plex Media Server without logging in. When the server is signed out and this value is set, only localhost and addresses on this list will be allowed.
A lot of people will have that set to there local subnet (say 192.168.1.0/255.255.255.0) so that devices in their home do not have to authenticate. If your reverse proxy inside interface is sitting on that range (say 192.168.1.20) then the PMS will see the client as 192.168.1.20 and not require authentication rather than the client’s true IP address from WAN (unless something has changed).
Either you have that setting also blank, or your reverse proxy is not on the same LAN as your PMS, or they are honoring the X-Forwarded-For header, or your reverse proxy is passing the request with the client’s true IP instead of its own. I am not an nginx person, so I cannot necessarily tell from the config which it is.
Yes, I am familiar with SSO and the fact that Plex is using it, and I am familiar with cookies and whatnot that help keep you logged into Plex. Neither of these apply here.
@kopfpilot said:
my lan settings in the network settings is blank. As a result the machines from the same subnet should be consideren beeing external as well, shouldn’t they?
Like i already wrote, it is blank. Since the container is running on a bridged network, it’s subnet is a private docker subnet and the interface is bound against the lo interface of the host! The incomming traffic to the reverse proxy is from eth0 which is definity not the same network as my lo interface
Nov 03, 2017 21:03:40.733 [0x7f22a0bff700] DEBUG - Using X-Forwarded-For: x.x.x.x as remote address
x.x.x.x is my clients real ip.
Though, one thing is quite disturbing: the very same file that is streamed via direct play from my home pms instance, is transcoded from my vps instance. Md5sum calculates the same hash value for the local and the remote file.
For someone beeing unfamilar with sso, it might appear like no authentification would be required… wouldn’t it?
@kopfpilot said:
Though, one thing is quite disturbing: the very same file that is streamed via direct play from my home pms instance, is transcoded from my vps instance. Md5sum calculates the same hash value for the local and the remote file.
It seems to be a bug in the Samsung Smart Hub client - Even with remote qualy 12, which is equals to the 20MBit setting.
While playback with PMP does direct play.
seems like no one else either is in the same situation or everyone just don’t care about operating plex behind a reverse proxy. Will mark it as solved now.
Pitty, i though this could be a chance to get the best possible reverse proxy configuration for all of us…
I have tried this with success but the connection is relayed instead of direct, how do you guys get around that issue? I have my plexserver set behind haproxy + pfsense
The above config is just playing fine. The streams are never relayed for me.
The only thing that is not working, is the indicator for remote accessibility in the server configurations.
The implementation to test remote accessiblity uses the IP rather than the URL, which naturaly fails for subdomain reverse proxying, if the ip itself is not reverse proxied to Plex as well.
Either, I live with the broken indicator or make the ip route to the same target as the subdomain. I feel the first is less of an evil.
@kopfpilot said: @JasonMeudt: what additional information did the provided link include comapared to this tread?
Sorry for the late reply… Out of town…
In short, outside of linking the two almost similarly entitled threads, the final post on the previous thread referenced the “Custom server access” entry, which, other than in your signature for remote connection issues or as a question in the initial post, goes entirely without mention in this thread.
Settings i made:
custom access url: https://example.myplexdomain.com:443
secure connection: prefered
I even added a pcks12 certificate (just to be sure)
network: remote connections enabled, manual port 443
You are right, I should have written “Custom Server Access url”, rather then just “custom access url”.
I assumed someone dealing with a reverse proxy would be able to understand it anyway. I was mistaken
Settings i made:
custom access url: https://example.myplexdomain.com:443
secure connection: prefered
I even added a pcks12 certificate (just to be sure)
network: remote connections enabled, manual port 443
You are right, I should have written “Custom Server Access url”, rather then just “custom access url”.
I assumed someone dealing with a reverse proxy would be able to understand it anyway. I was mistaken
Settings i made:
custom access url: https://example.myplexdomain.com:443
secure connection: prefered
I even added a pcks12 certificate (just to be sure)
network: remote connections enabled, manual port 443
You are right, I should have written “Custom Server Access url”, rather then just “custom access url”.
I assumed someone dealing with a reverse proxy would be able to understand it anyway. I was mistaken
Oooohhh… The sarcasm is literally dripping in this one. Lesson learned: Don’t jump into a conversation/thread where all but two posts are by the initial poster and expect something different/other than sarcasm.
It wasn’t ment to be sarcastic. I just reflected on what caused the missunderstanding and understood that I need to make sure I use the proper terms everyones knows from the ui.
Actualy, the whole thread can be closed or deleted. Reverse Proxy szenarios are not officialy supported by plex and appearently almost no one realy cares about them.
feisu: my container uses a port mapping that binds port 32400 to localhost only. -p 127.0.0.1:32400:32400.
My reverse-proxy host has exactly two open ports 443 and 22. Nothing else. Nginx proxies port 443 to 127.0.0.1:32400, which is the mapped port to the plex container.
Though, i am using a dedicated subdomain for that, which is also registered as “Custom Server Access url”.
This setup ensures that the CSA url is the single internet facing entry point to access the plex container.