15 Commits

28 changed files with 357 additions and 131 deletions

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# docker
docker_users:

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# Import my GPG key for git signature verification
root_gpgkeys:

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# Import my GPG key for git signature verification
root_gpgkeys:

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
users:
git:

View File

@@ -1,8 +1,8 @@
debian_version: 10.5.0
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# libvirt
libvirt_users: vagrant

View File

@@ -1,8 +1,8 @@
base_domain: local.krislamo.org
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
users:
jellyfin:

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# minecraft
# Agree to EULA to start service in Vagrant

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# docker
docker_users:

View File

@@ -1,21 +1,25 @@
##############
#### base ####
##############
selinux:
state: enforcing
allow_reboot: false
manage_network: false
base_allow_reboot: true
base_manage_network: false
root_gpgkeys:
- id: 42A3A92C5DA0F3E5F71A3710105B748C1362EB96
scripts:
- name: gotify
url: https://github.com/krislamo/dotfiles
version: 999d745710b9db500e82d1a0d0107ac5d623a669
path: gotify/.local/bin/gotify
dest: /usr/local/bin/gotify
trusted_keys:
- 42A3A92C5DA0F3E5F71A3710105B748C1362EB96
trusted_keys:
- id: 42A3A92C5DA0F3E5F71A3710105B748C1362EB96
repos:
- name: dotfiles
url: https://github.com/krislamo/dotfiles
version: 999d745710b9db500e82d1a0d0107ac5d623a669
scripts:
- src: gotify/.local/bin/gotify
dest: /usr/local/bin/gotify
################
#### proxy #####
@@ -23,35 +27,34 @@ scripts:
proxy:
servers:
- domain: cloud.local.krislamo.org
proxy_pass: http://127.0.0.1:8000
- domain: music.local.krislamo.org
proxy_pass: http://127.0.0.1:4533
################
#### podman ####
################
podman_label:
- path: /home/vagrant/navidrome
label: system_u:object_r:container_file_t:s0
owner: vagrant
group: vagrant
podman_compose:
vagrant:
root: /opt/oci
trusted_keys:
- id: 42A3A92C5DA0F3E5F71A3710105B748C1362EB96
compose:
- name: traefik
url: https://github.com/krislamo/traefik
version: d7197ddd5b7019c60faf5d164e555b6374972d40
- name: navidrome
url: https://github.com/krislamo/navidrome
version: 305f92cff143c0d497d21277145f605d9da830de
enabled: true
accept_newhostkey: true # Consider verifying manually instead
env:
VERSION: latest
SOCKET: /run/user/1000/podman/podman.sock
DASHBOARD: true
- name: nextcloud
url: https://github.com/krislamo/nextcloud
version: 245c91a22fa75e5dde1d423e88540529a4fa4f27
enabled: true
env:
VERSION: latest
DOMAIN: cloud.local.krislamo.org
DATA: /opt/oci/nextcloud/data/
REDIS_VERSION: latest
REDIS_PASSWORD: changeme
BASEURL: https://music.local.krislamo.org
MUSIC: /home/vagrant/navidrome
LASTFM_ENABLED: "false"
LASTFM_APIKEY: "n/a"
LASTFM_SECRET: "n/a"

View File

@@ -1,8 +1,8 @@
base_domain: local.krislamo.org
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
users:
git:

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
#mail:
# host: smtp.gmail.com

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# UniFi version
unifi_version: 6.1.71

View File

@@ -1,6 +1,6 @@
# base
allow_reboot: false
manage_network: false
base_allow_reboot: false
base_manage_network: false
# docker
docker_users:
@@ -22,7 +22,6 @@ wordpress_multisite: true
# database settings
wordpress_dbversion: latest
wordpress_dbpass: password
# multisite (enable in admin panel then uncomment)
#wordpress_rule: "Host(`{{ wordpress_domain }}`) ||
# Host(`site1.{{ wordpress_domain }}`) ||

7
playbooks/podman.yml Normal file
View File

@@ -0,0 +1,7 @@
- name: Install Podman server
hosts: "{{ PLAYBOOK_HOST | default('none') }}"
become: true
roles:
- base
- proxy
- podman

View File

@@ -1,10 +1,10 @@
allow_reboot: true
manage_firewall: true
manage_network: false
network_type: static
locale_default: en_US.UTF-8
base_allow_reboot: true
base_manage_firewall: true
base_manage_network: false
base_network_type: static
base_locale_default: en_US.UTF-8
packages:
base_packages:
- apache2-utils
- cryptsetup
- curl
@@ -20,3 +20,7 @@ packages:
- tree
- vim
- wget
base_scripts: /srv/.scripts
base_ssh_ufw_rule: limit

View File

@@ -3,11 +3,13 @@
msg: "Reboot initiated by Ansible"
connect_timeout: 5
listen: reboot_host
when: allow_reboot
when: base_allow_reboot
- name: Reconfigure locales
ansible.builtin.command: dpkg-reconfigure -f noninteractive locales
changed_when: false
listen: reconfigure_locales
when: not ansible_check_mode
- name: Restart WireGuard
ansible.builtin.service:

View File

@@ -18,10 +18,10 @@
default: allow
direction: outgoing
- name: Allow OpenSSH with rate limiting
- name: "{{ base_ssh_ufw_rule | capitalize }} OpenSSH"
community.general.ufw:
name: ssh
rule: limit
rule: "{{ base_ssh_ufw_rule | default('limit') }}"
- name: Remove Fail2ban defaults-debian.conf
ansible.builtin.file:

View File

@@ -9,12 +9,12 @@
- name: Import Firewall tasks
ansible.builtin.import_tasks: firewall.yml
tags: firewall
when: manage_firewall
when: base_manage_firewall
- name: Import Network tasks
ansible.builtin.import_tasks: network.yml
tags: network
when: manage_network
when: base_manage_network
- name: Import Mail tasks
ansible.builtin.import_tasks: mail.yml

View File

@@ -43,4 +43,4 @@
from: "{{ item }}"
state: enabled
loop: "{{ samba.firewall }}"
when: manage_firewall
when: base_manage_firewall

View File

@@ -1,16 +1,61 @@
- name: Install useful software
ansible.builtin.apt:
name: "{{ packages }}"
name: "{{ base_packages }}"
state: present
update_cache: true
- name: Get the default policy and basic SELinux utilities
ansible.builtin.apt:
name: ["selinux-basics", "selinux-policy-default", "auditd"]
state: present
when: selinux is defined and selinux is not false
- name: Configure SELinux
ansible.posix.selinux:
state: "{{ selinux.state | default('permissive') }}"
policy: "{{ selinux.policy | default('default') }}"
when: selinux is defined and selinux is not false
- name: Check for GRUB
ansible.builtin.stat:
path: /etc/default/grub
register: grub_config
when: selinux is defined and selinux is not false
- name: Check if SELinux is already activated in GRUB
ansible.builtin.command: grep -q 'security=selinux' /etc/default/grub
register: selinux_grub
changed_when: false
failed_when: false
when:
- selinux is defined
- selinux is not false
- grub_config.stat.exists
- name: Activate SELinux
ansible.builtin.command: selinux-activate
changed_when: true
when:
- selinux is defined
- selinux is not false
- grub_config.stat.exists
- selinux_grub.rc != 0
register: selinux_activated
- name: Reboot after SELinux activation
ansible.builtin.reboot:
when:
- selinux_activated is changed
- base_allow_reboot
- name: Install GPG
ansible.builtin.apt:
name: gpg
state: present
- name: Check for existing GPG keys
ansible.builtin.command: "gpg --list-keys {{ item.id }} 2>/dev/null"
ansible.builtin.command: >-
gpg --list-keys {{ item.id }} 2>/dev/null
register: gpg_check
loop: "{{ root_gpgkeys }}"
failed_when: false
@@ -19,9 +64,8 @@
- name: Import GPG keys
ansible.builtin.command: >-
gpg
--keyserver {{ item.item.server | default('keys.openpgp.org') }}
--recv-key {{ item.item.id }}
gpg --keyserver {{ item.item.server | default('keys.openpgp.org') }}
--recv-key {{ item.item.id }}
register: gpg_check_import
loop: "{{ gpg_check.results }}"
loop_control:
@@ -40,19 +84,21 @@
- not item.skipped | default(false)
- "'imported' not in item.stderr"
- name: Create /opt/scripts directories
- name: Create scripts directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "755"
mode: "700"
owner: root
group: root
loop:
- /opt/scripts
- /opt/scripts/.keys
- "{{ base_scripts }}"
- "{{ base_scripts }}/.keys"
when: scripts is defined
- name: Generate OpenSSH deploy keys for script clones
community.crypto.openssh_keypair:
path: /opt/scripts/.keys/id_ed25519
path: "{{ base_scripts }}/.keys/id_ed25519"
type: ed25519
comment: "{{ ansible_hostname }}-deploy-key"
mode: "400"
@@ -68,13 +114,20 @@
- name: Clone external scripts projects
ansible.builtin.git:
repo: "{{ item.url }}"
dest: "/opt/scripts/{{ item.name }}"
dest: "{{ base_scripts }}/{{ item.name }}"
version: "{{ item.version }}"
accept_newhostkey: "{{ item.accept_newhostkey | default(false) }}"
gpg_allowlist: "{{ item.trusted_keys | default([]) }}"
verify_commit: "{{ true if (item.trusted_keys is defined and item.trusted_keys) else false }}"
key_file: /opt/scripts/.keys/id_ed25519
loop: "{{ scripts }}"
gpg_allowlist: >-
{{ (item.trusted_keys | default(scripts.trusted_keys) | default([]))
| map(attribute='id')
| list }}
verify_commit: >-
{{ true if
((item.trusted_keys | default(scripts.trusted_keys)) is defined
and (item.trusted_keys | default(scripts.trusted_keys)))
else false }}
key_file: "{{ base_scripts }}/.keys/id_ed25519"
loop: "{{ scripts.repos }}"
loop_control:
label: "{{ item.url }}"
when: scripts is defined
@@ -82,15 +135,30 @@
- name: Synchronize scripts
ansible.posix.synchronize:
src: "/opt/scripts/{{ item.name }}/{{ item.path }}"
dest: "{{ item.dest }}"
src: "{{ base_scripts }}/{{ item.0.name }}/{{ item.1.src }}"
dest: "{{ item.1.dest }}"
delegate_to: "{{ inventory_hostname }}"
loop: "{{ scripts | default([]) }}"
loop: "{{ scripts.repos | default([]) | subelements('scripts') }}"
loop_control:
label: "{{ item.name }}"
label: "{{ item.0.name }}: {{ item.1.src }}"
when: scripts is defined and scripts | length > 0
tags: scripts
- name: Deploy cron jobs
ansible.builtin.cron:
name: "{{ item.name }}"
job: "{{ item.job }}"
user: "{{ item.user | default('root') }}"
minute: "{{ item.minute | default('*') }}"
hour: "{{ item.hour | default('*') }}"
day: "{{ item.day | default('*') }}"
month: "{{ item.month | default('*') }}"
weekday: "{{ item.weekday | default('*') }}"
state: "{{ item.state | default('present') }}"
disabled: "{{ item.disabled | default(false) }}"
loop: "{{ cron }}"
when: cron is defined and cron | length > 0
- name: Install NTPsec
ansible.builtin.apt:
name: ntpsec
@@ -103,7 +171,7 @@
- name: Generate locale
community.general.locale_gen:
name: "{{ locale_default }}"
name: "{{ base_locale_default }}"
state: present
notify: reconfigure_locales
@@ -111,7 +179,7 @@
ansible.builtin.lineinfile:
path: /etc/default/locale
regexp: "^LANG="
line: "LANG={{ locale_default }}"
line: "LANG={{ base_locale_default }}"
- name: Manage root authorized_keys
ansible.builtin.template:
@@ -119,6 +187,7 @@
dest: /root/.ssh/authorized_keys
mode: "400"
when: authorized_keys is defined
tags: users
- name: Create system user groups
ansible.builtin.group:
@@ -129,6 +198,7 @@
loop_control:
label: "{{ item.key }}"
when: users is defined
tags: users
- name: Create system users
ansible.builtin.user:
@@ -145,10 +215,12 @@
loop_control:
label: "{{ item.key }}"
when: users is defined
tags: users
- name: Create Ansible's temporary remote directory for users
ansible.builtin.file:
path: "{{ item.value.homedir | default('/home/' + item.key) }}/.ansible/tmp"
path: >-
{{ item.value.homedir | default('/home/' + item.key) }}/.ansible/tmp
state: directory
mode: "700"
owner: "{{ item.key }}"
@@ -159,6 +231,7 @@
when:
- users is defined
- item.value.tmp | default(true)
tags: users
- name: Set authorized_keys for system users
ansible.posix.authorized_key:
@@ -169,6 +242,7 @@
loop_control:
label: "{{ item.key }}"
when: users is defined and item.value.key is defined
tags: users
- name: Manage filesystem mounts
ansible.posix.mount:

View File

@@ -6,6 +6,17 @@ Address = {{ wireguard.address }}
{% if wireguard.listenport is defined %}
ListenPort = {{ wireguard.listenport }}
{% endif %}
{%- if wireguard.table is defined %}
Table = {{ wireguard.table }}
{% endif -%}
{%- if wireguard.postup is defined %}
PostUp = {{ wireguard.postup }}
{% endif -%}
{%- if wireguard.predown is defined %}
PreDown = {{ wireguard.predown }}
{% endif %}
{% for peer in wireguard.peers %}
{% if peer.name is defined %}

View File

@@ -1,40 +1,13 @@
- name: Install QEMU/KVM
- name: Install QEMU/KVM and libvirt
ansible.builtin.apt:
name: qemu-kvm
state: present
- name: Install Libvirt
ansible.builtin.apt:
name: ["libvirt-clients", "libvirt-daemon-system"]
name: ["qemu-system", "libvirt-clients", "libvirt-daemon-system"]
install_recommends: false
state: present
- name: Add users to libvirt group
ansible.builtin.user:
name: "{{ item }}"
groups: libvirt
append: yes
append: true
with_items: "{{ libvirt_users }}"
when: libvirt_users is defined
- name: Check for NODOWNLOAD file
ansible.builtin.stat:
path: /var/lib/libvirt/images/NODOWNLOAD
register: NODOWNLOAD
- name: Download GNU/Linux ISOs
ansible.builtin.get_url:
url: "{{ item.url }}"
dest: /var/lib/libvirt/images
checksum: "{{ item.hash }}"
owner: libvirt-qemu
group: libvirt-qemu
loop: "{{ libvirt_isos }}"
register: download_isos
when: libvirt_isos is defined and NODOWNLOAD.stat.exists == false
# Prevent downloaded ISOs from being rehashed every run
- name: Create NODOWNLOAD file
ansible.builtin.file:
path: /var/lib/libvirt/images/NODOWNLOAD
state: touch
when: download_isos.changed

View File

@@ -3,6 +3,7 @@
database: passwd
key: "{{ podman_user }}"
register: podman_user_info
tags: podman_compose
- name: Set user-specific variables
ansible.builtin.set_fact:
@@ -11,6 +12,7 @@
podman_homedir: "{{ podman_user_info.ansible_facts.getent_passwd[podman_user][4] }}"
podman_project: "{{ podman_compose_config.compose }}"
podman_repos: "{{ podman_compose_config.root }}/.compose_repos"
tags: podman_compose
- name: Create docker compose (podman) root directory for user
ansible.builtin.file:
@@ -51,6 +53,7 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Create .ssh directory for podman compose user
ansible.builtin.file:
@@ -62,10 +65,11 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Generate OpenSSH deploy keys for docker compose (podman) clones
community.crypto.openssh_keypair:
path: "{{ podman_ssh_key_path }}/podman-id_{{ podman_repos_keytype }}"
path: "{{ podman_homedir }}/.ssh/podman-id_{{ podman_repos_keytype }}"
type: "{{ podman_repos_keytype }}"
comment: "{{ ansible_hostname }}-{{ podman_user }}-deploy-key"
owner: "{{ podman_user }}"
@@ -73,6 +77,7 @@
mode: "0600"
state: present
when: podman_project is defined
tags: podman_compose
- name: Import trusted GPG keys for docker compose (podman) projects
ansible.builtin.command:
@@ -85,6 +90,7 @@
label: "{{ key.id }}"
changed_when: false
when: podman_compose_config.trusted_keys is defined
tags: podman_compose
- name: Clone external docker compose (podman) projects
ansible.builtin.git:
@@ -105,7 +111,7 @@
)
else false
}}
key_file: "{{ podman_ssh_key_path }}/podman-id_{{ podman_repos_keytype }}"
key_file: "{{ podman_homedir }}/.ssh/podman-id_{{ podman_repos_keytype }}"
become: true
become_user: "{{ podman_user }}"
loop: "{{ podman_project }}"
@@ -115,6 +121,7 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Create directories for docker compose (podman) projects
ansible.builtin.file:
@@ -130,6 +137,7 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Synchronize docker-compose.yml
ansible.posix.synchronize:
@@ -152,6 +160,7 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Update list of compose projects updated
ansible.builtin.set_fact:
@@ -162,6 +171,7 @@
loop_control:
label: "{{ podman_user }}/{{ item.project.name }}"
when: (podman_compose_update.results | default([]) | length) > 0
tags: podman_compose
- name: Fix ownership of synchronized compose files
ansible.builtin.file:
@@ -176,6 +186,7 @@
when:
- podman_project is defined
- podman_project | length > 0
tags: podman_compose
- name: Set environment variables for docker compose (podman) projects
ansible.builtin.template:
@@ -194,6 +205,7 @@
loop_var: project
label: "{{ project.name }}"
when: podman_project is defined and project.env is defined
tags: podman_compose
- name: Update list of compose projects who updated their .env
ansible.builtin.set_fact:
@@ -209,6 +221,7 @@
loop_control:
label: "{{ podman_user }}/{{ item.project.name }}"
when: (podman_compose_env_update.results | default([]) | length) > 0
tags: podman_compose
- name: Update list of enabled compose projects
ansible.builtin.set_fact:
@@ -217,3 +230,4 @@
+ [{'user': podman_user, 'service': project.name}] }}
when: project.enabled | default(false)
notify: podman_compose_enable
tags: podman_compose

View File

@@ -0,0 +1,20 @@
- name: "Get UID for {{ podman_user.key }}"
ansible.builtin.getent:
database: passwd
key: "{{ podman_user.key }}"
- name: Login to private Podman registry via Docker CLI
community.docker.docker_login:
registry_url: "{{ registry.key }}"
username: "{{ registry.value.username }}"
password: "{{ registry.value.password }}"
docker_host: "unix:///run/user/{{ podman_uid }}/podman/podman.sock"
vars:
podman_uid: "{{ ansible_facts.getent_passwd[podman_user.key][1] }}"
loop: "{{ podman_user.value | dict2items }}"
loop_control:
loop_var: registry
label: "{{ podman_user.key }} => {{ registry.key }}"
become: true
become_user: "{{ podman_user.key }}"
no_log: true

View File

@@ -105,6 +105,95 @@
state: present
when: podman_compose is defined
- name: Login to private Podman registries with Docker CLI for each user
ansible.builtin.include_tasks: login.yml
loop: "{{ podman_login | dict2items }}"
loop_control:
loop_var: podman_user
when: podman_login is defined
- name: Stat rootless Podman directory
ansible.builtin.stat:
path: "/home/{{ compose_user.key }}/.local/share/containers"
loop: "{{ podman_compose | dict2items }}"
loop_control:
loop_var: compose_user
label: "{{ compose_user.key }}"
register: podman_user_containers_stat
when:
- podman_compose is defined
- selinux is defined
- selinux is not false
- name: Create rootless Podman directory
ansible.builtin.file:
path: "/home/{{ item.compose_user.key }}/.local/share/containers"
state: directory
owner: "{{ item.compose_user.key }}"
group: "{{ item.compose_user.key }}"
mode: "700"
loop: "{{ podman_user_containers_stat.results }}"
loop_control:
label: "{{ item.compose_user.key }}"
when:
- podman_compose is defined
- selinux is defined
- selinux is not false
- not item.stat.exists
- name: Label rootless Podman directory
ansible.builtin.command: >-
restorecon -Rv /home/{{ item.compose_user.key }}/.local/share/containers
loop: "{{ podman_user_containers_stat.results }}"
loop_control:
label: "/home/{{ item.compose_user.key }}/.local/share/containers"
changed_when: true
when:
- podman_compose is defined
- selinux is defined
- selinux is not false
- not item.stat.exists
- name: Stat Podman label directories
ansible.builtin.stat:
path: "{{ item.path }}"
loop: "{{ podman_label }}"
register: podman_label_stat
loop_control:
label: "{{ item.path }}"
when:
- podman_label is defined
- selinux is defined
- selinux is not false
- name: Create Podman label directories
ansible.builtin.file:
path: "{{ item.item.path }}"
owner: "{{ item.item.owner | default(omit) }}"
group: "{{ item.item.group | default(omit) }}"
mode: "{{ item.item.mode | default('700') }}"
state: directory
loop: "{{ podman_label_stat.results }}"
loop_control:
label: "{{ item.item.path }}"
when:
- podman_label is defined
- selinux is defined
- selinux is not false
- not item.stat.exists
- name: Set labels on Podman label directories
ansible.builtin.command: "chcon {{ item.item.label }} {{ item.item.path }}"
loop: "{{ podman_label_stat.results }}"
changed_when: true
loop_control:
label: "{{ item.item.path }} => {{ item.item.label }}"
when:
- podman_label is defined
- selinux is defined
- selinux is not false
- not item.stat.exists
- name: Deploy Podman compose projects for each user
ansible.builtin.include_tasks: deploy.yml
vars:
@@ -114,3 +203,4 @@
loop_control:
loop_var: compose_user
when: podman_compose is defined
tags: podman_compose

View File

@@ -1 +1 @@
cached_dhparams_pem: /vagrant/scratch/dhparams.pem
proxy_cached_dhparams_pem: /vagrant/scratch/dhparams.pem

View File

@@ -10,18 +10,17 @@
state: started
enabled: true
- name: Check for cached dhparams.pem file
- name: Check if environment is vagrant
ansible.builtin.stat:
path: "{{ cached_dhparams_pem }}"
register: dhparams_file
path: /home/vagrant
register: vagrant_home
- name: Copy cached dhparams.pem to /etc/ssl/
ansible.builtin.copy:
src: "{{ cached_dhparams_pem }}"
- name: Download Mozilla's standard DH params (dev only)
ansible.builtin.get_url:
url: https://ssl-config.mozilla.org/ffdhe4096.txt
dest: /etc/ssl/dhparams.pem
mode: "600"
remote_src: true
when: dhparams_file.stat.exists
when: vagrant_home.stat.exists
- name: Generate DH Parameters
community.crypto.openssl_dhparam:
@@ -41,6 +40,8 @@
dest: "/etc/nginx/sites-available/{{ item.domain }}.conf"
mode: "400"
loop: "{{ proxy.servers }}"
loop_control:
label: "{{ item.domain }}"
notify: reload_nginx
register: nginx_sites
@@ -63,14 +64,14 @@
- name: Grab Cloudflare API token for configuration
ansible.builtin.slurp:
src: /root/.cloudflare-api
src: /etc/letsencrypt/cloudflare-api.key
register: cfapi
when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined
- name: Install Cloudflare API token
ansible.builtin.template:
src: cloudflare.ini.j2
dest: /root/.cloudflare.ini
dest: /etc/letsencrypt/cloudflare.ini
mode: "400"
diff: false
when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined
@@ -89,22 +90,46 @@
mode: "0755"
when: proxy.production is defined and proxy.production
- name: Enable SELinux bool certbot_acmesh to allow sh access for DNS-01
ansible.posix.seboolean:
name: certbot_acmesh
state: true
persistent: true
when:
- selinux is defined
- selinux is not false
- proxy is defined
- proxy.production is defined
- proxy.production
- proxy.dns_cloudflare is defined
- name: Run Cloudflare DNS-01 challenges on wildcard domains
ansible.builtin.shell: '/usr/bin/certbot certonly \
--non-interactive \
--agree-tos \
--email "{{ proxy.dns_cloudflare.email }}" \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.cloudflare.ini \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.{{ item }}" \
-d "{{ item }}" \
{{ proxy.dns_cloudflare.opts | default("") }}'
{{ proxy.dns_cloudflare.opts | default("") }}
< /dev/null'
args:
creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem"
loop: "{{ proxy.dns_cloudflare.wildcard_domains }}"
when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined
notify: reload_nginx
- name: Enable SELinux bool httpd_can_network_connect to give nginx networking
ansible.posix.seboolean:
name: httpd_can_network_connect
state: true
persistent: true
when:
- selinux is defined
- selinux is not false
- proxy is defined
- name: Add HTTP and HTTPS firewall rule
community.general.ufw:
rule: allow

View File

@@ -1,13 +1,17 @@
server {
listen 80;
{% if proxy.ipv6 is defined and proxy.ipv6 %}
listen [::]:80;
{% endif %}
server_name {{ item.domain }};
return 301 https://{{ item.domain }}$request_uri;
}
server {
listen 443 ssl http2;
{% if proxy.ipv6 is defined and proxy.ipv6 %}
listen [::]:443 ssl http2;
{% endif %}
server_name {{ item.domain }};
access_log /var/log/nginx/{{ item.domain }}.log main;
{% if proxy.production is defined and proxy.production and proxy.dns_cloudflare.wildcard_domains is defined and item.tls.cert is not defined %}