Networking Expert Please ! DuckDNS Http -> Https

Hi,

I have HASSIO running in Docker on Ubuntu 16.04 (my internal network IP for Ubuntu is static 192.168.1.50). I am using the DUCKDNS addon which has the Lets Encrypt SSL creation and renewal built in and works if I type https://domain.duckdns.org:555 into my browser I have port forwarded 555 external to internal 8123 port mapped to internal IP 192.168.1.50 which is is the static IP on my Ubuntu 16.04.

My configuration.yaml as follows:

  base_url: domain.duckdns.org
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem 

I want to be able to enter http://domain.duckdns.org or http://www.domain.duckdns.org without the port number 555 or 8123 into any browser and have it redirected to https://domain.duckdns.org and connect to the HASSIO dashboard on 192.168.1.50 so that all traffic to my HASSIO instance running in docker on Ubuntu Desktop at internal IP 192.168.1.50 and to browser is SSL secure.

How do I get http://domain.duckdns.org entered in the browser to convert to https://domain.duckdns.org and connect to 192.168.1.50 HASSIO dashboard securely with SSL?

Can I do this without port forwarding? If I have to use port forward for port 80 on my router, I dont want to allocate port 80 to just HASSIO on 192.168.1.50 either as I have other internal web servers I might want to expose externally also.

Any guidance would be great

What you need is something like NGINX running on your host. Here is my setup and what you mention works well in my case:

I have one certificate per domain (for HASS, but also for anything else I need to reach from outside like cameras and a few other hosts).

I only forwarded external port 443 to the internal IP running nginx (port 443 inside). That’s it. NGINX takes care of forwarding to the correct internal port and IP based on the domain name of the request. Most everything internally runs without SSL, but everything reached from outside uses SSL. With NGINX, you could force HTTP requests to redirect to HTTPS.

If you don’t want to use a port number in your URL, you HAVE to configure your installation to use port 80 for HTTP and 443 for HTTPS. There is no way around that from the Internet.

BTW, I’m not a networking expert…

Later,

1 Like

Totally agree with previous post, I forward port 80 and 443 from router to a raspberry pi running NGINX. I then have a separate config for each of the internal websites that I want to publish externally. An example config is below

server {
listen 80 ;
server_name hass.domainname.com;
return 301 https://hass.domainname.com$request_uri;
}

server {
listen 443 ssl;
server_name hass.domainname.com;
ssl_certificate /etc/letsencrypt/live/hass.domainname.com$/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/hass.domainname.com$/privkey.pem; # managed by Certbot
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA’;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparams.pem;

location / {

  proxy_set_header        Host $host:$server_port;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;
  proxy_buffering off;
  # Fix the "It appears that your reverse proxy set up is broken" error.
  proxy_pass          http://192.168.1.9:8123;
  proxy_read_timeout  90;
  
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_redirect      http://192.168.1.9:8123 https://hass.domainname.com;
}

}

The SSL certs are from Lets Encrypt and if you use certbot it has an nginx option that makes it really easy to generate the certs,

Hope that helps, let me know if you need anything else.

Hey great that you guys have responded I want to get this nailed.

@Madelinot appears you only accept https:// to NGINX, I want to come in with http:// that is port 80 then redirect to https:// 443 so secure to browser thereafter. I can let the connection in with port forwarding external 80 to internal 443 pointed to my HASSIO IP 192.168.1.50 but that locks in port 80 to one IP which is not what I want.

I have other hosts inside my network that run on port 80 that I might want to port forward external port 80 to internal port 80 to various internal IPs but my router will only allow 1 entry for external port 80 to internal port 80 mapping. Bummer.

@Macjob seems like 80 and 443 external to 80 and 443 internal to my Ubuntu 192.168.50 which would run NGINX to redirect to https:// on HASSIO which is also on Ubuntu 192.168.1.50 or any other IP at port 80 or 443 would work. I have not got this setup yet so I have some questions:

With DUCKDns addon it does the ddns domain.duckdns.org to my router and also creates and renews cert stuff automatically this is easy for me as I am not across certbot etc.

Please confirm to get all this working I would I need to uninstall DUCKDns addon then install NGINX not addon but full onto Ubuntu then somehow install lets encrypt not addon but full onto ubuntu then create certificate using certbot and manually renew every 30 days and then what would I put in configuration.yaml?

I am a bit lost but if you could provide step by step instructions I would be able to follow and learn. I have a free duckdns.org account which gives 3 subdomains xxx.duckdns.org

Thanks for both your help so far this has helped me get and understanding of different ways to approach things.

Please advise

Yes, there are always different options depending on what you want to achieve, but it sounds like you want a similar setup to myself.

I have a separate Pi running the full NGINX proxy. I have config for all the sites that I want to publish externally. I forward and 80 and 443 to the Pi from router and then within the NGINX config perform a redirect to https.

If you have the config setup you should the be able to run certbot, I run certbot-auto —nginx.

This then examines your nginx config and generates certs for each website you have. I have a cron script job that runs on a schedule to ensure certs are renewed.

So I think you want most likely want to uninstall nginx addon and then do below:-

  1. install nginx on a suitable server
  2. forward port 80 and 443 to this server
  3. configure nginx for the three domains you have - config I posted previously should help you
  4. install certbot and run to generate certs
  5. test

FYI, the traffic from the nginx server to other internal servers will be over http unless you have these services configured for ssl. Most people are not too bothered with http internal to there network but want ask for anything that is exposed externally.

Hope that helps. Let me know if not clear

Hi

Thanks for the info. I am running a single Ubuntu host so will need to run everything on it 192.168.1.50 that is NGNIX, HASSIO and Certbot. I want http or non-www to connect to NGINX but then switch to https so that all comms between browser and NGNIX is SSL secure.

Is it possible to run all what you have suggested on single host?

What do I put in configuration.yaml for HASSIO under http section?

Thanks

Hi,

Yes should be fine to run on one host.

You need to forward 80 and 443 from router to 192.168.1.50

The http section can just be left as default on HASSIO and then in nginx you would proxy the duck dns sub-domain that you want to use for home assistant with http://localhost:8123.

Hi,

Great thanks.

Is this a three step process?

  1. Browser enter http://domain.duckdns.org on port 80, resolved to my internet address and connects to router where I have ports 80 and 443 redirected to Ubuntu host running NGINX and HASSIO.

  2. Incoming connection on port 80 to NGINX converts the connection to SSL (lets encrypt) and browser automatically changes to https://domain.duckdns.org on port 443 and the padlock symbol in the browser

  3. NGINX has taken care of step 2 and SSL terminates at NGINX but then redirects https://domain.duckdns.org to http://localhost:8123

Not sure how steps 2 & 3 works or how to configure.

Can you point me in the direction of any instructions of how to install and configure NGINX for the above to work with Lets Encrypt and automatic SSL renewal and to redirect to http://localhost:8123

Cheers

yes, if you enter http on browser it will redirect to https. If you enter https then it will just go directly to that.

The config below is needed for port 80

server {
listen 80 ;
server_name hass.domainname.com;
return 301 https://hass.domainname.com$request_uri;
}

The return 301 causes the browser to redirect from http to https.

The following config is for port 443

server {
listen 443 ssl;
server_name hass.domainname.com;
ssl_certificate /etc/letsencrypt/live/hass.domainname.com$/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/hass.domainname.com$/privkey.pem; # managed by Certbot
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA’;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparams.pem;

location / {

proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;

proxy_pass http://192.168.1.9:8123;
proxy_read_timeout 90;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_redirect http://192.168.1.9:8123 https://hass.domainname.com;
}
}

The proxy pass and proxy_redirect lines are responsible for returning the internal website when you request the external site.

I would setup the nginx server configs for port 80 and 443, install certbot and then run ./certbot-auto --nginx

This soul then create ssl certs and update the nginx for you, I then create a cron job to schedule the run of ./certbot-auto renew, this renews the certs.

I would just give it a go and see how it goes

Thanks I will give it a go tonight.

Hi

Have you or do you know of anyone who has setup in docker?

Thanks

No sorry I don’t use docker at the moment and not sure who does.

Hi,

I installed nginx with the following instructions:

However it did not create a /etc/nginx/sites-available/default folder I only have /etc/nginx with nginx.conf with the following:

user  www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    default_type  application/octet-stream;

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

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Did I follow the wrong instructions to install Nginx?

No you should be fine. The configuration you posted includes

include /etc/nginx/sites-enabled/*;

So I would just create the sites-enabled folder and create a file inside with your server configuration and you should be ok

ppl i see u understand how to use NGINX
can u say how to redirect base_url doman.duckdns.org:6666 to local 192.168.1.100:8123 ?
because there is a problem with google tts after install duckdns plugin
it cant to access to dns name from internal network so i need to do local redirect on hassio

@Madelinot @macjob (or anyone else)

Right now I’m using Hassio with the DuckDns add on and I can get an SSL cert for myhass.duckdns.org. If I were to use ngnix to force redirect http to https, you mention I would need Certbot for ngnix. Why? Is the ngnix server actually using SSL? I thought it was just redirecting http requests. BTW, are you running the DuckDns add on, or are you running it outside of docker? I don’t get how the later would work because the cert wouldn’t be accessible from Hassio.

I am trying to implement NGNIX in hassio. I have read this post and have come to the conclusion that I have to do some port forwarding in my router. Unfortunately my service provider att use port 443 to service the router. I therefore can’t port forward 443 to my pi running NGNIX and hassio. First, am I reading the NGNIX docs correctly in that I have to port forward both 443 and 80 to my pi? Second, if this is true is there any work around.

Thanks