Skip to content

Commit deed76f

Browse files
committed
Add default ufw rules on storage host
1 parent 69f4743 commit deed76f

File tree

5 files changed

+42
-5
lines changed

5 files changed

+42
-5
lines changed

docs/guides/how_to_install_debian_on_storage_node.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,16 @@ Before running the storage playbook (`ansible-playbook -i inventory.sh storage.y
115115
- [ ] APT sources configured (for package installation)
116116
- [ ] Data drives are physically installed and visible: `lsblk` shows the expected disks
117117
- [ ] Data drives are partitioned (partition IDs match the inventory in `metal/inventory/metal.yml`)
118+
- [ ] Controller is reachable from the homelab network (see firewall warning below)
119+
120+
!!! warning "Firewall: SSH lockout risk"
121+
The storage playbook configures UFW with a **default deny incoming** policy. Only networks listed in `firewall_allowed_networks` (defaults to `10.10.10.0/24`) are allowed SSH and NFS access. If your Ansible controller is on a different subnet (e.g. `192.168.1.0/24`), **UFW will block SSH and you will be locked out** of the storage node.
122+
123+
To avoid this, either:
124+
125+
- Run the playbook from a machine on the `10.10.10.0/24` network, **or**
126+
- Add your controller's subnet to `firewall_allowed_networks` when running the playbook:
127+
128+
```bash
129+
make -C metal storage ANSIBLE_ARGS='-e "firewall_allowed_networks=[\"10.10.10.0/24\",\"192.168.1.0/24\"]"'
130+
```

docs/info/todo.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ title: ToDo
190190
191191
- [ ] Setup pi-hole on the cluster
192192
193-
- [ ] NFS Optimizations
193+
- [ ] Storage Node / NFS Optimizations
194194
- NFS mount monitoring/health check on K8s side
195195
There's no monitoring or alerting for NFS mount failures on the K8s side. If the NAS goes down, pods will hang on NFS operations. This is a common NFS issue. Consider adding:
196196
- NFS mount soft option (instead of default hard) for timeout behavior
@@ -202,3 +202,5 @@ title: ToDo
202202
This is optional and premature optimization, but should be kept in mind.
203203
- fstab entry cleanup
204204
- If you remove a data drive from inventory, the fstab entry persists (uses lineinfile with state: present, never absent). Not a concern for initial deployment.
205+
- Use `nftables` instead of `ufw` on Debian
206+
- Add equivalent `firewalld` tasks to properly support RedHat

metal/roles/storage/defaults/main.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ default_nfs_options: "rw,sync,no_subtree_check,no_root_squash,insecure"
77

88
# Firewall configuration
99
manage_firewall: true # Set to false to skip firewall configuration
10+
# TODO: should use nftables on Debian (+ firewalld equivalent if we trully want to support redhat OSes)
1011
install_ufw: true # Install UFW if not present (only when manage_firewall=true)
11-
nfs_allowed_networks:
12+
firewall_allowed_networks: # NB! The default will only allow connections (including SSH) from homelab network
1213
- "{{ homelab_net_cidr }}"
1314

1415
# Network configuration (optional)

metal/roles/storage/tasks/k8s_validation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
volumes:
5858
- name: nfs-volume
5959
nfs:
60-
server: {{ ansible_host }}
60+
server: "{{ ansible_host }}"
6161
path: /mnt/storage/Temp
6262
restartPolicy: Never
6363
dest: /tmp/nfs-test-pod.yaml

metal/roles/storage/tasks/nfs_firewall.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,35 @@
4343
changed_when: false
4444
failed_when: false
4545

46+
- name: Set UFW default deny incoming
47+
ufw:
48+
direction: incoming
49+
policy: deny
50+
51+
- name: Set UFW default allow outgoing
52+
ufw:
53+
direction: outgoing
54+
policy: allow
55+
56+
- name: Configure TCP ports in firewall
57+
ufw:
58+
rule: allow
59+
src: "{{ item.0 }}"
60+
port: "{{ item.1 }}"
61+
proto: tcp
62+
comment: "{{ item.1 }}/tcp"
63+
loop: "{{ firewall_allowed_networks | product(['22']) | list }}"
64+
loop_control:
65+
label: "{{ item.0 }} -> {{ item.1 }}/tcp"
66+
4667
- name: Configure NFS TCP ports in firewall
4768
ufw:
4869
rule: allow
4970
src: "{{ item.0 }}"
5071
port: "{{ item.1 }}"
5172
proto: tcp
5273
comment: "NFS {{ item.1 }}/tcp"
53-
loop: "{{ nfs_allowed_networks | product(['22', '111', '2049', '20048']) | list }}"
74+
loop: "{{ firewall_allowed_networks | product(['111', '2049', '20048']) | list }}"
5475
loop_control:
5576
label: "{{ item.0 }} -> {{ item.1 }}/tcp"
5677

@@ -62,7 +83,7 @@
6283
proto: udp
6384
comment: "NFS {{ item.1 }}/udp"
6485
# UDP 2049 to support potential NFSv3 clients
65-
loop: "{{ nfs_allowed_networks | product(['111', '2049']) | list }}"
86+
loop: "{{ firewall_allowed_networks | product(['111', '2049']) | list }}"
6687
loop_control:
6788
label: "{{ item.0 }} -> {{ item.1 }}/udp"
6889

0 commit comments

Comments
 (0)