diff --git a/inventories/chaosknoten/host_vars/sunders.sops.yaml b/inventories/chaosknoten/host_vars/sunders.sops.yaml index 75b2d10..904a8fb 100644 --- a/inventories/chaosknoten/host_vars/sunders.sops.yaml +++ b/inventories/chaosknoten/host_vars/sunders.sops.yaml @@ -2,7 +2,6 @@ ansible_pull__age_private_key: ENC[AES256_GCM,data:tP84jDYh2zeWjf7wqDoefm9zaeg/Q secret__sunders_db_root_password: ENC[AES256_GCM,data:m3Xt6dOKibRflon/rWG9KmdBPHEBbqE/GIpKdFI1Di7Lpl/THxzrgx12mTK6aZnwDrM=,iv:hD/UGwo88ye9CxyTCEQ0SVon2+ipPjeA9NF2/OhYwmc=,tag:DRdQ5hvTgUO5FVae/ul7kQ==,type:str] secret__sunders_db_camera_password: ENC[AES256_GCM,data:tOt4ImpedgfGvRpcThPO30YyEl/bP244ruJQzAYodJIsEhFuk5LxHpPASEnsqlN6m3M=,iv:rQXBjiYWZlzeUdaqDdTlrdbSSqGaPDeZOPhUaMjgcjU=,tag:lkSlIdJWFowyPfWEjpC/Zg==,type:str] secret__sunders_db_camera_select_password: ENC[AES256_GCM,data:PveGcD2WmvpMc8bafGY1c45aQ2XH/ym2yj5YacauQPeZO6Xem3kaxU0kwjs0Wd26ugc=,iv:tk288L9i0lxsJbTFq5ET5IiKkJfMQwc6uKNFXILcD7o=,tag:hOIivp3mOtDNBCsKvrSrBw==,type:str] -secret__acme_dns_api_key_sunders_hamburg_ccc_de: ENC[AES256_GCM,data:OXGasHc1qf4r8wj0N2qqjZzWO3zg5L5ZGRjAwmlEXi9/gaTpUWT1xw==,iv:pKaNajQ9JxxUwuv/scJZhP6UdSob3GrODShk2t75580=,tag:3atM6IddvYhoAmNlqooooQ==,type:str] sops: age: - recipient: age1na0nh9ndnr9cxpnlvstrxskr4fxf4spnkw48ufl7m43f98y40y7shhnvgd @@ -14,8 +13,8 @@ sops: KzBPS0Y3OXBUSjFWRVQwaGQ0M2M4ajgKYGgcfiDsBsJQmSodfPejhAcAekatqkJ9 Xa6Y7mWUiAKcbYY9to7/7/u5FUW3JYdv1GX7vAC2ZtZv6WXGLtjdwg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-31T14:49:48Z" - mac: ENC[AES256_GCM,data:Ln//LDvcSqRknJGQvdzwoRvZOK/ZBqfTJqnxm9fhQsfZudUchZ5u7PXQf/0y3GnrYVx9agGGoKQN3VFehrZfpUE4ygjvmLHiqJSZVREaD4Yq0PuaY54/wN4YX8H1nE7ILdm1QvFRzpMUpSnTM1Yrr6cMIFMHcRRpL73LfG1nwPY=,iv:NXT/cPTnbg7ESiI7Aj3OOpCLMM4j355NAMVJNsIppzY=,tag:iLFTfiFdDxpwvC88fLf3Mw==,type:str] + lastmodified: "2025-11-01T16:32:10Z" + mac: ENC[AES256_GCM,data:8Q6DBSFtzwHuVxduRlZYxlRWO0trSoesNGUR8r/dWnp9ashFBSZqVyffXb4Vq6DB5thANJ6/b3PCNsHdiAKn6Ai2UT8G0HimFjUUgNpZxo4xoNGmDhDvfdBgUL6O2pHhY+ojjguUXDYeYc99+eaxfKqZ3w+PAPaySltKm99foz8=,iv:ILOErdiWbUjk9kovXXZYcAqZFQp2Wo1Tm14sgK3niWg=,tag:Q2gT6wbQyhDXjoQEG2Lngw==,type:str] pgp: - created_at: "2026-03-05T19:17:55Z" enc: |- @@ -217,4 +216,4 @@ sops: -----END PGP MESSAGE----- fp: 41FFAF3D519CF5C039FBD8414BCC213729AF0E49 unencrypted_suffix: _unencrypted - version: 3.12.1 + version: 3.11.0 diff --git a/inventories/chaosknoten/host_vars/sunders.yaml b/inventories/chaosknoten/host_vars/sunders.yaml index 1fd5c40..4563a46 100644 --- a/inventories/chaosknoten/host_vars/sunders.yaml +++ b/inventories/chaosknoten/host_vars/sunders.yaml @@ -1,13 +1,8 @@ docker_compose__compose_file_content: "{{ lookup('ansible.builtin.template', 'resources/chaosknoten/sunders/docker_compose/compose.yaml.j2') }}" certbot__acme_account_email_address: le-admin@hamburg.ccc.de -certbot__certs: - - commonName: "sunders.hamburg.ccc.de" - challengeType: "dns-01-acme-dns" - dns_01_acme_dns: - subdomain: a5ee8a99-3cdf-4212-972e-c0b6fda1242f - apiUser: 45e4ea1c-8322-4d92-9f52-adf52b521131 - apiKey: "{{ secret__acme_dns_api_key_sunders_hamburg_ccc_de }}" +certbot__certificate_domains: + - "sunders.hamburg.ccc.de" certbot__new_cert_commands: - "systemctl reload nginx.service" diff --git a/resources/chaosknoten/public-reverse-proxy/nginx/acme_challenge.conf b/resources/chaosknoten/public-reverse-proxy/nginx/acme_challenge.conf index 7bb4993..d79f299 100644 --- a/resources/chaosknoten/public-reverse-proxy/nginx/acme_challenge.conf +++ b/resources/chaosknoten/public-reverse-proxy/nginx/acme_challenge.conf @@ -29,6 +29,7 @@ map $host $upstream_acme_challenge_host { wiki.hamburg.ccc.de wiki.hosts.hamburg.ccc.de:31820; www.hamburg.ccc.de 172.31.17.151:31820; tickets.hamburg.ccc.de tickets.hosts.hamburg.ccc.de:31820; + sunders.hamburg.ccc.de sunders.hosts.hamburg.ccc.de:31820; zammad.hamburg.ccc.de zammad.hosts.hamburg.ccc.de:31820; eh03.easterhegg.eu 172.31.17.151:31820; eh05.easterhegg.eu 172.31.17.151:31820; diff --git a/roles/certbot/README.md b/roles/certbot/README.md index d9b7e73..3ad35bf 100644 --- a/roles/certbot/README.md +++ b/roles/certbot/README.md @@ -6,24 +6,6 @@ Note: This role doesn't take care of deleting certificates. Also see the following documentation for a full How-to on how to get certificates using this role in the context of our infra: . -## Challenge Types - -For the `certbot__certs` configuration, depending on the challenge type, different preparation needs to be done. - -### `dns-01-acme-dns` - -For the `dns-01-acme-dns` challenge type, ensure that: - -1. An acme-dns entry got registered, so you have access to the `subdomain`, `apiUser` and `apiKey` for the configuration. The `apiKey` should be stored in some kind of secret, which then gets referenced in the relevant `certbot__certs` configuration. - For our acme-dns instance, go to , sign-in and register a new entry. -2. CNAME the `_acme-challenge` domain of the domain you want to obtain a certificate for (`certbot__certs.*.commonName`) to the full domain from the registration. - It should look something like this: `_acme-challenge.domainiwantcertfor.tld. CNAME 3ed25037-79f1-4a89-8934-db3e162fe2bc.auth.acmedns.hamburg.ccc.de.` - -For more info see: - -- [The ACME DNS hamburg.ccc.de Wiki page](https://wiki.hamburg.ccc.de/infrastructure:services:acme_dns) -- [The acme-dns GitHub](https://github.com/acme-dns/acme-dns) - ## Required Arguments - `certbot__acme_account_email_address`: The E-Mail address to use for the ACME account. @@ -33,18 +15,6 @@ For more info see: - `certbot__certificate_domains`: The domains for which to obtain a certificate using the HTTP-01 challenge. - `certbot__http_01_port`: The port number the bot listens on. Should be `80` if directly exposed to the internet. Defaults to `31820` (for the public-reverse-proxy setup). -- `certbot__certs`: Certificates to create. - Defaults to the empty list (`[ ]`). -- `certbot__certs.*.commonName`: The common name to issue the certificate for. -- `certbot__certs.*.challengeType`: The challenge type to use for getting the certificate. Challenge type-specific configuration must be provided as well. - Should be one of: - - `dns-01-acme-dns` -- `certbot__certs.*.dns_01_acme_dns`: Configuration for the `dns-01-acme-dns` challenge type. -- `certbot__certs.*.dns_01_acme_dns.serverUrl`: The acme-dns server API URL. - Defaults to `https://acmedns.hamburg.ccc.de`. -- `certbot__certs.*.dns_01_acme_dns.subdomain`: The acme-dns subdomain to use. -- `certbot__certs.*.dns_01_acme_dns.apiUser`: The acme-dns API user to use. -- `certbot__certs.*.dns_01_acme_dns.apiKey`: The acme-dns API key to use. - `certbot__new_cert_commands`: A list of commands to execute after getting a new certificate. Will be added into a bash script. Defaults to the empty list (`[ ]`). diff --git a/roles/certbot/defaults/main.yaml b/roles/certbot/defaults/main.yaml index ab48293..9e6551e 100644 --- a/roles/certbot/defaults/main.yaml +++ b/roles/certbot/defaults/main.yaml @@ -1,4 +1,3 @@ certbot__certificate_domains: [ ] certbot__http_01_port: 31820 -certbot__certs: [ ] certbot__new_cert_commands: [ ] diff --git a/roles/certbot/files/manual_auth_scripts/dns-01-acme-dns.sh b/roles/certbot/files/manual_auth_scripts/dns-01-acme-dns.sh deleted file mode 100644 index 1b39bd6..0000000 --- a/roles/certbot/files/manual_auth_scripts/dns-01-acme-dns.sh +++ /dev/null @@ -1,14 +0,0 @@ -# #!/usr/bin/env bash - -CERT_CONFIG_FILE="/etc/ansible_certbot/cert_configs/$CERTBOT_DOMAIN.json" -ACME_DNS_SERVER_URL=$( jq -er '.dns_01_acme_dns.serverUrl' "$CERT_CONFIG_FILE" ) -export ACME_DNS_SUBDOMAIN=$( jq -er '.dns_01_acme_dns.subdomain' "$CERT_CONFIG_FILE" ) -ACME_DNS_API_USER=$( jq -er '.dns_01_acme_dns.apiUser' "$CERT_CONFIG_FILE" ) -ACME_DNS_API_KEY=$( jq -er '.dns_01_acme_dns.apiKey' "$CERT_CONFIG_FILE" ) - -jq -nec '{ "subdomain": env.ACME_DNS_SUBDOMAIN, "txt": env.CERTBOT_VALIDATION }' | curl "$ACME_DNS_SERVER_URL/update" \ - --request POST \ - --fail-with-body \ - --header "X-Api-User: $ACME_DNS_API_USER" \ - --header "X-Api-Key: $ACME_DNS_API_KEY" \ - --json @- diff --git a/roles/certbot/meta/argument_specs.yaml b/roles/certbot/meta/argument_specs.yaml index 4899ea8..b895b5f 100644 --- a/roles/certbot/meta/argument_specs.yaml +++ b/roles/certbot/meta/argument_specs.yaml @@ -13,25 +13,6 @@ argument_specs: type: str required: false default: 31820 - certbot__certs: - type: list - elements: dict - required: false - default: [ ] - options: - commonName: - type: str - required: true - # ToDo: subjectAlternativeNames: - challengeType: - type: str - required: true - choices: - - dns-01-acme-dns - dns_01_acme_dns: - type: dict - required: false - # Further checking done in tasks/validate_cert.yaml certbot__new_cert_commands: type: list elements: str diff --git a/roles/certbot/tasks/main/cert.yaml b/roles/certbot/tasks/main/cert.yaml index 61f6d45..d829fb1 100644 --- a/roles/certbot/tasks/main/cert.yaml +++ b/roles/certbot/tasks/main/cert.yaml @@ -1,46 +1,24 @@ - name: get expiry date before - ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item.commonName }}/fullchain.pem + ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item }}/fullchain.pem ignore_errors: true become: true changed_when: false register: certbot__cert_expiry_before -- name: ensure directory for cert configs exists - ansible.builtin.file: - path: "/etc/ansible_certbot/cert_configs/" - state: directory - owner: root - group: root - mode: "0750" - become: true - -- name: ensure cert config is stored - ansible.builtin.copy: - content: "{{ cert_config_defaults[item.challengeType] | combine(item, recursive=True) | ansible.builtin.to_nice_json }}" - dest: "/etc/ansible_certbot/cert_configs/{{ item.commonName }}.json" - owner: root - group: root - mode: "0640" - become: true - vars: - cert_config_defaults: - dns-01-acme-dns: - dns_01_acme_dns: - serverUrl: "https://acmedns.hamburg.ccc.de" - -# # https://eff-certbot.readthedocs.io/en/stable/using.html#manual -- name: obtain the certificate using certbot and the manual auth hook - ansible.builtin.command: /usr/bin/certbot certonly --keep-until-expiring --agree-tos --non-interactive --email "{{ certbot__acme_account_email_address }}" --no-eff-email --manual --preferred-challenge dns --manual-auth-hook "/usr/local/lib/ansible_certbot/manual_auth_scripts/{{ item.challengeType }}.sh" -d "{{ item.commonName }}" +- name: obtain the certificate using certbot + ansible.builtin.command: /usr/bin/certbot certonly --keep-until-expiring --agree-tos --non-interactive --email "{{ certbot__acme_account_email_address }}" --no-eff-email --standalone --http-01-port "{{ certbot__http_01_port }}" -d "{{ item }}" become: true changed_when: false - name: get expiry date after - ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item.commonName }}/fullchain.pem + ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item }}/fullchain.pem become: true changed_when: false register: certbot__cert_expiry_after -- name: potentially report changed - ansible.builtin.debug: - msg: "If this reports changed, then the certificate expiry date and therefore the certificate changed." - changed_when: certbot__cert_expiry_before.stdout != certbot__cert_expiry_after.stdout +# Doesn't work anymore. Dunno why. +# TODO: Fix +# - name: potentially report changed +# ansible.builtin.debug: +# msg: "If this reports changed, then the certificate expiry date and therefore the certificate changed." +# changed_when: certbot__cert_expiry_before.stdout != certbot__cert_expiry_after.stdout diff --git a/roles/certbot/tasks/main/certs.yaml b/roles/certbot/tasks/main/certs.yaml index 16271b7..2b91184 100644 --- a/roles/certbot/tasks/main/certs.yaml +++ b/roles/certbot/tasks/main/certs.yaml @@ -1,14 +1,4 @@ -- name: obtain http-01 challenge certificates +- name: obtain certificates loop: "{{ certbot__certificate_domains }}" - ansible.builtin.include_tasks: - file: main/http_01_cert.yaml - -- name: validate certs config - loop: "{{ certbot__certs }}" - ansible.builtin.include_tasks: - file: main/validate_cert.yaml - -- name: obtain certs - loop: "{{ certbot__certs }}" ansible.builtin.include_tasks: file: main/cert.yaml diff --git a/roles/certbot/tasks/main/http_01_cert.yaml b/roles/certbot/tasks/main/http_01_cert.yaml deleted file mode 100644 index d829fb1..0000000 --- a/roles/certbot/tasks/main/http_01_cert.yaml +++ /dev/null @@ -1,24 +0,0 @@ -- name: get expiry date before - ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item }}/fullchain.pem - ignore_errors: true - become: true - changed_when: false - register: certbot__cert_expiry_before - -- name: obtain the certificate using certbot - ansible.builtin.command: /usr/bin/certbot certonly --keep-until-expiring --agree-tos --non-interactive --email "{{ certbot__acme_account_email_address }}" --no-eff-email --standalone --http-01-port "{{ certbot__http_01_port }}" -d "{{ item }}" - become: true - changed_when: false - -- name: get expiry date after - ansible.builtin.command: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/{{ item }}/fullchain.pem - become: true - changed_when: false - register: certbot__cert_expiry_after - -# Doesn't work anymore. Dunno why. -# TODO: Fix -# - name: potentially report changed -# ansible.builtin.debug: -# msg: "If this reports changed, then the certificate expiry date and therefore the certificate changed." -# changed_when: certbot__cert_expiry_before.stdout != certbot__cert_expiry_after.stdout diff --git a/roles/certbot/tasks/main/install.yaml b/roles/certbot/tasks/main/install.yaml index d0fa58d..40ccf75 100644 --- a/roles/certbot/tasks/main/install.yaml +++ b/roles/certbot/tasks/main/install.yaml @@ -1,30 +1,11 @@ -- name: ensure relevant packages are installed +- name: make sure the `openssl` package is installed ansible.builtin.apt: - name: - - openssl - - certbot - - jq + name: openssl state: present become: true -- name: ensure manual auth scripts are deployed - block: - - name: ensure manual auth scripts directory exists - ansible.builtin.file: - path: "/usr/local/lib/ansible_certbot/manual_auth_scripts" - state: directory - owner: root - group: root - mode: "0755" - become: true - - - name: ensure manual auth scripts are deployed - ansible.builtin.copy: - src: "manual_auth_scripts/{{ item }}.sh" - dest: "/usr/local/lib/ansible_certbot/manual_auth_scripts/{{ item }}.sh" - owner: root - group: root - mode: "0754" - become: true - loop: - - "dns-01-acme-dns" +- name: make sure the `certbot` package is installed + ansible.builtin.apt: + name: certbot + state: present + become: true diff --git a/roles/certbot/tasks/main/validate_cert.yaml b/roles/certbot/tasks/main/validate_cert.yaml deleted file mode 100644 index a13b3b9..0000000 --- a/roles/certbot/tasks/main/validate_cert.yaml +++ /dev/null @@ -1,31 +0,0 @@ -- name: validate dns-01-acme-dns challenge type config - when: item.challengeType == "dns-01-acme-dns" - block: - - name: assert dns_01_acme_dns config exists - ansible.builtin.assert: - that: item.dns_01_acme_dns is defined - - - name: assert dns_01_acme_dns config is valid - ansible.builtin.validate_argument_spec: - argument_spec: "{{ required_data }}" - provided_arguments: - dns_01_acme_dns: "{{ item.dns_01_acme_dns }}" - vars: - required_data: - dns_01_acme_dns: - type: dict - required: true - options: - serverUrl: - type: str - required: false - default: https://acmedns.hamburg.ccc.de - subdomain: - type: str - required: true - apiUser: - type: str - required: true - apiKey: - type: str - required: true