Last active
December 9, 2023 19:02
-
-
Save hazcod/3ef10a15f52c171a7839 to your computer and use it in GitHub Desktop.
Apache2 reverse proxy vhost configuration for Plex. Rerquires modules ssl, proxy, wstunnel
This file contains 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
This current configuration is based of at least Server Version 1.16.5.1488 and Web Version: 3.108.2. | |
This updated config file allows the playing of trailers and TV Show theme music where as the previous one did not. | |
## Requirements | |
1. Apache version > 2.4 | |
2. A bunch of mod's enabled (proxy, ssl, proxy_wstunnel, http, dir, env, headers, proxy_balancer, proxy_http, rewrite) | |
3. Protocols h2 http/1.1 needs apachectl -V 2.4.17 and higher... | |
## Apache .conf file | |
``` | |
DEFINE plex_url 127.0.0.1 | |
DEFINE plex_port 32400 | |
DEFINE public_url subdomain.plex.tv | |
DEFINE email admin@subdomain.plex.tv | |
ServerTokens Prod | |
SSLStaplingCache "shmcb:${APACHE_LOG_DIR}/stapling-cache(150000)" | |
SSLSessionCache "shmcb:${APACHE_LOG_DIR}/ssl_scache(512000)" | |
SSLSessionCacheTimeout 300 | |
### If you have Google's Mod PageSpeed, disable it | |
#ModPagespeed Off | |
<VirtualHost *:80> | |
ServerName ${public_url} | |
DocumentRoot /var/www/offline | |
ServerAdmin ${email} | |
RewriteEngine on | |
RewriteCond %{SERVER_NAME} =${public_url} | |
RewriteCond %{HTTPS} off | |
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] | |
</VirtualHost> | |
<VirtualHost *:443> | |
ServerName ${public_url} | |
DocumentRoot /var/www/offline | |
ServerAdmin ${email} | |
ErrorLog ${APACHE_LOG_DIR}/${public_url}.error.log | |
CustomLog ${APACHE_LOG_DIR}/${public_url}.access.log combined | |
SSLEngine On | |
SSLCertificateFile /etc/letsencrypt/live/${public_url}/fullchain.pem | |
SSLCertificateKeyFile /etc/letsencrypt/live/${public_url}/privkey.pem | |
#Include /etc/letsencrypt/options-ssl-apache.conf | |
### Forbid the http1.0 protocol ### | |
Protocols h2 http/1.1 | |
#Options -Includes -ExecCGI | |
#LimitRequestBody 512000 | |
#FileETag None | |
#TraceEnable off | |
Timeout 360 | |
ProxyRequests Off | |
ProxyPreserveHost On | |
ProxyTimeout 600 | |
ProxyReceiveBufferSize 4096 | |
SSLProxyEngine On | |
RequestHeader set Front-End-Https "On" | |
ServerSignature Off | |
SSLCompression Off | |
SSLUseStapling On | |
SSLStaplingResponderTimeout 5 | |
SSLStaplingReturnResponderErrors Off | |
SSLSessionTickets Off | |
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS | |
Header always set Strict-Transport-Security "max-age=15552000; preload" | |
Header always set X-Content-Type-Options nosniff | |
Header always set X-Robots-Tag none | |
Header always set X-XSS-Protection "1; mode=block" | |
Header always set X-Frame-Options "SAMEORIGIN" | |
Header always set Referrer-Policy "strict-origin-when-cross-origin" | |
Header always set Content-Security-Policy "default-src 'self' https:; font-src 'self' data: ${plex_url} ${public_url}; media-src 'self' blob: data: https: ${plex_url} ${public_url} *.plex.direct *.plex.tv plex.tv; script-src 'self' 'unsafe-inline' 'unsafe-eval' ${plex_url} ${public_url} plex.tv *.plex.tv gstatic.com *.gstatic.com *.plex.direct; style-src 'self' ${plex_url} ${public_url} *.plex.direct 'unsafe-inline'; img-src 'self' data: blob: ${plex_url} ${public_url} plex.tv *.plex.tv *.plex.direct; worker-src *; frame-src 'none'; connect-src 'self' wss: https: ${plex_url} ${public_url} plex.tv *.plex.direct *.plex.tv;" | |
Header always set Feature-Policy "geolocation 'self'; midi 'self'; sync-xhr 'self'; microphone 'self'; camera 'self'; magnetometer 'self'; gyroscope 'self'; speaker 'self'; fullscreen 'self'; payment 'self'" | |
### Use next two for very secure connections ### | |
SSLHonorCipherOrder On | |
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH | |
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 | |
### Use next two for secure connections and supports more endpoints ### | |
#SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 | |
#SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 | |
### Actually proxy the traffic and really the only important part ### | |
ProxyPassMatch ^/.well-known ! | |
ProxyPass / http://${plex_url}:${plex_port}/ | |
ProxyPassReverse / http://${plex_url}:${plex_port}/ | |
ProxyPass /:/ ws://${plex_url}:${plex_port}/:/ | |
ProxyPassReverse /:/ ws://${plex_url}:${plex_port}/:/ | |
ProxyPass /:/ wss://${plex_url}:${plex_port}/:/ | |
ProxyPassReverse /:/ wss://${plex_url}:${plex_port}/:/ | |
LimitRequestBody 512000 | |
FileETag None | |
TraceEnable off | |
#Header edit Set-Cookie ^(.*)$ ;HttpOnly;Secure | |
Timeout 60 | |
<Location /:/websockets/notifications> | |
ProxyPass wss://${plex_url}:${plex_port}/:/websockets/notifications | |
ProxyPassReverse wss://${plex_url}:${plex_port}/:/websockets/notifications | |
</Location> | |
<Proxy *> | |
Require all granted | |
</Proxy> | |
RewriteEngine on | |
RewriteCond %{REQUEST_URI} !^/web | |
RewriteCond %{HTTP:X-Plex-Device} ^$ | |
RewriteCond %{REQUEST_METHOD} !^(OPTIONS)$ | |
RewriteCond %{QUERY_STRING} (^|&)X-Plex-Device=(&|$) [OR] | |
RewriteCond %{QUERY_STRING} !(^|&)X-Plex-Device= | |
RewriteRule ^/$ /web/$1 [R,L] | |
</VirtualHost> | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this vhost configuration! After applying this configuration, I constantly got an error in /var/log/apache2/error.log containing these two lines:
"AH00898: Error during SSL Handshake with remote server returned by /:/websockets/notifications"
"AH01097: pass request body failed to <Local Plex Server IP Address>"
In the browser console it said that it could not connect to
"wss://plex.<domain>.<tld>/:/websockets/notifications?X-Plex-Token=<token>"
as well.I then figured out what to change in the configuration to fix it. These errors made me unable to see new content popping up on the dashboard after scanning libraries. I had to refresh the page to see the new content. Context menus would also stop working randomly. Here are the changes I did to fix this:
The configuration below now contains "ws" instead of "wss":
Header always set Content-Security-Policy "default-src 'self' https:; font-src 'self' data: ${plex_url} ${public_url}; media-src 'self' blob: data: https: ${plex_url} ${public_url} *.plex.direct *.plex.tv plex.tv; script-src 'self' 'unsafe-inline' 'unsafe-eval' ${plex_url} ${public_url} plex.tv *.plex.tv gstatic.com *.gstatic.com *.plex.direct; style-src 'self' ${plex_url} ${public_url} *.plex.direct 'unsafe-inline'; img-src 'self' data: blob: ${plex_url} ${public_url} plex.tv *.plex.tv *.plex.direct; worker-src *; frame-src 'none'; connect-src 'self' ws: https: ${plex_url} ${public_url} plex.tv *.plex.direct *.plex.tv;"
I have commented out these lines since I don't think they are necessary. It does not affect the problem, though:
The two lines inside the Location directive now contains ws instead of wss:
Restart Apache, and the errors should no longer appear, at least for systems with similar setup and configuration described below. Maybe someone finds this helpful.
Setup:
Debian 12
Apache 2.4.57
Plex Media Server 4.108.0
My setup uses no SSL certificate for Plex itself, only for Apache with reverse proxy.