diff --git a/roles/ppm/files/ppmfirewall b/roles/ppm/files/ppmfirewall index 1f63bd8..a91cf0a 100644 --- a/roles/ppm/files/ppmfirewall +++ b/roles/ppm/files/ppmfirewall @@ -3,20 +3,45 @@ # PPM Firewall {% for app in otherapps -%} +# App {{ app }} {%- if "firewall" in otherapps[app]["imports"] -%} {%- set oneapp = otherapps[app]["imports"]["firewall"] %} - -{% for redirect in oneapp.redirect %} +{%- for redirect in oneapp.redirect %} +{%- if redirect.version == "ipv4" %} +{%- if redirect.ip is defined %} +# Redirect {{ redirect.ip }}:{{ redirect.from }} to {{ redirect.to }} ({{ redirect.proto | default('tcp') }}) for {{ app }} +inputinterface=$(ip -o -4 addr show | awk '$3 == "inet" && index($4,"{{ redirect.ip }}/")==1 {print "-i " $2}') +iptables -A INPUT -d {{ redirect.ip }} $inputinterface -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT +iptables -t nat -A PREROUTING $inputinterface -d {{ redirect.ip }} -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +iptables -t nat -A OUTPUT -d {{ redirect.ip }} -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +{%- else %} # Redirect {{ redirect.from }} to {{ redirect.to }} ({{ redirect.proto | default('tcp') }}) for {{ app }} -iptables -A INPUT -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT -ip6tables -A INPUT -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT -iptables -t nat -A PREROUTING -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} -ip6tables -t nat -A PREROUTING -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} -{% endfor %} -{% for openport in oneapp.open %} +iptables -A INPUT -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT +iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +iptables -t nat -A OUTPUT -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +{%- endif %} +{%- else %}{# ipv6 #} +{%- if redirect.ip is defined %} +# Redirect {{ redirect.ip }}:{{ redirect.from }} to {{ redirect.to }} ({{ redirect.proto | default('tcp') }}) for {{ app }} +inputinterface=$(ip -o -6 addr show | awk '$3 == "inet6" && index($4,"{{ redirect.ip }}/")==1 {print "-i " $2}') +ip6tables -A INPUT -d {{ redirect.ip }} $inputinterface -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT +ip6tables -t nat -A PREROUTING -d {{ redirect.ip }} $inputinterface -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +ip6tables -t nat -A OUTPUT -d {{ redirect.ip }} -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +{%- else %} +# Redirect {{ redirect.from }} to {{ redirect.to }} ({{ redirect.proto | default('tcp') }}) for {{ app }} +ip6tables -A INPUT -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j ACCEPT +ip6tables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +ip6tables -t nat -A OUTPUT -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} +{%- endif %} +{%- endif %} +{%- endfor %} +{%- for openport in oneapp.open %} # Open port {{ openport.port }}/{{ openport.proto | default('tcp') }} for app {{ app }} -iptables -A INPUT -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT -ip6tables -A INPUT -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT -{% endfor %} -{% endif %} +{%- if redirect.version == "ipv4" %} +iptables -A INPUT {% if firewall_bindservices_ipv4 is defined %}-s {{firewall_bindservices_ipv4 }}{% endif %} -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT +{%- else %} +ip6tables -A INPUT {% if firewall_bindservices_ipv6 is defined %}-s {{firewall_bindservices_ipv6 }}{% endif %} -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT +{%- endif %} +{%- endfor %} +{%- endif %} {% endfor %} diff --git a/roles/ppm/tasks/main.yml b/roles/ppm/tasks/main.yml index 8a52276..e0bd451 100644 --- a/roles/ppm/tasks/main.yml +++ b/roles/ppm/tasks/main.yml @@ -7,7 +7,7 @@ loop_control: loop_var: ppm_app label: "{{ ppm_app.user }}" - when: ppm_app.on_server == inventory_hostname + when: ppm_app.on_server == inventory_hostname and ppm_app.enabled | default(true) - name: Arrange firewall ansible.builtin.import_tasks: firewall.yml diff --git a/roles/ppm/tasks/oneapp.yml b/roles/ppm/tasks/oneapp.yml index 976e9eb..ccfa54c 100644 --- a/roles/ppm/tasks/oneapp.yml +++ b/roles/ppm/tasks/oneapp.yml @@ -2,6 +2,7 @@ ansible.builtin.user: name: "{{ ppm_app.user }}" shell: /bin/bash + home: "{{ ppm_app.homedir | default(omit) }}" register: ppm_app_user # Enabling linger will make systemd start the user-systemd for this user at bootup time @@ -18,6 +19,23 @@ line: "export XDG_RUNTIME_DIR=/run/user/$(id -u)" regexp: ^export XDG_RUNTIME_DIR= +- name: "Ensure ssh configuration directory for user {{ ppm_app.user }}" + ansible.builtin.file: + state: directory + mode: "0700" + path: "{{ ppm_app_user.home }}/.ssh" + owner: "{{ ppm_app_user.name }}" + group: "{{ ppm_app_user.group }}" + +- name: "Place ssh key for user {{ ppm_app.user }}" + ansible.builtin.copy: + src: "{{ ppm_app.sshkey }}" + mode: "0600" + dest: "{{ ppm_app_user.home }}/.ssh/id_rsa" + owner: "{{ ppm_app_user.name }}" + group: "{{ ppm_app_user.group }}" + when: ppm_app.sshkey is defined + - name: "Place configuration ({{ ppm_app.user }})" ansible.builtin.copy: content: "{{ ppm_app.appconfig | dict2items | selectattr('key', 'ne', 'code') | items2dict | to_nice_yaml }}" @@ -56,3 +74,5 @@ - name: Show ppm output ansible.builtin.debug: var: ppm_setupstart + # Also mark it when the actual command changed, so it is easy to find... + changed_when: "'No changes have been made, everything was already ok' not in ppm_setupstart.stdout" diff --git a/roles/ppm/tasks/ppminstall.yml b/roles/ppm/tasks/ppminstall.yml index 022f3e8..3ece19d 100644 --- a/roles/ppm/tasks/ppminstall.yml +++ b/roles/ppm/tasks/ppminstall.yml @@ -10,6 +10,8 @@ - netavark # Required for rootless networking - slirp4netns + # Required for rootless networking - for trixie and above + - passt # podman-compose is also used in many apps we can install - podman-compose # Restic is currently the only supported backup system @@ -21,6 +23,8 @@ - git # Yeah we should use nftables, patches welcome. For now, we install iptables - iptables + # This is used in our zabbix scripts + - netcat-openbsd - name: Create state directory ansible.builtin.file: