iac/ansible/roles/ssh_hardening/tasks/main.yaml
2025-11-09 11:58:19 +02:00

104 lines
3.1 KiB
YAML

---
- name: Install iptables and iptables-persistent
ansible.builtin.apt:
name:
- iptables
- iptables-persistent
- netfilter-persistent
state: present
update_cache: true
- name: Deploy SSH hardening configuration
ansible.builtin.template:
src: 99-ssh-hardening.conf.j2
dest: /etc/ssh/sshd_config.d/99-ssh-hardening.conf
mode: '0644'
owner: root
group: root
validate: 'sshd -t -f %s'
register: ssh_config_changed
- name: Restart SSH daemon asynchronously (to maintain connection)
ansible.builtin.shell: "nohup systemctl restart sshd &"
when: ssh_config_changed.changed
changed_when: true
- name: Wait for SSH port to become available
ansible.builtin.wait_for:
host: "{{ ansible_host | default(inventory_hostname) }}"
port: 22
delay: 2
timeout: 30
state: started
when: ssh_config_changed.changed
delegate_to: localhost
- name: Reset SSH connection to pick up new configuration
ansible.builtin.meta: reset_connection
when: ssh_config_changed.changed
- name: Verify SSH connection after restart
ansible.builtin.ping:
when: ssh_config_changed.changed
- name: Configure iptables for SSH restrictions (non-Forgejo servers)
block:
- name: Accept SSH from WireGuard network
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: '22'
source: "{{ wireguard_network }}"
jump: ACCEPT
comment: Allow SSH from WireGuard VPN
- name: Accept SSH from VPC network
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: '22'
source: "{{ vpc_network }}"
jump: ACCEPT
comment: Allow SSH from internal VPC
- name: Accept established SSH connections
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: '22'
ctstate: ESTABLISHED,RELATED
jump: ACCEPT
comment: Allow established SSH connections
- name: Drop all other SSH connections
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: '22'
jump: DROP
comment: Drop SSH from untrusted networks
when: not ssh_allow_public_git
- name: Save iptables rules
ansible.builtin.shell: |
iptables-save > /etc/iptables/rules.v4
netfilter-persistent save
args:
executable: /bin/bash
changed_when: true
when: not ssh_allow_public_git
- name: Display SSH access information
ansible.builtin.debug:
msg: |
SSH hardening applied to {{ inventory_hostname }}:
- Shell users ({{ ssh_shell_users | join(', ') }}): Only from {{ ssh_allowed_networks | join(', ') }}
{% if ssh_allow_public_git %}
- Git user ({{ ssh_git_user }}): Public access allowed for Forgejo
- No iptables restrictions (sshd AllowUsers controls access)
{% else %}
- iptables rules: SSH blocked except from trusted networks
{% endif %}
- Strong cryptography enforced (RSA-SHA2, Ed25519, ChaCha20, AES-GCM)
- Authorized keys files: .ssh/authorized_keys (manual), .ssh/authorized_keys.forgejo (git-managed)