
Hello!
In this article I will describe how we solved the problem of centralized updating of certificates of Let's Encrypt and infrastructure management using ansible.
In our solution we will use:
I will offer two options for the architecture, in which our solution can be useful. In turn, you can offer your options in the comments.
Option 1: You have several frontend servers with public ip (for example 3) serving several domains. These domains can be added / deleted. In order not to monitor each of the frontend servers - it is more convenient to do it on one letsencrypt server 'e:

Option 2: You have only one server with public ip, and you need certificates on servers within the network:

The repository with roles available on the link .
There are 4 roles in the repository:
nginx on all hosts and copies base configs. By itself, the role does not start from the playbook. It runs on meta dependencies from other roles.rsyncd on the letsencrypt server host. In meta dependencies, it has the role nginx-simple . Accordingly, nginx will be installed first, and then the role of letsencrypt server will play.incron and copies the base config. The role also does not run directly as nginx-simple .incron and nginx-simple roles. After them, the front role copies the nginx configs needed for example.com, adds a task to cron to pick up new certificates from the letsencrypt server and the task to incron to check file changes and execute the nginx -s reload hook nginx -s reloadLet's go to practice:
Initially we have:
letsencrypt server )front )Ubuntu 16.04 is installed on all servers.
To begin with, we will install nginx on a common role of nginx-simple on all hosts and scatter nginx configs common for all hosts (nginx.conf, ssl parameters, certificate paths, etc).
For letsencrypt server in the template .../site-available/default.conf .well_known folder will be in /var/www/ :
{% if letsencrypt_server %} location /.well-known { root /var/www/; } For the server / servers of the front group, since the .well_known folder .well_known used not only for obtaining certificates, but also for other software, we import into the config example.conf letsencrypt-proxy.conf and nginx will search the folder locally on the front server using the try_file try_file :
{% if nginx_proxy_well_known %} try_files $uri $uri/ @letsencrypt; {% endif %} Configs for the domain will be filled depending on the variables from inventory. In the repository is the domain example.com
Also, depending on the letsencrypt_server variable, the nginx-simple role will install certbot on the letsencrypt server and add the cron task to update the certificates.
Since we solved this problem before the wildcard certificate from Let's Encrypt appeared, we will consider both options for obtaining a certificate.
On the letsencrypt server server we execute:
certbot certonly --agree-tos -d example.ru --webroot -w /var/www/ If there are more than one domains, we add the following ones using the -d key.
To obtain a wildcard certificate, we will need to add records to the DNS TXT. Currently, this is the only way to obtain such a certificate:
certbot certonly --agree-tos -d example.ru -d *.example.ru --preferred-challenges dns --manual --server https://acme-v02.api.letsencrypt.org/directory Certbot will write what TXT records you need to add.
We received the certificates, it remains to set up copying them to the front server / server. To do this, we will configure rsyncd on the letsencrypt read-only server for a limited list of ip addresses:
hosts allow = {{ hosts_allow }} hosts deny = * list = true use chroot = no [cert] path = /etc/letsencrypt/live/ uid = root gid = root read only = true Every 5 minutes the cron task from the front servers will check if the certificates have been updated and take them. Since certificates are rotated, /etc/letsencrypt/live/{{ domain }} are located in the /etc/letsencrypt/live/{{ domain }} folder. Add the -L switch to pull out the original files:
/usr/bin/rsync -zavL --chmod=D0750,F640 --delete rsync://{{ hostvars['letsencrypt-server'].ansible_eth0.ipv4.address }}/cert /etc/letsencrypt/live/ We set up nginx, received certificates, took them to the front server. It remains to determine that the files in the /etc/letsencrypt/live/{{ domain }} folder have changed and execute the nginx -s reload hook nginx -s reload
The linux inotify kernel subsystem and the incron daemon will help us in this. Read more about them here .
The incron role incron necessary packages, and from the front role template a task will be added to monitor the certificates and the necessary hook:
/etc/letsencrypt/live/{{ domain }}/ IN_CREATE,IN_DELETE,IN_MODIFY,IN_MOVED_TO nginx -s reload We tried to describe in detail the whole process of installation and configuration, and since everything is described in ansible playbooks - the article was very compact. As they often like to say - "a little more than 100 lines of code." Questions, criticism and comments will be happy to answer in the comments.
Source: https://habr.com/ru/post/352720/
All Articles