-
Notifications
You must be signed in to change notification settings - Fork 23
/
plex_request_nginx.conf
201 lines (166 loc) · 8.82 KB
/
plex_request_nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# https://github.com/toomuchio/plex-nginx-reverseproxy/blob/master/nginx.conf
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
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;
# SSL_DISABLED_BEGIN
listen 8000;
# SSL_DISABLED_END
# SSL_ENABLED_BEGIN
listen 8000 ssl http2;
# ssl
# ssl on; on;
ssl_certificate ${plex_request_ssl_path}/fullchain.pem;
ssl_certificate_key ${plex_request_ssl_path}/privkey.pem;
# ssl_certificate /etc/nginx/cert.pem;
# ssl_certificate_key /etc/nginx/key.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 ${plex_request_ssl_path}/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 ${plex_request_ssl_path}/dhparam.pem;
ssl_ecdh_curve secp384r1;
# SSL_ENABLED_END
#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 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;
# Plex Headers
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
proxy_set_header X-Plex-Container-Size $http_x_plex_container_size;
proxy_set_header X-Plex-Container-Start $http_x_plex_container_start;
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 $host;
proxy_set_header X-Real-IP $http_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
#Websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
#Buffering off send to the client as soon as the data is received from Plex.
proxy_redirect off;
proxy_buffering off;
location / {
proxy_pass ${plex_server_host};
proxy_read_timeout 86400;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# return 302 https://<PLEX_PUBLIC_HOST>$request_uri;
# access_log logs/plex.access.log;
# # enable the next two lines for http auth
# auth_basic "Restricted";
# auth_basic_user_file /config/nginx/.htpasswd;
# enable the next two lines for ldap auth
# auth_request /auth;
# error_page 401 =200 /ldaplogin;
}
location /auth {
proxy_pass http://unix:/app/sockets/plex_authentication.sock;
}
location /web/index.html {
proxy_pass ${plex_server_host}/web/index.html;
# access_log logs/plex.access.log;
sub_filter '</head>' '<script>
function checkToken() {
var token = localStorage.getItem("myPlexAccessToken");
if (token) {
sendTokenToServer(token);
return true;
}
return false;
}
function sendTokenToServer(token) {
fetch("/auth/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({token: token}),
})
.then(response => {
if (response.status === 201) {
localStorage.setItem("tokenFound", "true");
}
});
}
function hasFoundBefore() {
return localStorage.getItem("tokenFound") === "true";
}
if (!hasFoundBefore()) {
if (!checkToken()) {
var attempts = 0;
var interval = setInterval(function() {
if (checkToken() || ++attempts >= 60) {
clearInterval(interval);
}
}, 1000);
}
}
</script></head>';
sub_filter_once on;
}
location = /library/all {
proxy_pass http://unix:/app/sockets/plex_request.sock;
# access_log logs/plex.access.log;
}
location ~ ^/library/metadata/[^/]+/children$ {
proxy_pass http://unix:/app/sockets/plex_request.sock;
# access_log logs/plex.access.log;
}
location /library/request/ {
proxy_pass http://unix:/app/sockets/plex_request.sock;
# access_log logs/plex.access.log;
}
}