From d9c8951e60e8907816b8f5f9fc2242aac0f18603 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:30:42 +0200 Subject: [PATCH 1/6] remove ansible_managed This has been deprecated by ansible --- ansible.cfg | 1 - roles/baseline/templates/firewall.j2 | 4 ++-- roles/baseline/templates/mosh.j2 | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ansible.cfg b/ansible.cfg index 87040d1..4acf70d 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -2,7 +2,6 @@ inventory=inventory retry_files_enabled = False remote_user = root -ansible_managed = DO NOT MODIFY: this file is managed by ansible! deperaction_warnings = True display_skipped_hosts = True diff --git a/roles/baseline/templates/firewall.j2 b/roles/baseline/templates/firewall.j2 index dac129b..039cc3f 100644 --- a/roles/baseline/templates/firewall.j2 +++ b/roles/baseline/templates/firewall.j2 @@ -1,5 +1,5 @@ #!/bin/bash -# {{ ansible_managed }} +# This file is managed by ansible, do not modify! # IPv4: iptables -F @@ -75,4 +75,4 @@ ip6tables -A INPUT -j REJECT iptables -A FORWARD -j REJECT ip6tables -A FORWARD -j REJECT -# {{ansible_managed}} +# This file is managed by ansible, do not modify! diff --git a/roles/baseline/templates/mosh.j2 b/roles/baseline/templates/mosh.j2 index 379a7ba..96d7a61 100644 --- a/roles/baseline/templates/mosh.j2 +++ b/roles/baseline/templates/mosh.j2 @@ -1,5 +1,5 @@ #!/bin/sh -# {{ansible_managed}} +# DO NOT MODIFY: this file is written by ansible # Firewall to allow mosh sessions ip6tables -A INPUT -p udp --match multiport --dports 60001:60020 -j ACCEPT From c7a3cb40e9a14ab86d94aa0164fc17f2ad0ae87d Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:31:01 +0200 Subject: [PATCH 2/6] remove deprecated ansible config --- ansible.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible.cfg b/ansible.cfg index 4acf70d..21d28df 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -5,5 +5,5 @@ remote_user = root deperaction_warnings = True display_skipped_hosts = True -stdout_callback = yaml -stderr_callback = yaml +result_format=yaml + From 1df77aa74d97d83a24c5087f47e0348559676f59 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:32:39 +0200 Subject: [PATCH 3/6] install zabbix agent in the baseline --- group_vars/all/zabbix.yml | 2 + roles/baseline/files/zabbix-sudoers | 1 + roles/baseline/handlers/main.yml | 5 +++ roles/baseline/tasks/main.yml | 3 ++ roles/baseline/tasks/zabbix.yml | 41 +++++++++++++++++++++ roles/baseline/templates/zabbix-agent.j2 | 10 +++++ roles/baseline/templates/zabbix-firewall.j2 | 5 +++ 7 files changed, 67 insertions(+) create mode 100644 group_vars/all/zabbix.yml create mode 100644 roles/baseline/files/zabbix-sudoers create mode 100644 roles/baseline/tasks/zabbix.yml create mode 100644 roles/baseline/templates/zabbix-agent.j2 create mode 100644 roles/baseline/templates/zabbix-firewall.j2 diff --git a/group_vars/all/zabbix.yml b/group_vars/all/zabbix.yml new file mode 100644 index 0000000..b61ffa4 --- /dev/null +++ b/group_vars/all/zabbix.yml @@ -0,0 +1,2 @@ +zabbix_server: "{{ lookup('file', 'passwords/zabbix_server') }}" +zabbix_psk: "{{ lookup('file', 'passwords/zabbix_psk') }}" diff --git a/roles/baseline/files/zabbix-sudoers b/roles/baseline/files/zabbix-sudoers new file mode 100644 index 0000000..266d2d5 --- /dev/null +++ b/roles/baseline/files/zabbix-sudoers @@ -0,0 +1 @@ +zabbix ALL=(ALL) NOPASSWD: /usr/sbin/smartctl diff --git a/roles/baseline/handlers/main.yml b/roles/baseline/handlers/main.yml index 5ceb761..7fb1494 100644 --- a/roles/baseline/handlers/main.yml +++ b/roles/baseline/handlers/main.yml @@ -6,3 +6,8 @@ ansible.builtin.systemd: name: ssh state: restarted + +- name: Restart zabbix-agent2 + ansible.builtin.service: + name: zabbix-agent2 + state: restarted diff --git a/roles/baseline/tasks/main.yml b/roles/baseline/tasks/main.yml index 3b3a112..b016df3 100644 --- a/roles/baseline/tasks/main.yml +++ b/roles/baseline/tasks/main.yml @@ -7,5 +7,8 @@ - name: Manage root user ansible.builtin.import_tasks: rootuser.yml +- name: Get zabbix agent installed + ansible.builtin.import_tasks: zabbix.yml + - name: Ensure handlers have ran ansible.builtin.meta: flush_handlers diff --git a/roles/baseline/tasks/zabbix.yml b/roles/baseline/tasks/zabbix.yml new file mode 100644 index 0000000..ec2d5e7 --- /dev/null +++ b/roles/baseline/tasks/zabbix.yml @@ -0,0 +1,41 @@ +- name: Install zabbix related packages + ansible.builtin.apt: + pkg: + - zabbix-agent2 + # To monitor our physical disks health, not needed for vm's. + - smartmontools + +- name: Zabbix firewall + ansible.builtin.template: + dest: /etc/firewall.d/zabbix + group: root + owner: root + mode: "0755" + src: zabbix-firewall.j2 + notify: Restart firewall + +- name: Write psk file + ansible.builtin.copy: + content: "{{ zabbix_psk }}\n" + dest: /etc/zabbix/zabbix.psk + group: root + owner: root + mode: "0644" + notify: Restart zabbix-agent2 + +- name: Zabbix agent config file + ansible.builtin.template: + dest: /etc/zabbix/zabbix_agent2.d/ansible.conf + group: root + owner: root + mode: "0644" + src: zabbix-agent.j2 + notify: Restart zabbix-agent2 + +- name: Zabbix sudoers file + ansible.builtin.copy: + dest: /etc/sudoers.d/zabbix + group: root + owner: root + mode: "0644" + src: zabbix-sudoers diff --git a/roles/baseline/templates/zabbix-agent.j2 b/roles/baseline/templates/zabbix-agent.j2 new file mode 100644 index 0000000..6bc423b --- /dev/null +++ b/roles/baseline/templates/zabbix-agent.j2 @@ -0,0 +1,10 @@ +Server={{ zabbix_server }} +ServerActive= + +TLSConnect=psk +TLSAccept=psk +TLSPSKFile=/etc/zabbix/zabbix.psk +TLSPSKIdentity={{ inventory_hostname }} + + +UserParameter=smartctl.health[*],sudo /usr/sbin/smartctl -H /dev/$1 | grep 'overall-health' | awk '{print $NF}' diff --git a/roles/baseline/templates/zabbix-firewall.j2 b/roles/baseline/templates/zabbix-firewall.j2 new file mode 100644 index 0000000..7681135 --- /dev/null +++ b/roles/baseline/templates/zabbix-firewall.j2 @@ -0,0 +1,5 @@ +#!/bin/bash + +# Zabbix agent firewall + +iptables -A INPUT -p tcp -s {{ zabbix_server }} --dport 10050 -j ACCEPT From cd8e0cbad734b79f855a5fa32e6a6c5974f46f59 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:33:32 +0200 Subject: [PATCH 4/6] setup the app using ppm setup --- roles/ppm/tasks/oneapp.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/roles/ppm/tasks/oneapp.yml b/roles/ppm/tasks/oneapp.yml index 77e4dc9..976e9eb 100644 --- a/roles/ppm/tasks/oneapp.yml +++ b/roles/ppm/tasks/oneapp.yml @@ -34,3 +34,25 @@ - name: "Bootstrap the app definition ({{ ppm_app.user }})" ansible.builtin.include_tasks: copyappdef.yml when: ppm_app.chicken_egg_appdefinition is defined and not appdefinition.stat.exists + +- name: "Set up extra files for {{ ppm_app.user }}" + ansible.builtin.copy: + src: "{{ item.from }}" + dest: "{{ ppm_app_user.home }}/{{ item.to }}" + mode: "{{ item.mode | default('0644') }}" + owner: "{{ ppm_app_user.name }}" + group: "{{ ppm_app_user.group }}" + loop: "{{ ppm_app.extra_files | default([]) }}" + +- name: "Setup and run app ({{ ppm_app.user }})" + ansible.builtin.command: ppm setup --start + register: ppm_setupstart + changed_when: "'No changes have been made, everything was already ok' not in ppm_setupstart.stdout" + become: true + become_user: "{{ ppm_app.user }}" + environment: + XDG_RUNTIME_DIR: "/run/user/{{ ppm_app_user.uid }}" + +- name: Show ppm output + ansible.builtin.debug: + var: ppm_setupstart From 242a6d1cca3d3cf0a317ac82317defc87cc769b4 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:35:05 +0200 Subject: [PATCH 5/6] new firewall system Render the template system wide, then apply. This way, the appdefinition.yml can contain everything that is required, and we don't have to specify this anymore in the main config --- group_vars/all/applications.yml | 5 ----- roles/ppm/files/ppmfirewall | 22 ++++++++++++++++++++++ roles/ppm/tasks/firewall.yml | 13 +++++++++++++ roles/ppm/tasks/main.yml | 10 ++-------- roles/ppm/tasks/ppminstall.yml | 2 ++ roles/ppm/templates/ppmfirewall.j2 | 20 -------------------- 6 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 roles/ppm/files/ppmfirewall create mode 100644 roles/ppm/tasks/firewall.yml delete mode 100644 roles/ppm/templates/ppmfirewall.j2 diff --git a/group_vars/all/applications.yml b/group_vars/all/applications.yml index 40a27dd..3df2f28 100644 --- a/group_vars/all/applications.yml +++ b/group_vars/all/applications.yml @@ -15,11 +15,6 @@ ppm_apps: - on_server: ppm.pfoe.be user: nginx chicken_egg_appdefinition: ../nginx/ - firewall_redirect: - - from: 8080 - to: 80 - - from: 8443 - to: 443 appconfig: appinfo: url: https://ppm.pfoe.be/ppm/nginx.git diff --git a/roles/ppm/files/ppmfirewall b/roles/ppm/files/ppmfirewall new file mode 100644 index 0000000..1f63bd8 --- /dev/null +++ b/roles/ppm/files/ppmfirewall @@ -0,0 +1,22 @@ +#!/bin/bash + +# PPM Firewall + +{% for app in otherapps -%} +{%- if "firewall" in otherapps[app]["imports"] -%} +{%- set oneapp = otherapps[app]["imports"]["firewall"] %} + +{% for redirect in oneapp.redirect %} +# 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 %} +# 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 %} +{% endfor %} diff --git a/roles/ppm/tasks/firewall.yml b/roles/ppm/tasks/firewall.yml new file mode 100644 index 0000000..2b58d7b --- /dev/null +++ b/roles/ppm/tasks/firewall.yml @@ -0,0 +1,13 @@ +- name: Configure firewall options + ansible.builtin.copy: + dest: /home/.ppmfirewalltemplate + group: root + owner: root + mode: "0755" + src: ppmfirewall + +- name: Render firewall + ansible.builtin.shell: ppm template /home/.ppmfirewalltemplate /etc/firewall.d/ppmfirewall ; chmod 755 /etc/firewall.d/ppmfirewall + register: firewall_render + changed_when: "'content did not change' not in firewall_render.stdout" + notify: Restart firewall diff --git a/roles/ppm/tasks/main.yml b/roles/ppm/tasks/main.yml index b6acf32..d8bf828 100644 --- a/roles/ppm/tasks/main.yml +++ b/roles/ppm/tasks/main.yml @@ -9,11 +9,5 @@ label: "{{ ppm_app.user }}" when: ppm_app.on_server == inventory_hostname -- name: Configure firewall options - ansible.builtin.template: - dest: /etc/firewall.d/ppmfirewall - group: root - owner: root - mode: "0755" - src: ppmfirewall.j2 - notify: Restart firewall +- name: Arrange firewall + ansible.builtin.import_tasks: firewall.yml diff --git a/roles/ppm/tasks/ppminstall.yml b/roles/ppm/tasks/ppminstall.yml index 3619992..022f3e8 100644 --- a/roles/ppm/tasks/ppminstall.yml +++ b/roles/ppm/tasks/ppminstall.yml @@ -19,6 +19,8 @@ - python3-jsonschema # Git is required for checking out the app definitions - git + # Yeah we should use nftables, patches welcome. For now, we install iptables + - iptables - name: Create state directory ansible.builtin.file: diff --git a/roles/ppm/templates/ppmfirewall.j2 b/roles/ppm/templates/ppmfirewall.j2 deleted file mode 100644 index 1682c11..0000000 --- a/roles/ppm/templates/ppmfirewall.j2 +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# PPM Firewal, written by ansible - -{% for ppm_app in ppm_apps %} -# Firewall for {{ ppm_app.user }} -{% for redirect in ppm_app.firewall_redirect | default([]) %} -# Redirect {{ redirect.from }} to {{ redirect.to }} ({{ redirect.proto | default('tcp') }}) -iptables -A INPUT -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j ACCEPT -ip6tables -A INPUT -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.from }} -j ACCEPT -iptables -t nat -A PREROUTING -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j REDIRECT --to-ports {{ redirect.from }} -ip6tables -t nat -A PREROUTING -p {{ redirect.proto | default('tcp') }} --dport {{ redirect.to }} -j REDIRECT --to-ports {{ redirect.from }} -{% endfor %} -{% for openport in ppm_app.firewall_openport | default([]) %} -# Open port {{ openport.port }} ({{ openport.proto | default('tcp') }}) -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 %} - -{% endfor %} From bb5ee5085f7f8724b74b3cd50ba274e009b71475 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 14 Jul 2025 18:35:42 +0200 Subject: [PATCH 6/6] add new zabbix template so we can automatically add new checks --- roles/ppm/files/ppmzabbixagent | 12 ++++++++++++ roles/ppm/handlers/main.yml | 5 +++++ roles/ppm/tasks/main.yml | 3 +++ roles/ppm/tasks/zabbix.yml | 13 +++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 roles/ppm/files/ppmzabbixagent create mode 100644 roles/ppm/tasks/zabbix.yml diff --git a/roles/ppm/files/ppmzabbixagent b/roles/ppm/files/ppmzabbixagent new file mode 100644 index 0000000..7f23a5d --- /dev/null +++ b/roles/ppm/files/ppmzabbixagent @@ -0,0 +1,12 @@ +# Zabbix agent config for ppm + +{%- set ns = namespace() -%} +{%- set ns.allchecks = [] -%} +{%- for app in otherapps -%} +{%- if "monitoring" in otherapps[app]["imports"] -%} +{%- for check in otherapps[app]["imports"]["monitoring"]["checks"] %} +{%- set ns.allchecks = ns.allchecks + [check | combine({'app':app})] -%} +{% endfor -%}{%- endif -%}{%- endfor %} + +UserParameter=ppm.discover,/bin/echo '{{ ns.allchecks | tojson }}' +UserParameter=ppm.app[*],/bin/bash -c 'echo $2 | nc -U {{ statedir }}/$1.monitoring' \ No newline at end of file diff --git a/roles/ppm/handlers/main.yml b/roles/ppm/handlers/main.yml index f64b418..4fe15f5 100644 --- a/roles/ppm/handlers/main.yml +++ b/roles/ppm/handlers/main.yml @@ -1,3 +1,8 @@ - name: Restart firewall ansible.builtin.command: /etc/network/if-pre-up.d/firewall changed_when: true + +- name: Restart zabbix-agent2 + ansible.builtin.service: + name: zabbix-agent2 + state: restarted diff --git a/roles/ppm/tasks/main.yml b/roles/ppm/tasks/main.yml index d8bf828..8a52276 100644 --- a/roles/ppm/tasks/main.yml +++ b/roles/ppm/tasks/main.yml @@ -11,3 +11,6 @@ - name: Arrange firewall ansible.builtin.import_tasks: firewall.yml + +- name: Arrange zabbix + ansible.builtin.import_tasks: zabbix.yml diff --git a/roles/ppm/tasks/zabbix.yml b/roles/ppm/tasks/zabbix.yml new file mode 100644 index 0000000..ad254bd --- /dev/null +++ b/roles/ppm/tasks/zabbix.yml @@ -0,0 +1,13 @@ +- name: Configure firewall options + ansible.builtin.copy: + dest: /home/.zabbixagenttemplate + group: root + owner: root + mode: "0755" + src: ppmzabbixagent + +- name: Render zabbix template + ansible.builtin.command: ppm template /home/.zabbixagenttemplate /etc/zabbix/zabbix_agent2.d/ppm.conf + register: zabbix_render + changed_when: "'content did not change' not in zabbix_render.stdout" + notify: Restart zabbix-agent2