Compare commits

..

7 commits

Author SHA1 Message Date
c34b3c1d0f add passt as dependency 2025-08-15 22:58:22 +02:00
4d8c4e5f48 Cleanup firewall + make it more strict
- Do not put too many empty newlines in rendered file
- Also write redirect rules in the output chain.  This will allow us to
use the port from the same machine.  Note that redirect does rewrite the
destination to localhost if used on the same machine, so your
application should also listen to localhost
- made the file a bit clearer with better comments
- Add the explicit device if we can for redirects
2025-08-15 22:52:03 +02:00
dc99b61ea8 the zabbix scripts I use use netcat 2025-08-15 22:49:10 +02:00
0a32383de3 add ssh key option for apps
This way we can push ssh keys that can pull/push to repositories.  This
is very handy if we wish to edit/maintain the appinfo repository right
on the server where it is hosted....
2025-08-15 22:48:55 +02:00
5fda82d0d3 when the setup changed something, show output in changed color 2025-08-15 22:48:14 +02:00
b021bb2620 allow defining the home directory
The idea here is that we can have a backup server that should run on a
slow huge disk, and that the rest should run on your very fast nvme's.
To differentiate, you can specify where the homedir should be
2025-08-15 22:47:51 +02:00
a55246263b implement "enabled" apps 2025-08-15 22:46:42 +02:00
4 changed files with 62 additions and 13 deletions

View file

@ -3,20 +3,45 @@
# PPM Firewall # PPM Firewall
{% for app in otherapps -%} {% for app in otherapps -%}
# App {{ app }}
{%- if "firewall" in otherapps[app]["imports"] -%} {%- if "firewall" in otherapps[app]["imports"] -%}
{%- set oneapp = otherapps[app]["imports"]["firewall"] %} {%- 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 }} # 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 iptables -A INPUT -m addrtype --dst-type LOCAL -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 -m addrtype --dst-type LOCAL -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }}
iptables -t nat -A PREROUTING -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 }}
ip6tables -t nat -A PREROUTING -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j REDIRECT --to-ports {{ redirect.to }} {%- endif %}
{% endfor %} {%- else %}{# ipv6 #}
{% for openport in oneapp.open %} {%- 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 }} # Open port {{ openport.port }}/{{ openport.proto | default('tcp') }} for app {{ app }}
iptables -A INPUT -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT {%- if redirect.version == "ipv4" %}
ip6tables -A INPUT -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT iptables -A INPUT {% if firewall_bindservices_ipv4 is defined %}-s {{firewall_bindservices_ipv4 }}{% endif %} -p {{ openport.proto | default('tcp') }} --dport {{ openport.port }} -j ACCEPT
{% endfor %} {%- else %}
{% endif %} 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 %} {% endfor %}

View file

@ -7,7 +7,7 @@
loop_control: loop_control:
loop_var: ppm_app loop_var: ppm_app
label: "{{ ppm_app.user }}" 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 - name: Arrange firewall
ansible.builtin.import_tasks: firewall.yml ansible.builtin.import_tasks: firewall.yml

View file

@ -2,6 +2,7 @@
ansible.builtin.user: ansible.builtin.user:
name: "{{ ppm_app.user }}" name: "{{ ppm_app.user }}"
shell: /bin/bash shell: /bin/bash
home: "{{ ppm_app.homedir | default(omit) }}"
register: ppm_app_user register: ppm_app_user
# Enabling linger will make systemd start the user-systemd for this user at bootup time # 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)" line: "export XDG_RUNTIME_DIR=/run/user/$(id -u)"
regexp: ^export XDG_RUNTIME_DIR= 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 }})" - name: "Place configuration ({{ ppm_app.user }})"
ansible.builtin.copy: ansible.builtin.copy:
content: "{{ ppm_app.appconfig | dict2items | selectattr('key', 'ne', 'code') | items2dict | to_nice_yaml }}" content: "{{ ppm_app.appconfig | dict2items | selectattr('key', 'ne', 'code') | items2dict | to_nice_yaml }}"
@ -56,3 +74,5 @@
- name: Show ppm output - name: Show ppm output
ansible.builtin.debug: ansible.builtin.debug:
var: ppm_setupstart 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"

View file

@ -10,6 +10,8 @@
- netavark - netavark
# Required for rootless networking # Required for rootless networking
- slirp4netns - slirp4netns
# Required for rootless networking - for trixie and above
- passt
# podman-compose is also used in many apps we can install # podman-compose is also used in many apps we can install
- podman-compose - podman-compose
# Restic is currently the only supported backup system # Restic is currently the only supported backup system
@ -21,6 +23,8 @@
- git - git
# Yeah we should use nftables, patches welcome. For now, we install iptables # Yeah we should use nftables, patches welcome. For now, we install iptables
- iptables - iptables
# This is used in our zabbix scripts
- netcat-openbsd
- name: Create state directory - name: Create state directory
ansible.builtin.file: ansible.builtin.file: