[Guide] [Hassbian] own Domain / free 15 Year cloudflare wildcard cert & 1 file Nginx Reverse Proxy Set Up

Oh I struggled so hard with ngnix…
This should be a complete walkthrough from purchasing your own domain, Getting a wildcart cert with 15 jears of validity and making it more secure with NGNIX
First! Big thanks to @Tinkerer whom I took some nerves while troubleshooting my first few attempts @Ludeeus where roundabout happened the same and also recommended this setup!

Edit: after 6 Monts of using this setup it finaly come to my attention that the real IP`s are not beeing forwarded.
sadly you now also have to configure nginx.conf, create a bash script and run it via chrontab.
Just make this changes after you gone through the whole process.

Cloudflare IP`s could change- so i added here @sjabby chrontab setup insted of just including the servers one time.

First a bash script wich ll take the ip list from cloudflare and creates cf_real-ip.conf
sudo nano /etc/nginx/nginx.sh

#!/usr/bin/env bash

curl -s 'https://www.cloudflare.com/ips-v4' > /tmp/cf.txt
curl -s 'https://www.cloudflare.com/ips-v6' >> /tmp/cf.txt

sed 's/^/set_real_ip_from /' /tmp/cf.txt > /tmp/cf2.txt

sed -e 's/$/;/' /tmp/cf2.txt > /etc/nginx/cf_real-ip.conf

Save it, make it executable with sudo chmod +x /etc/nginx/nginx.sh

create a root chrontab with sudo crontab -e I gone for:
0 4 15 * * /etc/nginx/nginx.sh
wich says every 15th of the month at 4 in the morning (create a sheudle as you please )

now to your ngnix.conf
sudo nano /etc/nginx/nginx.conf

inside the http block we have to add:

    include /etc/nginx/cf_real-ip.conf;
    real_ip_header X-Forwarded-For; 

Wich schould then look like this :

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;

http {

        # Basic Settings

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        # SSL Settings

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        # Logging Settings

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        # Gzip Settings

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        # Virtual Host Configs

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
        include /etc/nginx/cf_real-ip.conf;
        real_ip_header X-Forwarded-For;

this will redirect the real IP`s to your HA instance

1: Get a Domain where you can change the name servers

Route53 from AWS is a pretty inexpensive way to go. but you’re free to use whichever domain registration you like as long you can update the name servers

2: Create a Cloudflare Account And change the name servers

there you already can add your new site - Now it the time to change the name servers.

In the case that you used Route53 - here another tutorial how to change the name servers
The change ll take some hours. Its depending on the TTL value of your domain.
24 hours is a typical default. So check back later

3: Create the certificates and copy them to your pi
When you get the E-Mail from Cloudflare that your name servers are updated, go to your cloudflare home tab, your domain, up to [Crypto] and a little further down Origin Certificates and hit [create Certificate]
RSA is fine and the settings should be already good - But check that there is *.domain.com & domain.com

While its open - SSH into your pi
$ sudo nano /etc/ssl/certs/cert.pem
and past the upper part in ( your ssl_certificate) ctrl+x and save & yes you should know it

The lower part is your key! so again
$ sudo nano /etc/ssl/private/key.pem
and past the lower part in
back it up again - on your drive or whatever - It ll be only shown once.

4: set up NGNIX

First, install NGINX. On any Debian based distribution (such as Raspbian) you do that with:
$ sudo aptitude update
$ sudo aptitude install nginx

If you get an error about aptitude not being found then:
$ sudo apt-get install aptitude

then try again.

just to play save
$ sudo systemctl stop nginx

If your configuration locks like this tree you’re golden
(sudo apt-get install tree - not nessasary at all but you see here - all the files are here )

[email protected]:~ $ tree /etc/nginx/
β”œβ”€β”€ conf.d
β”œβ”€β”€ fastcgi.conf
β”œβ”€β”€ fastcgi_params
β”œβ”€β”€ koi-utf
β”œβ”€β”€ koi-win
β”œβ”€β”€ mime.types
β”œβ”€β”€ modules-available
β”œβ”€β”€ modules-enabled
β”‚   β”œβ”€β”€ 50-mod-http-auth-pam.conf -> /usr/share/nginx/modules-available/mod-http-auth-pam.conf
β”‚   β”œβ”€β”€ 50-mod-http-dav-ext.conf -> /usr/share/nginx/modules-available/mod-http-dav-ext.conf
β”‚   β”œβ”€β”€ 50-mod-http-echo.conf -> /usr/share/nginx/modules-available/mod-http-echo.conf
β”‚   β”œβ”€β”€ 50-mod-http-geoip.conf -> /usr/share/nginx/modules-available/mod-http-geoip.conf
β”‚   β”œβ”€β”€ 50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf
β”‚   β”œβ”€β”€ 50-mod-http-subs-filter.conf -> /usr/share/nginx/modules-available/mod-http-subs-filter.conf
β”‚   β”œβ”€β”€ 50-mod-http-upstream-fair.conf -> /usr/share/nginx/modules-available/mod-http-upstream-fair.conf
β”‚   β”œβ”€β”€ 50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf
β”‚   β”œβ”€β”€ 50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf
β”‚   └── 50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf
β”œβ”€β”€ nginx.conf
β”œβ”€β”€ proxy_params
β”œβ”€β”€ scgi_params
β”œβ”€β”€ sites-available
β”‚   └── default
β”œβ”€β”€ sites-enabled
β”‚   └── default -> /etc/nginx/sites-available/default
β”œβ”€β”€ snippets
β”‚   β”œβ”€β”€ fastcgi-php.conf
β”‚   └── snakeoil.conf
β”œβ”€β”€ uwsgi_params
└── win-utf

you see [/etc/nginx/sites-enabled/default] points to [sites-available/default]
so lets change it to the new config;
(actualy from https://www.home-assistant.io/docs/ecosystem/nginx/ )
( Ctrl+K to cut the whole line)

$ sudo nano /etc/nginx/sites-available/default

and change the server name - to the domain of your certificate
just copy the text from [Origin Certificates] Hosts
( NGINX tests the request’s Host header field against the server_name )

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;

server {
    ### Update this line to be your IP at the end the ;
    server_name *.example.org example.org;

    # These shouldn't need to be changed
    listen [::]:80 default_server ipv6only=off;
    return 301 https://$host$request_uri;

server {
    ### Update this line to be your IP again dont forget  at the end the ;
    server_name *.example.org example.org;

    # Ensure these lines point to your SSL certificate and key (step 3)
    ssl_certificate          /etc/ssl/certs/cert.pem;
    ssl_certificate_key     /etc/ssl/private/key.pem;

    # These shouldn't need to be changed
    listen [::]:443 default_server ipv6only=off; # if your nginx version is >= 1.9.5 you can also add the "http2" flag here
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    ssl on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    proxy_buffering off;

    location / {
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

the 2 server names have to be identical - otherwise it gets you an error
the proxy_pass is passing all requests processed in this location to the proxied server at the specified address - so you could also run this from another device and route it to your Home Assistant

Check the syntax with
$ sudo nginx -t

Restart NGINX with
$ sudo systemctl restart nginx

short check in the error logs
$ sudo tail /var/log/nginx/error.log

Now go to your browser - put in the IP of your pi (without port) and you should be already be redirected to Home Assistant

5: Change the configuration and update Cloudflare

therefore check out the Docks - From 0.53 on Ludeuus custom cloudflare component got a official one

go to https://dash.cloudflare.com and klick Get your API key you want the Global API Key
Change the tab to DNS - and create a A record for the subdomain you want to use

For example β€œahsdzukadgzo8912378” let it point to any ip (it has to be set up for the Home assistant component - otherwise it cant update )
and change the configuration accordingly

zone: example.com
    - ahsdzukadgzo8912378

http: in your configuration.yaml
get rid of the SSL certificates - NGINX takes care of this now.
Update your base url and add trusted_proxies & use_x_forwarded_for: True
for example:

 api_password: !secret http_password
#   ssl_certificate: !secret ssl_certificate
#   ssl_key: !secret ssl_key
  use_x_forwarded_for: True
  base_url: !secret base_url

Now change the Port forwarding settings on the Router to [80>80] and [443>443]
and get rid of from [8123>8123]

When you used the hassbian-config duckdns tool get rid of the cron job while you’re on it
$ sudo crontab -u homeassistant -e

Tutorials I used to put this together



Thank you for the guide!
Any chance you could write a guide on setting up nginx one pi and hassio on another?

hi @hotdogwater try something like this: