--- - name: Server hardening hosts: all become: true vars: ssh_port: 22 k3s_api_port: 6443 flannel_vxlan_port: 8472 tasks: # ── SSH hardening ──────────────────────────────────────────────────────── - name: Disable root SSH login lineinfile: path: /etc/ssh/sshd_config regexp: '^#?PermitRootLogin' line: 'PermitRootLogin no' state: present notify: Restart sshd - name: Disable password authentication lineinfile: path: /etc/ssh/sshd_config regexp: '^#?PasswordAuthentication' line: 'PasswordAuthentication no' state: present notify: Restart sshd - name: Disable challenge-response authentication lineinfile: path: /etc/ssh/sshd_config regexp: '^#?ChallengeResponseAuthentication' line: 'ChallengeResponseAuthentication no' state: present notify: Restart sshd # ── UFW firewall ───────────────────────────────────────────────────────── - name: Install ufw apt: name: ufw state: present update_cache: yes - name: Set UFW default inbound policy to deny ufw: default: deny direction: incoming - name: Set UFW default outbound policy to allow ufw: default: allow direction: outgoing - name: Allow SSH ufw: rule: allow port: "{{ ssh_port }}" proto: tcp - name: Allow k3s API server ufw: rule: allow port: "{{ k3s_api_port }}" proto: tcp - name: Allow Flannel VXLAN (inter-node) ufw: rule: allow port: "{{ flannel_vxlan_port }}" proto: udp - name: Enable UFW ufw: state: enabled # ── fail2ban ───────────────────────────────────────────────────────────── - name: Install fail2ban apt: name: fail2ban state: present - name: Configure fail2ban SSH jail copy: dest: /etc/fail2ban/jail.d/sshd.conf content: | [sshd] enabled = true port = {{ ssh_port }} maxretry = 5 bantime = 3600 findtime = 600 mode: '0644' notify: Restart fail2ban - name: Enable and start fail2ban systemd: name: fail2ban enabled: true state: started # ── Shell hygiene ───────────────────────────────────────────────────────── - name: Set HISTCONTROL to suppress space-prefixed commands from history copy: dest: /etc/profile.d/histcontrol.sh content: | # Commands prefixed with a space are not recorded in shell history. # Use this when typing secrets interactively. export HISTCONTROL=ignorespace mode: '0644' handlers: - name: Restart sshd systemd: name: sshd state: restarted - name: Restart fail2ban systemd: name: fail2ban state: restarted