From 20892bd00cf4ba5c6cc0bc93efd2532d08663e63 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Wed, 4 Sep 2024 22:49:30 -0400 Subject: [PATCH 01/21] Correcting and adjusting Nginx docs --- docs/general/networking/nginx.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 0b7904048..eaaf1f915 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -21,7 +21,7 @@ The default X-Frame-Options header may cause issues with the webOS app, causing ::: -Create the file `/etc/nginx/conf.d/jellyfin.conf` which will forward requests to Jellyfin. +Create the file `/etc/nginx/sites-available/jellyfin` which will forward requests to Jellyfin. After you've finished, you will need to symlink this file to /etc/nginx/sites-enabled and then reload nginx. ```config # Uncomment the commented sections after you have acquired a SSL Certificate @@ -66,11 +66,6 @@ server { add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; - # COOP/COEP. Disable if you use external plugins/images/assets - add_header Cross-Origin-Opener-Policy "same-origin" always; - add_header Cross-Origin-Embedder-Policy "require-corp" always; - add_header Cross-Origin-Resource-Policy "same-origin" always; - # Permissions policy. May cause issues on some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; @@ -82,11 +77,6 @@ server { # NOTE: The default CSP headers may cause issues with the webOS app #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; - location = / { - return 302 http://$host/web/; - #return 302 https://$host/web/; - } - location / { # Proxy main Jellyfin traffic proxy_pass http://$jellyfin:8096; From 77034162ed32421274c6fe26892cc741bfc3ddfe Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 15:08:03 -0400 Subject: [PATCH 02/21] Correcting http2 switch, re-adding explicit XSS disable. --- docs/general/networking/nginx.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index eaaf1f915..9d9def4ac 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -35,9 +35,8 @@ server { #} #server { - # listen 443 ssl; - # listen [::]:443 ssl; - http2 on; + # listen 443 ssl http2; + # listen [::]:443 ssl http2; server_name DOMAIN_NAME; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. @@ -64,6 +63,7 @@ server { # Security / XSS Mitigation Headers # NOTE: X-Frame-Options may cause issues with the webOS app add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous add_header X-Content-Type-Options "nosniff"; # Permissions policy. May cause issues on some clients @@ -179,7 +179,7 @@ server { ### HTTPS config example -The following config is meant to work with Certbot / Let's Encrypt. +The following config is meant to work with Certbot / Let's Encrypt. Note that a server listening on http port 80 is required for the Certbot / Let's Encrypt certification creation / renewal process. ```conf # Jellyfin hosted on https://DOMAIN_NAME/jellyfin From 4751d5bdff57a175350b073615090173d6d02f11 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 15:58:28 -0400 Subject: [PATCH 03/21] Emphasizing HTTPS config, discouraging HTTP --- docs/general/networking/nginx.md | 103 ++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 9d9def4ac..f5dc40dc7 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -21,29 +21,30 @@ The default X-Frame-Options header may cause issues with the webOS app, causing ::: -Create the file `/etc/nginx/sites-available/jellyfin` which will forward requests to Jellyfin. After you've finished, you will need to symlink this file to /etc/nginx/sites-enabled and then reload nginx. +Create the file `/etc/nginx/sites-available/jellyfin` which will forward requests to Jellyfin. After you've finished, you will need to symlink this file to /etc/nginx/sites-enabled and then reload nginx. This example assumes you've already acquired certifications as documented in our [Let's Encrypt](https://jellyfin.org/docs/general/networking/letsencrypt#nginx) guide. + +Note that a server listening on http port 80 is required for the Certbot / Let's Encrypt certificate renewal process. ```config -# Uncomment the commented sections after you have acquired a SSL Certificate server { listen 80; listen [::]:80; - # server_name DOMAIN_NAME; + server_name DOMAIN_NAME; # Uncomment to redirect HTTP to HTTPS - # return 301 https://$host$request_uri; -#} + return 301 https://$host$request_uri; +} -#server { - # listen 443 ssl http2; - # listen [::]:443 ssl http2; +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; server_name DOMAIN_NAME; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; # Uncomment next line to Disable TLS 1.0 and 1.1 (Might break older devices) - # ssl_protocols TLSv1.3 TLSv1.2; + ssl_protocols TLSv1.3 TLSv1.2; # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS @@ -51,14 +52,11 @@ server { set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; - #ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; - #ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; - #include /etc/letsencrypt/options-ssl-nginx.conf; - #ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - #add_header Strict-Transport-Security "max-age=31536000" always; - #ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; - #ssl_stapling on; - #ssl_stapling_verify on; + ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; # Security / XSS Mitigation Headers # NOTE: X-Frame-Options may cause issues with the webOS app @@ -108,6 +106,72 @@ server { ``` +### HTTP Example +
+ Expand HTTP Example +```config +server { + listen 80; + listen [::]:80; + server_name DOMAIN_NAME + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + # use a variable to store the upstream proxy + # in this example we are using a hostname which is resolved via DNS + # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) + set $jellyfin jellyfin; + resolver 127.0.0.1 valid=30s; + + # Security / XSS Mitigation Headers + # NOTE: X-Frame-Options may cause issues with the webOS app + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues on some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + # NOTE: The default CSP headers may cause issues with the webOS app + #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; + + location / { + # Proxy main Jellyfin traffic + proxy_pass http://$jellyfin:8096; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } + + location /socket { + # Proxy Jellyfin Websockets traffic + proxy_pass http://$jellyfin:8096; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } +} + +``` +
+ ## Nginx with Subpath (example.org/jellyfin) When connecting to server from a client application, enter `http(s)://DOMAIN_NAME/jellyfin` in the address field. @@ -156,18 +220,13 @@ server { # https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/ location /jellyfin/ { # Proxy main Jellyfin traffic - proxy_pass http://$jellyfin:8096; - proxy_pass_request_headers on; - 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; proxy_set_header X-Forwarded-Host $http_host; - proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; From 3653ce54dd014b114f293311c6371d2377010454 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 16:02:05 -0400 Subject: [PATCH 04/21] Making lint happy --- docs/general/networking/nginx.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index f5dc40dc7..6dd60a508 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -107,6 +107,7 @@ server { ``` ### HTTP Example +
Expand HTTP Example ```config From cd7888d6d8fc4627a3362357af0c481734988298 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 16:07:12 -0400 Subject: [PATCH 05/21] Missed semicolon --- docs/general/networking/nginx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 6dd60a508..f50ab3fc8 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -114,7 +114,7 @@ server { server { listen 80; listen [::]:80; - server_name DOMAIN_NAME + server_name DOMAIN_NAME; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; From 5f0a8dffc62a663fc9c3e2b586c1ba8971459790 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 16:16:30 -0400 Subject: [PATCH 06/21] Removing # to make lint happy --- docs/general/networking/nginx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index f50ab3fc8..4b3794033 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -116,7 +116,7 @@ server { listen [::]:80; server_name DOMAIN_NAME; - ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + # The default client_max_body_size is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; # use a variable to store the upstream proxy From bfe02bcf11c620f4ec4967a81c477be2c85c2702 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 16:21:55 -0400 Subject: [PATCH 07/21] Make lint happy, yet again --- docs/general/networking/nginx.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 4b3794033..6aae8bc9a 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -103,20 +103,20 @@ server { proxy_set_header X-Forwarded-Host $http_host; } } - ``` ### HTTP Example
Expand HTTP Example + ```config server { listen 80; listen [::]:80; server_name DOMAIN_NAME; - # The default client_max_body_size is 1M, this might not be enough for some posters, etc. + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; # use a variable to store the upstream proxy @@ -169,8 +169,8 @@ server { proxy_set_header X-Forwarded-Host $http_host; } } - ``` +
## Nginx with Subpath (example.org/jellyfin) @@ -417,7 +417,6 @@ In the "Advanced" tab, enter the following in "Custom Nginx Configuration". Thi # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. # NOTE: The default CSP headers may cause issues with the webOS app #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com/cv/js/sender/v1/cast_sender.js https://www.gstatic.com/eureka/clank/95/cast_sender.js https://www.gstatic.com/eureka/clank/96/cast_sender.js https://www.gstatic.com/eureka/clank/97/cast_sender.js https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; - ``` In the "SSL" tab, use the jellyfin.example.org certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". From 2c90373dc09f11577586866563529eeb294e0883 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 17:17:25 -0400 Subject: [PATCH 08/21] Correcting subpath documentation for sockets --- docs/general/networking/nginx.md | 41 +++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 6aae8bc9a..810a340f7 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -234,13 +234,25 @@ server { # Disable buffering when the nginx proxy gets very resource heavy upon streaming proxy_buffering off; } + + location /jellyfin/socket { + # Proxy Jellyfin Websockets traffic + proxy_pass http://$jellyfin:8096; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } } ``` ### HTTPS config example -The following config is meant to work with Certbot / Let's Encrypt. Note that a server listening on http port 80 is required for the Certbot / Let's Encrypt certification creation / renewal process. - ```conf # Jellyfin hosted on https://DOMAIN_NAME/jellyfin @@ -260,14 +272,13 @@ server { server_name DOMAIN_NAME; # You can specify multiple domain names if you want #server_name jellyfin.local; + ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - add_header Strict-Transport-Security "max-age=31536000" always; ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; - ssl_stapling on; - ssl_stapling_verify on; + # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) @@ -275,7 +286,7 @@ server { resolver 127.0.0.1 valid=30s; # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) - # ssl_protocols TLSv1.3 TLSv1.2; + ssl_protocols TLSv1.3 TLSv1.2; # Jellyfin location /jellyfin { @@ -286,18 +297,13 @@ server { # https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/ location /jellyfin/ { # Proxy main Jellyfin traffic - proxy_pass http://$jellyfin:8096; - proxy_pass_request_headers on; - 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; proxy_set_header X-Forwarded-Host $http_host; - proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; @@ -305,6 +311,19 @@ server { proxy_buffering off; } + location /jellyfin/socket { + # Proxy Jellyfin Websockets traffic + proxy_pass http://$jellyfin:8096; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } } ``` From a22c2ca2553b301d44840c21f7ab0d0ca8972402 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 18:22:17 -0400 Subject: [PATCH 09/21] Rearragning subpath exmaples to emphasize HTTPS --- docs/general/networking/nginx.md | 73 +++++++++++++++++--------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 810a340f7..54aa90b97 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -179,38 +179,42 @@ When connecting to server from a client application, enter `http(s)://DOMAIN_NAM Set the [base URL](/docs/general/networking#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect. -### HTTP config example - -:::caution - -HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS (see below for HTTPS configuration example). [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). - -::: +### HTTPS config example ```conf -# Jellyfin hosted on http://DOMAIN_NAME/jellyfin +# Jellyfin hosted on https://DOMAIN_NAME/jellyfin server { listen 80; listen [::]:80; + server_name DOMAIN_NAME; + + # Uncomment to redirect HTTP to HTTPS + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; server_name DOMAIN_NAME; # You can specify multiple domain names if you want #server_name jellyfin.local; + ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; + # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; - # Uncomment and create directory to also host static content - #root /srv/http/media; - index index.html; - - location / { - try_files $uri $uri/ =404; - } + # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) + ssl_protocols TLSv1.3 TLSv1.2; # Jellyfin location /jellyfin { @@ -251,42 +255,41 @@ server { } ``` -### HTTPS config example +### HTTP config example + +:::caution + +HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS (see below for HTTPS configuration example). [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). + +
+ Expand HTTP Example + +::: ```conf -# Jellyfin hosted on https://DOMAIN_NAME/jellyfin +# Jellyfin hosted on http://DOMAIN_NAME/jellyfin server { listen 80; listen [::]:80; - server_name DOMAIN_NAME; - - # Uncomment to redirect HTTP to HTTPS - return 301 https://$host$request_uri; -} - -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; server_name DOMAIN_NAME; # You can specify multiple domain names if you want #server_name jellyfin.local; - ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; - # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; - # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) - ssl_protocols TLSv1.3 TLSv1.2; + # Uncomment and create directory to also host static content + #root /srv/http/media; + index index.html; + + location / { + try_files $uri $uri/ =404; + } # Jellyfin location /jellyfin { @@ -327,6 +330,8 @@ server { } ``` +
+ ## Extra Nginx Configurations ### Censor sensitive information in logs From 217d0a6a28a496d2a006f784d8b38ee9ff3681a6 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 18:24:28 -0400 Subject: [PATCH 10/21] Minor syntax change --- docs/general/networking/nginx.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 54aa90b97..2488f884a 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -264,8 +264,6 @@ HTTP is insecure. The following configuration is provided for ease of use only.
Expand HTTP Example -::: - ```conf # Jellyfin hosted on http://DOMAIN_NAME/jellyfin From ce131933bfc69d0df6d7ff80c3de4c630c01b9ae Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 18:28:56 -0400 Subject: [PATCH 11/21] Minor syntax change, accidentally removed caution close --- docs/general/networking/nginx.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 2488f884a..8a0efc00d 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -261,6 +261,8 @@ server { HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS (see below for HTTPS configuration example). [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). +::: +
Expand HTTP Example From 09fe9fa28d8d7db2cf82494ad4b43f625a14f83b Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 18:36:00 -0400 Subject: [PATCH 12/21] Adding, adjust headers for consistency --- docs/general/networking/nginx.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 8a0efc00d..99d94730d 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -25,6 +25,8 @@ Create the file `/etc/nginx/sites-available/jellyfin` which will forward request Note that a server listening on http port 80 is required for the Certbot / Let's Encrypt certificate renewal process. +### HTTPS config example + ```config server { listen 80; @@ -105,7 +107,7 @@ server { } ``` -### HTTP Example +### HTTP config example
Expand HTTP Example From e883026ea5d402fb680a12c8d99460d5d8ff105f Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Thu, 5 Sep 2024 18:37:23 -0400 Subject: [PATCH 13/21] Adding, adjust headers --- docs/general/networking/nginx.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 99d94730d..83d3e6a59 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -181,7 +181,7 @@ When connecting to server from a client application, enter `http(s)://DOMAIN_NAM Set the [base URL](/docs/general/networking#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect. -### HTTPS config example +### HTTPS subpath example ```conf # Jellyfin hosted on https://DOMAIN_NAME/jellyfin @@ -257,7 +257,7 @@ server { } ``` -### HTTP config example +### HTTP subpath example :::caution From 3e1019ff3cc4ef38da15fc0ef416a39783feac5e Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Fri, 6 Sep 2024 11:58:29 -0400 Subject: [PATCH 14/21] add_headers in subpaths, toning down cautions, updating CSP --- docs/general/networking/nginx.md | 91 ++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 83d3e6a59..f3ebf16a9 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -9,12 +9,6 @@ title: Nginx ## Nginx from a subdomain (jellyfin.example.org) -:::caution - -HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. - -::: - :::tip The default X-Frame-Options header may cause issues with the webOS app, causing it to remain stuck at a black screen. If enabled, the default Content Security Policy may also cause issues. @@ -31,7 +25,7 @@ Note that a server listening on http port 80 is required for the Certbot / Let's server { listen 80; listen [::]:80; - server_name DOMAIN_NAME; + server_name jellyfin.DOMAIN.TLD; # Uncomment to redirect HTTP to HTTPS return 301 https://$host$request_uri; @@ -40,7 +34,7 @@ server { server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name DOMAIN_NAME; + server_name jellyfin.DOMAIN.TLD; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; @@ -54,11 +48,11 @@ server { set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; - ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; + ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; + ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; # Security / XSS Mitigation Headers # NOTE: X-Frame-Options may cause issues with the webOS app @@ -69,13 +63,12 @@ server { # Permissions policy. May cause issues on some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; - # Content Security Policy # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP # Enforces https content and restricts JS/CSS to origin # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. # NOTE: The default CSP headers may cause issues with the webOS app - #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; location / { # Proxy main Jellyfin traffic @@ -109,6 +102,12 @@ server { ### HTTP config example +:::tip + +The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. + +::: +
Expand HTTP Example @@ -116,7 +115,7 @@ server { server { listen 80; listen [::]:80; - server_name DOMAIN_NAME; + server_name jellyfin.DOMAIN.TLD; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; @@ -141,7 +140,7 @@ server { # Enforces https content and restricts JS/CSS to origin # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. # NOTE: The default CSP headers may cause issues with the webOS app - #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; location / { # Proxy main Jellyfin traffic @@ -177,19 +176,19 @@ server { ## Nginx with Subpath (example.org/jellyfin) -When connecting to server from a client application, enter `http(s)://DOMAIN_NAME/jellyfin` in the address field. +When connecting to server from a client application, enter `http(s)://DOMAIN.TLD/jellyfin` in the address field. Set the [base URL](/docs/general/networking#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect. ### HTTPS subpath example ```conf -# Jellyfin hosted on https://DOMAIN_NAME/jellyfin +# Jellyfin hosted on https://DOMAIN.TLD/jellyfin server { listen 80; listen [::]:80; - server_name DOMAIN_NAME; + server_name DOMAIN.TLD; # Uncomment to redirect HTTP to HTTPS return 301 https://$host$request_uri; @@ -199,15 +198,18 @@ server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name DOMAIN_NAME; + server_name DOMAIN.TLD; # You can specify multiple domain names if you want #server_name jellyfin.local; - ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; + ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; + + # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) + ssl_protocols TLSv1.3 TLSv1.2; # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS @@ -215,8 +217,21 @@ server { set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; - # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) - ssl_protocols TLSv1.3 TLSv1.2; + # Security / XSS Mitigation Headers + # NOTE: X-Frame-Options may cause issues with the webOS app + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues on some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + # NOTE: The default CSP headers may cause issues with the webOS app + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; # Jellyfin location /jellyfin { @@ -259,23 +274,17 @@ server { ### HTTP subpath example -:::caution - -HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS (see below for HTTPS configuration example). [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). - -::: -
Expand HTTP Example ```conf -# Jellyfin hosted on http://DOMAIN_NAME/jellyfin +# Jellyfin hosted on http://DOMAIN.TLD/jellyfin server { listen 80; listen [::]:80; - server_name DOMAIN_NAME; + server_name DOMAIN.TLD; # You can specify multiple domain names if you want #server_name jellyfin.local; @@ -285,6 +294,22 @@ server { set $jellyfin jellyfin; resolver 127.0.0.1 valid=30s; + # Security / XSS Mitigation Headers + # NOTE: X-Frame-Options may cause issues with the webOS app + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues on some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + # NOTE: The default CSP headers may cause issues with the webOS app + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; + # Uncomment and create directory to also host static content #root /srv/http/media; index index.html; @@ -442,7 +467,7 @@ In the "Advanced" tab, enter the following in "Custom Nginx Configuration". Thi # Enforces https content and restricts JS/CSS to origin # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. # NOTE: The default CSP headers may cause issues with the webOS app - #add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com/cv/js/sender/v1/cast_sender.js https://www.gstatic.com/eureka/clank/95/cast_sender.js https://www.gstatic.com/eureka/clank/96/cast_sender.js https://www.gstatic.com/eureka/clank/97/cast_sender.js https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; ``` In the "SSL" tab, use the jellyfin.example.org certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". From c993a8164781fb337dc637319ed13744fe7ce3f3 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Fri, 6 Sep 2024 12:14:56 -0400 Subject: [PATCH 15/21] minor changes for uniformity --- docs/general/networking/nginx.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index f3ebf16a9..d848771c7 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -42,18 +42,18 @@ server { # Uncomment next line to Disable TLS 1.0 and 1.1 (Might break older devices) ssl_protocols TLSv1.3 TLSv1.2; - # use a variable to store the upstream proxy - # in this example we are using a hostname which is resolved via DNS - # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) - set $jellyfin jellyfin; - resolver 127.0.0.1 valid=30s; - ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; + # use a variable to store the upstream proxy + # in this example we are using a hostname which is resolved via DNS + # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) + set $jellyfin jellyfin; + resolver 127.0.0.1 valid=30s; + # Security / XSS Mitigation Headers # NOTE: X-Frame-Options may cause issues with the webOS app add_header X-Frame-Options "SAMEORIGIN"; @@ -202,15 +202,15 @@ server { # You can specify multiple domain names if you want #server_name jellyfin.local; + # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) + ssl_protocols TLSv1.3 TLSv1.2; + ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; - # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) - ssl_protocols TLSv1.3 TLSv1.2; - # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`) From 345e6670a03733ea43389f706e1d8a8ec61e6bc8 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Fri, 6 Sep 2024 14:18:47 -0400 Subject: [PATCH 16/21] Adjusting http2 syntax for versions 1.25+ --- docs/general/networking/nginx.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index d848771c7..db95dfc27 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -32,8 +32,14 @@ server { } server { + # Nginx versions prior to 1.25 listen 443 ssl http2; listen [::]:443 ssl http2; + + # Nginx versions 1.25+ + #listen 443 ssl; + #listen [::]:443 ssl; + #http2 on; server_name jellyfin.DOMAIN.TLD; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. @@ -195,9 +201,15 @@ server { } server { + # Nginx versions prior to 1.25 listen 443 ssl http2; listen [::]:443 ssl http2; + # Nginx versions 1.25+ + #listen 443 ssl; + #listen [::]:443 ssl; + #http2 on; + server_name DOMAIN.TLD; # You can specify multiple domain names if you want #server_name jellyfin.local; From fbeb3864cb298d2a7df8b14371483ea3c46601c0 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Fri, 6 Sep 2024 15:13:13 -0400 Subject: [PATCH 17/21] Adding HTTP3/QUIC options --- docs/general/networking/nginx.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index db95dfc27..977ae27c4 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -39,7 +39,15 @@ server { # Nginx versions 1.25+ #listen 443 ssl; #listen [::]:443 ssl; - #http2 on; + #http2 on; + + ## QUIC/HTTP3, requires Nginx 1.25+ w/http3 module + ## Can be used alongside http2 and http1.1 + #listen 443 quic reuseport; + #listen [::]:443 quic reuseport; + ## required for browsers to direct them to quic port + #add_header Alt-Svc 'h3=":443"; ma=86400'; + server_name jellyfin.DOMAIN.TLD; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. @@ -210,6 +218,13 @@ server { #listen [::]:443 ssl; #http2 on; + ## QUIC/HTTP3, requires Nginx 1.25+ w/http3 module + ## Can be used alongside http2 and http1.1 + #listen 443 quic reuseport; + #listen [::]:443 quic reuseport; + ## required for browsers to direct them to quic port + #add_header Alt-Svc 'h3=":443"; ma=86400'; + server_name DOMAIN.TLD; # You can specify multiple domain names if you want #server_name jellyfin.local; From 5196b389677a7ffa59c4e8a20dc25b78f019e358 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Fri, 6 Sep 2024 22:21:14 -0400 Subject: [PATCH 18/21] Removing QUIC/HTTP3, not ready --- docs/general/networking/nginx.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 977ae27c4..69bd9c5aa 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -41,13 +41,6 @@ server { #listen [::]:443 ssl; #http2 on; - ## QUIC/HTTP3, requires Nginx 1.25+ w/http3 module - ## Can be used alongside http2 and http1.1 - #listen 443 quic reuseport; - #listen [::]:443 quic reuseport; - ## required for browsers to direct them to quic port - #add_header Alt-Svc 'h3=":443"; ma=86400'; - server_name jellyfin.DOMAIN.TLD; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. @@ -218,13 +211,6 @@ server { #listen [::]:443 ssl; #http2 on; - ## QUIC/HTTP3, requires Nginx 1.25+ w/http3 module - ## Can be used alongside http2 and http1.1 - #listen 443 quic reuseport; - #listen [::]:443 quic reuseport; - ## required for browsers to direct them to quic port - #add_header Alt-Svc 'h3=":443"; ma=86400'; - server_name DOMAIN.TLD; # You can specify multiple domain names if you want #server_name jellyfin.local; From fd9a2da77b4730f90a8c1814615dfda8c96f0366 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Sat, 7 Sep 2024 10:15:20 -0400 Subject: [PATCH 19/21] Switching example.org for DOMAIN.TLD for consistency --- docs/general/networking/nginx.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 69bd9c5aa..ef961206e 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -7,7 +7,7 @@ title: Nginx "[Nginx](https://www.nginx.com/) (pronounced "engine X") is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The software was created by Igor Sysoev and first publicly released in 2004.[9] A company of the same name was founded in 2011 to provide support and Nginx plus paid software." - [Wikipedia](https://en.wikipedia.org/wiki/Nginx) -## Nginx from a subdomain (jellyfin.example.org) +## Nginx from a subdomain (jellyfin.DOMAIN.TLD) :::tip @@ -181,7 +181,7 @@ server {
-## Nginx with Subpath (example.org/jellyfin) +## Nginx with Subpath (DOMAIN.TLD/jellyfin) When connecting to server from a client application, enter `http(s)://DOMAIN.TLD/jellyfin` in the address field. @@ -483,4 +483,4 @@ In the "Advanced" tab, enter the following in "Custom Nginx Configuration". Thi add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; ``` -In the "SSL" tab, use the jellyfin.example.org certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". +In the "SSL" tab, use the jellyfin.DOMAIN.TLD certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". From aa4d6acc5dc2035f6d272482b3335e1963dd1559 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Sat, 7 Sep 2024 10:25:03 -0400 Subject: [PATCH 20/21] Making suggested changes --- docs/general/networking/nginx.md | 44 ++++++++++++++------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index ef961206e..21003267f 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -7,13 +7,7 @@ title: Nginx "[Nginx](https://www.nginx.com/) (pronounced "engine X") is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The software was created by Igor Sysoev and first publicly released in 2004.[9] A company of the same name was founded in 2011 to provide support and Nginx plus paid software." - [Wikipedia](https://en.wikipedia.org/wiki/Nginx) -## Nginx from a subdomain (jellyfin.DOMAIN.TLD) - -:::tip - -The default X-Frame-Options header may cause issues with the webOS app, causing it to remain stuck at a black screen. If enabled, the default Content Security Policy may also cause issues. - -::: +## Nginx from a subdomain (jellyfin.example.org) Create the file `/etc/nginx/sites-available/jellyfin` which will forward requests to Jellyfin. After you've finished, you will need to symlink this file to /etc/nginx/sites-enabled and then reload nginx. This example assumes you've already acquired certifications as documented in our [Let's Encrypt](https://jellyfin.org/docs/general/networking/letsencrypt#nginx) guide. @@ -25,7 +19,7 @@ Note that a server listening on http port 80 is required for the Certbot / Let's server { listen 80; listen [::]:80; - server_name jellyfin.DOMAIN.TLD; + server_name jellyfin.example.org; # Uncomment to redirect HTTP to HTTPS return 301 https://$host$request_uri; @@ -41,7 +35,7 @@ server { #listen [::]:443 ssl; #http2 on; - server_name jellyfin.DOMAIN.TLD; + server_name jellyfin.example.org; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; @@ -49,11 +43,11 @@ server { # Uncomment next line to Disable TLS 1.0 and 1.1 (Might break older devices) ssl_protocols TLSv1.3 TLSv1.2; - ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; + ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; + ssl_trusted_certificate /etc/letsencrypt/live/example.org/chain.pem; # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS @@ -111,7 +105,7 @@ server { :::tip -The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. +If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. ::: @@ -122,7 +116,7 @@ The following configuration is provided for ease of use only. If you are plannin server { listen 80; listen [::]:80; - server_name jellyfin.DOMAIN.TLD; + server_name jellyfin.example.org; ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. client_max_body_size 20M; @@ -181,21 +175,21 @@ server {
-## Nginx with Subpath (DOMAIN.TLD/jellyfin) +## Nginx with Subpath (example.org/jellyfin) -When connecting to server from a client application, enter `http(s)://DOMAIN.TLD/jellyfin` in the address field. +When connecting to server from a client application, enter `http(s)://example.org/jellyfin` in the address field. Set the [base URL](/docs/general/networking#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect. ### HTTPS subpath example ```conf -# Jellyfin hosted on https://DOMAIN.TLD/jellyfin +# Jellyfin hosted on https://example.org/jellyfin server { listen 80; listen [::]:80; - server_name DOMAIN.TLD; + server_name example.org; # Uncomment to redirect HTTP to HTTPS return 301 https://$host$request_uri; @@ -211,18 +205,18 @@ server { #listen [::]:443 ssl; #http2 on; - server_name DOMAIN.TLD; + server_name example.org; # You can specify multiple domain names if you want #server_name jellyfin.local; # Uncomment next line to disable TLS 1.0 and 1.1 (Might break older devices) ssl_protocols TLSv1.3 TLSv1.2; - ssl_certificate /etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/DOMAIN.TLD/privkey.pem; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.TLD/chain.pem; + ssl_trusted_certificate /etc/letsencrypt/live/example.org/chain.pem; # use a variable to store the upstream proxy # in this example we are using a hostname which is resolved via DNS @@ -291,13 +285,13 @@ server { Expand HTTP Example ```conf -# Jellyfin hosted on http://DOMAIN.TLD/jellyfin +# Jellyfin hosted on http://example.org/jellyfin server { listen 80; listen [::]:80; - server_name DOMAIN.TLD; + server_name example.org; # You can specify multiple domain names if you want #server_name jellyfin.local; @@ -483,4 +477,4 @@ In the "Advanced" tab, enter the following in "Custom Nginx Configuration". Thi add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; ``` -In the "SSL" tab, use the jellyfin.DOMAIN.TLD certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". +In the "SSL" tab, use the jellyfin.example.org certificate that you created with Nginx Proxy Manager and enable "Force SSL", "HTTP/2 Support", "HSTS Enabled", "HSTS Subdomains". From 10eedc52b10d2a0fa80cba2137fca1a671c3bf65 Mon Sep 17 00:00:00 2001 From: TheDreadPirate Date: Tue, 10 Sep 2024 09:53:41 -0400 Subject: [PATCH 21/21] minor grammatical changes --- docs/general/networking/nginx.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/general/networking/nginx.md b/docs/general/networking/nginx.md index 21003267f..b6905a11f 100644 --- a/docs/general/networking/nginx.md +++ b/docs/general/networking/nginx.md @@ -61,7 +61,7 @@ server { add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous add_header X-Content-Type-Options "nosniff"; - # Permissions policy. May cause issues on some clients + # Permissions policy. May cause issues with some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; # Content Security Policy @@ -105,7 +105,7 @@ server { :::tip -If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. +If you are planning on exposing your server over the Internet, you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys. ::: @@ -133,7 +133,7 @@ server { add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous add_header X-Content-Type-Options "nosniff"; - # Permissions policy. May cause issues on some clients + # Permissions policy. May cause issues with some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; # Content Security Policy @@ -230,7 +230,7 @@ server { add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous add_header X-Content-Type-Options "nosniff"; - # Permissions policy. May cause issues on some clients + # Permissions policy. May cause issues with some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; # Content Security Policy @@ -307,7 +307,7 @@ server { add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous add_header X-Content-Type-Options "nosniff"; - # Permissions policy. May cause issues on some clients + # Permissions policy. May cause issues with some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; # Content Security Policy @@ -317,7 +317,7 @@ server { # NOTE: The default CSP headers may cause issues with the webOS app add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; - # Uncomment and create directory to also host static content + # Uncomment and create a directory to also host static content #root /srv/http/media; index index.html;