From 9a4aece4423a72155316e76a0ff6de8c7bc162fa Mon Sep 17 00:00:00 2001 From: Kris Lamoureux Date: Mon, 23 May 2022 03:32:56 -0400 Subject: [PATCH] Use DNS-01 on Cloudflare for wildcard LE certs --- dev/host_vars/proxy.yml | 31 +++++++++---- roles/proxy/files/restart-nginx.sh | 2 + roles/proxy/tasks/main.yml | 54 +++++++++++++++++++--- roles/proxy/templates/cloudflare.ini.j2 | 2 + roles/proxy/templates/server-nginx.conf.j2 | 8 +++- 5 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 roles/proxy/files/restart-nginx.sh create mode 100644 roles/proxy/templates/cloudflare.ini.j2 diff --git a/dev/host_vars/proxy.yml b/dev/host_vars/proxy.yml index a65dfb7..6ce8de2 100644 --- a/dev/host_vars/proxy.yml +++ b/dev/host_vars/proxy.yml @@ -1,17 +1,28 @@ +base_domain: vm.krislamo.org + # base allow_reboot: false manage_network: false # proxy proxy: - - name: bitwarden - domain: "{{ bitwarden_domain }}" - proxy_pass: "http://127.0.0.1:8080" - production: false - - name: gitea - domain: "{{ gitea_domain }}" - proxy_pass: "http://127.0.0.1:3080" - production: false + #production: true + dns_cloudflare: + #email: realemail@example.com + #api_token: CLOUDFLARE_DNS01_API_TOKEN + wildcard_domains: + - "{{ base_domain }}" + servers: + - domain: "{{ bitwarden_domain }}" + proxy_pass: "http://127.0.0.1:8080" + tls: + cert: /etc/letsencrypt/live/{{ base_domain }}/fullchain.pem + key: /etc/letsencrypt/live/{{ base_domain }}/privkey.pem + - domain: "{{ gitea_domain }}" + proxy_pass: "http://127.0.0.1:3080" + tls: + cert: /etc/letsencrypt/live/{{ base_domain }}/fullchain.pem + key: /etc/letsencrypt/live/{{ base_domain }}/privkey.pem # docker docker_users: @@ -19,14 +30,14 @@ docker_users: # bitwarden # Get Installation ID & Key at https://bitwarden.com/host/ -bitwarden_domain: vault.vm.krislamo.org +bitwarden_domain: "vault.{{ base_domain }}" bitwarden_dbpass: password bitwarden_install_id: 4ea840a3-532e-4cb6-a472-abd900728b23 bitwarden_install_key: 1yB3Z2gRI0KnnH90C6p #bitwarden_prodution: true # gitea -gitea_domain: git.vm.krislamo.org +gitea_domain: "git.{{ base_domain }}" gitea_version: 1 gitea_dbversion: latest gitea_dbpass: password diff --git a/roles/proxy/files/restart-nginx.sh b/roles/proxy/files/restart-nginx.sh new file mode 100644 index 0000000..f17457e --- /dev/null +++ b/roles/proxy/files/restart-nginx.sh @@ -0,0 +1,2 @@ +#!/bin/bash +systemctl reload nginx diff --git a/roles/proxy/tasks/main.yml b/roles/proxy/tasks/main.yml index 8d3c6c1..3e8d55c 100644 --- a/roles/proxy/tasks/main.yml +++ b/roles/proxy/tasks/main.yml @@ -4,6 +4,12 @@ state: present update_cache: true +- name: Start nginx and enable on boot + service: + name: nginx + state: started + enabled: true + - name: Install nginx base configuration template: src: nginx.conf.j2 @@ -14,9 +20,9 @@ - name: Install nginx sites configuration template: src: server-nginx.conf.j2 - dest: "/etc/nginx/conf.d/{{ item.name }}.conf" + dest: "/etc/nginx/conf.d/{{ item.domain }}.conf" mode: '0644' - loop: "{{ proxy }}" + loop: "{{ proxy.servers }}" notify: reload_nginx - name: Generate self-signed certificate @@ -26,10 +32,44 @@ -out /etc/ssl/certs/nginx-selfsigned.crt' args: creates: /etc/ssl/certs/nginx-selfsigned.crt + when: not proxy.production notify: reload_nginx -- name: Start nginx and enable on boot - service: - name: nginx - state: started - enabled: true +- name: Install LE's certbot + apt: + name: ['certbot', 'python3-certbot-dns-cloudflare'] + state: present + when: proxy.production + +- name: Install Cloudflare API token + template: + src: cloudflare.ini.j2 + dest: /root/.cloudflare.ini + mode: '0600' + when: proxy.production and proxy.dns_cloudflare is defined + +- name: Create nginx post renewal hook directory + file: + path: /etc/letsencrypt/renewal-hooks/post + state: directory + +- name: Install nginx post renewal hook + copy: + src: restart-nginx.sh + dest: /etc/letsencrypt/renewal-hooks/post/nginx.sh + mode: '0755' + when: proxy.production + +- name: Run Cloudflare DNS-01 challenges on wildcard domains + shell: '/usr/bin/certbot certonly \ + --non-interactive \ + --agree-tos \ + --email "{{ proxy.dns_cloudflare.email }}" \ + --dns-cloudflare \ + --dns-cloudflare-credentials /root/.cloudflare.ini \ + -d "*.{{ item }}"' + args: + creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem" + loop: "{{ proxy.dns_cloudflare.wildcard_domains }}" + when: proxy.production and proxy.dns_cloudflare is defined + notify: reload_nginx diff --git a/roles/proxy/templates/cloudflare.ini.j2 b/roles/proxy/templates/cloudflare.ini.j2 new file mode 100644 index 0000000..eb66f68 --- /dev/null +++ b/roles/proxy/templates/cloudflare.ini.j2 @@ -0,0 +1,2 @@ +# Cloudflare API token used by Certbot +dns_cloudflare_api_token = {{ proxy.dns_cloudflare.api_token }} diff --git a/roles/proxy/templates/server-nginx.conf.j2 b/roles/proxy/templates/server-nginx.conf.j2 index 1545a4a..84f73a2 100644 --- a/roles/proxy/templates/server-nginx.conf.j2 +++ b/roles/proxy/templates/server-nginx.conf.j2 @@ -2,7 +2,13 @@ server { listen 443 ssl; server_name {{ item.domain }}; access_log /var/log/nginx/{{ item.domain }}.log main; -{% if not item.production %} +{% if proxy.production and item.tls.cert is not defined %} + ssl_certificate /etc/letsencrypt/live/{{ item.domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ item.domain }}/privkey.pem; +{% elif proxy.production and item.tls.cert is defined %} + ssl_certificate {{ item.tls.cert }}; + ssl_certificate_key {{ item.tls.key }}; +{% else %} ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; {% endif %}