diff --git a/README.md b/README.md index 6d621b9..32cfdf3 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,24 @@ This is a good playground to learn and I encourage you to adapt these roles to y | static-web | Static website hosting | | vpn | WireGuard server | +## Port Reservation Rules + +Reserved ports that **must not** be used as role defaults: + +| Port(s) | Protocol | Reserved for | +| --- | --- | --- | +| 80 | tcp | Nginx | +| 443 | tcp | Nginx | +| 3000-3009 | tcp | Testing | +| 4430 | tcp | Testing | +| 8080 | tcp | Testing | + +When adding a new role, pick a default port outside these ranges. + ## Requirements +Ansible `>=2.15` + Base tools: ```sh @@ -110,3 +126,17 @@ Linting: ansible-lint npx prettier --write . ``` + +## Q&A + +### Immich crash loop: `PostgresError: must be owner of extension vector` + +Immich tries to self-update the `pgvector` extension at startup, but its database user is intentionally `NOSUPERUSER`, so the `ALTER EXTENSION vector UPDATE` call fails and the microservices worker exits with code 1. + +Fix it on the running host by updating the extension as the `postgres` superuser: + +```sh +sudo -u postgres psql -d immich -c 'ALTER EXTENSION vector UPDATE;' +``` + +The Immich role also runs this automatically on subsequent playbook runs, so re-deployments after a pgvector package upgrade do not require manual intervention. diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..accfbd8 --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: ">=2.15" diff --git a/roles/net_config/handlers/main.yml b/roles/net_config/handlers/main.yml new file mode 100644 index 0000000..c11e8ea --- /dev/null +++ b/roles/net_config/handlers/main.yml @@ -0,0 +1,23 @@ +--- +# UFW must be fully restarted (disable + enable) — not just reloaded — to pick +# up changes in /etc/default/ufw (DEFAULT_FORWARD_POLICY) and the *nat block +# in /etc/ufw/before.rules. See ufw(8) "RULE SYNTAX" → IP forwarding. +- name: Restart ufw (ip-forwarding settings changed) + block: + - name: Validate ufw ruleset before restart (dry-run) + ansible.builtin.command: ufw --dry-run reload + changed_when: false + + - name: Disable ufw + ansible.builtin.command: ufw disable + changed_when: true + + - name: Enable ufw + ansible.builtin.command: ufw --force enable + changed_when: true + + - name: Verify ufw is active after restart + ansible.builtin.command: ufw status + register: ufw_status_after + changed_when: false + failed_when: "'Status: active' not in ufw_status_after.stdout" diff --git a/roles/net_config/tasks/main.yml b/roles/net_config/tasks/main.yml index 3e52d99..f34b3c5 100644 --- a/roles/net_config/tasks/main.yml +++ b/roles/net_config/tasks/main.yml @@ -32,3 +32,41 @@ ansible.builtin.set_fact: network_reload_required: true when: netdev_result is changed or network_result is changed + + ## Routing & NAT (when interface has forward + masquerade enabled) + - name: Enable IPv4 forwarding + ansible.posix.sysctl: + name: net.ipv4.ip_forward + value: "1" + state: present + sysctl_set: true + reload: true + when: + - interface.ipv4.forward | default(false) + - interface.ipv4.masquerade | default(false) + + - name: Set UFW default forward policy to ACCEPT + ansible.builtin.lineinfile: + path: /etc/default/ufw + regexp: "^DEFAULT_FORWARD_POLICY=" + line: 'DEFAULT_FORWARD_POLICY="ACCEPT"' + when: + - interface.ipv4.forward | default(false) + - interface.ipv4.masquerade | default(false) + notify: Restart ufw (ip-forwarding settings changed) + + - name: Configure NAT masquerade in UFW before.rules for {{ interface.name }} + ansible.builtin.blockinfile: + path: /etc/ufw/before.rules + insertbefore: "^\\*filter" + marker: "# {mark} ANSIBLE MANAGED - NAT {{ interface.name }}" + block: | + *nat + :POSTROUTING ACCEPT [0:0] + -A POSTROUTING -s {{ interface.ipv4.address | ansible.utils.ipaddr('network/prefix') }} -o {{ interface.ipv4.nat_out_interface }} -j MASQUERADE + COMMIT + when: + - interface.ipv4.forward | default(false) + - interface.ipv4.masquerade | default(false) + - interface.ipv4.nat_out_interface is defined + notify: Restart ufw (ip-forwarding settings changed)