Jump to content

HOW TO: emby with NGINX - With Windows Specific Tips and CSP options


pir8radio

Recommended Posts

rbjtech
10 minutes ago, Gecko said:

@rbjtech, I quickly set up caddyv2 locally this morning and made it work easily with this caddyfile if you want to try it :

:2080 {   # the http docker port opened for caddy
     reverse_proxy https://<embyIP>:<embyHTTPSPort> {
        transport http {
            tls_insecure_skip_verify
        }
    }
}

Emby dashboard says the connection is http/2. Seems really simple to set it up compared to nginx. I'll play with it tomorrow to see if there is any benefit performance wise. Since I have the Safari bug, I'll also check if it disappears. (I'm not sure I correctly set up keep_alive on my config since my reverse proxy and Emby are not on the same machine).

 

 

 

Thanks - but I'm probably not going to bother - as I use nginx in a dmz, with certbot renewals, have an A+ on the TLS testers blah blah (ie a lot of previous setup) - and also a separate nginx rp entity for my own internal services.   So unless there is a good reason to use http/2 (which it appears there isn't, http/1 for the backend has zero performance issues for me)  then i'll stick to nginx but good to know there is an alternative. :)

Edited by rbjtech
  • Like 1
Link to comment
Share on other sites

pir8radio

Yea if emby and nginx are on the same computer or even the same network,  running http between proxy and backend is the fastest.    HTTP2 requires https so you have a little extra work for the backend server as well as the proxy (emby Encrypt - (nginx decrypt - dothings - re-encrypt)). 

  • Like 1
Link to comment
Share on other sites

On 1/27/2023 at 11:35 PM, pir8radio said:

Yea if emby and nginx are on the same computer or even the same network,  running http between proxy and backend is the fastest.    HTTP2 requires https so you have a little extra work for the backend server as well as the proxy (emby Encrypt - (nginx decrypt - dothings - re-encrypt)). 

Thanks for the tips !

I read somewhere that mixing h1 and h2 on each side of a proxy was also giving mixed results performance wise. Anyway, I tried myself this week-end with caddy, connecting through https on the backend and everything is pretty smooth and fast. Except the fact that I still have some "Recovery from playback error" that pop up sometime (with http requests in red on the dev tools of chrome/safari). I think I'll keep Caddy instead of nginx for the time being :)

Link to comment
Share on other sites

pwhodges

Caddy is fine - no need to consider changing to nginx just because the first responders are nginx afficionados!  (Equally, I have no reason to suggest they change just because I use Caddy either!)

Paul

  • Haha 1
Link to comment
Share on other sites

sandro_rocha_1982

Good Morning. I have questions about the domain name for NPM. Creating a domain in DuckDNS (let's say teste123.duckdns.org) what would I have to put in NPM to allow Emby access?

Link to comment
Share on other sites

  • 2 months later...
dethknite

For any of the security conscience, it is worth mentioning that there are potential security issues with enabling gzip (with the notion that disabling it does slightly affect speed at the cost of removing some vulnerabilities), and so one should weigh the value/costs.

https://techblogs.42gears.com/mitigating-breach-attack-in-nginx-server/

Link to comment
Share on other sites

  • 1 month later...
exus

Hi I'm running nginx proxy manager and I'm have issues with remote playback control of chromecast/fire sticks remotely connected to my emby server (play/pause/stop in admin dashboard do not appear) everything is working fine with remote browser/emby theatre apps.

this is my config

server {
  set $forward_scheme http;
  set $server         "192.168.0.50";
  set $port           8096;

  listen 80;
listen [::]:80;

listen 443 ssl http2;
listen [::]:443 ssl http2;


  server_name my.sub.domain;


  # Let's Encrypt SSL
  include conf.d/include/letsencrypt-acme-challenge.conf;
  include conf.d/include/ssl-ciphers.conf;
  ssl_certificate /etc/letsencrypt/live/npm-1/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/npm-1/privkey.pem;


proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;


  access_log /data/logs/proxy-host-4_access.log proxy;
  error_log /data/logs/proxy-host-4_error.log warn;

proxy_buffering off; 
proxy_request_buffering off;
sendfile off;  ## Sendfile not used in a proxy environment.
gzip on;   ## Compresses the content to the client, speeds up client browsing.
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
    text/plain
    text/css
    text/js
    text/xml
    text/javascript
    application/javascript
    application/x-javascript
    application/json
    application/xml
    application/rss+xml
    image/svg+xml;
proxy_connect_timeout 1h;
proxy_send_timeout 1h;
proxy_read_timeout 24h;
client_max_body_size 1000M;  


  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto  $scheme;
    proxy_set_header X-Forwarded-For    $remote_addr;
    proxy_set_header X-Real-IP		$remote_addr;
    proxy_pass       http://192.168.0.50:8096; 
    
  # Block Exploits
  include conf.d/include/block-exploits.conf;

    
    # Force SSL
    include conf.d/include/force-ssl.conf;
    
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
    proxy_headers_hash_max_size  1024;
proxy_headers_hash_bucket_size 256; 
proxy_hide_header X-Powered-By;	
proxy_set_header Range $http_range; 
proxy_set_header If-Range $http_if_range; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  

add_header 'Referrer-Policy' 'no-referrer';

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

#add_header Permissions-Policy "geolocation=(self https://my.sub.domain), microphone=()";
#add_header Content-Security-Policy "frame-ancestors my.domain my.sub.domain;";

  }
  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
}

Firesticks/chromecast on local lan can be controlled

I tried to disable permission policy and content security policy without success. I'm not sure what's inside those included files (server_proxy[.]conf / force-ssl.conf / block-exploits.conf).

Anyone can help?

 

Link to comment
Share on other sites

rbjtech

I would upgrade the FireTV's to the latest beta - 2087a.  I don't believe this would have anything to do with the nginx config.

Link to comment
Share on other sites

exus

I'm trying to sideload the beta on the firestick but it's refusing to install. Anyway, I can control fire stick playback when it's connected to my lan, it's failing on remote connections (through nginx). That's why I was wondering if there's something wrong/missing in my config

Link to comment
Share on other sites

10 minutes ago, exus said:

I'm trying to sideload the beta on the firestick but it's refusing to install. Anyway, I can control fire stick playback when it's connected to my lan, it's failing on remote connections (through nginx). That's why I was wondering if there's something wrong/missing in my config

Why do you think it’s refusing?

Link to comment
Share on other sites

rbjtech
2 minutes ago, Luke said:

Why do you think it’s refusing?

You may need to delete the old version first, reboot and then try.

Link to comment
Share on other sites

exus
1 hour ago, Luke said:

Why do you think it’s refusing?

I managed to install the beta (I changed the apk installer I was using) but the issue persist Lan is fine, remote isn't

remotecontrolFireTV.jpg

Link to comment
Share on other sites

1 minute ago, exus said:

I managed to install the beta (I changed the apk installer I was using) but the issue persist Lan is fine, remote isn't

remotecontrolFireTV.jpg

What is this screenshot supposed to tell us?

Link to comment
Share on other sites

exus
1 minute ago, Luke said:

What is this screenshot supposed to tell us?

the remote controls (play/pause/stop) are missing

Link to comment
Share on other sites

1 minute ago, exus said:

the remote controls (play/pause/stop) are missing

That means there’s no open web socket connection. Most likely your reverse proxy configuration is preventing this.

Link to comment
Share on other sites

rbjtech
1 minute ago, Luke said:

That means there’s no open web socket connection. Most likely your reverse proxy configuration is preventing this.

                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

Add the above to your nginx location section to allow web sockets ... 

Link to comment
Share on other sites

exus
Just now, Luke said:

That means there’s no open web socket connection. Most likely your reverse proxy configuration is preventing this.

And that's exactly what I was asking in my first post in this page in which I put my nginx proxy manager config. This happens only on FireTv, all the other devices I tested (remotely) works fine

Link to comment
Share on other sites

exus
Just now, rbjtech said:
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";

Add the above to your nginx location section to allow web sockets ... 

Web sockets should already be allowed in my config

Link to comment
Share on other sites

rbjtech
Just now, exus said:

Web sockets should already be allowed in my config

Your config is slightly different to mine.. I have -

proxy_set_header Connection "upgrade";
Link to comment
Share on other sites

exus

I tried some other changes with no luck so I decided to switch from Nginx proxy manager to Swag docker and now everything seems to be working.

Link to comment
Share on other sites

seanbuff
10 minutes ago, exus said:

I tried some other changes with no luck so I decided to switch from Nginx proxy manager to Swag docker and now everything seems to be working.

Nice one, not sure about the default nginx.conf file in NPM, but this line in SWAG's version probably helped:
 

    # Helper variable for proxying websockets.
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

 

  • Like 1
Link to comment
Share on other sites

rbjtech

my nginx works just fine with web sockets (see my config above), so think it must be an issue in your config somewhere.

Anyway, all sorted now .. 👍

Link to comment
Share on other sites

  • 4 weeks later...
rbjtech

@pir8radio

Hi - Just a note to say that your original nginx config (still active on Page 1) uses the X-Forwarded-For header command - and I believe this should be removed as it is a potential security issue. (see link from Mozilla below)

My understanding is adding this X-Forwarded-For line may have been the reason people have been compromised with the recent emby LAN spoofing exploit even when using an NGINX reverse proxy ?

I used your original config as a framework when I first set up emby, but I went in-depth to understand each line of it - so I fortunately removed it and just included the X-Real-IP - there is no need to use the X-Forwarded-For.

The only time you would use this, is if you have other trusted reverse proxies in-line - and then you can add them specifically as trusted proxies.

 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#security_and_privacy_concerns

Quote

Any security-related use of X-Forwarded-For (such as for rate limiting or IP-based access control) must only use IP addresses added by a trusted proxy. Using untrustworthy values can result in rate-limiter avoidance, access-control bypass, memory exhaustion, or other negative security or availability consequences.

Maybe it's worth reviewing the original config and even worth putting out a suggestion or recommendation to remove that line ?

@softworkzFYI - I know this is not directly related to emby, but though I'd include you as I presume you will have details on the different types of effected systems - incl those behind a reverse proxy.

 

Edited by rbjtech
Link to comment
Share on other sites

RP chaining is very dangerous when not done right. Each RP in the chain needs to have an allow-list of known source proxies and the RP must check the physical source IP against this allow list. If using http headers for this check, the whole chain is compromised already.
This means that you also should have direct control over any source proxy you want to put into the allow-list - otherwise security is not in your own hands anymore and you can no longer assume that you would be safe.

Currently, Emby Server uses the first IP address from the X-FORWARDED-FOR header if available. Only if there's no X-FORWARDED-FOR header, then it will look for X-REAL-IP. 

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...