Compare commits

...

7 Commits

Author SHA1 Message Date
d51f8fefaa roles/common: minor configuration of Debian 13 SSH
Tweak some of the new OpenSSH per-source penalty settings on Debian
13. For now only adjusting the source network masks and reusing the
list of IPs to exempt from fail2ban.

These being built in makes them easier to use, but I think I will
end up sticking with fail2ban for the heavy lifting because it per-
sists across restarts of the daemon, whereas OpenSSH's doesn't. I
will monitor OpenSSH on Debian 13 to see how to best use it along
side fail2ban.
2025-09-23 10:33:24 +03:00
9ff6e19135 roles/common: use 127.0.0.0/8 for fail2ban ignoreip
We can re-use our fail2ban ignoreip setting for Debian 13's OpenSSH
PerSourcePenaltyExemptList, but OpenSSH is more strict with regards
to masks not being applied to the host portion. I had never noticed
that fail2ban's default was applying the mask on the host portion!
2025-09-23 10:33:23 +03:00
4680999680 roles/common: sshd overrides for Debian 13 2025-09-23 10:33:23 +03:00
602734acce roles: update ansible.builtin.systemd builtin
Use ansible.builtin.systemd_service instead.
2025-09-23 10:33:11 +03:00
0db7911b70 roles/common: remove sudoers.d
We are not using this.
2025-09-21 23:09:40 +03:00
ee4c62e5f9 roles: remove tests for Debian
We only run on Debian now.
2025-09-21 22:20:31 +03:00
a315db8a7c roles/common: use ansible_distribution_version
In most cases it is enough to use the full version (ie 12.12) since
we use Ansible's version comparison function. We rarely need to use
the major version (ie 12) directly.
2025-09-21 22:19:00 +03:00
20 changed files with 80 additions and 28 deletions

View File

@@ -3,7 +3,7 @@
# I'm currently not sure when we need to restart versus reload
- name: reload caddy
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: caddy
state: reloaded

View File

@@ -36,7 +36,7 @@
{% elif has_wordpress -%}
root * {{ document_root }}
encode
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('12', '==') -%}
{% if ansible_distribution_major_version is version('12', '==') -%}
php_fastcgi unix//run/php/php8.2-fpm-{{ domain_name }}.sock
{% endif -%}
file_server

View File

@@ -8,7 +8,7 @@ fail2ban_maxretry: 6
fail2ban_findtime: 3600
# 2 weeks in seconds
fail2ban_bantime: 1209600
fail2ban_ignoreip: 127.0.0.1/8
fail2ban_ignoreip: 127.0.0.0/8
# Disable SSH passwords. Must use SSH keys. This is OK because we add the keys
# before re-configuring the SSH daemon to disable passwords.

View File

@@ -1 +0,0 @@
provisioning ALL=(ALL) ALL

View File

@@ -2,7 +2,7 @@
# ansible.builtin.file: roles/common/handlers/main.yml
- name: Reload sshd
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: "{{ sshd_service_name }}"
state: reloaded
@@ -10,11 +10,11 @@
ansible.builtin.command: sysctl -p /etc/sysctl.conf
- name: Reload systemd
ansible.builtin.systemd:
ansible.builtin.systemd_service:
daemon_reload: true
- name: Restart nftables
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: nftables
state: restarted
@@ -22,6 +22,6 @@
# in the order they are defined, not in the order they are listed in the task's
# notify statement and we must restart fail2ban after updating the firewall.
- name: Restart fail2ban
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: fail2ban
state: restarted

View File

@@ -1,6 +1,6 @@
---
- name: Install fail2ban
when: ansible_distribution_major_version is version('11', '>=')
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.apt:
name:
- fail2ban
@@ -47,7 +47,7 @@
- Restart fail2ban
- name: Start and enable fail2ban service
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: fail2ban
state: started
enabled: true

View File

@@ -2,14 +2,14 @@
# Debian 11+ will use nftables directly, with no firewalld.
- name: Install Debian firewall packages
when: ansible_distribution_major_version is version('11', '>=')
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.apt:
name: nftables
state: present
cache_valid_time: 3600
- name: Remove iptables on newer Debian
when: ansible_distribution_major_version is version('11', '>=')
when: ansible_distribution_version is version('11', '>=')
ansible.builtin.apt:
pkg: iptables
state: absent
@@ -19,7 +19,7 @@
ansible.builtin.include_tasks: nftables.yml
- name: Configure fail2ban
when: ansible_distribution_major_version is version('9', '>=')
when: ansible_distribution_version is version('9', '>=')
ansible.builtin.include_tasks: fail2ban.yml
# vim: set sw=2 ts=2:

View File

@@ -76,11 +76,11 @@
# need to reload to pick up service/timer/environment changes
- name: Reload systemd daemon
when: nftables_systemd_units is changed
ansible.builtin.systemd: # noqa no-handler
ansible.builtin.systemd_service: # noqa no-handler
daemon_reload: true
- name: Start and enable nftables update timers
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: "{{ item }}"
state: started
enabled: true
@@ -88,7 +88,7 @@
- update-firehol-nftables.timer
- name: Start and enable nftables
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: nftables
state: started
enabled: true

View File

@@ -22,7 +22,7 @@
- name: Start and enable systemd's NTP client
when: ansible_service_mgr == 'systemd'
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: systemd-timesyncd
state: started
enabled: true

View File

@@ -1,6 +1,7 @@
---
# SSH configs don't change in Debian minor versions
# Only override the system sshd configuration on older Debian.
- name: Reconfigure /etc/ssh/sshd_config
when: ansible_distribution_version is version('12', '<=')
ansible.builtin.template:
src: "sshd_config_{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.j2"
dest: /etc/ssh/sshd_config
@@ -9,6 +10,18 @@
mode: "0600"
notify: Reload sshd
# Newer OpenSSH versions support including extra configuration. The includes
# happen at the beginning of the file and the first value to be read is used.
- name: Configure sshd_config.d overrides
when: ansible_distribution_version is version('13', '>=')
ansible.builtin.template:
src: etc/ssh/sshd_config.d/01-{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.conf.j2
dest: /etc/ssh/sshd_config.d/01-custom.conf
owner: root
group: root
mode: "0600"
notify: Reload sshd
# See: WeakDH (2015): https://weakdh.org/sysadmin.html
- name: Remove small Diffie-Hellman SSH moduli
block:

View File

@@ -0,0 +1,40 @@
{{ ansible_managed | comment }}
HostKey /etc/ssh/ssh_host_ed25519_key
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear
# audit track of which key was using to log in.
LogLevel VERBOSE
MaxAuthTries 4
AuthorizedKeysFile .ssh/authorized_keys
# To disable tunneled clear text passwords, change to no here!
{% if ssh_password_authentication == 'disabled' %}
PasswordAuthentication no
{% else %}
PasswordAuthentication yes
{% endif %}
X11Forwarding no
# Based on the ssh-audit profile for Debian 13, but with but with all algos with
# less than 256 bits removed, as NSA's Suite B removed them years ago and the
# new (2018) CNSA suite is 256 bits and up.
#
# See: ssh-audit.py -P "Hardened Debian 13 (version 1)"
# See: https://en.wikipedia.org/wiki/Commercial_National_Security_Algorithm_Suite
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com
{% if ssh_allowed_users is defined and ssh_allowed_users %}
AllowUsers {{ ssh_allowed_users|join(" ") }} {{ provisioning_user.name }}
{% endif %}
PerSourcePenaltyExemptList {{ fail2ban_ignoreip | replace(" ", ",") }}
# Mask to use for IPv4 and IPv6 respectively when applying network penalties.
# The default is 32:128.
PerSourceNetBlockSize 24:56

View File

@@ -6,14 +6,14 @@ PartOf=nftables.service
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=read-only
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11','>=') %}
{% if ansible_distribution_version is version('11','>=') %}
ProtectSystem=strict
{% else %}
{# Older systemd versions don't have ProtectSystem=strict #}
ProtectSystem=full
{% endif %}
NoNewPrivileges=yes
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11','>=') %}
{% if ansible_distribution_version is version('11','>=') %}
ReadWritePaths=-/var/run/fail2ban
ReadWritePaths=-/var/lib/fail2ban
ReadWritePaths=-/var/log/fail2ban.log

View File

@@ -1,6 +1,6 @@
---
- name: restart mariadb
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: mariadb
state: restarted

View File

@@ -1,4 +1,4 @@
---
# ansible.builtin.file: roles/munin/handlers/main.yml
- name: restart munin-node
ansible.builtin.systemd: name=munin-node state=restarted
ansible.builtin.systemd_service: name=munin-node state=restarted

View File

@@ -26,7 +26,7 @@
- restart munin-node
- name: Start munin-node
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: munin-node
state: started
enabled: true

View File

@@ -1,6 +1,6 @@
---
- name: Reload nginx
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: nginx
state: reloaded

View File

@@ -82,7 +82,7 @@
# always issues daemon-reload just in case the service/timer changed
- name: Start and enable systemd timer to renew Let's Encrypt certs
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: renew-letsencrypt.timer
state: started
enabled: true

View File

@@ -119,7 +119,7 @@
tags: nginx
- name: Start and enable nginx service
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: nginx
state: started
enabled: true

View File

@@ -77,7 +77,7 @@ server {
# See: https://httpoxy.org/
fastcgi_param HTTP_PROXY "";
{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('12', '==') %}
{% if ansible_distribution_major_version is version('12', '==') %}
fastcgi_pass unix:/run/php/php8.2-fpm-{{ domain_name }}.sock;
{% endif %}
fastcgi_index index.php;

View File

@@ -1,7 +1,7 @@
---
# For Debian 12
- name: Reload php8.2-fpm
ansible.builtin.systemd:
ansible.builtin.systemd_service:
name: php8.2-fpm
state: reloaded