diff --git a/roles/configure_firewall/defaults/main.yml b/roles/configure_firewall/defaults/main.yml new file mode 100644 index 0000000..575ebe9 --- /dev/null +++ b/roles/configure_firewall/defaults/main.yml @@ -0,0 +1,3 @@ +--- +sce_nft_table_name: sce_table +sce_nft_table_filename: sce-port-mapping diff --git a/roles/configure_firewall/handlers/main.yml b/roles/configure_firewall/handlers/main.yml new file mode 100644 index 0000000..e4c590d --- /dev/null +++ b/roles/configure_firewall/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- name: Reload systemd daemon + ansible.builtin.systemd_service: + daemon_reload: true + +- name: Reload port mapping service + ansible.builtin.systemd_service: + name: "{{ sce_nft_table_filename }}.service" + state: reloaded diff --git a/roles/configure_firewall/tasks/main.yml b/roles/configure_firewall/tasks/main.yml new file mode 100644 index 0000000..6ec0c29 --- /dev/null +++ b/roles/configure_firewall/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Install nftables + ansible.builtin.apt: + pkg: nftables + state: present + +- name: Install SCE port mapping rules + ansible.builtin.template: + src: nft.conf.j2 + dest: /etc/{{ sce_nft_table_filename }}.conf + mode: "0755" + validate: /usr/sbin/nft -cf %s + notify: Reload port mapping service + +- name: Install SCE port mapping systemd service + ansible.builtin.template: + src: nft.service.j2 + dest: /etc/systemd/system/{{ sce_nft_table_filename }}.service + notify: Reload systemd daemon + +# Must be placed here to ensure proper ordering of events +- name: Flush handlers + meta: flush_handlers + +- name: Ensure nft SCE port mapping service is started and enabled + ansible.builtin.systemd_service: + name: "{{ sce_nft_table_filename }}.service" + state: started + enabled: true diff --git a/roles/configure_firewall/templates/nft.conf.j2 b/roles/configure_firewall/templates/nft.conf.j2 new file mode 100644 index 0000000..a9fc910 --- /dev/null +++ b/roles/configure_firewall/templates/nft.conf.j2 @@ -0,0 +1,25 @@ +# {{ ansible_managed }} + +# type nat +# The chain type will be NAT +# hook prerouting +# Apply the rules to the prerouting hook +# priority filter + 1 +# Set the priority (which determine the order in which +# rules are evaluated to the predefined `filter` value). + +# Flush and recreate the entire table +# https://unix.stackexchange.com/questions/537030/nftables-flush-delete-when-changing-or-creating-new-table +table inet {{ sce_nft_table_name }} +flush table inet {{ sce_nft_table_name }} + +table inet {{ sce_nft_table_name }} { + chain sce_port_mapping { + type nat hook prerouting priority filter + 1; + policy accept; +{% for item in port_mapping %} +{% set from_port, to_port = item.split(':') %} + tcp dport {{ from_port }} counter redirect to :{{ to_port }} +{% endfor %} + } +} diff --git a/roles/configure_firewall/templates/nft.service.j2 b/roles/configure_firewall/templates/nft.service.j2 new file mode 100644 index 0000000..0a12023 --- /dev/null +++ b/roles/configure_firewall/templates/nft.service.j2 @@ -0,0 +1,22 @@ +# {{ ansible_managed }} +# Based on the default Debian 12 `/lib/systemd/system/nftables.service` +[Unit] +Description=nftables SCE port mapping rules +Wants=network-pre.target +Before=network-pre.target shutdown.target +Conflicts=shutdown.target +After=nftables.service +DefaultDependencies=no + +[Service] +Type=oneshot +RemainAfterExit=yes +StandardInput=null +ProtectSystem=full +ProtectHome=true +ExecStart=/usr/sbin/nft -f /etc/{{ sce_nft_table_filename }}.conf +ExecReload=/usr/sbin/nft -f /etc/{{ sce_nft_table_filename }}.conf +ExecStop=/usr/sbin/nft delete table inet {{ sce_nft_table_name }} + +[Install] +WantedBy=sysinit.target