certbot: Use DNS-01 instead of HTTP so it can work on other machines.

This commit is contained in:
Julien Palard 2021-09-10 14:09:00 +02:00
parent f36a6f42da
commit 361cdc7696
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
8 changed files with 279 additions and 58 deletions

View File

@ -1,6 +1,7 @@
---
letsencrypt_email: afpy-web@lists.afpy.org
admin_email: afpy-web@lists.afpy.org
ansible_python_interpreter: "/usr/bin/python3"
ansible_user: root
authorized_keys: |

View File

@ -1,43 +1,51 @@
$ANSIBLE_VAULT;1.1;AES256
38633036366433373461633534316662373966333165333566626366323630613437613566653836
6334653962643730386362313861636533353364353439610a323530383537353530366463656633
35613536623637393466306261623662383438626466653736643030376136386236323963313932
3137333838383133380a353634333766656430343938393730326533623636383930306462356233
34383730613030323430623837366538653834306538343263633265353964373936336130376564
30303532666434313034636163653432363635323563666237306663623061633863373464653239
36313030643133346532633361333465363730653137303234343037633733646466343530656437
62396563396233313932396232313631663832613464653262386161353364346331663731623530
36663438333062656135643330633737396465633436303136663639323838303465346436373835
30616439616333626364383231383835313362343861333234313032396661346434663064366239
35346364623035623334316361633736356462386432613961613334336430623266343931363330
64663838343337323137326234663963363863616564623934383761613938613535393137626532
33383436306363633266313735386233396232663635396662396438633464396465376533363239
38383661316233366235643530636465663339363534356262343231643431633565626339303237
66636235393763663938663931623830396266383432313734386563623837303736646132663263
62636530373966646539333835636436393031626666376534643464373365396439636335396465
36306531636566643166336565626132366638336462663239626434613839393365396537393334
62643434666362366439613762613761343561396638376135393361383439626563336561613233
39623465356530616538326533363835623137653234626232356535623231626336383465383435
38663164623337323631333662303466633966336433656638346535633238623333666332396538
31396138626339396465643661346161343762336131363462343166616163643663383534633866
35343433333961356133656364353632303534616161366638386630393833333365383838616531
65353436353763353934336637306563323130323961303032376562353432323865343830333064
66653565366432333765656564366266666433356132656332366335373865376430383936373337
32653937326162653831383732663635613134386633353236346131373536666535326538636464
66653564363837623564633330316466653064363861323063633064306335333035646465626361
39383830623936363032643230633264383163303863316666346361613263646635656537313730
34636266636336666336336461313839373132353830373630663861666439353234393731356466
32393233343135323537616566316164373565656362613433616337656131626262653661616564
37393831366462643433633230356630383331643537333631303564653930643136633866393534
33613033396632373337396635333666333637336436626335306133633933396562393430653732
37626263623938323333333362313763313464633139386130393535636639343139333662336137
34626636613630343335623332636662626531626131346531316663396633623531383063643062
32346332353361663164326662316333643635646635623663653638623737656262313166396363
64333462663031646534376163353734613833666438633633663664363237313733366531373330
32626662366663396363353435386631323530303632643761633438643666396437323637396439
33323466346263626639626336336638663930336562363564306132383330356461346236323962
36663663666536653532383333373836653966346537663666653634343566356335383163616463
36353665653231313239663530343539353765376263346338323933383435346437356462646531
30383539386365303331326335663166626130616235363238343633663863626466623837316237
66306333386163633966663038613631383537303963643465633738663138653936346339656532
3365313562613635626566633331386534643964303662306465
33346536623633343639613036313765373766306339356633663234393333393166666166633539
6562353533376661373361613132353031313635316339390a353565373164663332663431346531
61336639383763396234383564373962383533653063343033326161356334623362633937643036
3263623730323362330a373464663064616539623362653937633533356666323261363638383666
35333635373633343762613766306635363064663032333963333336616265616562636438386264
35643966343531326237343933313832343734303061393461666535336363613339636363393132
65306337643733663463333734326631663834353430343736613934353763613632613033313934
61336436316334666161326366643337393965643639653564623938653136663535343464643630
63373135386262653033333266306136306337653261326531346635633139646465656562623462
62343537353937323132633938323135393063666435626233353961643733626161366232626531
32313230666533373736336337613035336461383961323239383261636462623634393035383831
32303237353437663965633761646633323338653235636264313139646432663131396133626565
61333065316639653937363332313134663131666632653231646131373065323761336634333663
34356234616565646134353063366362643636633461343961336433613434653935333836373932
37333735346438633033633436316166613230326238393565653761396632613339633866343661
36316662383435313637323266383166343664356265393732373662643938373232333761356538
37353264333663383066373335373130663833383630323631326130366231613938656665626235
33653136373861346263323566616164333634303237613738336266323436336665343662633361
61353633313163343437313462303936393434373631623537306531656363356233363538386137
32623866396364363338623062623637363539363033366335336333373739633764316165663432
32626639376266363639653661643538333636326462656434393630326532646336616537636164
63646632363937663539303965306131343465613865346233303936393765626331643966373234
35646334366539306134303664626262366233386337343631663436313031333136383362643935
39323363653734303263346435663061336133366331616635623863363735393335373461666533
39393365323438323532323331666333326635386331303534623631646266356434613534313161
61623864333065626233303666373535613734376536653638323635633139373536643837383038
36613736626561353831383336343963346535303338613131633238636237633364323735633038
30343633656535353362653135646331313162393735393138633666636532626631623866323132
39373464313530393064636664316235373162393635363132323332653765643931643334393161
35636262313032303631346432396231336539666563623165316334363133323366363666313839
30383462323536353531663261646465366564306435626162353135343834343066346239643333
31396366363162326365373164623835373761383461643934613166373366313032316536313964
30333334396362336531666238343139623663386438376236323731646138393162653431313439
66613738646134386666356661366564353661363338353137666166383261313462316633346663
64346264356138643639313235326534653838383864653363663330663061396363316635346137
37323832343631396530346336363537366137373832653333353436613236386434653535333331
63356564363737646139616334383735363132646265333932363033313837346135336465383062
33656261386263656238636133356464616266373235613264323163653961613032396330656432
65363138623566313438613331393664326365373033656539643835633935626665383337646335
66363764363038663134333836643530343431303039313738656565643837346261646138393331
65316232313036373535363030613766383132396539316165653039333462383834373364313830
30306136396533383561383031396537653665333938613838653563653464396138363836653332
65343838623266356230623161656137616130343163616534646335383761653830363130646166
37333035653261363663353863646231363234366162326664333932373131366638316235343734
63373966613566333064396633646336323234666465393633663663303538666233333531383133
61623661616439633038336235383835363938373938343262356235656364616530373336313630
35626538636364393035313339643561613833663839316361613263643633653535363534343331
34653238626537333363613334306535613162363963666534383834653261316439613763303361
63636265356637376434613633393138653439383363656535313232643536306162653562313332
3431643737626438383139313835613266303161353034666530

View File

@ -2,6 +2,9 @@
- hosts: webservers
vars:
ovh_application_key: "{{ vault_ovh_application_key }}"
ovh_application_secret: "{{ vault_ovh_application_secret }}"
ovh_consumer_key: "{{ vault_ovh_consumer_key }}"
nginx_public_deploy_key: |
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINbgxOufHY7SxQrJNTlHmye+xeNHBA1O5SGtGhGeOVZM
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIvF5rwjx5lpjzH6B4Uce9kZhz260kkwzYvIieR189Q1
@ -10,26 +13,17 @@
include_role: name=common
- name: Setup PyConFr
include_role: name=julienpalard.nginx
include_role: name=nginx
vars:
nginx_owner: pyconfr
nginx_domain: pycon.fr
nginx_certificates: [pycon.fr, www.pycon.fr]
nginx_certificates: ['pycon.fr', 'www.pycon.fr']
nginx_path: /var/www/pycon.fr/
nginx_conf: |
server
{
listen 80;
server_name pycon.fr;
access_log /var/log/nginx/pycon.fr-access.log;
error_log /var/log/nginx/pycon.fr-error.log;
return 301 https://www.pycon.fr$request_uri;
}
server
{
listen 80;
server_name www.pycon.fr;
server_name .pycon.fr;
access_log /var/log/nginx/pycon.fr-access.log;
error_log /var/log/nginx/pycon.fr-error.log;
return 301 https://www.pycon.fr$request_uri;
@ -61,8 +55,34 @@
rewrite ^/2018/(A-Za-z-)+/$ /2018/fr/$1/ last;
}
- name: Setup PyConFr 2016
include_role: name=nginx
vars:
nginx_domain: 2016.pycon.fr
nginx_certificates: [2016.pycon.fr]
nginx_conf: |
server
{
listen 80;
server_name 2016.pycon.fr;
access_log /var/log/nginx/2016.pycon.fr-access.log;
error_log /var/log/nginx/2016.pycon.fr-error.log;
return 301 https://www.pycon.fr/2016/;
}
server
{
listen 443 ssl;
server_name 2016.pycon.fr;
access_log /var/log/nginx/2016.pycon.fr-access.log;
error_log /var/log/nginx/2016.pycon.fr-error.log;
include snippets/letsencrypt-2016.pycon.fr.conf;
return 301 https://www.pycon.fr/2016/;
}
- name: Setup PyConFr 2012
include_role: name=julienpalard.nginx
include_role: name=nginx
vars:
nginx_domain: 2012.pycon.fr
nginx_certificates: [2012.pycon.fr]
@ -87,7 +107,7 @@
}
- name: Setup PyConFr 2011
include_role: name=julienpalard.nginx
include_role: name=nginx
vars:
nginx_domain: 2011.pycon.fr
nginx_certificates: [2011.pycon.fr]
@ -112,7 +132,7 @@
}
- name: Setup PyConFr 2010
include_role: name=julienpalard.nginx
include_role: name=nginx
vars:
nginx_domain: 2010.pycon.fr
nginx_certificates: [2010.pycon.fr]
@ -137,12 +157,35 @@
}
- name: Setup sigal of paullaroid.pycon.fr
include_role: name=julienpalard.nginx
include_role: name=nginx
vars:
nginx_owner: paullaroid
nginx_domain: paullaroid.pycon.fr
nginx_certificates: [paullaroid.pycon.fr]
nginx_path: /var/www/paullaroid.pycon.fr/
nginx_conf: |
server
{
listen 80;
server_name paullaroid.pycon.fr;
access_log /var/log/nginx/paullaroid.pycon.fr-access.log;
error_log /var/log/nginx/paullaroid.pycon.fr-error.log;
return 301 https://$host$request_uri;
}
server
{
listen 443 ssl;
charset utf-8;
server_name paullaroid.pycon.fr;
access_log /var/log/nginx/paullaroid.pycon.fr-access.log;
error_log /var/log/nginx/paullaroid.pycon.fr-error.log;
include snippets/letsencrypt-paullaroid.pycon.fr.conf;
root /var/www/paullaroid.pycon.fr/;
index index.html;
}
- name: Setup fr.pycon.org
include_role: name=julienpalard.nginx

29
roles/nginx/README.md Normal file
View File

@ -0,0 +1,29 @@
# Nginx with Letsencrypt
This role sets up nginx with letsencrypt (using DNS-01 with OVH API) .
## Role Variables
The mandatory variables are:
- `admin_email`: For letsencrypt.
- ovh_application_key, ovh_application_secret, ovh_consumer_key ([see doc](https://certbot-dns-ovh.readthedocs.io/en/stable/#credentials)).
- `nginx_certificates`: A list of domain to put in this certificate.
- `nginx_domain`: Used for file names and certificate name.
- `nginx_conf`: The nginx config.
Optional variables are:
- `nginx_owner`: If a unix user has to be created for this project.
- `nginx_path`: To create a directory owned by `nginx_owner`.
- `ssl_ciphers`: [Specifies the enabled ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers).
- `ssl_protocols`: [Enables the specified protocols.](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols)
- `ssl_prefer_server_ciphers`: [Specifies that server ciphers should be preferred over client ciphers when using the SSLv3 and TLS protocols.](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers)
- `ssl_session_cache`: [Sets the types and sizes of caches that store session parameters.](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache).
- `HSTS_header`: HTTP header to inject.
### Author Information
Julien Palard — https://mdk.fr

View File

@ -0,0 +1,6 @@
---
ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
ssl_protocols: "TLSv1.2 TLSv1.3"
ssl_prefer_server_ciphers: "off"
ssl_session_cache: "shared:ssl_session_cache:10m"
HSTS_header: 'Strict-Transport-Security "max-age=63072000; always"'

View File

@ -0,0 +1,6 @@
---
- name: reload nginx
service:
name: nginx
state: reloaded

107
roles/nginx/tasks/main.yml Normal file
View File

@ -0,0 +1,107 @@
---
- name: Create SSL dhparam
get_url:
url: https://ssl-config.mozilla.org/ffdhe2048.txt
dest: /etc/ssl/certs/dhparam.pem
mode: 0644
- name: Prepare certbot+ovh venv
pip:
chdir: /root/
virtualenv_command: /usr/bin/python3 -m venv
virtualenv: /root/certbot-venv/
name:
- "pip>=21.0.1"
- "setuptools>=53.0.0"
- "wheel>=0.36.2"
- name: Install certbot+ovh in venv
pip:
chdir: /root/
virtualenv_command: /usr/bin/python3 -m venv
virtualenv: /root/certbot-venv/
name:
- certbot
- certbot-dns-ovh
- certbot-plugin-gandi
- name: Setup OVH credentials
copy:
content: |
dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = {{ ovh_application_key }}
dns_ovh_application_secret = {{ ovh_application_secret }}
dns_ovh_consumer_key = {{ ovh_consumer_key }}
dest: /root/ovh.ini
mode: 0600
- name: Generate TLS certificates
command: /root/certbot-venv/bin/certbot certonly --cert-name {{ nginx_domain | quote }} -n --agree-tos -d {{ nginx_certificates | join(",") | quote }} -m {{ admin_email | quote }} --dns-ovh --dns-ovh-credentials /root/ovh.ini --dns-ovh-propagation-seconds 120
register: certbot
changed_when: '"no action taken." not in certbot.stdout'
- name: Setup renewal cron
cron:
name: certbot
minute: "18"
hour: "8"
job: '/root/certbot-venv/bin/certbot -q renew'
- name: Install nginx
package:
state: present
name:
- nginx
- ca-certificates
- name: Ensure certbot is not installed from Debian packages
package:
state: absent
name:
- certbot
- python-certbot-nginx
- name: Create letsencrypt snippets
template:
src: letsencrypt.conf.j2
dest: '/etc/nginx/snippets/letsencrypt-{{ nginx_domain }}.conf'
- name: User
user:
system: true
name: "{{ nginx_owner }}"
when: nginx_owner is defined
- name: .ssh directory
file:
path: "~{{ nginx_owner }}/.ssh"
state: directory
owner: "{{ nginx_owner }}"
mode: 0755
when: nginx_owner is defined
- name: Deploy key
blockinfile:
create: true
owner: "{{ nginx_owner }}"
mode: 0644
path: "~{{ nginx_owner }}/.ssh/authorized_keys"
marker: "<!-- {mark} ANSIBLE MANAGED BLOCK: Deploy key for {{ nginx_domain }} -->"
block: "{{ nginx_public_deploy_key }}"
when: nginx_owner is defined and nginx_public_deploy_key is defined
- name: Configure nginx
copy:
content: "{{ nginx_conf }}"
dest: "/etc/nginx/conf.d/{{ nginx_domain }}.conf"
notify: reload nginx
- name: WWW directory
file:
path: "{{ nginx_path }}"
state: directory
owner: "{{ nginx_owner }}"
group: "{{ nginx_owner }}"
mode: 0755
when: nginx_owner is defined and nginx_path is defined

View File

@ -0,0 +1,21 @@
# Inspired from
# https://ssl-config.mozilla.org/#server=nginx&version=1.14.2&config=intermediate&openssl=1.1.1d&guideline=5.6
ssl_ciphers "{{ ssl_ciphers }}";
ssl_protocols {{ ssl_protocols }};
ssl_prefer_server_ciphers {{ ssl_prefer_server_ciphers }};
ssl_session_cache {{ ssl_session_cache }};
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_certificate /etc/letsencrypt/live/{{ nginx_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ nginx_domain }}/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
{% if HSTS_header %}
add_header {{ HSTS_header }};
{% endif %}