diff --git a/roles/TODO.md b/roles/TODO.md index 998dc933..0fb47ec1 100644 --- a/roles/TODO.md +++ b/roles/TODO.md @@ -38,4 +38,7 @@ All roles follow a consistent naming convention using a *primary prefix* and a * | heal- | Roles responsible for auto-repair or healing of system states (service recovery, resource fixes) | | system- | Roles for system configuration, hardening, and operating system tuning (security, storage optimization, timers) | | update- | Roles managing software update processes (package updates, Docker updates, repository management) | -| user- | Roles managing system users, accounts, and user-specific configuration (home directories, permissions) | \ No newline at end of file +| user- | Roles managing system users, accounts, and user-specific configuration (home directories, permissions) | + +# Implement the following roles +- Implement docker role for [radicle](https://radicle.xyz/) \ No newline at end of file diff --git a/roles/docker-mailu/tasks/generate-and-read-dkim.yml b/roles/docker-mailu/tasks/generate-and-read-dkim.yml index f1a8c7a6..8f6d4b19 100644 --- a/roles/docker-mailu/tasks/generate-and-read-dkim.yml +++ b/roles/docker-mailu/tasks/generate-and-read-dkim.yml @@ -1,13 +1,49 @@ +- name: Check if DKIM private key file exists in the antispam container + command: > + docker compose exec -T antispam + test -f {{mailu_dkim_key_path}} + register: dkim_key_file_stat + failed_when: false + changed_when: false + args: + chdir: "{{ docker_compose.directories.instance }}" + - name: Generate DKIM key command: > docker compose exec -T antispam - rspamadm dkim_keygen -s dkim -d {{ applications[application_id].domain }} -k {{ applications[application_id].domain }}.dkim.key + rspamadm dkim_keygen -s dkim -d {{ applications[application_id].domain }} -k {{ mailu_dkim_key_path }} register: dkim_keygen_output - chdir: "{{ docker_compose.directories.instance }}" + when: dkim_key_file_stat.rc != 0 + args: + chdir: "{{ docker_compose.directories.instance }}" -- name: Extract DKIM record from parentheses +- name: Fetch DKIM private key from antispam container + shell: > + docker compose exec -T antispam + cat {{ mailu_dkim_key_path }} + args: + chdir: "{{ docker_compose.directories.instance }}" + register: dkim_priv_content + failed_when: dkim_priv_content.rc != 0 + changed_when: false + +- name: Generate DKIM public key on the host + command: openssl rsa -pubout + args: + stdin: "{{ dkim_priv_content.stdout }}" + register: dkim_pub_raw + changed_when: false + +- name: Normalize and build Mailu DKIM TXT record set_fact: mailu_dkim_public_key: >- - {{ dkim_keygen_output.stdout - | regex_search('(?s)\((.*?)\)', '\\1') - | default('') }} \ No newline at end of file + v=DKIM1; k=rsa; p={{ + dkim_pub_raw.stdout + | regex_replace('-----BEGIN PUBLIC KEY-----', '') + | regex_replace('-----END PUBLIC KEY-----', '') + | regex_replace('\s+', '') + }} + +- name: Debug Mailu DKIM public key + debug: + msg: "Mailu DKIM public key: {{ mailu_dkim_public_key }}" \ No newline at end of file diff --git a/roles/docker-mailu/tasks/main.yml b/roles/docker-mailu/tasks/main.yml index 41ea93dd..614370bf 100644 --- a/roles/docker-mailu/tasks/main.yml +++ b/roles/docker-mailu/tasks/main.yml @@ -41,22 +41,7 @@ loop_control: loop_var: item when: run_once_docker_mailu is not defined - -- name: "Load Mailu DNS variables" - include_vars: vars/mailu-dns.yml - when: dns_provider == 'cloudflare' - -- name: Generate DKIM public key - include_tasks: generate-and-read-dkim.yml - when: - - not applications[application_id].credentials.dkim_public_key is defined - -- name: Set DKIM public key - set_fact: - mailu_dkim_public_key: >- - {{ applications[application_id].credentials.dkim_public_key }} - when: applications[application_id].credentials.dkim_public_key is defined - + - name: Set Mailu DNS records include_tasks: set-mailu-dns-records.yml when: dns_provider == 'cloudflare' diff --git a/roles/docker-mailu/tasks/set-mailu-dns-records.yml b/roles/docker-mailu/tasks/set-mailu-dns-records.yml index b44e07ce..bdf3e5fe 100644 --- a/roles/docker-mailu/tasks/set-mailu-dns-records.yml +++ b/roles/docker-mailu/tasks/set-mailu-dns-records.yml @@ -1,3 +1,9 @@ +- name: "Load Mailu DNS variables" + include_vars: vars/mailu-dns.yml + +- name: Generate DKIM public key + include_tasks: generate-and-read-dkim.yml + - name: "Set A record for mail server" community.general.cloudflare_dns: api_token: "{{ cloudflare_record_api_token }}" @@ -6,7 +12,7 @@ name: "{{ domain }}" content: "{{ mailu_dns_ip }}" proxied: false - ttl: 3600 + ttl: 1 state: present - name: "Set CNAME record for autoconfig" @@ -17,7 +23,7 @@ name: "autoconfig.{{ mailu_dns_zone }}" value: "{{ domain }}" proxied: false - ttl: 3600 + ttl: 1 state: present - name: "Set MX record" @@ -28,7 +34,7 @@ name: "{{ mailu_dns_zone }}" value: "{{ domain }}" priority: 10 - ttl: 3600 + ttl: 1 state: present - name: "Set SRV records" @@ -36,18 +42,19 @@ api_token: "{{ cloudflare_record_api_token }}" zone: "{{ mailu_dns_zone }}" type: SRV - name: "_{{ item.key }}._tcp" - data: - service: "_{{ item.key }}" - proto: "_tcp" - name: "{{ mailu_dns_zone }}" - priority: "{{ item.value.priority }}" - weight: "{{ item.value.weight }}" - port: "{{ item.value.port }}" - target: "{{ domain }}" - ttl: 3600 + service: "_{{ item.key }}" + proto: "_tcp" + priority: "{{ item.value.priority }}" + weight: "{{ item.value.weight }}" + port: "{{ item.value.port }}" + value: "{{ domain }}" + ttl: 1 state: present loop: "{{ mailu_dns_srv_records | dict2items }}" + ignore_errors: true + #register: srv_result + #failed_when: srv_result.rc != 0 and ("An identical record already exists" not in srv_result.stdout) + #changed_when: srv_result.rc == 0 and ("An identical record already exists" not in srv_result.stdout) - name: "Set SPF TXT record" community.general.cloudflare_dns: @@ -56,7 +63,7 @@ type: TXT name: "{{ mailu_dns_zone }}" value: "v=spf1 mx a:{{ domain }} ~all" - ttl: 3600 + ttl: 1 state: present - name: "Set DMARC TXT record" @@ -66,7 +73,7 @@ type: TXT name: "_dmarc.{{ mailu_dns_zone }}" value: "v=DMARC1; p=reject; ruf=mailto:{{ mailu_dmarc_ruf }}; adkim=s; aspf=s" - ttl: 3600 + ttl: 1 state: present - name: "Set DKIM TXT record" @@ -76,5 +83,5 @@ type: TXT name: "dkim._domainkey.{{ mailu_dns_zone }}" value: "{{ mailu_dkim_public_key }}" - ttl: 3600 + ttl: 1 state: present \ No newline at end of file diff --git a/roles/docker-mailu/vars/mailu-dns.yml b/roles/docker-mailu/vars/mailu-dns.yml index faadec6b..91cf4a80 100644 --- a/roles/docker-mailu/vars/mailu-dns.yml +++ b/roles/docker-mailu/vars/mailu-dns.yml @@ -5,7 +5,10 @@ mailu_dns_ip: "{{ networks.internet.ip4 }}" cloudflare_record_api_token: "{{ certbot_dns_api_token }}" -mailu_dmarc_ruf: "{{ applications[application_id].users.administrator.email }}" +mailu_dmarc_ruf: "{{ applications[application_id].users.administrator.email }}" + +mailu_dkim_key_file: "{{ applications[application_id].domain }}.dkim.key" +mailu_dkim_key_path: "/dkim/{{ mailu_dkim_key_file }}" mailu_dns_srv_records: submission: diff --git a/roles/letsencrypt/TODO.md b/roles/letsencrypt/TODO.md new file mode 100644 index 00000000..05318d46 --- /dev/null +++ b/roles/letsencrypt/TODO.md @@ -0,0 +1,2 @@ +# Todos +- Implement issuewild and iodef -> Not possible yet due to API issues \ No newline at end of file diff --git a/roles/letsencrypt/tasks/set-caa-records.yml b/roles/letsencrypt/tasks/set-caa-records.yml index 0c0271af..015cd4d0 100644 --- a/roles/letsencrypt/tasks/set-caa-records.yml +++ b/roles/letsencrypt/tasks/set-caa-records.yml @@ -1,17 +1,4 @@ --- -# tasks/main.yml -# Creates and sets CAA records (issue, issuewild, iodef) for all base domains - -- name: "Define CAA entries" - set_fact: - caa_entries: - - tag: issue - value: "letsencrypt.org" - - tag: issuewild - value: "letsencrypt.org" - - tag: iodef - value: "mailto:{{ users.administrator.email }}" - - name: "Ensure all CAA records are present" community.general.cloudflare_dns: api_token: "{{ certbot_dns_api_token }}" diff --git a/roles/letsencrypt/vars/main.yml b/roles/letsencrypt/vars/main.yml new file mode 100644 index 00000000..52212be1 --- /dev/null +++ b/roles/letsencrypt/vars/main.yml @@ -0,0 +1,7 @@ +caa_entries: + - tag: issue + value: "letsencrypt.org" +# - tag: issuewild +# value: "letsencrypt.org" +# - tag: iodef +# value: "mailto:{{ users.administrator.email }}" \ No newline at end of file diff --git a/templates/vars/applications.yml.j2 b/templates/vars/applications.yml.j2 index 8586ecb2..693e75fc 100644 --- a/templates/vars/applications.yml.j2 +++ b/templates/vars/applications.yml.j2 @@ -320,7 +320,7 @@ defaults_applications: mailu: version: "2024.06" # Docker Image Version users: - adminsitrator: + administrator: email: "{{users.administrator.email}}" # Administrator Email for DNS Records oidc: email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used