Setting up Cloudflare with Emby

enter image description here

enter image description here

So far I have documented different approaches to access Emby securely remotely.

This guide uses Cloudflare for DNS records of your domain name, create and maintain your SSL cert and add security to your connection.

So for anyone who doesnt know, Cloudflare acts like a middle man, or more like a big bouncer. Imagine you own a bar and you want security. You hire a bouncer and he lets your customers in but keeps the riff raff out. This is what cloudflare does it adds security to your Server, while allowing authorised people to access your server.

This guide will assume you have Emby Server already setup and working on your LAN.

Getting a Domain Name.

For this to work we need a domain name. You can get a free one from FreeNom or buy your own .com or .co.uk from a registrar such as NameCheap.

For this example I will use Freenom.

  1. Search for the domain name you want. I will use mymedia.cf

MyMedia

  1. Click Checkout. Enter your details. You will then see a button to manage domain, click that. Next click on Management Tools and Nameservers. You will see the below screen. Leave this open for now, we will come back to it.

enter image description here

CloudFlare

  • Head over to Cloudflare Create an account with Cloudflare and then add your Domain name you entered above mymedia.cf. note. when adding your site and starting the scan it might fail due to DNS propagation. Give it 5-15 mins and try again.

  • Once your Domain Name appears in Cloudflare you can click 'Continue Setup' and you will see the page below.

  • Create an 'A Record'

  • Name = emby

  • Value = your WAN IP

  • Status = make sure its an Orange cloud

cloudflare

  1. Select Free Plan

cloudflare

  1. You will now be given Nameservers. Copy the 2 name servers from Cloudflare and enter them into FreeNom. If FreeNom has 4 delete all of them and only enter the 2 from cloudflare. Should look something like the below image.

freenom

  1. It will take some time for DNS propagation before the Nameservers change to Cloudflare. In this time lets setup Emby Server and Port Forwarding on your router. Go to your Emby Server and Dashboard Manager > Advanced.

  2. Change your Public HTTP port to 80 and HTTPS port to 443. Enter your new domain name. I get emby.mymedia.cf from the CloudFlare DNS page. Emby was the name of the DNS record, so the full record is emby.mymedia.cf.

emby

  1. Save and Restart Emby.

  2. Log into your router. All routers are different. Find the section to port forward and create a new rule. Forward External port 443 to internal port 8920 and IP address of your Emby Server. You can also forward 80 to 8096, however this will mean users can connect insecurely to your Emby server.

  3. Head back to CloudFlare and click 'Recheck Nameservers' if successfull you will see a green bar, and Cloudflare Active.

cloudflare

  1. We now need to create a SSL cert for Cloudflare to connect to your Server Securely. On Cloudflare go to 'Crypto', and then 'Origin Certificates'.

enter image description here

  1. Click Create Certificate, on the next screen leave everything default and click next.

enter image description here

  1. You will now be given 2 boxes, A Certificate code and Private Key code. Copy both of them into separate notepads and Save both. Call them cert.pem and private.key respectively

enter image description here

  • Once you have your 2 files, cert.pem and private.key we need to convert it to a .pfx. Go to https://www.sslshopper.com/ssl-converter.html
  • Current type = Standard PEM
  • Type to Convert to = PFX/PKCS#12
  • PFX Password = "what ever you want"
  • Certificate File to convert = cert.pem
  • Private Key File = private.key

Click convert and you should end up with a PFX certificate.

  • Head back to Emby Server > Dashboard > Advanced.
  • Custom SSL certificate Path = your PFX file
  • Certificate Password = the one used above "what ever you want"

Save and Restart Emby

enter image description here

  1. Head back to Cloudflare > Crypto Tab You now need to change SSL from Flexible to Full. (This means users connect to Cloudflare [uses cloudflare cert] Then Cloudflare connects to your emby server using the Cert we just created). Thus A Full SSL Path from user to server.

enter image description here

  1. go to https://emby.mymedia.cf and enjoy your movies.

Optional Steps

  1. On Cloudflare > Crypto You can enable 'Always use HTTPS' and 'Automatic HTTPS Rewrites'. Anyone trying to browse to HTTP will be forwarded to HTTPS.

enter image description here

  1. On Cloudflare > Page Rules Add the following rules to cache your images.
URL = *mymedia.cf/emby/item/*/images/*
Cache Level = Cache Everything
Edge Cache TTL = a month

Add a Second Rule

URL = *mymedia.cf/*
Edge Cache TTL = a month

If you have a DHCP WAN IP then you will also need to do some additional steps so that Cloudflare forwards to your IP even if it changes. For this you need to use DNS-O-Matic, a Guide can be found HERE.

SSL Config For NGINX

ssl_session_timeout 30m;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_certificate      E:\le64\Domain.crt;
ssl_certificate_key  E:\le64\Domain.key;
ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;


proxy_hide_header X-Powered-By;
add_header x-xss-protection 1;
proxy_hide_header X-Frame-Options;
add_header X-Content-Type-Options "nosniff"  always;
add_header Strict-Transport-Security "max-age=2592000; includeSubdomains" always;
add_header 'Referrer-Policy' 'origin';
add_header Content-Security-Policy "frame-ancestors mydomain.media www.mydomain.media update.mydomain.media blog.mydomain.media cctv.mydomain.media emby.mydomain.media guest.mydomain.media htpc.mydomain.media nzb.mydomain.media plex.mydomain.media prtg.mydomain.media smartthings.mydomain.media sonarr.mydomain.media stats.mydomain.media heat.mydomain.media home.mydomain.media unifi.mydomain.media utorrent.mydomain.media radarr.mydomain.media ombi.mydomain.media requests.mydomain.media sophos.mydomain.media;";
add_header X-Frame-Options "ALLOW-FROM https://home.mydomain.media";

ZeroSSL - Windows Tool

enter image description here I have posted previously regarding gaining a SSL certificate for your own domain name. Previous post here.

This post will demonstrate gaining a cert using a Windows Tool. The tool is available from ZeroSSL here.

ZeroSSL Tool

Download the file which represents your file system x32 or x64. Unzip the file and you should see a single file called le64.exe

enter image description here

NGINX Config & File Structure

To get the tool to automatically fetch certificates we need to amend the NGINX config slighty.

We need to add the following line to each server block

   location ^~ /.well-known/acme-challenge/ {
}

Here is my emby block with the line above

##EMBY Server##

    server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name emby.mydomain.com; 

    include ssl.conf;

     location / {
        proxy_pass http://127.0.0.1:8096;  

        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        }
        location ^~ /.well-known/acme-challenge/ {
}
}

The extra line allows the ACME challenge to verify you own the domain that you are trying to get a certificate for. The line above needs to be added to each Server Block for it to work.

Save the config and restart NGINX

LE64.exe

Next we need to use a command line to start le64.exe with our custom arguments.

In your command prompt change the directory to where you extracted the LE64.exe to

CD C:\le64\

Now run the following command

le64.exe --key account.key --email "[email protected]" --csr domain.csr --csr-key domain.key --crt domain.crt --domains "mydomain.com,emby.mydomain.com,www.mydomain.com,plex.mydomain.com" --generate-missing --unlink --path E:\NGINX\html\.well-known\acme-challenge

There's a few options you need to change

  • --email "[email protected]" - to your email address keeping the ""
  • --domains "mydomain.com,emby.mydomain.com" (list all your domains you want the cert to cover - i think max is 50~)
  • --path E:\NGINX\html.well-known\acme-challenge (change E:\NGINX to your NGINX locaiton, keeping the html.well-known....

when you hit enter it will test your setup for the correct files and config, it basically gets a fake certificate. if this completes with no errors you now need to add the argument --live to the end of the script above, like so

le64.exe --key account.key --email "[email protected]" --csr domain.csr --csr-key domain.key --crt domain.crt --domains "mydomain.com,emby.mydomain.com,www.mydomain.com,plex.mydomain.com" --generate-missing --unlink --path E:\NGINX\html\.well-known\acme-challenge --live

hit enter and it should go off an fetch your real domain.csr account.key and domain.crt and domain.key. these will be downloaded into the le64 folder. Keep the csr and account.key safe, you will need these for renewal.

Now you have all this setup you can re-run the above le64.exe script come renew and its all done.

Unifi Controller SSL (HTTPS)

Unifi

If like me you are running a Unifi system at home then you will probably want to connect to the controller via HTTPS. This also applies to the Guest Portal, providing them with a Trusted Certificate and not a self signed one.

This guide is for machines running Windows, but has some similarities for other OS.

Pre-Requisites

  • Unifi Controller installed and running either by a service or the app
  • A Trusted Certificate and private.key If you havent already done so, check out my post on how to get a certificate for free Easy Let's Encrypt Certificate

Also you can find out how to install and configure a Unifi Controller here. (Coming Soon!)

Step 1 - Key Store Explorer

Head over to Keystore Explorer and download the program and install it. This is used to import our certificates to the keystore unifi uses.

enter image description here

Step 2 - Creating a PKCS #12

If you are familiar with creating a PKCS #12 certificate then please create one with your unifi controllers domain name and the guest portals domain name with the password of aircontrolenterprise.

If you arent familiar with creating a PKCS #12 file, see below.

Step 3 - Importing the Certificates

Find the location of the Unifi Controller directory. On Windows the default directory is

C:\Users\%USER NAME%\Ubiquiti UniFi

In the folder 'data' there is a file called keystore. Open the keystore file with key store explorer.

enter image description here

The password is aircontrolenterprise

You should now see the below

enter image description here

Select the unifi key in keystore explorer then click on 'tools' and import key pair and choose 'PKCS #12'.

Decryption password is aircontrolenterprise

Enter the alias 'unifi' in lower case

enter image description here

If it asks to overwrite click 'YES'

Save the Keystore file.

Finally restart your unifi controller and it should now have a working certificate!

NGINX Reverse Proxy

enter image description here

This is a guide on how to install NGINX for Windows and add extra security to it.

Ever want to get an A security rating for your website. Then look no further

enter image description here

Pre-Requisites

Your own Domain name A Trust certificate in either .crt or .pem format A Private.key to go with the certificate Access to your router for port forwarding Either a DDNS or have an A Record for WAN IP.

If you havent got a Trusted Certificate you can use my guide Easy Let's Encrypt Certificate to get a free one.

This guide assumes you have either setup a DDNS or have an A record setup to point your Domain Name to your WAN IP. If you dont have this setup go here.

Step 1 - Port Forwarding

Every router is different and rather than try to describe how to do this on all the different brands I will simplify it so it is more relevant to all routers.

  • Log into your router
  • Head over to port forwarding
  • Create a new rule to forward port 443 and port 80 to the machine that NGINX will be running on.

Step 2 - Installing NGINX

Head over to NGINX-Win and download the latest version of NGINX for Windows. As of writing this guide the latest version is 1.13.1.1 Violet.

NGINX

Extract the .zip folder somewhere easy to find. for my example I will extract it to C:\NGINX\ Open up the config folder C:\NGINX\configNGINX Open up notepad (I recommend Notepad++) and copy the following into it.

Worker_processes  2;

events {
    worker_connections  8192;
}

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

    gzip on;
    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;

         tcp_nodelay on;

    sendfile        off;

    server_names_hash_bucket_size 128;
    map_hash_bucket_size 64;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
 ## End: Timeouts ##

This is some default code to let NGINX know what to do. For security i added

server_tokens off;

This prevents outsiders looking up what version of NGINX the server is running. This prevent version weaknesses being easily exploited.

After the part above copy in this code

## Default Listening ##

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
 return 301 https://$host$request_uri;
}

This part makes NGINX listen on port 80 and any traffic it receives on port 80 (HTTP) it redirects to port 443 (HTTPS). It forces the connection to use a secure connection. listen [::]:80 is only required if you have users connecting on IPv6 addresses.

The next part is to configure NGINX to forward the traffic it receives to the correct location. Copy the code below into the same notepad.

##Server Block##

    server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name mysite.com; 

Anything with # in front of it means that its a note or a disabled configuration.

From the code above change mysite.com to what ever your sub-domain name is. listen 443 ssl http2; means that NGINX listens on port 443 and uses the http2 protocol.

Next we look at adding our beefed up security into the config.

        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_certificate      SSL/cert.pem;
        ssl_certificate_key  SSL/private.key;
        ssl_session_cache shared:SSL:10m;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

Most of the above is to do with the ciphers to create the secure connection. ssl_protocols lists in order the protocols to use. TLSv1.2 is the most secure. These have replaced SSL which are now obsolete. In the very near future TLSv1.3 will make all the other versions of TLS obsolete. Preferred ciphers just list in the order of the ciphers used to create the secure connection.

So from the above we need to edit the following

ssl_certificate      SSL/cert.pem;
ssl_certificate_key  SSL/private.key;

This is the location of our cert.pem and private.key. I have them located in my NGINX folder in the following location C:\NGINX\config\SSLNGINX To find out how to create the Certs please use the guide Easy Let's Encrypt Certificates At the bottom it describes how to create .pem certs.

        add_header X-Xss-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        proxy_hide_header X-Powered-By;
        add_header 'Referrer-Policy' 'no-referrer';
        add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";

Most of the above is to do with the headers in html. They add extra security to the connection.

X-Xss-Protection - sets the configuration for the cross-site scripting filters built into most browsers. The best configuration is "X-XSS-Protection: 1; mode=block".

#

X-content-type-options - stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. The only valid value for this header is "X-Content-Type-Options: nosniff".

#

Strict-Transport-Security - is an excellent feature to support on your site and strengthens your implementation of TLS by getting the User Agent to enforce the use of HTTPS.

#

X-Frame - tells the browser whether you want to allow your site to be framed or not. By preventing a browser from framing your site you can defend against attacks like clickjacking.

#

Referrer Policy - is a new header that allows a site to control how much information the browser includes with navigations away from a document and should be set by all sites.

#

Content-Security-Policy - is an effective measure to protect your site from XSS attacks. By whitelisting sources of approved content, you can prevent the browser from loading malicious assets. Analyse this policy in more detail.

Next part we need to change from the above is

add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";

Change mysite.com emby.mysite.com to your Domain names. Also you need to add in here ALL your other sub domains that NGINX will manage. for example mysite.com emby.mysite.com sonarr.mysite.com

The next block is the location block, add this to your notepad.

         location / {
            proxy_pass http://127.0.0.1:*PORT;  

            proxy_set_header Range $http_range;
            proxy_set_header If-Range $http_if_range;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            }
    }
}

The location block tells NGINX what to do when it received data and where to forward it to. It is also required for web sockets to work.

Edit the proxy_pass and point it to the location of your Service that you are running. If it is running on the same machine as NGINX you can leave it as http://127.0.0.1:PORT. If its running on another machine you will need to know the IP. http://192.168.1.10:PORT etc.

    location / {
    proxy_pass http://127.0.0.1:*PORT;  

The whole config should now look like this.

worker_processes  2;

events {
    worker_connections  8192;
}


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

    gzip on;
    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;

    tcp_nodelay on;

    sendfile        off;

    server_names_hash_bucket_size 128;
    map_hash_bucket_size 64;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
## End: Timeouts ##



## Default Listening ##

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;


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

##Server Block##

    server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name mysite.com; 

        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_certificate      SSL/cert.pem;
        ssl_certificate_key  SSL/private.key;
        ssl_session_cache shared:SSL:10m;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;


        add_header X-Xss-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        proxy_hide_header X-Powered-By;
        add_header 'Referrer-Policy' 'no-referrer';
        add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";


     location / {
        proxy_pass http://127.0.0.1:*PORT;  

        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        }


}
}

Save the notepad as nginx.config in the following location C:\NGINX\config

Step 3 - Set NGINX as a Windows Service

To get NGINX to start with Windows we need to donwload an application called NSSM (Non-sucking service manager). Download it and extract it. You will have a choice to use win32 or win64 version. Choice the version that relates to your Windows installation. Copy the nssm.exe to C:\Windows\System32

Open up a command prompt (Run as administrator) type the following

nssm install NGINX

It will now display this

NGINX

Fill in the Path to the NGINX.exe and the Startup Directory as above.

Click ok

enter image description here

Open up Service.msc and find the NGINX Service we just installed.

Right click and Start.

enter image description here

To Test, we can navigate to emby.mysite.com and it should bring up your Emby Server!

If you have any problems drop a comment below. I will also be creating a Troubleshooting NGINX post soon.

Emby Server HTTPS (Reverse Proxy)

enter image description here

There are 2 ways to connect to your Emby server using HTTPS.

This Guide is for setting up Emby behind a reverse proxy such as NGINX or Apache. For the purposes of this guide it will follow Installing and configuring NGINX on a Windows based machine.

For a basic HTTPS connection to Emby please see the Direct Connection (Simple) Guide 'HERE'.

Pre-Requisites

  • Emby Server installed and running
  • Your own Domain name
  • A Trust certificate in either .crt or .pem format
  • A Private.key to go with the certificate
  • Access to your router for port forwarding
  • Either a DDNS or have an A Record for WAN IP.

If you havent got a Trusted Certificate you can use my guide Easy Let's Encrypt Certificate to get a free one.

This guide assumes you have either setup a DDNS or have an A record setup to point your Domain Name to your WAN IP. If you dont have this setup go here.

Step 1 - Port Forwarding

Every router is different and rather than try to describe how to do this on all the different brands I will simplify it so it is more relevant to all routers.

  • Log into your router
  • Head over to port forwarding
  • Create a new rule to forward port 443 and port 80 to the machine that NGINX will be running on.

Step 2 - Installing NGINX

Head over to NGINX-Win and download the latest version of NGINX for Windows. As of writing this guide the latest version is 1.13.1.1 Violet.

NGINX

Extract the .zip folder somewhere easy to find. for my example I will extract it to C:\NGINX\ Open up the config folder C:\NGINX\configNGINX Open up notepad (I recommend Notepad++) and copy the following into it.

Worker_processes  2;

events {
    worker_connections  8192;
}

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

    gzip on;
    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;

         tcp_nodelay on;

    sendfile        off;

    server_names_hash_bucket_size 128;
    map_hash_bucket_size 64;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
 ## End: Timeouts ##

This is some default code to let NGINX know what to do.

After the part above copy in this code

## Default Listening ##

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
 return 301 https://$host$request_uri;
}

This part makes NGINX listen on port 80 and any traffic it receives on port 80 (HTTP) it redirects to port 443 (HTTPS). It forces the connection to use a secure connection.

The next part is to configure NGINX to forward the traffic it receives for Emby to the correct location. Copy the code below into the same notepad.

##EMBY Server##

    server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name emby.mysite.com; 

Anything with # in front of it means that its a note or a disabled configuration.

From the code above change emby.mysite.com to what ever your sub-domain name is.

Next we look at adding our beefed up security into the config.

        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_certificate      SSL/cert.pem;
        ssl_certificate_key  SSL/private.key;
        ssl_session_cache shared:SSL:10m;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;


        add_header X-Xss-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        proxy_hide_header X-Powered-By;
        add_header 'Referrer-Policy' 'no-referrer';
        add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";

Without going into too much detail for this guide, the above section tells NGINX what encryption ciphers to use, the location of our certs and adds some extra security measures to the html headers.

So from the above we need to edit the following

ssl_certificate      SSL/cert.pem;
ssl_certificate_key  SSL/private.key;

This is the location of our cert.pem and private.key. I have them located in my NGINX folder in the following location C:\NGINX\config\SSLNGINX To find out how to create the Certs please use the guide Easy Let's Encrypt Certificates At the bottom it describes how to create .pem certs.

Next part we need to change from the above is

add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";

Change mysite.com emby.mysite.com to your Domain names. Also you need to add in here ALL your other sub domains that NGINX will manage. for example mysite.com emby.mysite.com sonarr.mysite.com

The next block is the location block, add this to your notepad.

         location / {
            proxy_pass http://127.0.0.1:8096;  

            proxy_set_header Range $http_range;
            proxy_set_header If-Range $http_if_range;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            }
    }
}

The location block tells NGINX what to do when it received data and where to forward it to. It is also required for web sockets to work.

Edit the proxy_pass and point it to the location of your Emby Server. If it is running on the same machine as NGINX you can leave it as http://127.0.0.1:8096. If its running on another machine you will need to know the IP. http://192.168.1.10:8096 etc.

    location / {
    proxy_pass http://127.0.0.1:8096;  

The whole config should now look like this.

worker_processes  2;

events {
    worker_connections  8192;
}


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

    gzip on;
    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;

    tcp_nodelay on;

    sendfile        off;

    server_names_hash_bucket_size 128;
    map_hash_bucket_size 64;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
## End: Timeouts ##



## Default Listening ##

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;


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

##EMBY Server##

    server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name emby.mysite.com; 

        ssl_session_timeout 30m;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_certificate      SSL/cert.pem;
        ssl_certificate_key  SSL/private.key;
        ssl_session_cache shared:SSL:10m;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;


        add_header X-Xss-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Strict-Transport-Security "max-age=2592000; includeSubdomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        proxy_hide_header X-Powered-By;
        add_header 'Referrer-Policy' 'no-referrer';
        add_header Content-Security-Policy "frame-ancestors mysite.com emby.mysite.com;";


     location / {
        proxy_pass http://127.0.0.1:8096;  

        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        }


}
}

Save the notepad as nginx.config in the following location C:\NGINX\config

Step 3 - Set NGINX as a Windows Service

To get NGINX to start with Windows we need to donwload an application called NSSM (Non-sucking service manager). Download it and extract it. You will have a choice to use win32 or win64 version. Choice the version that relates to your Windows installation. Copy the nssm.exe to C:\Windows\System32

Open up a command prompt (Run as administrator) type the following

nssm install NGINX

It will now display this

NGINX

Fill in the Path to the NGINX.exe and the Startup Directory as above.

Click ok

enter image description here

Open up Service.msc and find the NGINX Service we just installed.

Right click and Start.

enter image description here

To Test, we can navigate to emby.mysite.com and it should bring up your Emby Server!

If you have any problems drop a comment below. I will also be creating a Troubleshooting NGINX post soon.

Emby Server HTTPS (Direct Connect)

enter image description here

There are 2 ways to connect to your Emby server using HTTPS.

This Guide is for Direct Connection (Simple). Go 'HERE' if you want the reverse proxy connection (Advanced).

Pre-Requisites

  • Emby Server installed and running
  • Your own Domain name
  • A Trusted Certificate in .pfx format
  • Access to your router for port forwarding.
  • Either have DDNS or have A Record for WAN IP

If you want to find out how to get a Certificate and convert it to .pfx head over to Easy Let's Encrypt Cert

This guide assumes you have either setup a DDNS or have an A record setup to point your Domain Name to your WAN IP. If you dont have this setup go here.

Step 1 - Router Access

Every router is different and rather than try to describe how to do this on all the different brands I will simplify it so it is more relevant to all routers.

  • Log into your router
  • Head over to port forwarding
  • Create a new rule to forward port 443 to the machine that Emby Server runs on.

Step 2 - Configure Emby Server

Head over to your your Emby server via a web browser. Usually accessed by HTTP://IP-Address:8096 Go to Server Management and then 'Expert' and 'Advanced' Embyconfig

Most of this page can stay the same except

    Public HTTPS port number = 443
    Custom certificate path = *path to your .pfx certificate
    Certificate password = *your .pfx password
    External Domain = https://emby.mysite.com
    Report HTTPS as external address = Yes

Save and Restart Emby Server

To test go to HTTPS://DomainName (https://emby.mysite.com) and it should work.

Easy Let's Encrypt Certificate

enter image description here

So you run a website or services and at the moment they are accessible over HTTP (port 80). However you want a secure connection and a nice green padlock to be displayed in your web browser. In that case you need to create a HTTPS (port 443) connection which requires the webpage/service and the user to communicate over a encrypted connection using secure protocols such as SSL (Secure Sockets Layer) or TLS (Transport Layer Security).

Let's Encrypt.

Normally you would have to pay a fee to get a certificate and pay a yearly fee. However Let's Encrypt are dishing out free certificates with the only catch being they are valid for 90 days. The cert will need to be renewed every 90 days. I tend to renew with at least 15-20 days left before expiry just incase I have any issues with the new cert and it gives me time to install and test it.

Pre-Requisites .

  • Having your own Domain Name. My example *.mysite.com
  • Access to your Domain Registrars DNS settings

Step 1 - Generate the cert.

Head over to ZeroSSL and click on Online Tools and free SSL Certificate Wizard ZeroSSL main page Enter the details it asks for. ZeroSSL3 In the Domain box enter all the domains and subdomains you require the certificate to cover separated by a space. Example:-

  • mysite.com blog.mysite.com test.mysite.com

Accept both the TOS and SA and change the verification from HTTP to DNS.

Click next and it will generate a CSR key. Copy the CSR and save it as you will need this when it comes time to renew.

Click next again and it will generate an account key (RSA PRIVATE KEY). Again Copy and save the private key, we will need it to renew.

ZeroSSL4

We should now see the Verification screen like below.

ZeroSSL6

Step 2 - DNS Verification.

For this step we need to prove to ZeroSSL that we own the domain name we are trying to create the cert for.

Head over to your domain registrar. For this example I will user namecheap.com

Login and head over to DNS or Advanced DNS. We need to create a TXT Record for each of our domains and subdomains. Like in the example below. Set TTL (Time to Live) to 1min or the lowest setting.

ZeroSSL5

IMPORTANT - We should now leave it 15mins to allow the TXT Records we created above to propagate through the internet. If you click 'Next' on the ZeroSSL page too soon then it will fail to find the TXT Records. To test to see whether the Records have updated you can run a command prompt on your PC and type

nslookup -q=TXT _acme-challenge.blog.mysite.com

It should reply with the TXT Record Value. If it replies with:-

can't find _acme-challenge.blog.mysite.com: Non-existent domain

Then you have to wait longer.

Eventually you can click 'Next' and it should take you to your Certificates.

ZeroSSL7

They are available to download on the right or you can copy and paste the keys.

The Certificate includes 2 parts, you can see this from the 2 sections

-----BEGIN CERTIFICATE-----
Your Domain Certificate
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
Your Certificate Authority
-----END CERTIFICATE-----

The first part is your Certificate for the domain/subdomain you listed The second Part is the Issuing Authorities Certificate or CA Root you listed. You can either keep these together as 1 certificate (ca_bundle.crt) or split them into 2, (cert.crt) and (ca_root.crt).

Finally the second box is your Private key. Save this key as private.key

Congratulations you now have your own Certificate signed by Let's Encrypt.

Step 3 - Certificate Formats (Optional)

crt to pem

We currently have the certificates in a .crt format. To create a .pem file we need to include the cert.crt and ca_root.crt into one file. You can use notepad to do this. Copy both your cert and the ca_root into notepad like below.

----BEGIN CERTIFICATE-----
Your Domain Certificate
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Your Certificate Authority
-----END CERTIFICATE-----

and then save the file as cert.pem. Simple as that!

crt to pfx Creating a .pfx certificate isnt as simple as a pem. A pfx file contains your cert, the CA root cert and your private.key into one file. It also usually contains a password to open/import and export.

If you have access to OpenSSL you can use the command below

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in cert.crt -certfile CA_root.crt

Another option is to use SSLShopper free online utility.

ZeroSSLConvert

First of all change the 'Type To Convert To' to PFX/PKCS#12

Certificate to convert = your domain cert.crt
Private Key file = your private.key
Chain Certification File (optional) = your ca_root.crt
PFX = create a strong password and remember it!

Click 'Convert' and you should then get the new .pfx file automatically downloaded.

Congratulations you know how a Trusted Certificate. Have a look through my sites for other guides and how you can use a certificate. Dont forget you need to renew it as it will expire after 90 days.