From c054d22c4818d916ac6dd9c8d7a7a2c614408e17 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Sun, 20 Aug 2023 23:02:06 +0200 Subject: append .j2 extension to templates I saw a good point somewhere that it should help with syntax highlighting. --- roles/firewall/tasks/main.yml | 4 +- roles/firewall/templates/rules.v4 | 50 --------------------- roles/firewall/templates/rules.v4.j2 | 50 +++++++++++++++++++++ roles/firewall/templates/rules.v6 | 60 -------------------------- roles/firewall/templates/rules.v6.j2 | 60 ++++++++++++++++++++++++++ roles/letsencrypt/tasks/digitalocean.yml | 2 +- roles/letsencrypt/tasks/domain.yml | 2 +- roles/letsencrypt/templates/certbot.ini | 3 -- roles/letsencrypt/templates/certbot.ini.j2 | 3 ++ roles/letsencrypt/templates/domain_list.txt | 5 --- roles/letsencrypt/templates/domain_list.txt.j2 | 5 +++ roles/sshd/tasks/main.yml | 2 +- roles/sshd/templates/sshd_config | 31 ------------- roles/sshd/templates/sshd_config.j2 | 31 +++++++++++++ roles/wireguard/tasks/main.yml | 2 +- roles/wireguard/templates/wg0.conf | 35 --------------- roles/wireguard/templates/wg0.conf.j2 | 35 +++++++++++++++ 17 files changed, 190 insertions(+), 190 deletions(-) delete mode 100644 roles/firewall/templates/rules.v4 create mode 100644 roles/firewall/templates/rules.v4.j2 delete mode 100644 roles/firewall/templates/rules.v6 create mode 100644 roles/firewall/templates/rules.v6.j2 delete mode 100644 roles/letsencrypt/templates/certbot.ini create mode 100644 roles/letsencrypt/templates/certbot.ini.j2 delete mode 100644 roles/letsencrypt/templates/domain_list.txt create mode 100644 roles/letsencrypt/templates/domain_list.txt.j2 delete mode 100644 roles/sshd/templates/sshd_config create mode 100644 roles/sshd/templates/sshd_config.j2 delete mode 100644 roles/wireguard/templates/wg0.conf create mode 100644 roles/wireguard/templates/wg0.conf.j2 diff --git a/roles/firewall/tasks/main.yml b/roles/firewall/tasks/main.yml index 95d02d3..82584e2 100644 --- a/roles/firewall/tasks/main.yml +++ b/roles/firewall/tasks/main.yml @@ -8,8 +8,8 @@ - name: Configure rule files ansible.builtin.include_tasks: file.yml loop: - - {src: rules.v4, dest: /etc/iptables/rules.v4, tool: iptables} - - {src: rules.v6, dest: /etc/iptables/rules.v6, tool: ip6tables} + - {src: rules.v4.j2, dest: /etc/iptables/rules.v4, tool: iptables} + - {src: rules.v6.j2, dest: /etc/iptables/rules.v6, tool: ip6tables} - name: Reboot if necessary ansible.builtin.meta: flush_handlers diff --git a/roles/firewall/templates/rules.v4 b/roles/firewall/templates/rules.v4 deleted file mode 100644 index 1bfeb94..0000000 --- a/roles/firewall/templates/rules.v4 +++ /dev/null @@ -1,50 +0,0 @@ -{{ ansible_managed | comment }} - -*filter - -# By default, drop incoming packets: -:INPUT DROP [0:0] -:FORWARD DROP [0:0] -# By default, accept outgoing packets: -:OUTPUT ACCEPT [0:0] - -# Accept packets for localhost: --A INPUT -i lo -j ACCEPT - -# Accept any packet for an open connection: --A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - -# The SSH port is always open: -{% set ssh_port = hostvars[inventory_hostname].ansible_port %} - -# Open TCP ports: -{% set tcp_ports = [ssh_port] + firewall_ports_tcp + firewall_ports4_tcp %} -{% set tcp_ports = tcp_ports | unique %} - -{% for port in tcp_ports %} -{% set num = port.port if port.port is defined else port %} -{% set src = '-s ' + port.source if port.source is defined else '' %} --A INPUT -p tcp {{ src }} --dport {{ num }} -m conntrack --ctstate NEW -j ACCEPT -{% endfor %} - -# Open UDP ports: -{% set udp_ports = firewall_ports_udp + firewall_ports4_udp %} -{% set udp_ports = udp_ports | unique %} - -{% for port in udp_ports %} -{% set num = port.port if port.port is defined else port %} -{% set src = '-s ' + port.source if port.source is defined else '' %} --A INPUT -p udp {{ src }} --dport {{ num }} -j ACCEPT -{% endfor %} - -# Any additional IPv4 rules: -{{ firewall_rules4 | join('\n') }} - -# ICMP; allow only pings and rate-limit them: --A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT - -# Log denies (this must be at the bottom of the file): --A INPUT -m limit --limit 3/min -j LOG --log-prefix "iptables denied: " --log-level 4 - -COMMIT diff --git a/roles/firewall/templates/rules.v4.j2 b/roles/firewall/templates/rules.v4.j2 new file mode 100644 index 0000000..1bfeb94 --- /dev/null +++ b/roles/firewall/templates/rules.v4.j2 @@ -0,0 +1,50 @@ +{{ ansible_managed | comment }} + +*filter + +# By default, drop incoming packets: +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +# By default, accept outgoing packets: +:OUTPUT ACCEPT [0:0] + +# Accept packets for localhost: +-A INPUT -i lo -j ACCEPT + +# Accept any packet for an open connection: +-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + +# The SSH port is always open: +{% set ssh_port = hostvars[inventory_hostname].ansible_port %} + +# Open TCP ports: +{% set tcp_ports = [ssh_port] + firewall_ports_tcp + firewall_ports4_tcp %} +{% set tcp_ports = tcp_ports | unique %} + +{% for port in tcp_ports %} +{% set num = port.port if port.port is defined else port %} +{% set src = '-s ' + port.source if port.source is defined else '' %} +-A INPUT -p tcp {{ src }} --dport {{ num }} -m conntrack --ctstate NEW -j ACCEPT +{% endfor %} + +# Open UDP ports: +{% set udp_ports = firewall_ports_udp + firewall_ports4_udp %} +{% set udp_ports = udp_ports | unique %} + +{% for port in udp_ports %} +{% set num = port.port if port.port is defined else port %} +{% set src = '-s ' + port.source if port.source is defined else '' %} +-A INPUT -p udp {{ src }} --dport {{ num }} -j ACCEPT +{% endfor %} + +# Any additional IPv4 rules: +{{ firewall_rules4 | join('\n') }} + +# ICMP; allow only pings and rate-limit them: +-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT + +# Log denies (this must be at the bottom of the file): +-A INPUT -m limit --limit 3/min -j LOG --log-prefix "iptables denied: " --log-level 4 + +COMMIT diff --git a/roles/firewall/templates/rules.v6 b/roles/firewall/templates/rules.v6 deleted file mode 100644 index 2e94e25..0000000 --- a/roles/firewall/templates/rules.v6 +++ /dev/null @@ -1,60 +0,0 @@ -{{ ansible_managed | comment }} - -*filter - -# By default, drop incoming packets: -:INPUT DROP [0:0] -:FORWARD DROP [0:0] -# By default, accept outgoing packets: -:OUTPUT ACCEPT [0:0] - -# Accept packets for localhost: --A INPUT -i lo -j ACCEPT - -# Accept any packet for an open connection: --A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - -# The SSH port is always open: -{% set ssh_port = hostvars[inventory_hostname].ansible_port %} - -# Open TCP ports: -{% set tcp_ports = [ssh_port] + firewall_ports_tcp + firewall_ports6_tcp %} -{% set tcp_ports = tcp_ports | unique %} - -{% for port in tcp_ports %} -{% set num = port.port if port.port is defined else port %} -{% set src = '-s ' + port.source if port.source is defined else '' %} --A INPUT -p tcp {{ src }} --dport {{ num }} -m conntrack --ctstate NEW -j ACCEPT -{% endfor %} - -# Open UDP ports: -{% set udp_ports = firewall_ports_udp + firewall_ports6_udp %} -{% set udp_ports = udp_ports | unique %} - -{% for port in udp_ports %} -{% set num = port.port if port.port is defined else port %} -{% set src = '-s ' + port.source if port.source is defined else '' %} --A INPUT -p udp {{ src }} --dport {{ num }} -j ACCEPT -{% endfor %} - -# Any additional IPv6 rules: -{{ firewall_rules6 | join('\n') }} - -# ICMP; allow only pings and rate-limit them: --A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT - -# ICMP; IPv6 stuff. To be honest, I don't really understand it; this was copied -# from trailofbits/algo's rules.v6 template at -# -# https://github.com/trailofbits/algo/blob/master/roles/common/templates/rules.v6.j2 -# --A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT --A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT --A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT --A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT - -# Log denies (this must be at the bottom of the file): --A INPUT -m limit --limit 3/min -j LOG --log-prefix "iptables denied: " --log-level 4 - -COMMIT diff --git a/roles/firewall/templates/rules.v6.j2 b/roles/firewall/templates/rules.v6.j2 new file mode 100644 index 0000000..2e94e25 --- /dev/null +++ b/roles/firewall/templates/rules.v6.j2 @@ -0,0 +1,60 @@ +{{ ansible_managed | comment }} + +*filter + +# By default, drop incoming packets: +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +# By default, accept outgoing packets: +:OUTPUT ACCEPT [0:0] + +# Accept packets for localhost: +-A INPUT -i lo -j ACCEPT + +# Accept any packet for an open connection: +-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + +# The SSH port is always open: +{% set ssh_port = hostvars[inventory_hostname].ansible_port %} + +# Open TCP ports: +{% set tcp_ports = [ssh_port] + firewall_ports_tcp + firewall_ports6_tcp %} +{% set tcp_ports = tcp_ports | unique %} + +{% for port in tcp_ports %} +{% set num = port.port if port.port is defined else port %} +{% set src = '-s ' + port.source if port.source is defined else '' %} +-A INPUT -p tcp {{ src }} --dport {{ num }} -m conntrack --ctstate NEW -j ACCEPT +{% endfor %} + +# Open UDP ports: +{% set udp_ports = firewall_ports_udp + firewall_ports6_udp %} +{% set udp_ports = udp_ports | unique %} + +{% for port in udp_ports %} +{% set num = port.port if port.port is defined else port %} +{% set src = '-s ' + port.source if port.source is defined else '' %} +-A INPUT -p udp {{ src }} --dport {{ num }} -j ACCEPT +{% endfor %} + +# Any additional IPv6 rules: +{{ firewall_rules6 | join('\n') }} + +# ICMP; allow only pings and rate-limit them: +-A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT + +# ICMP; IPv6 stuff. To be honest, I don't really understand it; this was copied +# from trailofbits/algo's rules.v6 template at +# +# https://github.com/trailofbits/algo/blob/master/roles/common/templates/rules.v6.j2 +# +-A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT +-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT +-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT +-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT + +# Log denies (this must be at the bottom of the file): +-A INPUT -m limit --limit 3/min -j LOG --log-prefix "iptables denied: " --log-level 4 + +COMMIT diff --git a/roles/letsencrypt/tasks/digitalocean.yml b/roles/letsencrypt/tasks/digitalocean.yml index 6cb1198..42f4ec0 100644 --- a/roles/letsencrypt/tasks/digitalocean.yml +++ b/roles/letsencrypt/tasks/digitalocean.yml @@ -21,7 +21,7 @@ - name: Configure certbot.ini ansible.builtin.template: - src: certbot.ini + src: certbot.ini.j2 dest: '{{ certbot_ini }}' owner: root group: root diff --git a/roles/letsencrypt/tasks/domain.yml b/roles/letsencrypt/tasks/domain.yml index d3cb50a..636230a 100644 --- a/roles/letsencrypt/tasks/domain.yml +++ b/roles/letsencrypt/tasks/domain.yml @@ -6,7 +6,7 @@ block: - name: Cache domain list ansible.builtin.template: - src: domain_list.txt + src: domain_list.txt.j2 dest: '/etc/letsencrypt/.domains_{{ certificate_name }}.txt' owner: root group: root diff --git a/roles/letsencrypt/templates/certbot.ini b/roles/letsencrypt/templates/certbot.ini deleted file mode 100644 index 71095d6..0000000 --- a/roles/letsencrypt/templates/certbot.ini +++ /dev/null @@ -1,3 +0,0 @@ -{{ ansible_managed | comment }} - -dns_digitalocean_token = {{ digitalocean_token }} diff --git a/roles/letsencrypt/templates/certbot.ini.j2 b/roles/letsencrypt/templates/certbot.ini.j2 new file mode 100644 index 0000000..71095d6 --- /dev/null +++ b/roles/letsencrypt/templates/certbot.ini.j2 @@ -0,0 +1,3 @@ +{{ ansible_managed | comment }} + +dns_digitalocean_token = {{ digitalocean_token }} diff --git a/roles/letsencrypt/templates/domain_list.txt b/roles/letsencrypt/templates/domain_list.txt deleted file mode 100644 index d45c7f0..0000000 --- a/roles/letsencrypt/templates/domain_list.txt +++ /dev/null @@ -1,5 +0,0 @@ -{{ ansible_managed | comment }} - -{% for domain in certificate_domains %} -{{ domain }} -{% endfor %} diff --git a/roles/letsencrypt/templates/domain_list.txt.j2 b/roles/letsencrypt/templates/domain_list.txt.j2 new file mode 100644 index 0000000..d45c7f0 --- /dev/null +++ b/roles/letsencrypt/templates/domain_list.txt.j2 @@ -0,0 +1,5 @@ +{{ ansible_managed | comment }} + +{% for domain in certificate_domains %} +{{ domain }} +{% endfor %} diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml index d31ac79..ed60e75 100644 --- a/roles/sshd/tasks/main.yml +++ b/roles/sshd/tasks/main.yml @@ -1,7 +1,7 @@ - name: Configure sshd become: true ansible.builtin.template: - src: sshd_config + src: sshd_config.j2 dest: /etc/ssh/sshd_config owner: root group: root diff --git a/roles/sshd/templates/sshd_config b/roles/sshd/templates/sshd_config deleted file mode 100644 index abcf0d7..0000000 --- a/roles/sshd/templates/sshd_config +++ /dev/null @@ -1,31 +0,0 @@ -{{ ansible_managed | comment }} - -# Parameters that have sane defaults on Debian 11 are omitted. - -{% set ssh_port = hostvars[inventory_hostname].ansible_port %} -{% set ssh_user = hostvars[inventory_hostname].ansible_user %} - -{% set groups = [ssh_user] + ssh_allowed_groups %} -{% set groups = groups | sort | unique %} - -Port {{ ssh_port }} - -# Whitelist users: -PermitRootLogin no -AllowGroups {{ groups | join(' ') }} - -# Only public key authentication: -PasswordAuthentication no -ChallengeResponseAuthentication no -AuthenticationMethods publickey - -# Whitelist accepted environment variables: -AcceptEnv LANG LC_* - -# Drop idle sessions: -ClientAliveCountMax 3 -ClientAliveInterval 15 - -# Miscellaneous: -PrintMotd no -Subsystem sftp /usr/lib/openssh/sftp-server diff --git a/roles/sshd/templates/sshd_config.j2 b/roles/sshd/templates/sshd_config.j2 new file mode 100644 index 0000000..abcf0d7 --- /dev/null +++ b/roles/sshd/templates/sshd_config.j2 @@ -0,0 +1,31 @@ +{{ ansible_managed | comment }} + +# Parameters that have sane defaults on Debian 11 are omitted. + +{% set ssh_port = hostvars[inventory_hostname].ansible_port %} +{% set ssh_user = hostvars[inventory_hostname].ansible_user %} + +{% set groups = [ssh_user] + ssh_allowed_groups %} +{% set groups = groups | sort | unique %} + +Port {{ ssh_port }} + +# Whitelist users: +PermitRootLogin no +AllowGroups {{ groups | join(' ') }} + +# Only public key authentication: +PasswordAuthentication no +ChallengeResponseAuthentication no +AuthenticationMethods publickey + +# Whitelist accepted environment variables: +AcceptEnv LANG LC_* + +# Drop idle sessions: +ClientAliveCountMax 3 +ClientAliveInterval 15 + +# Miscellaneous: +PrintMotd no +Subsystem sftp /usr/lib/openssh/sftp-server diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml index b91ad8a..64b0f76 100644 --- a/roles/wireguard/tasks/main.yml +++ b/roles/wireguard/tasks/main.yml @@ -9,7 +9,7 @@ - name: Write wg-quick config file ansible.builtin.template: - src: wg0.conf + src: wg0.conf.j2 dest: '/etc/wireguard/{{ wg_name }}.conf' owner: root group: root diff --git a/roles/wireguard/templates/wg0.conf b/roles/wireguard/templates/wg0.conf deleted file mode 100644 index fca9a0b..0000000 --- a/roles/wireguard/templates/wg0.conf +++ /dev/null @@ -1,35 +0,0 @@ -{{ ansible_managed | comment }} - -[Interface] -PrivateKey = {{ wg_private_key }} -Address = {{ wg_addr4 }}, {{ wg_addr6 }} -ListenPort = {{ wg_listen_port }} -SaveConfig = false - -{% if wg_firewall %} -PostUp = iptables -t nat -A POSTROUTING -s {{ wg_addr4 }} -m policy --pol none --dir out -j MASQUERADE -PostUp = iptables -A FORWARD -s {{ wg_addr4 }} -j ACCEPT -PostUp = ip6tables -t nat -A POSTROUTING -s {{ wg_addr6 }} -m policy --pol none --dir out -j MASQUERADE -PostUp = ip6tables -A FORWARD -s {{ wg_addr6 }} -j ACCEPT -PostDown = iptables -t nat -D POSTROUTING -s {{ wg_addr4 }} -m policy --pol none --dir out -j MASQUERADE -PostDown = iptables -D FORWARD -s {{ wg_addr4 }} -j ACCEPT -PostDown = ip6tables -t nat -A POSTROUTING -s {{ wg_addr6 }} -m policy --pol none --dir out -j MASQUERADE -PostDown = ip6tables -D FORWARD -s {{ wg_addr6 }} -j ACCEPT -{% endif %} -{% if wg_peers is defined %} -{% for peer in wg_peers %} - -[Peer] -PublicKey = {{ peer.public_key }} -{% if peer.preshared_key is defined %} -PresharedKey = {{ peer.preshared_key }} -{% endif %} -AllowedIPs = {{ peer.allowed_ips }} -{% if peer.endpoint is defined %} -Endpoint = {{ peer.endpoint }} -{% endif %} -{% if peer.persistent_keepalive is defined and peer.persistent_keepalive %} -PersistentKeepalive = 25 -{% endif %} -{% endfor %} -{% endif %} diff --git a/roles/wireguard/templates/wg0.conf.j2 b/roles/wireguard/templates/wg0.conf.j2 new file mode 100644 index 0000000..fca9a0b --- /dev/null +++ b/roles/wireguard/templates/wg0.conf.j2 @@ -0,0 +1,35 @@ +{{ ansible_managed | comment }} + +[Interface] +PrivateKey = {{ wg_private_key }} +Address = {{ wg_addr4 }}, {{ wg_addr6 }} +ListenPort = {{ wg_listen_port }} +SaveConfig = false + +{% if wg_firewall %} +PostUp = iptables -t nat -A POSTROUTING -s {{ wg_addr4 }} -m policy --pol none --dir out -j MASQUERADE +PostUp = iptables -A FORWARD -s {{ wg_addr4 }} -j ACCEPT +PostUp = ip6tables -t nat -A POSTROUTING -s {{ wg_addr6 }} -m policy --pol none --dir out -j MASQUERADE +PostUp = ip6tables -A FORWARD -s {{ wg_addr6 }} -j ACCEPT +PostDown = iptables -t nat -D POSTROUTING -s {{ wg_addr4 }} -m policy --pol none --dir out -j MASQUERADE +PostDown = iptables -D FORWARD -s {{ wg_addr4 }} -j ACCEPT +PostDown = ip6tables -t nat -A POSTROUTING -s {{ wg_addr6 }} -m policy --pol none --dir out -j MASQUERADE +PostDown = ip6tables -D FORWARD -s {{ wg_addr6 }} -j ACCEPT +{% endif %} +{% if wg_peers is defined %} +{% for peer in wg_peers %} + +[Peer] +PublicKey = {{ peer.public_key }} +{% if peer.preshared_key is defined %} +PresharedKey = {{ peer.preshared_key }} +{% endif %} +AllowedIPs = {{ peer.allowed_ips }} +{% if peer.endpoint is defined %} +Endpoint = {{ peer.endpoint }} +{% endif %} +{% if peer.persistent_keepalive is defined and peer.persistent_keepalive %} +PersistentKeepalive = 25 +{% endif %} +{% endfor %} +{% endif %} -- cgit v1.2.3