Jump to content

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


pir8radio

Recommended Posts

pir8radio

NGINX and emby   image.png.30c3e86054a731539f1ec9d0dd024a7f.png

Config Version 1.0.2
Last Update 9-23-2021
Update by Pir8Radio

 

  • Why Use NGINX reverse proxy ahead of my application servers like emby?
  • With NGINX or any reverse proxy ahead of an application server you have more control over your setup.  You can do things the application servers were not built to handle,  have better control over your security and logging, replace lines of code without editing the application server code, better control of caching, etc, etc....   One of the main reasons is so that you don't have to open a new port on your firewall for every application server you host, all you really need to open is 80 & 443 and the internet can reach all of your different servers through one entrance.
  • Will NGINX work on my OS?
  • Most likely, you can find various versions of NGINX for most OS's and they come in different flavors, with options baked in, or just the bare NGINX that you need to compile.  See below for download links to get you started.
  • Will NGINX break things on emby?
  • Absolutely if you don't configure it correctly!    I HIGHLY suggest when choosing a scheme to setup your domain URL you choose SUB-DOMAIN and NOT sub-directory, more below.  Also if you come to the emby forum with things not working, or issues you have and you use a Reverse Proxy, PLEASE make sure that is one of the first things you mention in your forum post.  ESPECIALLY  if emby works on one platform or client, but not another.   So many times people complain  "but it works on chrome, so I didn't think it was the reverse proxy".  Mention you have a Reverse Proxy please.   If the reverse proxy is setup correctly it should be totally transparent to the user and the application server (emby). 

 

I'm not going to go into how to purchase and setup a domain name.   Lots of how-to's on that out there.     Once you have a domain name and its pointed to your IP address, you can go to that domain name and hit your server then continue on.... 

 

Sub-Domain vs Sub-Directory:

Lets say your domain name is:   domain.com     there are two main ways you can direct traffic from the internet to your backend application servers like emby.   One is sub-directory, something like domain.com/emby    or  domain.com/other-server     This is doable in nginx, but there are some catches and you need to know how your reverse proxy and application server work in detail.. This often breaks different features in emby and other application servers..    To keep with our "Totally Transparent" goal sub-directory doesn't work well, it requires a lot of rewriting and work-arounds to make it work smoothly, if you choose sub-directory you will run into issues you will need to address.     The other option is Sub-Domain, this is the cleanest, most transparent, easiest to setup and maintain, it's also what I highly suggest you setup.   A sub-domain looks like:   emby.domain.com     or   other-server.domain.com    The below config is based on Sub-Domain  I will include a sub-directory example as well.

 

NGINX Downloads:

  • Official nginx downloads(LINUX):       nginx.org
  • Official nginx downloads(Windows):  nginx.org
  • WINDOWS users I suggest this version: nginx-win.ecsds.eu  download links are at the bottom of the page.    This Windows version has lots of cool features compiled into it already, and is optimized for windows.  They keep up with updates, its a FREE (for non-commercial) third party build that I highly recommend.

Additional Links:

Content Security Policy info (CSP) (For Advanced Users): 

  • A CSP WILL break your server if you don't know what you are doing, I suggest reading up, lots of googleing, and understand what a CSP's function is and is not prior to venturing into this area  🙂  

 

 

Example NGINX Reverse Proxy Config:

  • 3-29-2020 - ADDED A LINE FOR CLOUDFLARE USERS SO THAT THE X-REAL-IP HEADER IS CORRECTED. THIS ONLY EFFECTS Cloudflare USERS.
  • 4-11-2020 (V1.0.1) - MOVED proxy_buffering off; FROM LOCATION BLOCK TO SERVER BLOCK
  • 12-18-2020 (V1.0.2) - ADDED 301 SERVER SECTION TO FORCE ALL TRAFFIC TO SSL. 
  • 9-23-2021  no nginx config change, but cloudflare changed how they cache video files, so emby users that use Cloudflare now need to add a rule like below to make sure video is seekable and playable.  

 

 

** The below "Page Rules" are only needed for Cloudflare CDN users, otherwise ignore. 

image.png.af1f00331b49ae634ed71ac4d9d1f45b.png

 

worker_processes  auto;

error_log  logs/error.log;

events {
    worker_connections  8192;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_bucket_size 64;
    server_tokens off;

    ## The below will create a separate log file for your emby server which includes
    ## userId's and other emby specific info, handy for external log viewers.
    ## Cloudflare users will want to swap $remote_addr in first line below to $http_CF_Connecting_IP
    ## to log the real client IP address
    log_format  emby  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_time $server_port "$http_x_emby_authorization"';


    log_format default '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_time $server_port';

    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 1h;
    tcp_nodelay on;  ## Sends data as fast as it can not buffering large chunks, saves about 200ms per request.

    ## The below will force all nginx traffic to SSL, make sure all other server blocks only listen on 443
server {
    listen 80 default_server;
    server_name _;

    return 301 https://$host$request_uri;
}

    ## Start of actual server blocks
server {

    listen [::]:443 ssl http2;	## Listens on port 443 IPv6 with http2 and ssl enabled
    listen 443 ssl http2;	## Listens on port 443 IPv4 with http2 and ssl enabled
    proxy_buffering off;        ## Sends data as fast as it can not buffering large chunks.

    server_name emby.domainname.com;    ## enter your service name and domain name here example emby.domainname.com

    access_log  logs/emby.log  emby;  ## Creates a log file with this name and the log info above.

     ## SSL SETTINGS ##
        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
	ssl_certificate      ssl/pub.pem;  ## Location of your public PEM file.
	ssl_certificate_key  ssl/pvt.pem;  ## Location of your private PEM file.
        ssl_session_cache shared:SSL:10m;

     location ^~ /swagger {   ## Disables access to swagger interface
        return 404;
}

     location / {
        proxy_pass http://127.0.0.1:8096;  ## Enter the IP and port of the backend emby server here.

	proxy_hide_header X-Powered-By;	 ## Hides nginx server version from bad guys.
	proxy_set_header Range $http_range;  ## Allows specific chunks of a file to be requested.
	proxy_set_header If-Range $http_if_range;  ## Allows specific chunks of a file to be requested.
	proxy_set_header X-Real-IP $remote_addr;  ## Passes the real client IP to the backend server.
        #proxy_set_header X-Real-IP $http_CF_Connecting_IP;  ## if you use cloudflare un-comment this line and comment out above line.
        proxy_set_header Host $host;  ## Passes the requested domain name to the backend server.
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  ## Adds forwarded IP to the list of IPs that were forwarded to the backend server.

     ## ADDITIONAL SECURITY SETTINGS ##
     ## Optional settings to improve security ##
     ## add these after you have completed your testing and ssl setup ##
     ## NOTICE: For the Strict-Transport-Security setting below, I would recommend ramping up to this value ##
     ##         See https://hstspreload.org/ read through the "Deployment Recommendations" section first!   ##
	add_header 'Referrer-Policy' 'origin-when-cross-origin';
	add_header Strict-Transport-Security "max-age=15552000; preload" always;
	add_header X-Frame-Options "SAMEORIGIN" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header X-XSS-Protection "1; mode=block" always;

     ## WEBSOCKET SETTINGS ## Used to pass two way real time info to and from emby and the client.
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
    }
}
}

 

Edited by pir8radio
  • Like 11
Link to comment
Share on other sites

feerlessleadr

This is awesome, thanks for posting. I've been using your nginx config since you first posted it way back when you had a guide on how to setup your own subdomain on namecheap. 

Still working perfectly today with the tweaks you've made along the way.

  • Thanks 1
Link to comment
Share on other sites

Thank you for your manual and config. I am trying to get this to work on a QNap running Windows server within a VM. So Emby is running natively on the QNap and Nginx on the windows box. I have used your config, changed the domain name an local address and ssl certificated. The config tested good when i run nginx_basic.exe -t.

Emby itself is running fine with ssl when i open ports in the (Ubiquiti) firewall as follows (outside-inside): 80-8096 and 443-8920 (Emby is running on it's default ports). When configured this way i can access Emby from the outside, it switches to SSL automaticly and all seems to be working fine. Except from the 'F' score that is 😞

When i switch Emby to Reverse proxy mode and turn on Nginx i only get "Unable to connect" screens in the browser. I have made a firewall rule within the windows server firewall for Nginx. When i don't map the 80 and 443 ports to the inside Emby ports on the Ubiquiti, nothing changes. It's still not working...

Is there something i am missing?

 

Edited by Bartype
Link to comment
Share on other sites

Ah, i found it, i was forwarding to the Qnap but i had to forward to the Windows server of course! This seems to work, however, it seems Nginx is not switching to https by itself, so Emby is accessible unsecured...

  • Like 1
Link to comment
Share on other sites

horstepipe

Another question if you have time 🙂

It caught my eye that some requests show up multiple times in nginx logs:

 

clientip - cloudflareip - - [17/Dec/2020:16:07:27 +0100] "POST /emby/Items/14731/PlaybackInfo?UserId=xxx&StartTimeTicks=0&IsPlayback=false&AutoOpenLiveStream=false&MaxStreamingBitrate=120000000&DirectPlayProtocols=File%2CHttp%2CRtp%2CRtmp%2CRtsp%2CFtp&X-Emby-Client=Emby%20Theater&X-Emby-Device-Name=device&X-Emby-Device-Id=device&X-Emby-Client-Version=3.0.11&X-Emby-Token=yyy HTTP/1.1" 200 1102 "https://tv.emby.media/index.html?autostart=false" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) EmbyTheater/3.0.11 Chrome/80.0.3987.137 Electron/8.1.0 Safari/537.36" "clientip" 0.006 443 "-"
clientip - cloudflareip - - [17/Dec/2020:16:07:27 +0100] "POST /emby/Items/14731/PlaybackInfo?UserId=xxx&StartTimeTicks=0&IsPlayback=false&AutoOpenLiveStream=false&MaxStreamingBitrate=120000000&DirectPlayProtocols=File%2CHttp%2CRtp%2CRtmp%2CRtsp%2CFtp&X-Emby-Client=Emby%20Theater&X-Emby-Device-Name=device&X-Emby-Device-Id=device&X-Emby-Client-Version=3.0.11&X-Emby-Token=yyy HTTP/1.1" 200 1102 "https://tv.emby.media/index.html?autostart=false" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) EmbyTheater/3.0.11 Chrome/80.0.3987.137 Electron/8.1.0 Safari/537.36" "clientip" 0.007 443 "-"
clientip - cloudflareip - - [17/Dec/2020:16:07:27 +0100] "POST /emby/Items/14731/PlaybackInfo?UserId=xxx&StartTimeTicks=0&IsPlayback=false&AutoOpenLiveStream=false&MaxStreamingBitrate=120000000&DirectPlayProtocols=File%2CHttp%2CRtp%2CRtmp%2CRtsp%2CFtp&X-Emby-Client=Emby%20Theater&X-Emby-Device-Name=device&X-Emby-Device-Id=device&X-Emby-Client-Version=3.0.11&X-Emby-Token=yyy HTTP/1.1" 200 1102 "https://tv.emby.media/index.html?autostart=false" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) EmbyTheater/3.0.11 Chrome/80.0.3987.137 Electron/8.1.0 Safari/537.36" "clientip" 0.006 443 "-"

Any idea why this happens?

Link to comment
Share on other sites

pir8radio
10 hours ago, horstepipe said:

thank you very much @pir8radio.
Would you mind to spend some words about the keepalive directive? Why don't you suggest to use it?

Keepalive is only good for http 1.1 so I guess it could help between nginx and emby.   Otherwise my config is setup to natively use http2 which you are not supposed to enable keepalive with, its out of spec to use keepalive with http2, but http2 has keepalive sort of built-in, its just how http2 works.    So between the client and the nginx server http2 takes care of keepalive.   But from nginx to emby if you are connecting with http1.1 keepalive might be handy... I'll have to play around and see if there is a noticeable performance increase...  I thought keepalive only works within the upstream module (like for load balancing) I'll have to look and see if it can even work just under server or location sections.   

I don't have a good way to see how emby's http server is working, like a status page that shows connection counts or anything... so it might be hard to test. But I cant imagine keepalive would be noticeable since people usually have nginx and emby on the same LAN or even the same PC/Server where open-send-receive-close connections would wiz on by...  

 

Not sure why you are seeing the multiple POSTs Just checked my log nothing jumped out, gots some more examples?  🙂    are they all "playbackInfo" every time?

Edited by pir8radio
  • Thanks 1
Link to comment
Share on other sites

On 12/17/2020 at 3:54 PM, Bartype said:

Ah, i found it, i was forwarding to the Qnap but i had to forward to the Windows server of course! This seems to work, however, it seems Nginx is not switching to https by itself, so Emby is accessible unsecured...

Hi pir8radio,

Is it correct your config is tested a "B"?

Also it seems when i open port 80 on my router Nginx doesn't switch to "https" by itself. In your config, there is no "return 301 https://my.domain.com$request_uri;" I tried to add this but this doesn't work either, too many relays.

What is the best way to make sure all traffic runs via Nginx to https ?

Edited by Bartype
Link to comment
Share on other sites

pir8radio
10 hours ago, Bartype said:

Hi pir8radio,

Is it correct your config is tested a "B"?

Also it seems when i open port 80 on my router Nginx doesn't switch to "https" by itself. In your config, there is no "return 301 https://my.domain.com$request_uri;" I tried to add this but this doesn't work either, too many relays.

What is the best way to make sure all traffic runs via Nginx to https ?


 

** I didn't originally do this because some people still wanted HTTP only, not SSL, but SSL is so mainstream these days, I updated Post#1 config to include the below info.

add_header Strict-Transport-Security "max-age=15552000; preload" always;

will tell the client to only use SSL going forward, AFTER their first visit to the SSL version, this is already included in the base config in post #1

But add this in as the first server block:

server {
    listen 80 default_server;
    server_name _;

    return 301 https://$host$request_uri;
}

*none of your other server blocks should contain "default_server", well they shouldn't in a somewhat normal config that is.. lol 

with the above server block you will need to REMOVE (the below listen directives) from all of your other server blocks..   So all of your server blocks should only listen on your ssl port which is usually 443.        this way none of your servers blocks are listening on 80,  so any request to any domain name or ip address on port  80 will fall into the above trap, then get redirected to the SSL version which WILL match your other server blocks that are only listening on 443,  then the client will pick up the Strict-Transport directive and not need a redirect going forward. 

    listen [::]:80;   		## Listens on port 80 IPv6
    listen 80; 			## Listens on port 80 IPv4

 

 

Yes its true mine tests to a B   Because I enable TLS 1 and weaker 128 bit cyphers for compatibility reasons..  If you are not worried about that you can force higher security encryption.

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

Great thank you for your reply! This works great indeed! Now i can tell my mother from 78 that she doesn't have to type "https://" before the domain on an onscreen keyboard with IR remote 😉

 

Link to comment
Share on other sites

pir8radio
On 12/18/2020 at 4:13 PM, Bartype said:

Great thank you for your reply! This works great indeed! Now i can tell my mother from 78 that she doesn't have to type "https://" before the domain on an onscreen keyboard with IR remote 😉

 

Well..........    Not entirely true some emby apps (the OS's that is) don't follow redirects.. lol  

Edited by pir8radio
Link to comment
Share on other sites

horstepipe
On 12/18/2020 at 3:05 AM, pir8radio said:

Keepalive is only good for http 1.1 so I guess it could help between nginx and emby.   Otherwise my config is setup to natively use http2 which you are not supposed to enable keepalive with, its out of spec to use keepalive with http2, but http2 has keepalive sort of built-in, its just how http2 works.    So between the client and the nginx server http2 takes care of keepalive.   But from nginx to emby if you are connecting with http1.1 keepalive might be handy... I'll have to play around and see if there is a noticeable performance increase...  I thought keepalive only works within the upstream module (like for load balancing) I'll have to look and see if it can even work just under server or location sections.   

I don't have a good way to see how emby's http server is working, like a status page that shows connection counts or anything... so it might be hard to test. But I cant imagine keepalive would be noticeable since people usually have nginx and emby on the same LAN or even the same PC/Server where open-send-receive-close connections would wiz on by...  

 

Not sure why you are seeing the multiple POSTs Just checked my log nothing jumped out, gots some more examples?  🙂    are they all "playbackInfo" every time?

thank you very much for those insights and sorry for the late reply.
So then I think I should investigate http2 first, here.
I'm using cloudflare in front of nginx, but I think you're doing the same? http2 is enabled in cloudflare, but in nginx logs almost all requests show HTTP/1.1. Does Cloudflare communicate to the edge via http 1.1 and does this have impact to your above statements?
From client to cloudflare http2 is enabled, at least the cloudflare check page (https://domain.com/cdn-cgi/trace) shows http2 is being used.

Link to comment
Share on other sites

pir8radio
6 hours ago, horstepipe said:

thank you very much for those insights and sorry for the late reply.
So then I think I should investigate http2 first, here.
I'm using cloudflare in front of nginx, but I think you're doing the same? http2 is enabled in cloudflare, but in nginx logs almost all requests show HTTP/1.1. Does Cloudflare communicate to the edge via http 1.1 and does this have impact to your above statements?
From client to cloudflare http2 is enabled, at least the cloudflare check page (https://domain.com/cdn-cgi/trace) shows http2 is being used.

Yes,  from what I'm reading there isn't much advantage from using http2 on the back end, since most of those requests should already be cached or something on the edge and coming from the edge anyway.   if you don't use cloudflare then most likely your nginx and emby are on the same high speed LAN and the many un multiplexed connections from nginx to emby wont even be noticed. 

 

there are some cool things out there that i have not had time to play with like:

I did find this gRPC example, sounds like the gRPC module will pass regular http2 traffic.    I have not messed with this. 


http {
     upstream grpcservers {
         server 192.168.X.X:XXXX;
     }


     server {
         listen 443 http2;

         location / {
             grpc_pass grpc://grpcservers;
             error_page 502 = /error502grpc;
         }

         location = /error502grpc {
             internal;
             default_type application/grpc;
             add_header grpc-status 14;
             add_header grpc-message "unavailable";
             return 204;
         }
     }
}

 

Edited by pir8radio
  • Thanks 1
Link to comment
Share on other sites

Bartype
On 12/19/2020 at 10:23 PM, pir8radio said:

Well..........    Not entirely true some emby apps (the OS's that is) don't follow redirects.. lol  

That seem to be true 🙂

Another question if i may, what is the best way to add another server to be reverse proxied to the config, one for ombi for example? I tried just copying the emby server and location settings, paste them below those for emby and changed the settings to those for ombi. But this doesn't work...

Also, i use a subdomain now for emby, such as "sub.domain.com", when using this, all works fine, getting a 'B' on the various test sites. But when i access using just "domain.com" the certificate is not correct and the tests ending up a 'D'. is there a way to redirect everything not being "sub.domain.com" to the correct sub domain? And if so, is it still possible to add the above reverse proxy for ombi AND doing the same there?

Thank you again for all the tips and info!

 

Edited by Bartype
Link to comment
Share on other sites

They are two different applications so it's hard to say for sure if an nginx configuration intended for Emby would work for Ombi.

Link to comment
Share on other sites

pir8radio
10 hours ago, Bartype said:

That seem to be true 🙂

Another question if i may, what is the best way to add another server to be reverse proxied to the config, one for ombi for example? I tried just copying the emby server and location settings, paste them below those for emby and changed the settings to those for ombi. But this doesn't work...

Also, i use a subdomain now for emby, such as "sub.domain.com", when using this, all works fine, getting a 'B' on the various test sites. But when i access using just "domain.com" the certificate is not correct and the tests ending up a 'D'. is there a way to redirect everything not being "sub.domain.com" to the correct sub domain? And if so, is it still possible to add the above reverse proxy for ombi AND doing the same there?

Thank you again for all the tips and info!

 

what does your config look like that you pasted and tried..  lets see if we can see what went wrong. 

Link to comment
Share on other sites

Bartype
20 hours ago, pir8radio said:

what does your config look like that you pasted and tried..  lets see if we can see what went wrong. 

Hey pir8radio,

 

thank you for your reply! I found the problem, it was a missing "{". So, the config works now for two services, emby and ombi both as a subdomain. Is it possible to reroute the main domain to one of those subdomains?

 

Link to comment
Share on other sites

pir8radio
Posted (edited)
3 hours ago, Bartype said:

Hey pir8radio,

 

thank you for your reply! I found the problem, it was a missing "{". So, the config works now for two services, emby and ombi both as a subdomain. Is it possible to reroute the main domain to one of those subdomains?

 

yea no routing needed, just add to the Server tag,  remember those "server" and "location" sections are like logic, they only respond to what you tell them to respond to..  

So just add whatever other domain names you want that section to respond to space separated:

server_name emby.yourdomain.com www.yourdomain.com yourdomain.com; 

just remove  www.yourdomain.com and yourdomain.com from other server sections so nginx doesn't act on them first..   make sense?

Edited by pir8radio
Link to comment
Share on other sites

Bartype
12 hours ago, pir8radio said:

yea no routing needed, just add to the Server tag,  remember those "server" and "location" sections are like logic, they only respond to what you tell them to respond to..  

So just add whatever other domain names you want that section to respond to space separated:


server_name emby.yourdomain.com www.yourdomain.com yourdomain.com; 

just remove  www.yourdomain.com and yourdomain.com from other server sections so nginx doesn't act on them first..   make sense?

Hi, thanks again! Well, the above i tried, and it works, but... I have ssl certificates active for emby.mydomain.com and ombi.mydomain.com, but not for mydomain.com. So i get certificate errors when going to mydomain.com. Is it possible to route all traffic coming from "mydomain.com" to "emby.mydomain.com" while still being able to reach "ombi.mydomain.com"?

 

Link to comment
Share on other sites

pir8radio
13 hours ago, Bartype said:

Hi, thanks again! Well, the above i tried, and it works, but... I have ssl certificates active for emby.mydomain.com and ombi.mydomain.com, but not for mydomain.com. So i get certificate errors when going to mydomain.com. Is it possible to route all traffic coming from "mydomain.com" to "emby.mydomain.com" while still being able to reach "ombi.mydomain.com"?

 

oh...  you should have went with a "wildcard" cert, it will cover *.yourdimain.com    otherwise, yea you need to go with different certs for every domain.. so n that case you can just forward them to the other urls, but the base domain.com will go away and they will see  other.domain.com that you sent them too.. is that ok?

 

Link to comment
Share on other sites

Bartype
21 hours ago, pir8radio said:

oh...  you should have went with a "wildcard" cert, it will cover *.yourdimain.com    otherwise, yea you need to go with different certs for every domain.. so n that case you can just forward them to the other urls, but the base domain.com will go away and they will see  other.domain.com that you sent them too.. is that ok?

 

Hmm yeah, next year when those certificates run out i will look for wildcard. Up until then, it's this way then. Indeed, for these services domain.com isn't needed...

Link to comment
Share on other sites

neunghaha28
On 12/16/2020 at 10:34 PM, pir8radio said:

NGINX and emby   image.png.30c3e86054a731539f1ec9d0dd024a7f.png

Config Version 1.0.2
Last Update 12-18-2020
Update by Pir8Radio

 

  • Why Use NGINX reverse proxy ahead of my application servers like emby?
  • With NGINX or any reverse proxy ahead of an application server you have more control over your setup.  You can do things the application servers were not built to handle,  have better control over your security and logging, replace lines of code without editing the application server code, better control of caching, etc, etc....   One of the main reasons is so that you don't have to open a new port on your firewall for every application server you host, all you really need to open is 80 & 443 and the internet can reach all of your different servers through one entrance.
  • Will NGINX work on my OS?
  • Most likely, you can find various versions of NGINX for most OS's and they come in different flavors, with options baked in, or just the bare NGINX that you need to compile.  See below for download links to get you started.
  • Will NGINX break things on emby?
  • Absolutely if you don't configure it correctly!    I HIGHLY suggest when choosing a scheme to setup your domain URL you choose SUB-DOMAIN and NOT sub-directory, more below.  Also if you come to the emby forum with things not working, or issues you have and you use a Reverse Proxy, PLEASE make sure that is one of the first things you mention in your forum post.  ESPECIALLY  if emby works on one platform or client, but not another.   So many times people complain  "but it works on chrome, so I didn't think it was the reverse proxy".  Mention you have a Reverse Proxy please.   If the reverse proxy is setup correctly it should be totally transparent to the user and the application server (emby). 

 

I'm not going to go into how to purchase and setup a domain name.   Lots of how-to's on that out there.     Once you have a domain name and its pointed to your IP address, you can go to that domain name and hit your server then continue on.... 

 

Sub-Domain vs Sub-Directory:

Lets say your domain name is:   domain.com     there are two main ways you can direct traffic from the internet to your backend application servers like emby.   One is sub-directory, something like domain.com/emby    or  domain.com/other-server     This is doable in nginx, but there are some catches and you need to know how your reverse proxy and application server work in detail.. This often breaks different features in emby and other application servers..    To keep with our "Totally Transparent" goal sub-directory doesn't work well, it requires a lot of rewriting and work-arounds to make it work smoothly, if you choose sub-directory you will run into issues you will need to address.     The other option is Sub-Domain, this is the cleanest, most transparent, easiest to setup and maintain, it's also what I highly suggest you setup.   A sub-domain looks like:   emby.domain.com     or   other-server.domain.com    The below config is based on Sub-Domain  I will include a sub-directory example as well.

 

NGINX Downloads:

  • Official nginx downloads(LINUX):       nginx.org
  • Official nginx downloads(Windows):  nginx.org
  • WINDOWS users I suggest this version: nginx-win.ecsds.eu  download links are at the bottom of the page.    This Windows version has lots of cool features compiled into it already, and is optimized for windows.  They keep up with updates, its a FREE (for non-commercial) third party build that I highly recommend.

Additional Links:

Content Security Policy info (CSP) (For Advanced Users): 

  • A CSP WILL break your server if you don't know what you are doing, I suggest reading up, lots of googleing, and understand what a CSP's function is and is not prior to venturing into this area  🙂  

 

 

Example NGINX Reverse Proxy Config:

  • 3-29-2020 - ADDED A LINE FOR CLOUDFLARE USERS SO THAT THE X-REAL-IP HEADER IS CORRECTED. THIS ONLY AFFECTS Cloudflare USERS.
  • 4-11-2020 (V1.0.1) - MOVED proxy_buffering off; FROM LOCATION BLOCK TO SERVER BLOCK
  • 12-18-2020 (V1.0.2) - ADDED 301 SERVER SECTION TO FORCE ALL TRAFFIC TO SSL. 

 


worker_processes  auto;

error_log  logs/error.log;

events {
    worker_connections  8192;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_bucket_size 64;
    server_tokens off;

    ## The below will create a separate log file for your emby server which includes
    ## userId's and other emby specific info, handy for external log viewers.
    ## Cloudflare users will want to swap $remote_addr in first line below to $http_CF_Connecting_IP
    ## to log the real client IP address
    log_format  emby  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_time $server_port "$http_x_emby_authorization"';


    log_format default '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $request_time $server_port';

    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 1h;
    tcp_nodelay on;  ## Sends data as fast as it can not buffering large chunks, saves about 200ms per request.

    ## The below will force all nginx traffic to SSL, make sure all other server blocks only listen on 443
server {
    listen 80 default_server;
    server_name _;

    return 301 https://$host$request_uri;
}

    ## Start of actual server blocks
server {

    listen [::]:443 ssl http2;	## Listens on port 443 IPv6 with http2 and ssl enabled
    listen 443 ssl http2;	## Listens on port 443 IPv4 with http2 and ssl enabled
    proxy_buffering off;        ## Sends data as fast as it can not buffering large chunks.

    server_name emby.domainname.com;    ## enter your service name and domain name here example emby.domainname.com

    access_log  logs/emby.log  emby;  ## Creates a log file with this name and the log info above.

     ## SSL SETTINGS ##
        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
	ssl_certificate      ssl/pub.pem;  ## Location of your public PEM file.
	ssl_certificate_key  ssl/pvt.pem;  ## Location of your private PEM file.
        ssl_session_cache shared:SSL:10m;

     location ^~ /swagger {   ## Disables access to swagger interface
        return 404;
}

     location / {
        proxy_pass http://127.0.0.1:8096;  ## Enter the IP and port of the backend emby server here.

	proxy_hide_header X-Powered-By;	 ## Hides nginx server version from bad guys.
	proxy_set_header Range $http_range;  ## Allows specific chunks of a file to be requested.
	proxy_set_header If-Range $http_if_range;  ## Allows specific chunks of a file to be requested.
	proxy_set_header X-Real-IP $remote_addr;  ## Passes the real client IP to the backend server.
        #proxy_set_header X-Real-IP $http_CF_Connecting_IP;  ## if you use cloudflare un-comment this line and comment out above line.
        proxy_set_header Host $host;  ## Passes the requested domain name to the backend server.
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  ## Adds forwarded IP to the list of IPs that were forwarded to the backend server.

     ## ADDITIONAL SECURITY SETTINGS ##
     ## Optional settings to improve security ##
     ## add these after you have completed your testing and ssl setup ##
     ## NOTICE: For the Strict-Transport-Security setting below, I would recommend ramping up to this value ##
     ##         See https://hstspreload.org/ read through the "Deployment Recommendations" section first!   ##
	add_header 'Referrer-Policy' 'origin-when-cross-origin';
	add_header Strict-Transport-Security "max-age=15552000; preload" always;
	add_header X-Frame-Options "SAMEORIGIN" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header X-XSS-Protection "1; mode=block" always;

     ## WEBSOCKET SETTINGS ## Used to pass two way real time info to and from emby and the client.
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
    }
}
}

 

help me.

nginx: [emerg] "worker_processes" directive is not allowed here in /etc/nginx/conf.d/emby.conf:1

Link to comment
Share on other sites

pir8radio
13 hours ago, neunghaha28 said:

help me.

nginx: [emerg] "worker_processes" directive is not allowed here in /etc/nginx/conf.d/emby.conf:1

you are using a pre-built container that someone else has already started programming.   Is this a fresh nginx install?

Link to comment
Share on other sites

neunghaha28
9 hours ago, pir8radio said:

you are using a pre-built container that someone else has already started programming.   Is this a fresh nginx install?

I use docker container nginx:latest.

Link to comment
Share on other sites

pir8radio
17 hours ago, neunghaha28 said:

I use docker container nginx:latest.

yea so that docker container is a prebuilt nginx, with their config..  You first need to understand how the configs work in order to just slap a new config in one of these pre-built containers.   Usually the best thing is to get rid of their 10 different linked configs,  and go with one nginx master config.       

  • Like 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...