mirror of
https://github.com/RWejlgaard/pez-infra.git
synced 2026-07-04 15:46:16 +00:00
Samba on london-b was allowed on 445/tcp from anywhere via UFW, exposing SMB/CIFS to the public internet. Tailscale already reaches it through the tailscale0 allow-all rule, so scope the explicit rule to the local London LAN (192.168.1.0/24) instead of the world. The common UFW task only ever adds allow rules, so it gained support for an optional per-port from_ip, plus a follow-up task that deletes the superseded world-open variant of any source-restricted port — otherwise the old '445 ALLOW Anywhere' rule would linger on the host and defeat the change. PESO-145
128 lines
3.3 KiB
YAML
128 lines
3.3 KiB
YAML
---
|
|
# Common baseline for all Linux hosts.
|
|
# Installs core packages, configures SSH, sets up the shell environment.
|
|
|
|
- name: Update apt cache
|
|
ansible.builtin.apt:
|
|
update_cache: true
|
|
cache_valid_time: 3600
|
|
|
|
- name: Install baseline packages
|
|
ansible.builtin.apt:
|
|
name:
|
|
- curl
|
|
- wget
|
|
- git
|
|
- htop
|
|
- tmux
|
|
- vim
|
|
- jq
|
|
- unzip
|
|
- fish
|
|
- rsync
|
|
- fail2ban
|
|
- ufw
|
|
state: present
|
|
|
|
- name: Get fish shell path
|
|
ansible.builtin.command: which fish
|
|
changed_when: false
|
|
register: common_fish_path
|
|
when: inventory_hostname != 'london-a'
|
|
|
|
- name: Set fish as default shell
|
|
ansible.builtin.user:
|
|
name: root
|
|
shell: "{{ common_fish_path.stdout }}"
|
|
when: inventory_hostname != 'london-a'
|
|
|
|
- name: Ensure SSH directory exists
|
|
ansible.builtin.file:
|
|
path: /root/.ssh
|
|
state: directory
|
|
mode: '0700'
|
|
|
|
- name: Harden SSH config
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
regexp: "{{ item.regexp }}"
|
|
line: "{{ item.line }}"
|
|
state: present
|
|
loop:
|
|
- {regexp: '^#?PermitRootLogin', line: 'PermitRootLogin prohibit-password'}
|
|
- {regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no'}
|
|
- {regexp: '^#?X11Forwarding', line: 'X11Forwarding no'}
|
|
notify: Restart sshd
|
|
|
|
- name: Enable fail2ban
|
|
ansible.builtin.service:
|
|
name: fail2ban
|
|
state: started
|
|
enabled: true
|
|
|
|
# --- UFW firewall ---
|
|
|
|
- name: Set UFW default deny incoming
|
|
community.general.ufw:
|
|
direction: incoming
|
|
default: deny
|
|
when: common_ufw_enabled | bool
|
|
notify: Reload ufw
|
|
|
|
- name: Set UFW default allow outgoing
|
|
community.general.ufw:
|
|
direction: outgoing
|
|
default: allow
|
|
when: common_ufw_enabled | bool
|
|
notify: Reload ufw
|
|
|
|
- name: Allow all traffic on Tailscale interface
|
|
community.general.ufw:
|
|
rule: allow
|
|
direction: in
|
|
interface: tailscale0
|
|
comment: "Tailscale mesh - allow all"
|
|
when: common_ufw_enabled | bool
|
|
notify: Reload ufw
|
|
|
|
- name: Allow SSH (safety net)
|
|
community.general.ufw:
|
|
rule: allow
|
|
port: '22'
|
|
proto: tcp
|
|
comment: "SSH"
|
|
when: common_ufw_enabled | bool
|
|
notify: Reload ufw
|
|
|
|
- name: Allow host-specific ports
|
|
community.general.ufw:
|
|
rule: allow
|
|
port: "{{ item.port | string }}"
|
|
proto: "{{ item.proto | default('tcp') }}"
|
|
from_ip: "{{ item.from_ip | default(omit) }}"
|
|
comment: "{{ item.comment | default(omit) }}"
|
|
loop: "{{ common_ufw_allowed_ports }}"
|
|
when:
|
|
- common_ufw_enabled | bool
|
|
- common_ufw_allowed_ports | length > 0
|
|
notify: Reload ufw
|
|
|
|
# When a port is restricted to a source (from_ip), make sure the older
|
|
# unrestricted "allow from anywhere" variant of the same rule isn't left
|
|
# lingering on the host — UFW keeps it otherwise, which would defeat the
|
|
# source restriction. Deleting an absent rule is a no-op, so this is safe
|
|
# on hosts that never had the broad rule.
|
|
- name: Remove superseded world-open rules for source-restricted ports
|
|
community.general.ufw:
|
|
rule: allow
|
|
port: "{{ item.port | string }}"
|
|
proto: "{{ item.proto | default('tcp') }}"
|
|
delete: true
|
|
loop: "{{ common_ufw_allowed_ports | selectattr('from_ip', 'defined') | list }}"
|
|
when: common_ufw_enabled | bool
|
|
notify: Reload ufw
|
|
|
|
- name: Enable UFW
|
|
community.general.ufw:
|
|
state: enabled
|
|
when: common_ufw_enabled | bool
|