How to Setup Plex With Cloudflare CDN⚓︎
Summary⚓︎
This article will explain how to leverage Cloudflare CDN to accelerate Plex streaming. It's assumed that a Cloudflare account has already been created with a domain already configured. Plex is also assumed to already be installed.
NGINX Settings⚓︎
SSH to your server and create a .conf file for your NGINX proxy
Copy and paste the below configuration into plex.conf:
plex.conf
#Must be set in the global scope see: <https://forum.nginx.org/read.php?2,152294,152294>
#Why this is important especially with Plex as it makes a lot of requests <http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html> / <https://www.peterbe.com/plog/ssl_session_cache-ab>
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#Upstream to Plex
upstream plex_backend {
#Set this to the IP address that appears in `ifconfig` (NATTED LAN IP or Public IP address) if you want the bandwidth meter in the server status page to work
server 192.168.30.7:32400;
keepalive 32;
}
server {
listen 80;
#Enabling http2 can cause some issues with some devices, see #29 - Disable it if you experience issues
listen 443 ssl http2; #http2 can provide a substantial improvement for streaming: https://blog.cloudflare.com/introducing-http2/
server_name xen-plex.davelevine.io;
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/nginx/ssl/distributedcomputing.io.pem;
ssl_certificate_key /etc/nginx/ssl/distributedcomputing.io.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
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$
#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/nginx/ssl/distributedcomputing.io.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 /path/to/dhparam.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$
#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 encounte$
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;
#When using ngx_http_realip_module change $proxy_add_x_forwarded_for to '$http_x_forwarded_for,$realip_remote_addr'
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
#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;
}
#PlexPy forward example, works the same for other services.
#location /plexpy {
# proxy_pass http://127.0.0.1:8181;
#}
}
Press ctrl+x and Y to save and exit. Ensure that nginx reflects the changes by issuing a restart with service nginx restart.
Danger
Failure to configure CloudFlare correctly will result in page loading errors. Under no circumstance do we want CloudFlare to cache any of the data Plex plays. This will result in your account getting terminated.
DNS Setup⚓︎
Assuming you already completed the initial setup of CloudFlare, the following records should be listed:
- A-record for your davelevine.io pointing to server IP.
- Use CNAME for the subdomain (xen-plex.davelevine.io) pointing to domain.com (@ will also work)
Note
“Orange cloud” means your domain is behind CloudFlare proxy. You will no longer be able to SSH using your domain name. Instead use the server IP.
SSL/TLS⚓︎
| Setting Name | Value |
|---|---|
| SSL | Full |
| Edge Certificates | |
| Always Use HTTPS | Yes |
| HTTP Strict Transport Security (HSTS) | Yes |
| Include Subdomains: On, Preload: On | |
| Minimum TLS Version | TLS 1.2 |
| Opportunistic Encryption | Yes |
| TLS 1.3 | Yes |
| Automatic HTTPS Rewrites | Yes |
| Disable Universal SSL | Keep Universal SSL On |
Caching⚓︎
| Setting Name | Value |
|---|---|
| Caching Level | Standard |
| Browser Cache Expiration | Respect Existing Headers |
| CSAM Scanning Tool | Off |
| Always Online | Off |
| Development Mode | Off |
Page Rules⚓︎
Danger
Missing Page Rule settings will result in your CloudFlare account getting closed!
Create a rule and add the additional settings:
| Setting Name | Value |
|---|---|
| SSL | FULL |
| Cache Level | Bypass |
| Automatic HTTPS Rewrites | Yes |
Network⚓︎
| Setting Name | Value |
|---|---|
| HTTP/2 | On |
| HTTP/3 (with QUIC) | On |
| 0-RTT Connection Resumption | On |
| IPv6 Compatibility | Off |
| WebSockets | On |
| Onion Routing | Off |
| Pseudo IPv4 | Off |
| IP Geolocation | On |
| Maximum Upload Size | 100mb |
Cloudflare as Content Delivery Network (CDN) for Plex⚓︎
Plex Settings⚓︎
- Go to https://app.plex.tv > Settings > Network (Show Advanced settings)
| Plex Network Setting | Value |
|---|---|
| Treat WAN IP As LAN Bandwidth | Checked |
| Custom server access URLs | https://xen-plex.davelevine.io:443 |
It is important that you make sure https:// and :443 is included!
Plex Remote access⚓︎
Disable Remote Access. Everything will still connect, including all the apps. Remote Access will show as “red”. Learn to ignore this. Everything will still connect provided the above steps were followed.
Flushing Cache⚓︎
Once you have applied these changes, make sure you clear your browser cache and purge the CloudFlare cache!
Bandwidth Usage control⚓︎
When setup have been running for a while pay attention to the Analytics tab in CloudFlare. All data should be listed as uncached bandwith.
References⚓︎
https://quickbox.io/knowledge-base/setting-up-cloudflare-and-plex-cdn/