Renamed webserver roles to more speakable names

This commit is contained in:
2025-08-20 08:54:17 +02:00
parent 9cfb8f3a60
commit a4f39ac732
101 changed files with 147 additions and 147 deletions

View File

@@ -0,0 +1,24 @@
# Lets Encrypt SSL for Nginx 🔐
## Description
Automates obtaining, configuring, and renewing Lets Encrypt SSL certificates for Nginx with Certbot. Keeps your sites secure with minimal fuss! 🌐
## Overview
This Ansible role sets up the necessary Nginx configuration and Certbot integration to:
- Redirect HTTP traffic to HTTPS
- Serve the ACME challenge for certificate issuance
- Apply strong SSL/TLS defaults
- Schedule automatic renewals
Its idempotent: configuration and certificate tasks only run when needed. ✅
## Purpose
Ensure all your Nginx-hosted sites use free, trusted SSL certificates from Lets Encrypt—all managed automatically via Ansible. 🎯
## Features
- **Automatic Certificate Issuance**: Uses Certbots webroot plugin to request and install certificates. 📜
- **Nginx Redirect**: Creates a temporary HTTP → HTTPS redirect block. ↪️
- **ACMEChallenge Handling**: Configures `/.well-known/acme-challenge/` for Certbot validation. 🔍
- **Secure SSL Defaults**: Includes modern cipher suites, HSTS, OCSP stapling, and session settings. 🔒
- **AutoRenewal**: Leverages system scheduling (cron or systemd timer) to renew certs before expiration. 🔄
- **OneTime Setup**: Tasks guarded by a “run once” fact to avoid re-applying unchanged templates. 🏃‍♂️

View File

@@ -0,0 +1,2 @@
# Todos
- Implement issuewild and iodef -> Not possible yet due to API issues

View File

@@ -0,0 +1,23 @@
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "An Ansible role to automate Lets Encrypt SSL certificate issuance and renewal for Nginx"
license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
min_ansible_version: "2.9"
platforms:
- name: Archlinux
versions:
- rolling
galaxy_tags:
- letsencrypt
- nginx
- ssl
- certificate
- security
repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://docs.infinito.nexus"

View File

@@ -0,0 +1,14 @@
- name: Include dependency 'sys-ctl-mtn-cert-renew'
include_role:
name: sys-ctl-mtn-cert-renew
when: run_once_sys_ctl_mtn_cert_renew is not defined
- name: create nginx letsencrypt config file
template:
src: "letsencrypt.conf.j2"
dest: "{{NGINX.DIRECTORIES.HTTP.GLOBAL}}letsencrypt.conf"
notify: restart openresty
- name: "Set CAA records for all base domains"
include_tasks: 01_set-caa-records.yml
when: DNS_PROVIDER == 'cloudflare'

View File

@@ -0,0 +1,24 @@
---
- name: "Validate CLOUDFLARE_API_TOKEN"
fail:
msg: >
The variable "CLOUDFLARE_API_TOKEN" must be defined and cannot be empty!
when: (CLOUDFLARE_API_TOKEN|default('')|trim) == ''
- name: "Ensure all CAA records are present"
community.general.cloudflare_dns:
api_token: "{{ CLOUDFLARE_API_TOKEN }}"
zone: "{{ item.0 }}"
record: "@"
type: CAA
flag: 0
tag: "{{ item.1.tag }}"
value: "{{ item.1.value }}"
ttl: 1
state: present
loop: "{{ base_sld_domains | product(caa_entries) | list }}"
loop_control:
label: "{{ item.0 }} → {{ item.1.tag }}"
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"

View File

@@ -0,0 +1,4 @@
- block:
- include_tasks: 01_core.yml
- include_tasks: utils/run_once.yml
when: run_once_srv_letsencrypt is not defined

View File

@@ -0,0 +1,16 @@
server
{
listen 80;
listen [::]:80;
location /
{
return 301 https://$host$request_uri;
}
#letsencrypt
location ^~ /.well-known/acme-challenge/ {
allow all;
root {{ LETSENCRYPT_WEBROOT_PATH }};
default_type "text/plain";
try_files $uri =404;
}
}

View File

@@ -0,0 +1,3 @@
ssl_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem;
ssl_certificate_key {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem;
ssl_trusted_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/chain.pem;

View File

@@ -0,0 +1,15 @@
listen {{ WEB_PORT }} ssl http2;
listen [::]:{{ WEB_PORT }} ssl http2;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:P-256;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
{% include 'roles/srv-letsencrypt/templates/ssl_credentials.j2' %}

View File

@@ -0,0 +1,4 @@
caa_entries:
- tag: issue
value: letsencrypt.org
base_sld_domains: '{{ current_play_domains_all | generate_base_sld_domains }}'