If suddenly this whole story has passed you, Let's Encrypt is a certification authority from the non-profit organization ISRG, which exists with the support of EFF and many companies, which has taken on the mission to give people free SSL / TLS certificates for websites and servers. Certificates from Let's Encrypt are already used on more than 10 million domains .
In addition to the obvious free of charge, the certificates from Let's Encrypt have a special advantage that any other commercial certification center lacks: if you once received a certificate from Let's Encrypt, then, other things being equal, it is forever. You do not need to manually renew certificates once a year or two. There is no need to remember that there are certificates somewhere. Got it, set it up and forget it!
An attentive reader will immediately want to argue: how is it, because it is known that certificates are issued with a validity of three months? The thing is in automatic renewal of certificates, which is possible in the complete absence of human actions.
The organization of automatic renewal of certificates in the article is paid close attention so that you can fully appreciate this fundamental advantage of Let's Encrypt.
The EFF website has brief instructions on how to use Certbot , the recommended program for obtaining certificates, but they are most likely designed for those who log into their server via SSH only for urgent reasons. More detailed documentation is also available , but as long as you read it all and find everything that you really need to know ... In addition, it does not cover some of the important strategic issues of using certificates.
Obviously, we need a short and clear instruction for those who are accustomed to the server console, but want to understand everything without wasting time.
From this article you will learn ...
You know everything about SNI? Read about the installation immediately.
In the instructions below, I assume that your sites will use SNI. This TLS protocol extension allows browsers to provide the desired site name before receiving and verifying the SSL certificate from the server. Thanks to SNI, you can host as many sites as HTTPS on a single IP. But not everything is so simple - otherwise why would I write about it?
There are a number of old browsers in principle not supporting SNI. These include any version of IE in an already abandoned Windows XP , embedded browser in Android 2.3 and 2.2 from 2010, as well as some other more exotic browsers and libraries like Java version 1.6 and Python up to version 2.7.9 .
If you still want your site to open in IE in Windows XP, then this problem cannot be solved by just giving up SNI. It is necessary to select ciphers in a special way, already abandoning forward secrecy and risking getting a low mark from SSL Labs . As you can guess, this issue deserves a separate discussion, if only because users of IE under XP can sympathize - half the Internet does not open up!
A year ago, limited search for this technology by some search bots like Bing could keep you from switching to SNI, but now with the advent of dozens of sites with free certificates from Cloudflare that can’t open without SNI, the Bing bot ( which is easy to check ) and bots other major search engines have come to terms with reality. Now you can not worry about it. I note that Googlebot never had such problems.
Another cause for excitement can be various means of accessing your site's API. If you have had an API for a long time, then there is a small chance that there are some of your customers using older versions of Java or Python. If you do not have these, then nothing to worry about. If there is - my condolences.
It's simple. You do not need to constantly keep in mind the facts about the issued certificates. For which domain the certificate was issued first. To which certificate you need to add more domains . And so on ... You don't need to think about anything like that with SNI.
For example, you can view domains in the Thematic Media certificate:
true | openssl s_client -showcerts -connect habrahabr.ru:443 2>&1 | openssl x509 -text | grep -o 'DNS:[^,]*' | cut -f2 -d:
At the time of this writing, this command will display a detailed list of all possible TM domains:
habrastorage.org api.geektimes.ru api.habrahabr.ru geektimes.ru habrahabr.ru id.tmtm.ru lab.geektimes.ru m.geektimes.ru m.habrahabr.ru special.geektimes.ru special.habrahabr.ru www.geektimes.ru www.habrahabr.ru
No secrets and no secrets. Do you want that?
If you are reading this text from the future, when Certbot is already in Debian stable and Ubuntu without a hitch, it’s all simple:
apt-get install certbot
Either use aptitude
or another package manager for your distribution.
If you still have Debian stable "jessie" that is relevant at the end of 2016, then everything is just a little more complicated.
You need to connect Debian Backports by adding a line to /etc/apt/sources.list
:
deb http://ftp.debian.org/debian/ jessie-backports main contrib non-free
Now you can install with the indication of the source:
apt-get update apt-get install certbot -t jessie-backports
(The section is relevant until only stretch has become stable.)
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install --upgrade letsencrypt
Further everywhere instead of certbot
use letsencrypt
.
If you have any other distribution kit, then additional installation instructions are on the official website Certbot . If you do without the package manager, then the installation usually comes down to ...
wget -O /usr/local/bin/certbot-auto https://dl.eff.org/certbot-auto chmod +x /usr/local/bin/certbot-auto ln -s /usr/local/bin/certbot-auto /usr/local/bin/certbot
Anywhere below you can use the certbot-auto
command instead of the certbot
command.
We will receive certificates using the webroot method without reconfiguring or stopping the web server, which means nginx. We need some directory in which certbot
will write its files, and which one should be accessible from the network to the certifying server according to the ACME protocol.
In order not to write a long line of options each time, and even better not to remember them, we will write the basic settings into the configuration file that certbot
expects to find in /etc/letsencrypt/cli.ini
:
authenticator = webroot webroot-path = /var/www/html post-hook = service nginx reload text = True
The last directive is needed to save us from the charms and beauties of ncurses, which is necessary so that you can compare the output of the commands here in this article and in yourselves.
We also need to gently restart nginx (without interruption in service) when the certificates have been successfully renewed. At the same time, nothing prevents the restarting of other services like Postfix that use the received certificates. Commands are separated by a semicolon.
If you see this error:
letsencrypt: error: Unexpected line 14 in /etc/letsencrypt/cli.ini: post-hook = service nginx reload; service postfix reload
Then you need to update python-configargparse
. The error was fixed in 0.11.0 .
It is expected that certbot
will create the necessary files for checking domain rights in subdirectories down the hierarchy to the specified one. Like these:
/var/www/html/.well-known/acme-challenge/example.html
These files will need to be accessible from the network on the target domain at least over HTTP:
http://www.example.com/.well-known/acme-challenge/example.html
For the following checks, create some kind of file:
mkdir -p /var/www/html/.well-known/acme-challenge echo Success > /var/www/html/.well-known/acme-challenge/example.html
Registration needs to be done only once:
certbot register --email me@example.com
There is nothing complicated.
In general, to obtain a certificate, it is necessary in all server
blocks to add the following block to other location
blocks:
location /.well-known { root /var/www/html; }
It is clear that to inscribe such a block explicitly for each site is a moveton, therefore we will create the file /etc/nginx/acme
with the block contents above.
# cat /etc/nginx/acme location /.well-known { root /var/www/html; }
Then, for each domain and subdomain for which you need to get certificates, in the server
block in front of all the location
blocks, we specify:
include acme;
Hosts redirectors (for example, from the bare domain on www) can be skipped. ACME server must take into account the standard redirection. More on this below.
Reload nginx and check that our test file is visible:
# service nginx reload # curl -L http://www.example.com/.well-known/acme-challenge/example.html Success
After checking, it is better to delete the test file - certbot
likes to delete everything unnecessary, and such a file will interfere and cause an error message (Unable to clean up challenge directory).
rm /var/www/html/.well-known/acme-challenge/example.html
Now we are ready to receive our first certificate .
As already mentioned, the ACME Boulder server takes into account redirection with codes 301 and 302 . In this sense, it does not matter where, ultimately, the files required for passing the checks are found. Redirection is possible even to non-standard ports , without restrictions on the final HTTP or HTTPS protocol. Let's Encrypt themselves recommend using redirection to create a single point of verification of domain rights .
If you can get these files with curl
with a limit of ten redirections, then Boulder will see these files. There should be no restrictions on IP addresses .
curl --location --max-redirs 10 http://example.com/.well-known/acme-challenge/example.html
This is convenient if you have a complex structure of redirections between different versions of sites. It should be enough to connect that block with location
only on the main site to get certificates for all the others.
$ curl --head --silent --location --max-redirs 10 http://somewhere.example.net/... | grep ^HTTP HTTP/1.1 301 Moved Permanently HTTP/1.1 301 Moved Permanently HTTP/1.1 200 OK
Verification always begins with an HTTP request on port 80.
If you already have all the websites working over HTTPS, then the whole scheme will work if you have a forwarding server on port 80, saving $request_uri
in the response.
Another thing is that you can shorten the path and connect our block with the location
in the default server for port 80, which does forwarding to HTTPS. Then it will not be necessary to add anything to the configs of individual sites.
An example of the configuration of such a forwarding all-in-a-HTTPS server:
server { listen server.example.com:80 default_server; include acme; location / { return 301 https://$host$request_uri; } }
Such a config should be defined in /etc/nginx/conf.d/default.conf
, aside from configs of specific sites.
We start the server explicitly on the external IP in order not to reconfigure Apache to another port. If this is not a problem for you, you can skip specifying the server name in the listen
directive.
A typical example is a certificate for servers dedicated to SMTP or IMAP, on which there are no sites at all. Either use a universal forwarding service that is higher, or ...
server { server_name smtp.example.com imap.example.com; listen server.example.com:80; include acme; location / { return 404; } }
Unfortunately, the ACME protocol requires that such a server be available during each check. This is practically equivalent to continuous availability, due to the requirement to obtain and renew certificates without restarting the server. Do not delete this config after receiving the certificate.
If you have Apache2, and there is no way to switch to your favorite nginx, then ... Add the following lines to /etc/apache2/conf-available/certbot.conf
:
Alias /.well-known/ /var/www/html/.well-known/ <Directory /var/www/html/.well-known/> Satisfy any </Directory>
Then
a2enconf certbot mkdir -p /var/www/html/.well-known service apache2 reload
And be sure to check this:
mkdir -p /var/www/html/.well-known/acme-challenge echo Success > /var/www/html/.well-known/acme-challenge/example.html curl -L http://localhost/.well-known/acme-challenge/example.html && rm /var/www/html/.well-known/acme-challenge/example.html
There are many reasons why this scheme may not work for you in Apache2. Pairs of text screens are not enough to describe them all. Do not be angry - article about nginx.
Let's Encrypt have limits on the number of requests for certificates , so we first try to get the necessary certificate in test mode:
certbot certonly --dry-run -d example.com -d www.example.com
At the end, the program should report on successful work:
The dry run was successful.
Now you can safely receive a certificate in fact. Be sure to explicitly list all the necessary subdomains, such as www.
# certbot certonly -d example.com -d www.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: http-01 challenge for example.com http-01 challenge for www.example.com Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2017-04-01. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew"
Hooray! With the receipt of the certificate is finished!
If you suddenly forgot to specify the www
subdomain, or you need to add another domain or subdomain to the certificate (there can be up to 100 in one certificate ), then this is easy to do after receiving the certificate. Just run the command again, adding the required name:
certbot certonly -d example.com -d www.example.com -d shop.example.com
You will have no alternative to add this domain to the certificate. If you want to avoid questions, you can immediately specify the key approving this behavior:
certbot certonly --expand -d example.com -d www.example.com -d shop.example.com
The operation can be repeated.
Make sure that the received certificate is exactly what we need:
# openssl x509 -text -in /etc/letsencrypt/live/example.com/cert.pem Certificate: Signature Algorithm: ... Validity Not Before: Jan 3 06:00:00 2017 GMT Not After : Apr 3 06:00:00 2017 GMT X509v3 extensions: ... X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com
Or, if you don’t need the details:
cat /etc/letsencrypt/live/*/cert.pem | openssl x509 -text | grep -o 'DNS:[^,]*' | cut -f2 -d:
The team should list the domains in the certificate.
Certbot does not overwrite certificates, but replaces them with links to the most current certificate options in a specific directory, which is the same with the first certificate domain (ie, CN
).
Let's see what files we have:
# find /etc/letsencrypt/live/ -type l /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/chain.pem /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/cert.pem
With this knowledge, we can set the SSL settings for nginx:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
As you can see, cert.pem
is not used anywhere in the config, and this is not an error. For nginx it is not needed.
Full working example config:
server { server_name www.example.com; listen www.example.com:443 ssl; # default_server; # default_server SNI ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; resolver 127.0.0.1 8.8.8.8; # http- add_header Strict-Transport-Security "max-age=31536000"; # "" http:// add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests"; # #location / { # proxy_pass ...; #} }
Config for forwarding from a bare domain without www:
server { server_name example.com; listen example.com:443 ssl; access_log off; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; resolver 127.0.0.1 8.8.8.8; add_header Strict-Transport-Security "max-age=31536000"; expires max; return 301 https://www.example.com$request_uri; }
It is understood that you are using some kind of local server to cache DNS queries. If this is not the case, then 127.0.0.1
in the resolver
directive must be replaced with the IP of the DNS server being used.
Cipher settings and stuff like that ( ssl_dhparam
, ssl_session_cache
) are best kept outside the configs of individual servers.
If you are worried that Certbot can steal keys from your certificate in spite of open source codes , which means that in theory some villains will be able to decipher all traffic, then I hasten to reassure you. If ciphers from the DHE and ECDHE families are used to connect to your site, then a key leak will not allow you to decrypt traffic. In these ciphers, the certificate key is used only for authentication, and is not used as a key for encryption. All modern browsers support these ciphers.
If for ECDHE on elliptic curves nothing needs to be done, then for DHE it would be possible to use enhanced parameters. It would be best to turn off DHE altogether.
If for some reason you cannot do without DHE, then we first create the parameters:
openssl dhparam -out /etc/ssl/private/dhparam.pem 2048
Then we write in /etc/nginx/conf.d/ssl_dhparam.conf
one line:
ssl_dhparam /etc/ssl/private/dhparam.pem;
Certificates are issued for three months . Not for half a year, not for a year, but only for three months. Naturally this raises questions. Do I need to go through this whole procedure in three months? Is it necessary to do this always before the end of time? Maybe you should still invest in a paid certificate to forget about it all and not remember a couple of years?
But no, do not rush to look for payment instruments! As promised at the beginning of the article, there are no problems with updating certificates.
If you have Debian, you only need to add the --allow-subset-of-names
key to the --allow-subset-of-names
call in /etc/cron.d/certbot
:
# /etc/cron.d/certbot # certbot -q renew, certbot -q renew --allow-subset-of-names
If you have Debian and systemd, see these instructions .
If you do not have Debian or do not have a file, then add only one line to the crontab
from root
( sudo crontab -e
):
42 */12 * * * certbot renew --quiet --allow-subset-of-names
According to the recommendations of Let's Encrypt, you should try to renew certificates twice a day. This should be done at a randomly selected minute of that hour, which means that you need to replace 42
in this line with another number in the range between 0
and 59
. Or you can do it the way it is done in /etc/cron.d/certbot
.
In this command, the --allow-subset-of-names
key is needed so that Certbot tries to get certificates for a partial set of domains.
For example, you had on your server sites www.example.com and shop.example.com , passing under one certificate, but then you transferred shop.example.com to another server. If you do not specify such a key, Certbot will fail with an error when you try to confirm the ownership of shop.example.com without receiving any certificate for you at all. The certificate will expire and your site will go offline. With this key, you still get certificates for at least a partial set of domains, leaving your sites online.
If you are close in spirit to tee
and sed
, then there is a much shorter instruction on how to configure a bunch of Let's Encrypt and nginx , provided the hostname
correctly configured. Just copy the commands and paste.
Found a bug? Write in a personal, please.
Source: https://habr.com/ru/post/318952/
All Articles