Do you want to use http and https? or force port 80 to go to 443 to create a secure connection.
I have a nginx reverse proxy setup with DDNS and lets encrypt running with personal certificate auth with fallback to basic auth. I never was able to get the satisify rule to work with my LAN.
I followed this thread and managed to put together something that works.
configuration.yaml
http:
server_host: 127.0.0.1
Removed api_password
I have my nginx configuration broken up, so nginx.conf is just the default and a custom file in /etc/nginx/sites-available/
hass
server {
# Update this line to be your domain
server_name domain.duckdns.org;
# These shouldn't need to be changed
listen 80;
# listen [::]:80 ipv6only=on;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
# Update this line to be your domain
server_name domain.duckdns.org;
ssl on;
# Ensure these lines point to your SSL certificate and key
ssl_certificate /etc/letsencrypt/live/domain.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.duckdns.org/privkey.pem;
ssl_client_certificate /etc/nginx/ssl/auth/client.pem;
ssl_verify_client optional; # or `on` if you require client key
# These shouldn't need to be changed
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-$
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_session_ticket_key file.key;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
#ssl_buffer_size 16k; #for throughput, video applications
ssl_buffer_size 4k; #for quick first byte delivery
client_body_buffer_size 8K;
client_max_body_size 20m;
client_body_timeout 10s;
client_header_buffer_size 1k;
large_client_header_buffers 2 16k;
client_header_timeout 5s;
proxy_buffering off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
keepalive_timeout 40;
location / {
if ($ssl_client_verify != SUCCESS)
{
## if no ssl-client-auth forward to port 444 (see below)
proxy_pass https://127.0.0.1:444;
}
proxy_pass http://127.0.0.1:8123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
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 "upgrade";
}
}
## fallback server for basic-auth if ssl-client-auth failed
server {
listen 444 ssl http2;
server_name domain.duckdns.org;
ssl_certificate /etc/letsencrypt/live/domain.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.duckdns.org/privkey.pem;
# These shouldn't need to be changed
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-$
ssl_prefer_server_ciphers on;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_session_ticket_key file.key;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
#ssl_buffer_size 16k; #for throughput, video applications
ssl_buffer_size 4k; #for quick first byte delivery
client_body_buffer_size 8K;
client_max_body_size 20m;
client_body_timeout 10s;
client_header_buffer_size 1k;
large_client_header_buffers 2 16k;
client_header_timeout 5s;
proxy_buffering off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
satisfy any;
allow 192.168.x.0/24;
deny all;
auth_basic "Restricted";
# Create this with: htpasswd -c /etc/nginx/.htpasswd some-username
# If you add more users, omit the -c
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
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 "upgrade";
}
}
This is very crude and probably much simpler to implement, but it seems to work. Basically port 80 requests are redirected to https, and a simple check personal certificate check is asked. I have it optional so it can be denied and just use basic authentication. The fallback goes to another port (444) that allows authentication.
Please make sure your port forward this port or whatever port you change it to.