[nginx] IPv4 OK, IPv6 NOK

Hello,

After successfully converting my home-based server from HTTP to HTTPS using Let's Encrypt, I'd like to add support for IPv6.

Did I make a mistake reconfiguring nginx for that purpose?

#OK
curl -4 https://www.acme.com
#OK
curl -6 https://www.acme.com
#OK
Chrome http://[2a01:blah:7ac6]/
#NOK
Chrome https://[2a01:blah:7ac6]/
"Your connection to this site is not secure"

Thank you.

~# cat /etc/nginx/sites-available/default
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }
}

server {
        root /usr/share/nginx/acme;
        index index.html index.htm;
        server_name www.acme.com acme.com;

        error_page 404 /404.html;

        #Add to allow IPv6
        listen          [::]:443 ssl;

        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/www.acme.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/www.acme.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.acme.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name www.acme.com acme.com;
    listen 80;
    #Add to allow IPv6
    listen          [::]:80;

    return 404; # managed by Certbot
}

Only the www is being redirected...
What should happen when acme.com is requested?

4 Likes

You cannot use the IP address in the HTTPS URL unless the IP address itself is also in the certificate. Chrome matches the URL hostname to the identifiers in the cert.

Let's Encrypt recently added support for IP addresses in the cert. However, this requires use of the shortlived profile and an ACME client that supports profiles, IP addresses, and is very reliable since shortlived certs expire in less than 7 days. For routine web servers a domain name is probably much better suited which allows longer lived certs. See: Profiles - Let's Encrypt

Someone owns and operates that domain. But it isn't you. Please don't use other people's domains in examples. Use something like example.com which is an industry acceptable name for such purposes.

We prefer seeing your actual domain name.

4 Likes

Thanks for pointing it out.

I'll see how to rewrite the file to support both items.

The servername takes care of which FQDNs will be handled by that section.
There is no need for the IF case.

3 Likes

I can't publish the actual domain name.

Is that error a problem in real life, or can I leave things as is?

That's fine. Just please don't use other people's valid names in the future.

Do you mean the failure using the IP address in the URL?

If so, just don't do that :slight_smile: use the domain name instead

Your IPv4 address would not work in the URL either.

2 Likes

Should I rewrite it this way?

#HTTPS
server {
	root /usr/share/nginx/acme;
	index index.html index.htm;
	server_name www.acme.com acme.com;

    #Add to allow IPv6
    listen          [::]:443 ssl;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.acme.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.acme.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

#HTTP
server {
    #if ($host = www.acme.com) {
    #    return 301 https://$host$request_uri;
    #} # managed by Certbot
    return 301 https://$host$request_uri;

    server_name www.acme.com acme.com;
    listen 80;
    #Add to allow IPv6
    listen          [::]:80;

    return 404; # managed by Certbot
}

That should now redirect both FQDNs.
[yes]

1 Like

No, I wouldn't do it that way. While it redirects every HTTP request to HTTPS it would be better to exclude the HTTP Challenge request. Like this:

server {
    listen 80;
    listen [::]:80;    
    server_name example.com www.example.com;

    location /.well-known/acme-challenge/ {
        root   /usr/share/nginx/acme;       # make/use folder as you prefer
    }
    location / {
       return 301 https://$host$request_uri;
    }
}
4 Likes