Compare commits
2 Commits
29b94a10f8
...
debian13
| Author | SHA1 | Date | |
|---|---|---|---|
|
9790415da1
|
|||
|
85473f0fe9
|
@@ -20,6 +20,10 @@ Once you've satisfied the the above assumptions, you can execute:
|
|||||||
|
|
||||||
$ ansible-playbook web.yml
|
$ ansible-playbook web.yml
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- Switch from tarsnap to restic
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Copyright (C) 2014–2021 Alan Orth
|
Copyright (C) 2014–2021 Alan Orth
|
||||||
|
|
||||||
|
|||||||
@@ -16,26 +16,19 @@ nginx_ssl_dhparam: /etc/ssl/certs/dhparam.pem
|
|||||||
nginx_ssl_protocols: TLSv1.2 TLSv1.3
|
nginx_ssl_protocols: TLSv1.2 TLSv1.3
|
||||||
nginx_ssl_ecdh_curve: X25519:prime256v1:secp384r1
|
nginx_ssl_ecdh_curve: X25519:prime256v1:secp384r1
|
||||||
|
|
||||||
# DNS resolvers for OCSP stapling (default to Cloudflare public DNS)
|
# DNS resolvers (default to Cloudflare public DNS)
|
||||||
# See: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
|
nginx_resolver: 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]
|
||||||
nginx_ssl_stapling_resolver: 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]
|
|
||||||
|
|
||||||
# HTTP Strict-Transport-Security header, recommended by Google to be ~1 year
|
# HTTP Strict-Transport-Security header, recommended by Google to be ~1 year
|
||||||
# in seconds, see: https://hstspreload.org/
|
# in seconds, see: https://hstspreload.org/
|
||||||
nginx_hsts_max_age: 31536000
|
nginx_hsts_max_age: 31536000
|
||||||
|
|
||||||
# install acme.sh?
|
# Use Let's Encrypt via nginx's acme module?
|
||||||
# true unless you're in development and using "localhost" + snakeoil certs
|
# true unless you're in development and using "localhost" + snakeoil certs
|
||||||
use_letsencrypt: true
|
use_letsencrypt: true
|
||||||
|
|
||||||
# Directory root for Let's Encrypt certs
|
# Email address to use for the ACME account managing the site's certificates.
|
||||||
letsencrypt_root: /etc/ssl
|
letsencrypt_contact: foo@example.com
|
||||||
|
|
||||||
# Location where to save initial acme.sh script. After installation the script
|
|
||||||
# will automatically create its home in the /root/.acme.sh directory (including
|
|
||||||
# a copy of the script itself). The initial script is not needed after.
|
|
||||||
letsencrypt_acme_script_temp: /root/acme.sh
|
|
||||||
letsencrypt_acme_home: /root/.acme.sh
|
|
||||||
|
|
||||||
# stable is 1.26.x
|
# stable is 1.26.x
|
||||||
# mainline is 1.27.x
|
# mainline is 1.27.x
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Renew Let's Encrypt certificates
|
|
||||||
|
|
||||||
[Timer]
|
|
||||||
# twice a day, at midnight and noon
|
|
||||||
OnCalendar=*-*-* 00,12:00:00
|
|
||||||
# Add a random delay of 0–3600 seconds
|
|
||||||
RandomizedDelaySec=3600
|
|
||||||
Persistent=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=timers.target
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
---
|
---
|
||||||
# Use acme.sh instead of certbot because they only support installation via
|
# Remove any standalone Let's Encrypt clients because we use nginx's acme module.
|
||||||
# snap now.
|
- name: Remove standalone Let's Encrypt clients
|
||||||
- name: Install and configure Let's Encrypt
|
|
||||||
tags: letsencrypt
|
tags: letsencrypt
|
||||||
when:
|
when:
|
||||||
- ansible_facts["distribution"] == 'Debian'
|
- ansible_facts["distribution"] == 'Debian'
|
||||||
@@ -20,72 +19,17 @@
|
|||||||
- /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh
|
- /etc/letsencrypt/renewal-hooks/pre/stop-nginx.sh
|
||||||
- /etc/letsencrypt/renewal-hooks/post/start-nginx.sh
|
- /etc/letsencrypt/renewal-hooks/post/start-nginx.sh
|
||||||
|
|
||||||
- name: Check if acme.sh is installed
|
- name: Remove unused Let's Encrypt well-known directory
|
||||||
ansible.builtin.stat:
|
|
||||||
path: "{{ letsencrypt_acme_home }}"
|
|
||||||
register: acme_home
|
|
||||||
|
|
||||||
- name: Download acme.sh
|
|
||||||
when: not acme_home.stat.exists
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh
|
|
||||||
dest: "{{ letsencrypt_acme_script_temp }}"
|
|
||||||
mode: "0700"
|
|
||||||
register: acme_download
|
|
||||||
|
|
||||||
# Run the "install" for acme.sh so it creates the .acme.sh dir (currently I
|
|
||||||
# have to chdir to the /root directory where the script exists or else it
|
|
||||||
# fails. Ansible runs it, but the script can't find itself...).
|
|
||||||
- name: Install acme.sh
|
|
||||||
when: acme_download is changed
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: "{{ letsencrypt_acme_script_temp }} --install --no-profile --no-cron"
|
|
||||||
creates: "{{ letsencrypt_acme_home }}/acme.sh"
|
|
||||||
chdir: /root
|
|
||||||
register: acme_install
|
|
||||||
|
|
||||||
- name: Remove temporary acme.sh script
|
|
||||||
when:
|
|
||||||
- acme_install.rc is defined
|
|
||||||
- acme_install.rc == 0
|
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
dest: "{{ letsencrypt_acme_script_temp }}"
|
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Set default certificate authority for acme.sh
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: "{{ letsencrypt_acme_home }}/acme.sh --set-default-ca --server letsencrypt"
|
|
||||||
|
|
||||||
- name: Prepare Let's Encrypt well-known directory
|
|
||||||
ansible.builtin.file:
|
|
||||||
state: directory
|
|
||||||
path: /var/lib/letsencrypt/.well-known
|
path: /var/lib/letsencrypt/.well-known
|
||||||
owner: root
|
|
||||||
group: nginx
|
|
||||||
mode: g+s
|
|
||||||
|
|
||||||
- name: Copy systemd service to renew Let's Encrypt certs
|
- name: Remove unused Let's Encrypt systemd units
|
||||||
ansible.builtin.template:
|
ansible.builtin.file:
|
||||||
src: renew-letsencrypt.service.j2
|
state: absent
|
||||||
dest: /etc/systemd/system/renew-letsencrypt.service
|
path: "{{ item }}"
|
||||||
mode: "0644"
|
loop:
|
||||||
owner: root
|
- /etc/systemd/system/renew-letsencrypt.service
|
||||||
group: root
|
- /etc/systemd/system/renew-letsencrypt.timer
|
||||||
|
|
||||||
- name: Copy systemd timer to renew Let's Encrypt certs
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: renew-letsencrypt.timer
|
|
||||||
dest: /etc/systemd/system/renew-letsencrypt.timer
|
|
||||||
mode: "0644"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
# always issues daemon-reload just in case the service/timer changed
|
|
||||||
- name: Start and enable systemd timer to renew Let's Encrypt certs
|
|
||||||
ansible.builtin.systemd_service:
|
|
||||||
name: renew-letsencrypt.timer
|
|
||||||
state: started
|
|
||||||
enabled: true
|
|
||||||
daemon_reload: true
|
|
||||||
|
|
||||||
# vim: set ts=2 sw=2:
|
# vim: set ts=2 sw=2:
|
||||||
|
|||||||
@@ -31,25 +31,28 @@
|
|||||||
|
|
||||||
- name: Install nginx
|
- name: Install nginx
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
pkg: nginx
|
pkg: [nginx, nginx-module-acme]
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
state: present
|
state: present
|
||||||
tags:
|
tags:
|
||||||
- nginx
|
- nginx
|
||||||
- packages
|
- packages
|
||||||
|
|
||||||
- name: Copy nginx.conf
|
- name: Copy nginx configs (templates)
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: nginx.conf.j2
|
src: "{{ item.src }}"
|
||||||
dest: /etc/nginx/nginx.conf
|
dest: "{{ item.dest }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
loop:
|
||||||
|
- { src: nginx.conf.j2, dest: /etc/nginx/nginx.conf }
|
||||||
|
- { src: 01-acme.conf.j2, dest: /etc/nginx/conf.d/01-acme.conf }
|
||||||
notify:
|
notify:
|
||||||
- Reload nginx
|
- Reload nginx
|
||||||
tags: nginx
|
tags: nginx
|
||||||
|
|
||||||
- name: Copy extra nginx configs
|
- name: Copy nginx configs (files)
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: "{{ item }}"
|
src: "{{ item }}"
|
||||||
dest: /etc/nginx/{{ item }}
|
dest: /etc/nginx/{{ item }}
|
||||||
|
|||||||
14
roles/nginx/templates/01-acme.conf.j2
Normal file
14
roles/nginx/templates/01-acme.conf.j2
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{{ ansible_managed | comment }}
|
||||||
|
|
||||||
|
# Setting the resolver is important because nginx uses it for upstream servers
|
||||||
|
# and ACME requests. nginx attempts to resolve these at startup and will fail
|
||||||
|
# if it cannot.
|
||||||
|
resolver {{ nginx_resolver }};
|
||||||
|
|
||||||
|
acme_issuer letsencrypt {
|
||||||
|
uri https://acme-v02.api.letsencrypt.org/directory;
|
||||||
|
contact {{ letsencrypt_contact }};
|
||||||
|
challenge tls-alpn;
|
||||||
|
state_path /var/cache/nginx/acme-letsencrypt;
|
||||||
|
accept_terms_of_service;
|
||||||
|
}
|
||||||
@@ -14,10 +14,13 @@
|
|||||||
{# otherwise, assume host is using letsencrypt #}
|
{# otherwise, assume host is using letsencrypt #}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
# concatenated key + cert
|
acme_certificate letsencrypt;
|
||||||
# See: http://nginx.org/en/docs/http/configuring_https_servers.html
|
|
||||||
ssl_certificate {{ letsencrypt_root }}/certs/{{ domain_name }}.fullchain.pem;
|
ssl_certificate $acme_certificate;
|
||||||
ssl_certificate_key {{ letsencrypt_root }}/private/{{ domain_name }}.key.pem;
|
ssl_certificate_key $acme_certificate_key;
|
||||||
|
|
||||||
|
# do not parse the certificate on each request
|
||||||
|
ssl_certificate_cache max=2;
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@@ -31,14 +34,6 @@
|
|||||||
ssl_ciphers "{{ tls_cipher_suite }}";
|
ssl_ciphers "{{ tls_cipher_suite }}";
|
||||||
ssl_prefer_server_ciphers off;
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
{# OSCP stapling only works with real certs #}
|
|
||||||
{% if use_letsencrypt == true or item.tls_certificate_path %}
|
|
||||||
# OCSP stapling...
|
|
||||||
ssl_stapling on;
|
|
||||||
ssl_stapling_verify on;
|
|
||||||
resolver {{ nginx_ssl_stapling_resolver }};
|
|
||||||
{% endif %} {# end: use_letsencrypt #}
|
|
||||||
|
|
||||||
{% if enable_hsts == true %}
|
{% if enable_hsts == true %}
|
||||||
# Enable this if you want HSTS (recommended, but be careful)
|
# Enable this if you want HSTS (recommended, but be careful)
|
||||||
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
|
# Include all subdomains and indicate to Google that we want this pre-loaded in Chrome's HSTS store
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ error_log /var/log/nginx/error.log warn;
|
|||||||
# The file storing the process ID of the main process
|
# The file storing the process ID of the main process
|
||||||
pid /var/run/nginx.pid;
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
load_module modules/ngx_http_acme_module.so;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
# If you need more connections than this, you start optimizing your OS.
|
# If you need more connections than this, you start optimizing your OS.
|
||||||
# That's probably the point at which you hire people who are smarter than you as this is *a lot* of requests.
|
# That's probably the point at which you hire people who are smarter than you as this is *a lot* of requests.
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Renew Let's Encrypt certificates
|
|
||||||
ConditionFileIsExecutable={{ letsencrypt_acme_home }}/acme.sh
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart={{ letsencrypt_acme_home }}/acme.sh --cron --home {{ letsencrypt_acme_home }} --reloadcmd "/bin/systemctl reload nginx" -w /var/lib/letsencrypt
|
|
||||||
|
|
||||||
SuccessExitStatus=0 2
|
|
||||||
@@ -21,8 +21,6 @@ server {
|
|||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name {{ domain_name }} {{ domain_aliases }};
|
server_name {{ domain_name }} {{ domain_aliases }};
|
||||||
|
|
||||||
{% include 'well-known.j2' %}
|
|
||||||
|
|
||||||
# redirect http -> https
|
# redirect http -> https
|
||||||
location / {
|
location / {
|
||||||
# ? in rewrite makes sure nginx doesn't append query string again
|
# ? in rewrite makes sure nginx doesn't append query string again
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
location ^~ /.well-known/acme-challenge/ {
|
|
||||||
allow all;
|
|
||||||
root /var/lib/letsencrypt/;
|
|
||||||
default_type "text/plain";
|
|
||||||
try_files $uri =404;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user