ipv6only

This website is so secure now, right? It has been a very long time since my last post. Was not able to catch a sleep, so here is a tiny article discussing how it was done. Context: I'm using Nginx 1.2.1 as the webserver, and Debian Wheezy as the Operating System.

Why I lestencrypted my website:

  • Because of this very solid point.
  • Because why not? After all, it is so easy to do now.

Why I didn't before:

  • Because, you'll never have to send any personal informations to this website.
  • Because I don't really trust centralized things, nor SPOF.
  • Because, you're not safe using a secure connection to an untrustworthy website.
  • Because, the cobbler's children are always the worst-shod.

How I've done it:

It is recommended that most people with shell access use the Certbot ACME client. We have a shell access, so we'll use this client:

[email protected]:~# wget https://dl.eff.org/certbot-auto # download client
[email protected]:~# chmod a+x certbot-auto # make client executable


We're feeling more conservative and we would like to make the changes to your Nginx configuration by hand, we'll use the certonly subcommand:

[email protected]:~# ./certbot-auto --nginx certonly


After answering a couple of questions, and if everything went well, we should receive this message:

congratulations

At this point, we need to update our Nginx server block related to the https traffic.

Double check using curl:

check



What I've learned in this very short process:

I was configuring my server blocks, then I tried to restart Nginx, then Nginx told me the port 443 was already in use:

[email protected]:/etc/nginx/sites-enabled# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[email protected]:/etc/nginx/sites-enabled#
[email protected]:/etc/nginx/sites-enabled# service nginx restart
Restarting nginx: nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:443 failed (98: Address already in use)
nginx: [emerg] still could not bind()
nginx.
[email protected]:/etc/nginx/sites-enabled#


Not running anything on port 443, you know where to look at:

listen 443 ssl;
listen [::]:443 ssl;


I'm using Nginx 1.2.1 yeah, I should feel bad about that, and in that version, the option ipv6only defaulted to off.

So the line listen [::]:443 ssl is basically saying: the IPv6 socket listening on a widcard address will accept both IPv6 and IPv4 connections. Which is, with the first line, redundant right? So one of the correct configuration is:

listen 443 ssl; # accept IPv4 connections
listen [::]:443 ssl ipv6only=on; # accept IPv6 connections


Or you can simply:

listen [::]:443 ssl; # Accepting both IPv4 and IPv6 connections, Nginx ver < 1.3.4


Or you should use a more recent version of Nginx. From the documentation, we can read: ipv6only

The other thing I've learned in this very short process:

I was not renewing my certs, I was creating them, for the first time. But I had to pause the CloudFlare Proxy for the tls handshake to succeed. I've not yet understood why this step was necessary, but it seems related to the following note:

cloudlfare


Going further: traffic redirection

Now that we have brand new shiny certs, we may want to redirect all the traffic to https. In our case, we'll add the following line inside the server block managing the http requests:

return 302 https://$host$request_uri;



Going a little bit further: renewal

After 90 days, we'll have to renew our certs. Renewal certificates can be tested with the following commands:

[email protected]:~# ./certbot-auto renew --dry-run --webroot --webroot-path /var/www/html
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mlvin.xyz.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for mlvin.xyz
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/mlvin.xyz/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/mlvin.xyz/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------
[email protected]:~#


The renewal operation can and should be automated

Final Nginx configuration:

Here are, the default server block, used for the http traffic, and the default-443 server block, used for https traffic.

Special shoutout to one of my greatest mentors

jpoesen

Special shoutout to kane for giving me a good advice for the future

kane


Thanks for reading. I really hope you've learned something. If you want to know more on the topic, I highly recommend this link, or one of the following: