From 9c84e9518281a218a2a87970cc3ce071a3e93bb4 Mon Sep 17 00:00:00 2001 From: Mathieu Trossevin Date: Wed, 2 Mar 2022 16:21:39 +0100 Subject: [PATCH 01/79] Repair keepalived role --- CHANGELOG.md | 2 ++ keepalived/tasks/main.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 216de3dd..3abfcd21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Fixed +* Repair keepalived role + ### Removed ### Security diff --git a/keepalived/tasks/main.yml b/keepalived/tasks/main.yml index 807713a8..e468da58 100644 --- a/keepalived/tasks/main.yml +++ b/keepalived/tasks/main.yml @@ -28,7 +28,7 @@ owner: root group: root force: yes - tags: + tags: - keepalived - nrpe From d455de52b3bc31ebd578200f682521b5473cf52c Mon Sep 17 00:00:00 2001 From: Alexis Ben Miloud--Josselin Date: Thu, 3 Mar 2022 11:48:39 +0100 Subject: [PATCH 02/79] Check if /etc/libvirt/qemu/*xml exists before sync This will prevent sending e-mails saying the file does not exists. --- kvm-host/tasks/ssh.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml index 54f69652..dfd4eda2 100644 --- a/kvm-host/tasks/ssh.yml +++ b/kvm-host/tasks/ssh.yml @@ -33,7 +33,7 @@ state: present special_time: "hourly" user: root - job: "rsync -a --delete /etc/libvirt/qemu/*xml {{ hostvars[kvm_pair]['lan.ip'] }}:/root/libvirt-{{ inventory_hostname }}/" + job: "if ! ls /etc/libvirt/qemu/*xml > /dev/null 2> /dev/null; then rsync -a --delete /etc/libvirt/qemu/*xml {{ hostvars[kvm_pair]['lan.ip'] }}:/root/libvirt-{{ inventory_hostname }}/; fi" when: - kvm_pair is defined - kvm_pair is not none From 3ef6381ba628e745b391a5c98f28141433b38664 Mon Sep 17 00:00:00 2001 From: Alexis Ben Miloud--Josselin Date: Thu, 3 Mar 2022 11:52:03 +0100 Subject: [PATCH 03/79] Fix redis' README title --- redis/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis/README.md b/redis/README.md index 9b43635b..850af13a 100644 --- a/redis/README.md +++ b/redis/README.md @@ -1,4 +1,4 @@ -# munin +# Redis Installation and basic configuration of Redis. From 87a3fd48df8500e02b7dcd40beaf4eaffa3e3d59 Mon Sep 17 00:00:00 2001 From: Alexis Ben Miloud--Josselin Date: Thu, 3 Mar 2022 11:54:32 +0100 Subject: [PATCH 04/79] Fix commit d455de5 --- kvm-host/tasks/ssh.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml index dfd4eda2..3c097abc 100644 --- a/kvm-host/tasks/ssh.yml +++ b/kvm-host/tasks/ssh.yml @@ -33,7 +33,7 @@ state: present special_time: "hourly" user: root - job: "if ! ls /etc/libvirt/qemu/*xml > /dev/null 2> /dev/null; then rsync -a --delete /etc/libvirt/qemu/*xml {{ hostvars[kvm_pair]['lan.ip'] }}:/root/libvirt-{{ inventory_hostname }}/; fi" + job: "if ls /etc/libvirt/qemu/*xml > /dev/null 2> /dev/null; then rsync -a --delete /etc/libvirt/qemu/*xml {{ hostvars[kvm_pair]['lan.ip'] }}:/root/libvirt-{{ inventory_hostname }}/; fi" when: - kvm_pair is defined - kvm_pair is not none From b4f35af35cf37a17152216c566f63f56ac4163df Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 8 Mar 2022 16:48:41 +0100 Subject: [PATCH 05/79] backup-server-state: skip iptables if nft is installed --- evolinux-base/files/backup-server-state.sh | 57 ++++++++++++---------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 8e64c423..2858f7b1 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -426,37 +426,42 @@ backup_iptables() { debug "Backup iptables" iptables_bin=$(command -v iptables) + nft_bin=$(command -v nft) - if [ -n "${iptables_bin}" ]; then - last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } > "${backup_dir}/iptables.txt") - last_rc=$? - - if [ ${last_rc} -eq 0 ]; then - debug "* iptables OK" - else - debug "* iptables ERROR" - debug "${last_result}" - rc=10 - fi + if [ -n "${nft_bin}" ]; then + debug "* nft found, skip iptables" else - debug "* iptables not found" - fi + if [ -n "${iptables_bin}" ]; then + last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${backup_dir}/iptables.txt") + last_rc=$? - iptables_save_bin=$(command -v iptables-save) - - if [ -n "${iptables_save_bin}" ]; then - last_result=$(${iptables_save_bin} > "${backup_dir}/iptables-save.txt") - last_rc=$? - - if [ ${last_rc} -eq 0 ]; then - debug "* iptables-save OK" + if [ ${last_rc} -eq 0 ]; then + debug "* iptables OK" + else + debug "* iptables ERROR" + debug "${last_result}" + rc=10 + fi else - debug "* iptables-save ERROR" - debug "${last_result}" - rc=10 + debug "* iptables not found" + fi + + iptables_save_bin=$(command -v iptables-save) + + if [ -n "${iptables_save_bin}" ]; then + last_result=$(${iptables_save_bin} > "${backup_dir}/iptables-save.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* iptables-save OK" + else + debug "* iptables-save ERROR" + debug "${last_result}" + rc=10 + fi + else + debug "* iptables-save not found" fi - else - debug "* iptables-save not found" fi } From a733e2794f43a37748eceabb6764809d97f57c71 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 8 Mar 2022 16:49:53 +0100 Subject: [PATCH 06/79] evolinux-base: backup-server-state release 22.03 --- CHANGELOG.md | 2 ++ evolinux-base/files/backup-server-state.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3abfcd21..041e0d73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed +* evolinux-base: backup-server-state release 22.03 + ### Fixed * Repair keepalived role diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 2858f7b1..60af732d 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="backup-server-state" -VERSION="22.01.3" +VERSION="22.03" readonly VERSION backup_dir= From c880ce43a2d14085c8d6934ad0560da213aa5375 Mon Sep 17 00:00:00 2001 From: Brice Waegeneire Date: Thu, 10 Mar 2022 16:20:30 +0100 Subject: [PATCH 07/79] nagios-nrpe: Improve readability for check_mount_rw --- nagios-nrpe/files/plugins/check_mount_rw | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/nagios-nrpe/files/plugins/check_mount_rw b/nagios-nrpe/files/plugins/check_mount_rw index 06ffbd45..c26f8553 100755 --- a/nagios-nrpe/files/plugins/check_mount_rw +++ b/nagios-nrpe/files/plugins/check_mount_rw @@ -1,30 +1,40 @@ #!/bin/sh +# +# Verify that given mountpoints have 'read-write' option. -output=$(mktemp --tmpdir $(basename $0).XXXXXXXXXX) +output=$(mktemp --tmpdir $(basename "$0").XXXXXXXXXX) critical_count=0 ok_count=0 trap "rm -f $output" EXIT for mountpoint in $@; do + # We verify no mointpoints have 'read-only' option instead of checking + # for 'read-write' option, because there could be multiple device + # mounted on a sigle path. In that edge case only checking for the + # presence of the 'read-write' option would yeild a flase positive. if findmnt -O ro --noheadings "$mountpoint" 1>/dev/null 2>&1; then echo "CRITICAL - $mountpoint" >> "$output" - critical_count=$(( critical_count + 1)) + critical_count=$(( critical_count + 1)) else echo "OK - $mountpoint" >> "$output" - ok_count=$(( ok_count + 1)) + ok_count=$(( ok_count + 1)) fi done total_count=$(( ok_count + critical_count )) +plural='' +test "$total_count" -gt 1 && plural='s' + if [ $ok_count -eq $total_count ]; then - printf "OK - %d/%d no read-only mountpoint\n\n" "$ok_count" "$total_count" + printf "OK - %d/%d mountpoint%s have 'read-write' option\n\n" \ + "$ok_count" "$total_count" "$plural" cat "$output" exit 0 else - printf "CRITICAL - %d/%d read-only mountpoint\n\n" "$critical_count" "$total_count" + printf "CRITICAL - %d/%d mountpoint%s don't have 'read-write' option\n\n" \ + "$critical_count" "$total_count" "$plural" cat "$output" exit 2 fi - From ab1f3fd6d4f5f43acafc9841d7c2b148f39adfbd Mon Sep 17 00:00:00 2001 From: "William Hirigoyen (Evolix)" Date: Wed, 2 Mar 2022 09:51:59 +0100 Subject: [PATCH 08/79] Merge --- dovecot/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml index 49afb681..69771cb0 100644 --- a/dovecot/tasks/main.yml +++ b/dovecot/tasks/main.yml @@ -81,3 +81,4 @@ - include: munin.yml tags: - dovecot + From a565e8f8e853901ca3b69f7c302d0c982b2acb56 Mon Sep 17 00:00:00 2001 From: "William Hirigoyen (Evolix)" Date: Wed, 2 Mar 2022 11:07:14 +0100 Subject: [PATCH 09/79] Add Out of memory log2mail alert to dovecot role --- dovecot/handlers/main.yml | 6 ++++++ dovecot/tasks/main.yml | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/dovecot/handlers/main.yml b/dovecot/handlers/main.yml index 8d1b78d8..7d40488b 100644 --- a/dovecot/handlers/main.yml +++ b/dovecot/handlers/main.yml @@ -8,3 +8,9 @@ service: name: dovecot state: reloaded + +- name: restart log2mail + service: + name: log2mail + state: restarted + diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml index 69771cb0..c9de6045 100644 --- a/dovecot/tasks/main.yml +++ b/dovecot/tasks/main.yml @@ -82,3 +82,24 @@ tags: - dovecot +- name: log2mail is installed + apt: + name: log2mail + state: present + tags: dovecot + +- name: dovecot is configured in log2mail + blockinfile: + path: /etc/log2mail/config/mail.conf + create: true + owner: log2mail + group: adm + mode: "0640" + block: | + file = /var/log/mail.log + pattern = "Out of memory" + mailto = {{ log2mail_alert_email or general_alert_email | mandatory }} + template = /etc/log2mail/mail + notify: restart log2mail + tags: dovecot + From 4a31961ba0ea9b98401151a59539bec184b3d216 Mon Sep 17 00:00:00 2001 From: "William Hirigoyen (Evolix)" Date: Tue, 15 Mar 2022 10:04:13 +0100 Subject: [PATCH 10/79] =?UTF-8?q?Ajoute=20le=20d=C3=A9confinement=20d'AppA?= =?UTF-8?q?rmor=20dans=20la=20config=20par=20d=C3=A9faut=20des=20conteneur?= =?UTF-8?q?s=20LXC=20pour=20les=20version=20de=20Debian=20>=3D=209.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lxc/templates/default.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxc/templates/default.conf b/lxc/templates/default.conf index c4b38d42..a4f75d38 100644 --- a/lxc/templates/default.conf +++ b/lxc/templates/default.conf @@ -36,4 +36,6 @@ lxc.start.auto = 1 {% if ansible_distribution_major_version is version('9', '>') %} # Set LXC container unconfined in AppArmor lxc.apparmor.profile = unconfined +{% else %} +lxc.aa_profile = unconfined {% endif %} From 6df10be6eff6f7b118454ce4039b056fb4a9d21c Mon Sep 17 00:00:00 2001 From: Brice Waegeneire Date: Tue, 15 Mar 2022 10:20:43 +0100 Subject: [PATCH 11/79] evolinux-base: Fix top config. The wrong file was used as topdefaultrc. And we were using the wrong encoding, as top use ISO-8859 instead of UTF-8. --- evolinux-base/files/topdefaultrc | 24 ++++++++++++------------ evolinux-base/tasks/top.yml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/evolinux-base/files/topdefaultrc b/evolinux-base/files/topdefaultrc index b49be289..1faac8ba 100644 --- a/evolinux-base/files/topdefaultrc +++ b/evolinux-base/files/topdefaultrc @@ -1,15 +1,15 @@ top's Config File (Linux processes with windows) Id:j, Mode_altscr=0, Mode_irixps=1, Delay_time=3.0, Curwin=0 -Def fieldscur=Ä·&')*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz - winflags=193844, sortindx=18, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 - summclr=1, msgsclr=1, headclr=3, taskclr=1 -Job fieldscur=(Ä»@<)*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz - winflags=193844, sortindx=0, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 - summclr=6, msgsclr=6, headclr=7, taskclr=6 -Mem fieldscur=?@ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz - winflags=193844, sortindx=3, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 - summclr=3, msgsclr=3, headclr=2, taskclr=3 +Def fieldscur=¥¨³´»½À¼Ä·º¹Å&')*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz + winflags=177460, sortindx=18, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 + summclr=1, msgsclr=1, headclr=3, taskclr=1 +Job fieldscur=¥¦¹·º(³´Ä»½@<§Å)*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz + winflags=193844, sortindx=0, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 + summclr=6, msgsclr=6, headclr=7, taskclr=6 +Mem fieldscur=¥º»<½¾¿ÀÁMBNÃD34·Å&'()*+,-./0125689FGHIJKLOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz + winflags=193844, sortindx=21, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 + summclr=5, msgsclr=5, headclr=4, taskclr=5 +Usr fieldscur=¥¦§¨ª°¹·ºÄÅ)+,-./1234568;<=>?@ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz + winflags=193844, sortindx=3, maxtasks=0, graph_cpus=0, graph_mems=0, double_up=0, combine_cpus=0 + summclr=3, msgsclr=3, headclr=2, taskclr=3 Fixed_widest=0, Summ_mscale=1, Task_mscale=0, Zero_suppress=0 diff --git a/evolinux-base/tasks/top.yml b/evolinux-base/tasks/top.yml index 12eff20c..64fdf6b6 100644 --- a/evolinux-base/tasks/top.yml +++ b/evolinux-base/tasks/top.yml @@ -2,6 +2,6 @@ - name: Deploy top configuration file copy: # The config format is unredable; ATM it only add the SWAP column - src: htoprc + src: topdefaultrc dest: /etc/topdefaultrc mode: "0644" From 5a2dc5cbd1f6bfeb6972a53d90d07df67a5ebfce Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Thu, 10 Mar 2022 11:57:56 +0100 Subject: [PATCH 12/79] etc-git: Make it work on non-debian systems --- etc-git/tasks/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index 11be1899..34c4a1ca 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -6,6 +6,8 @@ state: present tags: - etc-git + when: + - ansible_distribution == "Debian" - include_role: name: evolix/remount-usr From 0e768809b7cdf5df45b9c985a81168ece1e8ac14 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Thu, 10 Mar 2022 11:58:35 +0100 Subject: [PATCH 13/79] evomaintenance: Make it work on non-debian systems --- evomaintenance/tasks/install_vendor_other.yml | 31 +++++++++++++++++++ evomaintenance/tasks/main.yml | 6 ++++ 2 files changed, 37 insertions(+) create mode 100644 evomaintenance/tasks/install_vendor_other.yml diff --git a/evomaintenance/tasks/install_vendor_other.yml b/evomaintenance/tasks/install_vendor_other.yml new file mode 100644 index 00000000..a28eeab3 --- /dev/null +++ b/evomaintenance/tasks/install_vendor_other.yml @@ -0,0 +1,31 @@ +--- + +- include_role: + name: evolix/remount-usr + tags: + - evomaintenance + +- name: /usr/share/scripts exists + file: + dest: /usr/share/scripts + mode: "0700" + owner: root + group: root + state: directory + tags: + - evomaintenance + +- name: Evomaintenance script and template are installed + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + force: yes + backup: yes + loop: + - { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' } + - { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' } + tags: + - evomaintenance \ No newline at end of file diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml index 0a4e5010..1f4a6f55 100644 --- a/evomaintenance/tasks/main.yml +++ b/evomaintenance/tasks/main.yml @@ -10,6 +10,12 @@ - evomaintenance_install_vendor | bool - ansible_distribution == "Debian" +- include: install_vendor_other.yml + when: + - evomaintenance_install_vendor | bool + - ansible_distribution != "Debian" + + - include: config.yml - include: minifirewall.yml From 913e6d96e870c1a8a63e36a460b01a882930b9fe Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 15 Mar 2022 10:53:06 +0100 Subject: [PATCH 14/79] generate-ldif: Add services check for bkctld --- CHANGELOG.md | 1 + generate-ldif/templates/generateldif.sh.j2 | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 041e0d73..fc7b013d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evolinux-base: backup-server-state release 22.03 +* generate-ldif: Add services check for bkctld ### Fixed diff --git a/generate-ldif/templates/generateldif.sh.j2 b/generate-ldif/templates/generateldif.sh.j2 index 3b2a6fd2..cfae731c 100755 --- a/generate-ldif/templates/generateldif.sh.j2 +++ b/generate-ldif/templates/generateldif.sh.j2 @@ -709,6 +709,37 @@ EOT fi +# bkctld +if is_pkg_installed bkctld; then + bkctld_version=$(get_pkg_version bkctld) +fi +if [ -n "${bkctld_version}" ]; then + cat <> "${ldif_file}" + +dn: ServiceName=bkctld_jails,${computer_dn} +NagiosEnabled: TRUE +objectClass: EvoService +ServiceName: bkctld_jails +ServiceType: backup +ServiceVersion: bkctld ${bkctld_version} + +dn: ServiceName=bkctld_setup,${computer_dn} +NagiosEnabled: TRUE +objectClass: EvoService +ServiceName: bkctld_setup +ServiceType: backup +ServiceVersion: bkctld ${bkctld_version} + +dn: ServiceName=disk-worktime,${computer_dn} +NagiosEnabled: TRUE +objectClass: EvoService +ServiceName: disk-worktime +ServiceType: disk +ServiceVersion: Undefined +EOT +fi + + # test if we have a stdout if [ -t 1 ]; then echo "Output is in ${ldif_file}" From 17f884b04ab1b3c2d092b7ac4a641c89dffb9255 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 15 Mar 2022 11:35:20 +0100 Subject: [PATCH 15/79] evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware --- CHANGELOG.md | 1 + evolinux-base/tasks/hardware.yml | 5 ++++- evolinux-base/tasks/main.yml | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc7b013d..fac22e94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evolinux-base: backup-server-state release 22.03 +* evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld ### Fixed diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index ab838284..2e68cc36 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -32,11 +32,14 @@ ## Dedicated hardware -- name: Install freepmi when it's dedicated hardware +- name: Install some additionnals tools when it dedicated hardware apt: name: - libipc-run-perl - freeipmi + - ipmitool + - firmware-linux-nonfree + - intel-microcode state: present tags: - packages diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index 5a0532a3..dba5e97b 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -14,6 +14,7 @@ apt_install_basics: "{{ evolinux_apt_replace_default_sources }}" apt_install_evolix_public: "{{ evolinux_apt_public_sources }}" apt_upgrade: "{{ evolinux_apt_upgrade }}" + apt_basics_components: "{{ 'main contrib non-free' if ansible_virtualization_role == 'host' else 'main' }}" when: evolinux_apt_include | bool - name: /etc versioning with Git From ba90203f219b96093f2b748a0deefe7cf8ae1a16 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 23:07:33 +0100 Subject: [PATCH 16/79] minifirewall: upstream release 22.03.1 and use includes directory --- CHANGELOG.md | 1 + minifirewall/defaults/main.yml | 12 +- minifirewall/files/minifirewall | 845 +++++++++++++++++++++++++ minifirewall/files/minifirewall.conf | 106 ++-- minifirewall/tasks/config.yml | 65 +- minifirewall/tasks/install.yml | 14 +- minifirewall/tasks/main.yml | 6 + minifirewall/tasks/tail.yml | 14 +- minifirewall/templates/minifirewall.j2 | 492 -------------- 9 files changed, 971 insertions(+), 584 deletions(-) create mode 100755 minifirewall/files/minifirewall delete mode 100755 minifirewall/templates/minifirewall.j2 diff --git a/CHANGELOG.md b/CHANGELOG.md index fac22e94..96cb6838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: backup-server-state release 22.03 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld +* minifirewall: upstream release 22.03.1 and use includes directory ### Fixed diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml index fd4e726b..51d169cb 100644 --- a/minifirewall/defaults/main.yml +++ b/minifirewall/defaults/main.yml @@ -1,13 +1,19 @@ --- -minifirewall_main_file: /etc/default/minifirewall -minifirewall_tail_file: /etc/default/minifirewall.tail +# Deprecated variable +# minifirewall_main_file: /etc/default/minifirewall + +minifirewall_tail_file: zzz-tail minifirewall_tail_included: False minifirewall_tail_force: True +# Overwrite files completely minifirewall_force_upgrade_script: False minifirewall_force_upgrade_config: False +# Update specific values in configuration +minifirewall_update_config: True + minifirewall_git_url: "https://forge.evolix.org/minifirewall.git" minifirewall_checkout_path: "/tmp/minifirewall" minifirewall_int: "{{ ansible_default_ipv4.interface }}" @@ -31,7 +37,7 @@ minifirewall_private_ports_tcp: [5666] minifirewall_private_ports_udp: [] # Keep a null value to leave the setting as is -# otherwise use an Array, eg. "minifirewall_ssh_ok: ['0.0.0.0/0']" +# otherwise use an Array, eg. "minifirewall_ssh_ok: ['0.0.0.0/0', '::/0']" minifirewall_dns_servers: Null minifirewall_http_sites: Null minifirewall_https_sites: Null diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall new file mode 100755 index 00000000..b1595471 --- /dev/null +++ b/minifirewall/files/minifirewall @@ -0,0 +1,845 @@ +#!/bin/sh + +# minifirewall is shellscripts for easy firewalling on a standalone server +# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel +# See https://gitea.evolix.org/evolix/minifirewall + +# Copyright (c) 2007-2022 Evolix +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License. + +# Description +# script for standalone server + +# Start or stop minifirewall +# + +### BEGIN INIT INFO +# Provides: minifirewall +# Required-Start: +# Required-Stop: +# Should-Start: $network $syslog $named +# Should-Stop: $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the firewall +# Description: Firewall designed for standalone server +### END INIT INFO + +VERSION="22.03.1" + +NAME="minifirewall" +DESC="Firewall designed for standalone server" + +set -u + +# Variables configuration +######################### + +config_file="/etc/default/minifirewall" +includes_dir="/etc/minifirewall.d" + +# iptables paths +IPT=$(command -v iptables) +if [ -z "${IPT}" ]; then + echo "Unable to find 'iptables\` command in PATH." >&2 + exit 1 +fi +IPT6=$(command -v ip6tables) +if [ -z "${IPT6}" ]; then + echo "Unable to find 'ip6tables\` command in PATH." >&2 + exit 1 +fi + +# TCP/IP variables +LOOPBACK='127.0.0.0/8' +CLASSA='10.0.0.0/8' +CLASSB='172.16.0.0/12' +CLASSC='192.168.0.0/16' +CLASSD='224.0.0.0/4' +CLASSE='240.0.0.0/5' +ALL='0.0.0.0' +BROAD='255.255.255.255' +PORTSROOT='0:1023' +PORTSUSER='1024:65535' + +# Configuration + +INT='' +IPV6='' +DOCKER='' +INTLAN='' +TRUSTEDIPS='' +PRIVILEGIEDIPS='' +SERVICESTCP1p='' +SERVICESUDP1p='' +SERVICESTCP1='' +SERVICESUDP1='' +SERVICESTCP2='' +SERVICESUDP2='' +SERVICESTCP3='' +SERVICESUDP3='' +DNSSERVEURS='' +HTTPSITES='' +HTTPSSITES='' +FTPSITES='' +SSHOK='' +SMTPOK='' +SMTPSECUREOK='' +NTPOK='' +PROXY='' +PROXYBYPASS='' +PROXYPORT='' +BACKUPSERVERS='' + +LEGACY_CONFIG='off' + +is_ipv6_enabled() { + test "${IPV6}" != "off" +} +is_docker_enabled() { + test "${DOCKER}" = "on" +} +is_proxy_enabled() { + test "${PROXY}" = "on" +} +is_ipv6() { + echo "$1" | grep -q ':' +} +is_legacy_config() { + test "${LEGACY_CONFIG}" != "off" +} +chain_exists() { + chain_name="$1" + if [ $# -ge 2 ]; then + intable="--table $2" + fi + # shellcheck disable=SC2086 + iptables ${intable} -nL "${chain_name}" >/dev/null 2>&1 +} +source_file_or_error() { + file=$1 + echo "...sourcing '${file}\`" + + tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) + . "${file}" 2>"${tmpfile}" >&2 + + if [ -s "${tmpfile}" ]; then + echo "${file} returns standard or error output (see below). Stopping." >&2 + cat "${tmpfile}" + exit 1 + fi + rm "${tmpfile}" +} +source_configuration() { + if ! test -f ${config_file}; then + echo "${config_file} does not exist" >&2 + + ## We still want to deal with this really old configuration file + ## even if it has been deprecated since Debian 8 + old_config_file="/etc/firewall.rc" + if test -f ${old_config_file}; then + echo "${old_config_file} is deprecated. Rename it to ${config_file}" >&2 + fi + + exit 1 + fi + + if grep -e "iptables" -e "ip6tables" "${config_file}" | grep -qvE "^#"; then + # Backward compatible mode + ########################### + + echo "Legacy config detected" + LEGACY_CONFIG='on' + + # Non-backward compatible mode + ############################### + + # If we ever want to remove the backward compatible mode + # we can remove the two lines above and uncomment the lines below. + # They break if any iptables/ip6tables command is found in the configuration file + + # echo "iptables/ip6tables commands found in ${config_file}." >&2 + # echo "Move them in included files (in ${includes_dir})." >&2 + # exit 1 + fi + + if is_legacy_config; then + # In this mode, we extract all variable definitions + # to a temporary file that we can source. + # It allow iptables/ip6tables commands to remain in the configuration file + # and not interfere with the configuration step. + + tmp_config_file=$(mktemp --tmpdir=/tmp minifirewall.XXX) + grep -E "^\s*[_a-zA-Z0-9]+=" "${config_file}" > "${tmp_config_file}" + + source_file_or_error "${tmp_config_file}" + rm "${tmp_config_file}" + else + source_file_or_error "${config_file}" + fi +} +source_includes() { + if [ -d "${includes_dir}" ]; then + include_files=$(find ${includes_dir} -type f -readable -not -name '*.*' | sort -h) + for include_file in ${include_files}; do + source_file_or_error "${include_file}" + done + fi +} + +start() { + echo "Start IPTables rules..." + + # Stop and warn if error! + set -e + trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + + # sysctl network security settings + ################################## + + # Set 1 to ignore broadcast pings (default) + : "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS:=1}" + # Set 1 to ignore bogus ICMP responses (default) + : "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES:=1}" + # Set 0 to disable source routing (default) + : "${SYSCTL_ACCEPT_SOURCE_ROUTE:=0}" + # Set 1 to enable TCP SYN cookies (default) + # cf http://cr.yp.to/syncookies.html + : "${SYSCTL_TCP_SYNCOOKIES:=1}" + # Set 0 to disable ICMP redirects (default) + : "${SYSCTL_ICMP_REDIRECTS:=0}" + # Set 1 to enable Reverse Path filtering (default) + # Set 0 if VRRP is used + : "${SYSCTL_RP_FILTER:=1}" + # Set 1 to log packets with inconsistent address (default) + : "${SYSCTL_LOG_MARTIANS:=1}" + + if [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "1" ] || [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "0" ]; then + echo "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + else + echo "Invalid SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS value '${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "1" ] || [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "0" ]; then + echo "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + else + echo "Invalid SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES value '${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "1" ] || [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do + echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_ACCEPT_SOURCE_ROUTE value '${SYSCTL_ACCEPT_SOURCE_ROUTE}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_TCP_SYNCOOKIES}" = "1" ] || [ "${SYSCTL_TCP_SYNCOOKIES}" = "0" ]; then + echo "${SYSCTL_TCP_SYNCOOKIES}" > /proc/sys/net/ipv4/tcp_syncookies + else + echo "Invalid SYSCTL_TCP_SYNCOOKIES value '${SYSCTL_TCP_SYNCOOKIES}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_ICMP_REDIRECTS}" = "1" ] || [ "${SYSCTL_ICMP_REDIRECTS}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_redirects; do + echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}" + done + for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do + echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_ICMP_REDIRECTS value '${SYSCTL_ICMP_REDIRECTS}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_RP_FILTER}" = "1" ] || [ "${SYSCTL_RP_FILTER}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do + echo "${SYSCTL_RP_FILTER}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_RP_FILTER value '${SYSCTL_RP_FILTER}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_LOG_MARTIANS}" = "1" ] || [ "${SYSCTL_LOG_MARTIANS}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do + echo "${SYSCTL_LOG_MARTIANS}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_LOG_MARTIANS value '${SYSCTL_LOG_MARTIANS}', must be '0' or '1'." >&2 + exit 1 + fi + + # IPTables configuration + ######################## + + ${IPT} -N LOG_DROP + ${IPT} -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' + ${IPT} -A LOG_DROP -j DROP + ${IPT} -N LOG_ACCEPT + ${IPT} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' + ${IPT} -A LOG_ACCEPT -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -N LOG_DROP + ${IPT6} -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' + ${IPT6} -A LOG_DROP -j DROP + ${IPT6} -N LOG_ACCEPT + ${IPT6} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' + ${IPT6} -A LOG_ACCEPT -j ACCEPT + fi + + # Trusted ip addresses + ${IPT} -N ONLYTRUSTED + ${IPT} -A ONLYTRUSTED -j LOG_DROP + if is_ipv6_enabled; then + ${IPT6} -N ONLYTRUSTED + ${IPT6} -A ONLYTRUSTED -j LOG_DROP + fi + for ip in ${TRUSTEDIPS}; do + if is_ipv6 ${ip}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi + done + + # Privilegied ip addresses + # (trusted ip addresses *are* privilegied) + ${IPT} -N ONLYPRIVILEGIED + ${IPT} -A ONLYPRIVILEGIED -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -N ONLYPRIVILEGIED + ${IPT6} -A ONLYPRIVILEGIED -j ONLYTRUSTED + fi + for ip in ${PRIVILEGIEDIPS}; do + if is_ipv6 ${ip}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi + done + + # Chain for restrictions (blacklist IPs/ranges) + ${IPT} -N NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -N NEEDRESTRICT + fi + + # We allow all on loopback interface + ${IPT} -A INPUT -i lo -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -i lo -j ACCEPT + fi + # if OUTPUTDROP + ${IPT} -A OUTPUT -o lo -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -o lo -j ACCEPT + fi + + # We avoid "martians" packets, typical when W32/Blaster virus + # attacked windowsupdate.com and DNS was changed to 127.0.0.1 + # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP + for IP in ${LOOPBACK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -s ${IP} ! -i lo -j DROP + fi + else + ${IPT} -A INPUT -s ${IP} ! -i lo -j DROP + fi + done + + if is_docker_enabled; then + # WARN: IPv6 not yet supported for Docker rules + ${IPT} -N MINIFW-DOCKER-TRUSTED + ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP + + ${IPT} -N MINIFW-DOCKER-PRIVILEGED + ${IPT} -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED + ${IPT} -A MINIFW-DOCKER-PRIVILEGED -j RETURN + + ${IPT} -N MINIFW-DOCKER-PUB + ${IPT} -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED + ${IPT} -A MINIFW-DOCKER-PUB -j RETURN + + # Flush DOCKER-USER if exist, create it if absent + if chain_exists 'DOCKER-USER'; then + ${IPT} -F DOCKER-USER + else + ${IPT} -N DOCKER-USER + fi; + + # Pipe new connection through MINIFW-DOCKER-PUB + ${IPT} -A DOCKER-USER -i ${INT} -m state --state NEW -j MINIFW-DOCKER-PUB + ${IPT} -A DOCKER-USER -j RETURN + fi + + + # Local services restrictions + ############################# + + # Allow services for ${INTLAN} (local server or local network) + for IP in ${INTLAN}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -s ${IP} -j ACCEPT + fi + done + + # Enable protection chain for sensible services + for port in ${SERVICESTCP1p}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT + fi + done + + for port in ${SERVICESUDP1p}; do + ${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT + fi + done + + # Public service + for port in ${SERVICESTCP1}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT + fi + done + + for port in ${SERVICESUDP1}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT + fi + done + + # Privilegied services + for port in ${SERVICESTCP2}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED + fi + done + + for port in ${SERVICESUDP2}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED + fi + done + + # Private services + for port in ${SERVICESTCP3}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED + fi + done + + for port in ${SERVICESUDP3}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED + fi + done + + + if is_docker_enabled; then + # WARN: IPv6 not yet supported + + # Public services defined in SERVICESTCP1 & SERVICESUDP1 + for dstport in ${SERVICESTCP1}; do + ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN + done + + for dstport in ${SERVICESUDP1}; do + ${IPT} -I MINIFW-DOCKER-PUB -p udp --dport "${dstport}" -j RETURN + done + + # Privileged services (accessible from privileged & trusted IPs) + for dstport in ${SERVICESTCP2}; do + for srcip in ${PRIVILEGIEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + done + + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + done + done + + for dstport in ${SERVICESUDP2}; do + for srcip in ${PRIVILEGIEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + done + + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + done + done + + # Trusted services (accessible from trusted IPs) + for dstport in ${SERVICESTCP3}; do + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + done + done + + for dstport in ${SERVICESUDP3}; do + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + done + done + fi + + # External services + ################### + + # DNS authorizations + for IP in ${DNSSERVEURS}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT + fi + done + + # HTTP (TCP/80) authorizations + for IP in ${HTTPSITES}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # HTTPS (TCP/443) authorizations + for IP in ${HTTPSSITES}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # FTP (so complex protocol...) authorizations + for IP in ${FTPSITES}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + # requests on Control connection + ${IPT6} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + # FTP port-mode on Data Connection + ${IPT6} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + ${IPT6} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + # requests on Control connection + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + # FTP port-mode on Data Connection + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # SSH authorizations + for IP in ${SSHOK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # SMTP authorizations + for IP in ${SMTPOK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # secure SMTP (TCP/465 et TCP/587) authorizations + for IP in ${SMTPSECUREOK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # NTP authorizations + for IP in ${NTPOK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --sport 123 -s ${IP} -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 123 --match state --state NEW -j ACCEPT + fi + else + ${IPT} -A INPUT -p udp --sport 123 -s ${IP} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 123 --match state --state NEW -j ACCEPT + fi + done + + # Proxy (Squid) + if is_proxy_enabled; then + # WARN: Squid only listen on IPv4 yet + # TODO: verify that the pattern used for IPv4 is relevant with IPv6 + + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT + for dstip in ${PROXYBYPASS}; do + if ! is_ipv6 ${dstip}; then + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT + fi + done + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port "${PROXYPORT:-'8888'}" + fi + + # Output for backup servers + for server in ${BACKUPSERVERS}; do + server_port=$(echo "${server}" | awk -F : '{print $(NF)}') + server_ip=$(echo "${server}" | sed -e "s/:${server_port}$//") + + if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then + if is_ipv6 ${server_ip}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + else + echo "Unrecognized syntax for BACKUPSERVERS '${server}\`. Use space-separated IP:PORT tuples." >&2 + exit 1 + fi + done + + # Always allow ICMP + ${IPT} -A INPUT -p icmp -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p icmpv6 -j ACCEPT + fi + + + # IPTables policy + ################# + + # by default DROP INPUT packets + ${IPT} -P INPUT DROP + if is_ipv6_enabled; then + ${IPT6} -P INPUT DROP + fi + + # by default, no FORWARDING (deprecated for Virtual Machines) + #echo 0 > /proc/sys/net/ipv4/ip_forward + #${IPT} -P FORWARD DROP + #${IPT6} -P FORWARD DROP + + # by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) + ${IPT} -P OUTPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P OUTPUT ACCEPT + fi + + ${IPT} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + fi + + ${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + fi + + ${IPT} -A OUTPUT -p udp -j DROP + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -p udp -j DROP + fi + + if is_legacy_config; then + source_file_or_error "${config_file}" + fi + + # Source files present in optional directory + source_includes + + trap - INT TERM EXIT + + echo "...starting IPTables rules is now finish : OK" +} + +stop() { + echo "Flush all rules and accept everything..." + + # Delete all rules + ${IPT} -F INPUT + if is_ipv6_enabled; then + ${IPT6} -F INPUT + fi + + ${IPT} -F OUTPUT + if is_ipv6_enabled; then + ${IPT6} -F OUTPUT + fi + + ${IPT} -F LOG_DROP + ${IPT} -F LOG_ACCEPT + ${IPT} -F ONLYTRUSTED + ${IPT} -F ONLYPRIVILEGIED + ${IPT} -F NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -F LOG_DROP + ${IPT6} -F LOG_ACCEPT + ${IPT6} -F ONLYTRUSTED + ${IPT6} -F ONLYPRIVILEGIED + ${IPT6} -F NEEDRESTRICT + fi + + ${IPT} -t mangle -F + if is_ipv6_enabled; then + ${IPT6} -t mangle -F + fi + + if is_docker_enabled; then + # WARN: IPv6 not yet supported + + ${IPT} -F DOCKER-USER + ${IPT} -A DOCKER-USER -j RETURN + + ${IPT} -F MINIFW-DOCKER-PUB + ${IPT} -X MINIFW-DOCKER-PUB + ${IPT} -F MINIFW-DOCKER-PRIVILEGED + ${IPT} -X MINIFW-DOCKER-PRIVILEGED + ${IPT} -F MINIFW-DOCKER-TRUSTED + ${IPT} -X MINIFW-DOCKER-TRUSTED + else + ${IPT} -t nat -F + fi + + # Accept all + ${IPT} -P INPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P INPUT ACCEPT + fi + + ${IPT} -P OUTPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P OUTPUT ACCEPT + fi + #${IPT} -P FORWARD ACCEPT + #${IPT} -t nat -P PREROUTING ACCEPT + #${IPT} -t nat -P POSTROUTING ACCEPT + + # Delete non-standard chains + ${IPT} -X LOG_DROP + ${IPT} -X LOG_ACCEPT + ${IPT} -X ONLYPRIVILEGIED + ${IPT} -X ONLYTRUSTED + ${IPT} -X NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -X LOG_DROP + ${IPT6} -X LOG_ACCEPT + ${IPT6} -X ONLYPRIVILEGIED + ${IPT6} -X ONLYTRUSTED + ${IPT6} -X NEEDRESTRICT + fi + + echo "...flushing IPTables rules is now finish : OK" +} + +status() { + ${IPT} -L -n -v --line-numbers + ${IPT} -t nat -L -n -v --line-numbers + ${IPT} -t mangle -L -n -v --line-numbers + ${IPT6} -L -n -v --line-numbers + ${IPT6} -t mangle -L -n -v --line-numbers +} + +reset() { + echo "Reset all IPTables counters..." + + ${IPT} -Z + if is_ipv6_enabled; then + ${IPT6} -Z + fi + + ${IPT} -t nat -Z + + ${IPT} -t mangle -Z + if is_ipv6_enabled; then + ${IPT6} -t mangle -Z + fi + + echo "...reseting IPTables counters is now finish : OK" +} + +echo "${NAME} version ${VERSION}" +source_configuration + +case "${1:-''}" in + start) + start + ;; + + stop) + stop + ;; + + status) + status + ;; + + reset) + reset + ;; + + restart) + stop + start + ;; + + *) + echo "Usage: $0 {start|stop|restart|status|reset}" + exit 1 + ;; +esac + +exit 0 diff --git a/minifirewall/files/minifirewall.conf b/minifirewall/files/minifirewall.conf index 47be78bf..1cd73d7f 100644 --- a/minifirewall/files/minifirewall.conf +++ b/minifirewall/files/minifirewall.conf @@ -1,31 +1,37 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall -# Version 20.12 — 2020-12-01 22:55:35 +# Version 22.03.1 — 2022-03-15 +# shellcheck shell=sh disable=SC2034 # Main interface INT='eth0' # IPv6 -IPV6=on +IPV6='on' # Docker Mode # Changes the behaviour of minifirewall to not break the containers' network # For instance, turning it on will disable nat table purge -# Also, we'll add the DOCKER-USER chain, in iptable +# Also, we'll add the DOCKER-USER chain, in iptables +# +# WARNING : If the port mapping is different between the host and the container +# (ie: Listen on :8090 on host, but :8080 in container) +# then you need to give the port used inside the container DOCKER='off' -# Trusted IPv4 local network -# ...will be often IP/32 if you don't trust anything -INTLAN='192.168.0.2/32' +# Trusted local network +# ...will be often IPv4/32 or IPv6/128 if you don't trust anything +INTLAN='192.0.2.1/32 2001:db8::1/128' -# Trusted IPv4 addresses for private and semi-public services -TRUSTEDIPS='31.170.9.129 62.212.121.90 31.170.8.4 82.65.34.85 54.37.106.210 51.210.84.146' +# Trusted IP addresses for private and semi-public services +# TODO: add all our IPv6 adresses +TRUSTEDIPS='31.170.9.129 2a01:9500:37:129::/64 62.212.121.90 31.170.8.4 2a01:9500::fada/128 82.65.34.85 54.37.106.210 51.210.84.146' -# Privilegied IPv4 addresses for semi-public services +# Privilegied IP addresses for semi-public services # (no need to add again TRUSTEDIPS) PRIVILEGIEDIPS='' -# Local services IPv4/IPv6 restrictions +# Local services IP restrictions ####################################### # Protected services @@ -45,62 +51,86 @@ SERVICESUDP2='' SERVICESTCP3='5666' SERVICESUDP3='' -# Standard output IPv4 access restrictions + +# Standard output IPv4/IPv6 access restrictions ########################################## # DNS authorizations # (if you have local DNS server, set 0.0.0.0/0) -DNSSERVEURS='0.0.0.0/0' +DNSSERVEURS='0.0.0.0/0 ::/0' # HTTP authorizations # (you can use DNS names but set cron to reload minifirewall regularly) # (if you have HTTP proxy, set 0.0.0.0/0) -# HTTPSITES='security.debian.org pub.evolix.net security-cdn.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org ocsp.int-x3.letsencrypt.org' -HTTPSITES='0.0.0.0/0' +HTTPSITES='0.0.0.0/0 ::/0' # HTTPS authorizations -HTTPSSITES='0.0.0.0/0' +HTTPSSITES='0.0.0.0/0 ::/0' # FTP authorizations FTPSITES='' # SSH authorizations -SSHOK='0.0.0.0/0' +SSHOK='0.0.0.0/0 ::/0' # SMTP authorizations -SMTPOK='0.0.0.0/0' +SMTPOK='0.0.0.0/0 ::/0' # SMTP secure authorizations (ports TCP/465 and TCP/587) SMTPSECUREOK='' # NTP authorizations -NTPOK='0.0.0.0/0' +NTPOK='0.0.0.0/0 ::/0' + +# Proxy (Squid) +PROXY='off' +# (proxy port) +PROXYPORT='8888' +# (destinations that bypass the proxy) +PROXYBYPASS="${INTLAN} 127.0.0.0/8 ::1/128" + +# Backup servers +# (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') +BACKUPSERVERS='' -# IPv6 Specific rules +# Includes ##################### -# Example: allow SSH from Trusted IPv6 addresses -/sbin/ip6tables -A INPUT -i $INT -p tcp --dport 22 -s 2a01:9500:37:129::/64 -j ACCEPT +# Files in /etc/minifirewall.d/* (without "." in name) +# are automatically included in alphanumerical order. +# +# Within included files, you can use those helper functions : +# * is_ipv6_enabled: returns true if IPv6 is enabled, or false +# * is_docker_enabled: returns true if Docker mode is eabled, or false +# * is_proxy_enabled: returns true if Proxy mode is enabled , or false -# Example: allow outgoing SSH/HTTP/HTTPS/SMTP/DNS traffic -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 22 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT -# Example: allow output DNS, NTP and traceroute traffic -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT -#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +# Custom sysctl values (advanced) +################################# -# Example: allow DHCPv6 -/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT +# In most cases, the default values set by minifirewall are good. +# If you really know what you are doing, +# you can uncomment some lines and customize the values. -# IPv4 Specific rules -##################### +# Set 1 to ignore broadcast pings (default) +# SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS='1' -# /sbin/iptables ... +# Set 1 to ignore bogus ICMP responses (default) +# SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES='1' + +# Set 0 to disable source routing (default) +# SYSCTL_ACCEPT_SOURCE_ROUTE='0' + +# Set 1 to enable TCP SYN cookies (default) +# SYSCTL_TCP_SYNCOOKIES='1' + +# Set 0 to disable ICMP redirects (default) +# SYSCTL_ICMP_REDIRECTS='0' + +# Set 1 to enable Reverse Path filtering (default) +# Set 0 if VRRP is used +# SYSCTL_RP_FILTER='1' + +# Set 1 to log packets with inconsistent address (default) +# SYSCTL_LOG_MARTIANS='1' \ No newline at end of file diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 04ed3a9c..c0afd2b1 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -9,11 +9,12 @@ - name: Stat minifirewall config file (before) stat: - path: "{{ minifirewall_main_file }}" + path: "/etc/default/minifirewall" register: minifirewall_before - name: Check if minifirewall is running - shell: /sbin/iptables -L -n | grep -E "^(DROP\s+udp|ACCEPT\s+icmp)\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$" + shell: + cmd: /sbin/iptables -L -n | grep -E "^(DROP\s+udp|ACCEPT\s+icmp)\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$" changed_when: False failed_when: False check_mode: no @@ -25,14 +26,14 @@ - name: Begin marker for IP addresses lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "# BEGIN ANSIBLE MANAGED BLOCK FOR IPS" insertbefore: '^# Main interface' create: no - name: End marker for IP addresses lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" create: no line: "# END ANSIBLE MANAGED BLOCK FOR IPS" insertafter: '^PRIVILEGIEDIPS=' @@ -43,12 +44,16 @@ msg: You must provide at least 1 trusted IP - debug: - msg: "Warning: minifirewall_trusted_ips='0.0.0.0/0', the firewall is useless!" - when: minifirewall_trusted_ips == ["0.0.0.0/0"] + msg: "Warning: minifirewall_trusted_ips contains '0.0.0.0/0', the firewall is useless on IPv4!" + when: "'0.0.0.0/0' in minifirewall_trusted_ips" + +- debug: + msg: "Warning: minifirewall_trusted_ips contains '::/0', the firewall is useless on IPv6!" + when: "'::/0' in minifirewall_trusted_ips" - name: Configure IP addresses blockinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" marker: "# {mark} ANSIBLE MANAGED BLOCK FOR IPS" block: | # Main interface @@ -60,8 +65,12 @@ # Docker Mode # Changes the behaviour of minifirewall to not break the containers' network # For instance, turning it on will disable nat table purge - # Also, we'll add the DOCKER-USER chain, in iptable - DOCKER='{{ minifirewall_docker }}' + # Also, we'll add the DOCKER-USER chain, in iptables + # + # WARNING : If the port mapping is different between the host and the container + # (ie: Listen on :8090 on host, but :8080 in container) + # then you need to give the port used inside the container + DOCKER='off' # Trusted IPv4 local network # ...will be often IP/32 if you don't trust anything @@ -78,21 +87,21 @@ - name: Begin marker for ports lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "# BEGIN ANSIBLE MANAGED BLOCK FOR PORTS" insertbefore: '^# Protected services' create: no - name: End marker for ports lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "# END ANSIBLE MANAGED BLOCK FOR PORTS" insertafter: '^SERVICESUDP3=' create: no - name: Configure ports blockinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" marker: "# {mark} ANSIBLE MANAGED BLOCK FOR PORTS" block: | # Protected services @@ -116,7 +125,7 @@ - name: Configure DNSSERVEURS lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "DNSSERVEURS='{{ minifirewall_dns_servers | join(' ') }}'" regexp: "DNSSERVEURS='.*'" create: no @@ -124,7 +133,7 @@ - name: Configure HTTPSITES lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "HTTPSITES='{{ minifirewall_http_sites | join(' ') }}'" regexp: "HTTPSITES='.*'" create: no @@ -132,7 +141,7 @@ - name: Configure HTTPSSITES lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "HTTPSSITES='{{ minifirewall_https_sites | join(' ') }}'" regexp: "HTTPSSITES='.*'" create: no @@ -140,7 +149,7 @@ - name: Configure FTPSITES lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "FTPSITES='{{ minifirewall_ftp_sites | join(' ') }}'" regexp: "FTPSITES='.*'" create: no @@ -148,7 +157,7 @@ - name: Configure SSHOK lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "SSHOK='{{ minifirewall_ssh_ok | join(' ') }}'" regexp: "SSHOK='.*'" create: no @@ -156,7 +165,7 @@ - name: Configure SMTPOK lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "SMTPOK='{{ minifirewall_smtp_ok | join(' ') }}'" regexp: "SMTPOK='.*'" create: no @@ -164,7 +173,7 @@ - name: Configure SMTPSECUREOK lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "SMTPSECUREOK='{{ minifirewall_smtp_secure_ok | join(' ') }}'" regexp: "SMTPSECUREOK='.*'" create: no @@ -172,29 +181,15 @@ - name: Configure NTPOK lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "NTPOK='{{ minifirewall_ntp_ok | join(' ') }}'" regexp: "NTPOK='.*'" create: no when: minifirewall_ntp_ok is not none -- name: evomaintenance - lineinfile: - dest: "{{ minifirewall_main_file }}" - line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT" - insertafter: "^# EvoMaintenance" - loop: "{{ evomaintenance_hosts }}" - -- name: remove minifirewall example rule for the evomaintenance - lineinfile: - dest: "{{ minifirewall_main_file }}" - regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)' - state: absent - when: evomaintenance_hosts | length > 0 - - name: Stat minifirewall config file (after) stat: - path: "{{ minifirewall_main_file }}" + path: "/etc/default/minifirewall" register: minifirewall_after - name: restart minifirewall diff --git a/minifirewall/tasks/install.yml b/minifirewall/tasks/install.yml index 5d6438ed..e537fb6f 100644 --- a/minifirewall/tasks/install.yml +++ b/minifirewall/tasks/install.yml @@ -6,18 +6,26 @@ state: present - name: init script is copied - template: - src: minifirewall.j2 + copy: + src: minifirewall dest: /etc/init.d/minifirewall force: "{{ minifirewall_force_upgrade_script | default('no') }}" mode: "0700" owner: root group: root +- name: include directory is present + file: + path: /etc/minifirewall.d/ + state: directory + owner: root + group: root + mode: "0700" + - name: configuration is copied copy: src: minifirewall.conf - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" force: "{{ minifirewall_force_upgrade_config | default('no') }}" mode: "0600" owner: root diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index 2a053d4f..5f442eb1 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -4,9 +4,15 @@ set_fact: minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" +- name: Fail if minifirewall_main_file is defined + fail: + msg: "Variable minifirewall_main_file is deprecated and not configurable anymore." + when: minifirewall_main_file is defined + - include: install.yml - include: config.yml + when: minifirewall_update_config | bool - include: nrpe.yml diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index c8c4440e..199b4c7a 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -2,7 +2,7 @@ - name: Add some rules at the end of minifirewall file template: src: "{{ item }}" - dest: "{{ minifirewall_tail_file }}" + dest: "/etc/minifirewall.d/{{ minifirewall_tail_file }}" force: "{{ minifirewall_tail_force | bool }}" loop: "{{ query('first_found', templates) }}" vars: @@ -17,18 +17,6 @@ var: minifirewall_tail_template verbosity: 1 -- name: source minifirewall.tail at the end of the main file - blockinfile: - dest: "{{ minifirewall_main_file }}" - marker: "# {mark} ANSIBLE MANAGED EXTERNAL RULES" - block: ". {{ minifirewall_tail_file }}" - insertbefore: EOF - register: minifirewall_tail_source - -- debug: - var: minifirewall_tail_source - verbosity: 1 - - name: restart minifirewall # service: # name: minifirewall diff --git a/minifirewall/templates/minifirewall.j2 b/minifirewall/templates/minifirewall.j2 deleted file mode 100755 index 13b5130d..00000000 --- a/minifirewall/templates/minifirewall.j2 +++ /dev/null @@ -1,492 +0,0 @@ -#!/bin/sh - -# minifirewall is shellscripts for easy firewalling on a standalone server -# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel -# See https://gitea.evolix.org/evolix/minifirewall - -# Copyright (c) 2007-2020 Evolix -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 -# of the License. - -# Description -# script for standalone server - -# Start or stop minifirewall -# - -### BEGIN INIT INFO -# Provides: minfirewall -# Required-Start: -# Required-Stop: -# Should-Start: $network $syslog $named -# Should-Stop: $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: start and stop the firewall -# Description: Firewall designed for standalone server -### END INIT INFO - -DESC="minifirewall" -NAME="minifirewall" - - -# Variables configuration -######################### - -# iptables paths -IPT=/sbin/iptables -IPT6=/sbin/ip6tables - -# TCP/IP variables -LOOPBACK='127.0.0.0/8' -CLASSA='10.0.0.0/8' -CLASSB='172.16.0.0/12' -CLASSC='192.168.0.0/16' -CLASSD='224.0.0.0/4' -CLASSE='240.0.0.0/5' -ALL='0.0.0.0' -BROAD='255.255.255.255' -PORTSROOT='0:1023' -PORTSUSER='1024:65535' - -chain_exists() -{ - local chain_name="$1" ; shift - [ $# -eq 1 ] && local intable="--table $1" - iptables $intable -nL "$chain_name" >/dev/null 2>&1 -} - -# Configuration -oldconfigfile="/etc/firewall.rc" -configfile="{{ minifirewall_main_file }}" - -IPV6=$(grep "IPV6=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') -DOCKER=$(grep "DOCKER=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') -INT=$(grep "INT=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') - -case "$1" in - start) - - echo "Start IPTables rules..." - -# Stop and warn if error! -set -e -trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT - - -# sysctl network security settings -################################## - -# Don't answer to broadcast pings -echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts - -# Ignore bogus ICMP responses -echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses - -# Disable Source Routing -for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do -echo 0 > $i -done - -# Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks -# cf http://cr.yp.to/syncookies.html -echo 1 > /proc/sys/net/ipv4/tcp_syncookies - -# Disable ICMP redirects -for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do -echo 0 > $i -done - -for i in /proc/sys/net/ipv4/conf/*/send_redirects; do -echo 0 > $i -done - -# Enable Reverse Path filtering : verify if responses use same network interface -for i in /proc/sys/net/ipv4/conf/*/rp_filter; do -echo 1 > $i -done - -# log des paquets avec adresse incoherente -for i in /proc/sys/net/ipv4/conf/*/log_martians; do -echo 1 > $i -done - -# IPTables configuration -######################## - -$IPT -N LOG_DROP -$IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' -$IPT -A LOG_DROP -j DROP -$IPT -N LOG_ACCEPT -$IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' -$IPT -A LOG_ACCEPT -j ACCEPT - -if test -f $oldconfigfile; then - echo "$oldconfigfile is deprecated, rename to $configfile" >&2 - exit 1 -fi - -if ! test -f $configfile; then - echo "$configfile does not exist" >&2 - exit 1 -fi - -tmpfile=`mktemp` -. $configfile 2>$tmpfile >&2 -if [ -s $tmpfile ]; then - echo "$configfile returns standard or error output (see below). Stopping." >&2 - cat $tmpfile - exit 1 -fi -rm $tmpfile - -# Trusted ip addresses -$IPT -N ONLYTRUSTED -$IPT -A ONLYTRUSTED -j LOG_DROP -for x in $TRUSTEDIPS - do - $IPT -I ONLYTRUSTED -s $x -j ACCEPT - done - -# Privilegied ip addresses -# (trusted ip addresses *are* privilegied) -$IPT -N ONLYPRIVILEGIED -$IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED -for x in $PRIVILEGIEDIPS - do - $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT - done - -# Chain for restrictions (blacklist IPs/ranges) -$IPT -N NEEDRESTRICT - -# We allow all on loopback interface -$IPT -A INPUT -i lo -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT -# if OUTPUTDROP -$IPT -A OUTPUT -o lo -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT - -# We avoid "martians" packets, typical when W32/Blaster virus -# attacked windowsupdate.com and DNS was changed to 127.0.0.1 -# $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP -$IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP - - -if [ "$DOCKER" = "on" ]; then - - $IPT -N MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-TRUSTED -j DROP - - $IPT -N MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN - - $IPT -N MINIFW-DOCKER-PUB - $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PUB -j RETURN - - # Flush DOCKER-USER if exist, create it if absent - if chain_exists 'DOCKER-USER'; then - $IPT -F DOCKER-USER - else - $IPT -N DOCKER-USER - fi; - - # Pipe new connection through MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -j RETURN - -fi - - -# Local services restrictions -############################# - -# Allow services for $INTLAN (local server or local network) -$IPT -A INPUT -s $INTLAN -j ACCEPT - -# Enable protection chain for sensible services -for x in $SERVICESTCP1p - do - $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT - done - -for x in $SERVICESUDP1p - do - $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT - done - -# Public service -for x in $SERVICESTCP1 - do - $IPT -A INPUT -p tcp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT - done - -for x in $SERVICESUDP1 - do - $IPT -A INPUT -p udp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT - done - -# Privilegied services -for x in $SERVICESTCP2 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED - done - -for x in $SERVICESUDP2 - do - $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED - done - -# Private services -for x in $SERVICESTCP3 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED - done - -for x in $SERVICESUDP3 - do - $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED - done - - -if [ "$DOCKER" = "on" ]; then - - # Public services defined in SERVICESTCP1 & SERVICESUDP1 - for dstport in $SERVICESTCP1 - do - $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN - done - - for dstport in $SERVICESUDP1 - do - $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN - done - - # Privileged services (accessible from privileged & trusted IPs) - for dstport in $SERVICESTCP2 - do - for srcip in $PRIVILEGIEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done - - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done - done - - for dstport in $SERVICESUDP2 - do - for srcip in $PRIVILEGIEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done - - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done - done - - # Trusted services (accessible from trusted IPs) - for dstport in $SERVICESTCP3 - do - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done - done - - for dstport in $SERVICESUDP3 - do - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done - done -fi - -# External services -################### - -# DNS authorizations -for x in $DNSSERVEURS - do - $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT - done - -# HTTP (TCP/80) authorizations -for x in $HTTPSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT - done - -# HTTPS (TCP/443) authorizations -for x in $HTTPSSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT - done - -# FTP (so complex protocol...) authorizations -for x in $FTPSITES - do - # requests on Control connection - $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT - # FTP port-mode on Data Connection - $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT - # FTP passive-mode on Data Connection - # WARNING, this allow all connections on TCP ports > 1024 - $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT - done - -# SSH authorizations -for x in $SSHOK - do - $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT - done - -# SMTP authorizations -for x in $SMTPOK - do - $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT - done - -# secure SMTP (TCP/465 et TCP/587) authorizations -for x in $SMTPSECUREOK - do - $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT - done - -# NTP authorizations -for x in $NTPOK - do - $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT - done - -# Always allow ICMP -$IPT -A INPUT -p icmp -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT - - -# IPTables policy -################# - -# by default DROP INPUT packets -$IPT -P INPUT DROP -[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP - -# by default, no FORWARING (deprecated for Virtual Machines) -#echo 0 > /proc/sys/net/ipv4/ip_forward -#$IPT -P FORWARD DROP -#$IPT6 -P FORWARD DROP - -# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) -$IPT -P OUTPUT ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT -$IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -$IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT -$IPT -A OUTPUT -p udp -j DROP -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP - -trap - INT TERM EXIT - - echo "...starting IPTables rules is now finish : OK" - ;; - - stop) - - echo "Flush all rules and accept everything..." - - # Delete all rules - $IPT -F INPUT - $IPT -F OUTPUT - $IPT -F LOG_DROP - $IPT -F LOG_ACCEPT - $IPT -F ONLYTRUSTED - $IPT -F ONLYPRIVILEGIED - $IPT -F NEEDRESTRICT - [ "$DOCKER" = "off" ] && $IPT -t nat -F - $IPT -t mangle -F - [ "$IPV6" != "off" ] && $IPT6 -F INPUT - [ "$IPV6" != "off" ] && $IPT6 -F OUTPUT - - if [ "$DOCKER" = "on" ]; then - $IPT -F DOCKER-USER - $IPT -A DOCKER-USER -j RETURN - - $IPT -F MINIFW-DOCKER-PUB - $IPT -X MINIFW-DOCKER-PUB - $IPT -F MINIFW-DOCKER-PRIVILEGED - $IPT -X MINIFW-DOCKER-PRIVILEGED - $IPT -F MINIFW-DOCKER-TRUSTED - $IPT -X MINIFW-DOCKER-TRUSTED - - fi - - # Accept all - $IPT -P INPUT ACCEPT - $IPT -P OUTPUT ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -P INPUT ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT - #$IPT -P FORWARD ACCEPT - #$IPT -t nat -P PREROUTING ACCEPT - #$IPT -t nat -P POSTROUTING ACCEPT - - # Delete non-standard chains - $IPT -X LOG_DROP - $IPT -X LOG_ACCEPT - $IPT -X ONLYPRIVILEGIED - $IPT -X ONLYTRUSTED - $IPT -X NEEDRESTRICT - - echo "...flushing IPTables rules is now finish : OK" - ;; - - status) - - $IPT -L -n -v --line-numbers - $IPT -t nat -L -n -v --line-numbers - $IPT -t mangle -L -n -v --line-numbers - $IPT6 -L -n -v --line-numbers - $IPT6 -t mangle -L -n -v --line-numbers - ;; - - reset) - - echo "Reset all IPTables counters..." - - $IPT -Z - $IPT -t nat -Z - $IPT -t mangle -Z - [ "$IPV6" != "off" ] && $IPT6 -Z - [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z - - echo "...reseting IPTables counters is now finish : OK" - ;; - - restart) - - $0 stop - $0 start - ;; - - *) - - echo "Usage: $0 {start|stop|restart|status|reset|squid}" - exit 1 -esac - -exit 0 From 545226f6f6a08dd6dd3e6234bcbcba114b0aa93e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 23:25:15 +0100 Subject: [PATCH 17/79] evocheck: upstream release 22.03 --- CHANGELOG.md | 1 + evocheck/files/evocheck.sh | 69 ++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96cb6838..1c9d1bef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed +* evocheck: upstream release 22.03 * evolinux-base: backup-server-state release 22.03 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index fb8a6eeb..56805105 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -4,7 +4,7 @@ # Script to verify compliance of a Debian/OpenBSD server # powered by Evolix -VERSION="21.10.4" +VERSION="22.03" readonly VERSION # base functions @@ -13,7 +13,7 @@ show_version() { cat <, +Copyright 2009-2022 Evolix , Romain Dessort , Benoit Série , Gregory Colpart , @@ -142,9 +142,9 @@ failed() { RC=1 if [ "${QUIET}" != 1 ]; then if [ -n "${check_comments}" ] && [ "${VERBOSE}" = 1 ]; then - printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" 2>&1 + printf "%s FAILED! %s\n" "${check_name}" "${check_comments}" >> "${main_output_file}" else - printf "%s FAILED!\n" "${check_name}" 2>&1 + printf "%s FAILED!\n" "${check_name}" >> "${main_output_file}" fi fi } @@ -328,8 +328,11 @@ check_tmoutprofile() { check_alert5boot() { if is_debian_buster || is_debian_bullseye; then grep -qs "^date" /usr/share/scripts/alert5.sh || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script" - test -f /etc/systemd/system/alert5.service || failed "IS_ALERT5BOOT" "alert5 unit file is missing" - systemctl is-enabled alert5 -q || failed "IS_ALERT5BOOT" "alert5 unit is not enabled" + if [ -f /etc/systemd/system/alert5.service ]; then + systemctl is-enabled alert5.service -q || failed "IS_ALERT5BOOT" "alert5 unit is not enabled" + else + failed "IS_ALERT5BOOT" "alert5 unit file is missing" + fi else if [ -n "$(find /etc/rc2.d/ -name 'S*alert5')" ]; then grep -q "^date" /etc/rc2.d/S*alert5 || failed "IS_ALERT5BOOT" "boot mail is not sent by alert5 init script" @@ -592,9 +595,9 @@ check_evobackup() { } # Vérification de l'exclusion des montages (NFS) dans les sauvegardes check_evobackup_exclude_mount() { - excludes_file=$(mktemp) - # shellcheck disable=SC2064 - trap "rm -f ${excludes_file}" 0 + excludes_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.evobackup_exclude_mount.XXXXX") + files_to_cleanup="${files_to_cleanup} ${excludes_file}" + # shellcheck disable=SC2044 for evobackup_file in $(find /etc/cron* -name '*evobackup*' | grep -v -E ".disabled$"); do grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}" @@ -603,7 +606,6 @@ check_evobackup_exclude_mount() { failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script" done done - rm -rf "${excludes_file}" } # Verification de la presence du userlogrotate check_userlogrotate() { @@ -809,8 +811,10 @@ check_tune2fs_m5() { check_evolinuxsudogroup() { if is_debian_stretch || is_debian_buster || is_debian_bullseye; then if grep -q "^evolinux-sudo:" /etc/group; then - grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \ - || failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file" + if [ -f /etc/sudoers.d/evolinux ]; then + grep -qE '^%evolinux-sudo +ALL ?= ?\(ALL:ALL\) ALL' /etc/sudoers.d/evolinux \ + || failed "IS_EVOLINUXSUDOGROUP" "missing evolinux-sudo directive in sudoers file" + fi fi fi } @@ -827,7 +831,7 @@ check_userinadmgroup() { } check_apache2evolinuxconf() { if is_debian_stretch || is_debian_buster || is_debian_bullseye; then - if test -d /etc/apache2; then + if is_installed apache2; then { test -L /etc/apache2/conf-enabled/z-evolinux-defaults.conf \ && test -L /etc/apache2/conf-enabled/zzz-evolinux-custom.conf \ && test -f /etc/apache2/ipaddr_whitelist.conf; @@ -1006,6 +1010,8 @@ check_mysqlmunin() { test "${VERBOSE}" = 1 || break fi done + munin-run mysql_commands 2> /dev/null > /dev/null + test $? -eq 0 || failed "IS_MYSQLMUNIN" "Munin plugin mysql_commands returned an error" fi fi } @@ -1062,8 +1068,10 @@ check_squidevolinuxconf() { check_duplicate_fs_label() { # Do it only if thereis blkid binary BLKID_BIN=$(command -v blkid) - if [ -x "$BLKID_BIN" ]; then - tmpFile=$(mktemp -p /tmp) + if [ -n "$BLKID_BIN" ]; then + tmpFile=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.duplicate_fs_label.XXXXX") + files_to_cleanup="${files_to_cleanup} ${tmpFile}" + parts=$($BLKID_BIN -c /dev/null | grep -ve raid_member -e EFI_SYSPART | grep -Eo ' LABEL=".*"' | cut -d'"' -f2) for part in $parts; do echo "$part" >> "$tmpFile" @@ -1076,7 +1084,6 @@ check_duplicate_fs_label() { labels=$(echo -n $tmpOutput | tr '\n' ' ') failed "IS_DUPLICATE_FS_LABEL" "Duplicate labels: $labels" fi - rm "$tmpFile" else failed "IS_DUPLICATE_FS_LABEL" "blkid not found in ${PATH}" fi @@ -1395,6 +1402,7 @@ get_command() { listupgrade) command -v "evolistupgrade.sh" ;; old-kernel-autoremoval) command -v "old-kernel-autoremoval.sh" ;; mysql-queries-killer) command -v "mysql-queries-killer.sh" ;; + minifirewall) echo "/etc/init.d/minifirewall" ;; ## General case, where the program name is the same as the command name *) command -v "${program}" ;; @@ -1415,6 +1423,9 @@ get_version() { add-vm) grep '^VERSION=' "${command}" | head -1 | cut -d '=' -f 2 ;; + minifirewall) + ${command} status | head -1 | cut -d ' ' -f 3 + ;; ## Let's try the --version flag before falling back to grep for the constant kvmstats) if ${command} --version > /dev/null 2> /dev/null; then @@ -1457,9 +1468,9 @@ add_to_path() { echo "$PATH" | grep -qF "${new_path}" || export PATH="${PATH}:${new_path}" } check_versions() { - versions_file=$(mktemp --tmpdir=/tmp "evocheck-versions.XXXXX") - # shellcheck disable=SC2064 - trap "rm -f ${versions_file}" 0 + versions_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.versions.XXXXX") + files_to_cleanup="${files_to_cleanup} ${versions_file}" + download_versions "${versions_file}" add_to_path "/usr/share/scripts" @@ -1477,8 +1488,6 @@ check_versions() { fi fi done - - rm -f "${versions_file}" } main() { @@ -1487,6 +1496,9 @@ main() { # Detect operating system name, version and release detect_os + main_output_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.main.XXXXX") + files_to_cleanup="${files_to_cleanup} ${main_output_file}" + #----------------------------------------------------------- # Tests communs à tous les systèmes #----------------------------------------------------------- @@ -1715,8 +1727,19 @@ main() { # - NRPEDISK et NRPEPOSTFIX fi + if [ -f "${main_output_file}" ]; then + if [ $(cat "${main_output_file}" | wc -l) -gt 0 ]; then + + cat "${main_output_file}" 2>&1 + fi + fi + exit ${RC} } +cleanup_temp_files() { + # shellcheck disable=SC2086 + rm -f ${files_to_cleanup} +} PROGNAME=$(basename "$0") # shellcheck disable=SC2034 @@ -1730,6 +1753,10 @@ readonly ARGS export LANG=C export LANGUAGE=C +files_to_cleanup="" +# shellcheck disable=SC2064 +trap cleanup_temp_files 0 + # Source configuration file # shellcheck disable=SC1091 test -f /etc/evocheck.cf && . /etc/evocheck.cf From 8a9faa0250552a9d071e71d81ba099eba6636697 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 16 Mar 2022 23:49:34 +0100 Subject: [PATCH 18/79] * minifirewall: upstream release 22.03.2 --- CHANGELOG.md | 2 +- minifirewall/files/blacklist-countries.sh | 23 ++++++++++ minifirewall/files/minifirewall | 29 ++++++++++--- minifirewall/files/minifirewall.d/zzz-custom | 11 +++++ minifirewall/files/minifirewall.d/zzzz-ban | 7 +++ minifirewall/tasks/install.yml | 45 ++++++++++++++++---- 6 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 minifirewall/files/blacklist-countries.sh create mode 100644 minifirewall/files/minifirewall.d/zzz-custom create mode 100644 minifirewall/files/minifirewall.d/zzzz-ban diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c9d1bef..d1fa35d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: backup-server-state release 22.03 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld -* minifirewall: upstream release 22.03.1 and use includes directory +* minifirewall: upstream release 22.03.2 and use includes directory ### Fixed diff --git a/minifirewall/files/blacklist-countries.sh b/minifirewall/files/blacklist-countries.sh new file mode 100644 index 00000000..3a3d20db --- /dev/null +++ b/minifirewall/files/blacklist-countries.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +ripedeny_file=/var/tmp/ripe_deny + +cd /var/tmp + +rm -f $ripedeny_file + +GET http://antispam00.evolix.org/spam/ripe.cidr.md5 > ripe.cidr.md5 +GET http://antispam00.evolix.org/spam/ripe.cidr > ripe.cidr + +for i in CN KR RU; do + + grep "^$i|" ripe.cidr >> $ripedeny_file + +done + +/sbin/iptables -F NEEDRESTRICT + +for i in $(cat $ripedeny_file); do + BLOCK=$(echo $i | cut -d"|" -f2) + /sbin/iptables -I NEEDRESTRICT -s $BLOCK -j DROP +done diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index b1595471..0367968a 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -28,9 +28,10 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.03.1" +VERSION="22.03.2" NAME="minifirewall" +# shellcheck disable=SC2034 DESC="Firewall designed for standalone server" set -u @@ -115,6 +116,8 @@ chain_exists() { chain_name="$1" if [ $# -ge 2 ]; then intable="--table $2" + else + intable="" fi # shellcheck disable=SC2086 iptables ${intable} -nL "${chain_name}" >/dev/null 2>&1 @@ -476,34 +479,46 @@ start() { # Privileged services (accessible from privileged & trusted IPs) for dstport in ${SERVICESTCP2}; do for srcip in ${PRIVILEGIEDIPS}; do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done for srcip in ${TRUSTEDIPS}; do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done done for dstport in ${SERVICESUDP2}; do for srcip in ${PRIVILEGIEDIPS}; do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done for srcip in ${TRUSTEDIPS}; do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done done # Trusted services (accessible from trusted IPs) for dstport in ${SERVICESTCP3}; do for srcip in ${TRUSTEDIPS}; do - ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done done for dstport in ${SERVICESUDP3}; do for srcip in ${TRUSTEDIPS}; do - ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + if ! is_ipv6 ${srcip}; then + ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + fi done done fi diff --git a/minifirewall/files/minifirewall.d/zzz-custom b/minifirewall/files/minifirewall.d/zzz-custom new file mode 100644 index 00000000..7ac24f06 --- /dev/null +++ b/minifirewall/files/minifirewall.d/zzz-custom @@ -0,0 +1,11 @@ +### custom minifirewall commands +# +# You can add any custom command in files like this; +# either this one, or others in the same directory. +# They are executed as shell scripts. +# They are automatically included in alphanumerical order. +# +# Within included files, you can use those helper functions : +# * is_ipv6_enabled: returns true if IPv6 is enabled, or false +# * is_docker_enabled: returns true if Docker mode is eabled, or false +# * is_proxy_enabled: returns true if Proxy mode is enabled , or false diff --git a/minifirewall/files/minifirewall.d/zzzz-ban b/minifirewall/files/minifirewall.d/zzzz-ban new file mode 100644 index 00000000..6dc516b0 --- /dev/null +++ b/minifirewall/files/minifirewall.d/zzzz-ban @@ -0,0 +1,7 @@ +### ban rules +# +# If you have ban rules in /root/ban.iptables +# (either manually or with /usr/share/scripts/blacklist-countries.sh) +# ou can automatically import them with the following command: +# +# cat /root/ban.iptables | iptables-restore -n diff --git a/minifirewall/tasks/install.yml b/minifirewall/tasks/install.yml index e537fb6f..5eeed116 100644 --- a/minifirewall/tasks/install.yml +++ b/minifirewall/tasks/install.yml @@ -14,14 +14,6 @@ owner: root group: root -- name: include directory is present - file: - path: /etc/minifirewall.d/ - state: directory - owner: root - group: root - mode: "0700" - - name: configuration is copied copy: src: minifirewall.conf @@ -30,3 +22,40 @@ mode: "0600" owner: root group: root + +- name: includes directory is present + file: + path: /etc/minifirewall.d/ + state: directory + owner: root + group: root + mode: "0700" + +- name: examples for includes are present + copy: + src: "minifirewall.d/" + dest: "/etc/minifirewall.d/" + force: "no" + mode: "0600" + owner: root + group: root + +- include_role: + name: evolix/remount-usr + +- name: /usr/share/scripts exists + file: + dest: /usr/share/scripts + mode: "0700" + owner: root + group: root + state: directory + +- name: blacklist-countries.sh is copied + copy: + src: blacklist-countries.sh + dest: /usr/share/scripts/blacklist-countries.sh + force: "no" + mode: "0700" + owner: root + group: root From fb41c81e9976b82b10d9bdc62bca5c4ce9998c4c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 17 Mar 2022 10:45:44 +0100 Subject: [PATCH 19/79] backup-server-state: release 22.03.2 update documentation for --dpkg-full vs. --dpkg-status --- CHANGELOG.md | 2 +- evolinux-base/files/backup-server-state.sh | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1fa35d7..52fa0a8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evocheck: upstream release 22.03 -* evolinux-base: backup-server-state release 22.03 +* evolinux-base: backup-server-state release 22.03.2 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.2 and use includes directory diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 60af732d..588ff6e5 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="backup-server-state" -VERSION="22.03" +VERSION="22.03.2" readonly VERSION backup_dir= @@ -34,8 +34,10 @@ Options -f, --force keep existing backup directory and its content --etc backup copy of /etc --no-etc no backup copy of /etc (default) - --dpkg backup copy of /var/lib/dpkg - --no-dpkg no backup copy of /var/lib/dpkg (default) + --dpkg-full backup copy of /var/lib/dpkg + --no-dpkg-full no backup copy of /var/lib/dpkg (default) + --dpkg-status backup copy of /var/lib/dpkg/status (default) + --no-dpkg-status no backup copy of /var/lib/dpkg/status --apt-states backup copy of apt extended states (default) --no-apt-states no backup copy of apt extended states --apt-config backup copy of apt configuration (default) @@ -471,7 +473,7 @@ backup_sysctl() { sysctl_bin=$(command -v sysctl) if [ -n "${sysctl_bin}" ]; then - last_result=$(${sysctl_bin} -a | sort -h > "${backup_dir}/sysctl.txt") + last_result=$(${sysctl_bin} -a --ignore 2>/dev/null | sort -h > "${backup_dir}/sysctl.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then From 444bd72944d653e068b1d8be1085298348d1e7f4 Mon Sep 17 00:00:00 2001 From: Mathieu Trossevin Date: Thu, 17 Mar 2022 17:36:35 +0100 Subject: [PATCH 20/79] generate-ldif: Correct generated entries for php-fpm in containers --- CHANGELOG.md | 1 + generate-ldif/templates/generateldif.sh.j2 | 24 +++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52fa0a8a..4228d173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Fixed * Repair keepalived role +* generate-ldif: Correct generated entries for php-fpm in containers ### Removed diff --git a/generate-ldif/templates/generateldif.sh.j2 b/generate-ldif/templates/generateldif.sh.j2 index cfae731c..86bfc0eb 100755 --- a/generate-ldif/templates/generateldif.sh.j2 +++ b/generate-ldif/templates/generateldif.sh.j2 @@ -608,11 +608,11 @@ if is_pkg_installed lxc; then if lxc-ls | grep -q php56 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm56,${computer_dn} +dn: ServiceName=php-fpm56,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm56 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 5.6 (multiphp) @@ -622,11 +622,11 @@ fi if lxc-ls | grep -q php70 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm70,${computer_dn} +dn: ServiceName=php-fpm70,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm70 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 7.0 (multiphp) @@ -636,11 +636,11 @@ fi if lxc-ls | grep -q php73 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm73,${computer_dn} +dn: ServiceName=php-fpm73,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm73 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 7.3 (multiphp) @@ -650,11 +650,11 @@ fi if lxc-ls | grep -q php74 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm74,${computer_dn} +dn: ServiceName=php-fpm74,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm74 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 7.4 (multiphp) @@ -664,11 +664,11 @@ fi if lxc-ls | grep -q php80 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm80,${computer_dn} +dn: ServiceName=php-fpm80,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm80 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 8.0 (multiphp) @@ -678,11 +678,11 @@ fi if lxc-ls | grep -q php81 ; then cat <> "${ldif_file}" -dn: ServiceName=ServiceName=php-fpm81,${computer_dn} +dn: ServiceName=php-fpm81,${computer_dn} NagiosEnabled: TRUE ipServiceProtocol: tcp objectClass: EvoService -ServiceName: PHP-FPM (multiphp) +ServiceName: php-fpm81 ipServicePort: 443 ServiceType: web ServiceVersion: PHP-FPM 8.1 (multiphp) From e7594c6c8675f5590a836528e7178f5c24a52bd4 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 21 Mar 2022 11:32:08 +0100 Subject: [PATCH 21/79] evolinux-base: backup-server-state release 22.03.2 --- CHANGELOG.md | 2 +- evolinux-base/files/backup-server-state.sh | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4228d173..43ddbf67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evocheck: upstream release 22.03 -* evolinux-base: backup-server-state release 22.03.2 +* evolinux-base: backup-server-state release 22.03.3 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.2 and use includes directory diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 588ff6e5..9bf16a59 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="backup-server-state" -VERSION="22.03.2" +VERSION="22.03.3" readonly VERSION backup_dir= @@ -667,15 +667,20 @@ backup_mysql_processes() { mysqladmin_bin=$(command -v mysqladmin) if [ -n "${mysqladmin_bin}" ]; then - last_result=$(${mysqladmin_bin} --verbose processlist > "${backup_dir}/mysql-processlist.txt") - last_rc=$? + # Look for local MySQL or MariaDB process + if pgrep mysqld > /dev/null || pgrep mariadbd > /dev/null; then + last_result=$(${mysqladmin_bin} --verbose processlist > "${backup_dir}/mysql-processlist.txt") + last_rc=$? - if [ ${last_rc} -eq 0 ]; then - debug "* mysqladmin OK" + if [ ${last_rc} -eq 0 ]; then + debug "* mysqladmin OK" + else + debug "* mysqladmin ERROR" + debug "${last_result}" + rc=10 + fi else - debug "* mysqladmin ERROR" - debug "${last_result}" - rc=10 + debug "* no mysqld or mariadbd process is running" fi else debug "* mysqladmin not found" From 5895f5a99b52be20f18db12fef3023c2603e867e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 21 Mar 2022 14:35:20 +0100 Subject: [PATCH 22/79] minifirewall: upstream release 22.03.3 --- CHANGELOG.md | 2 +- minifirewall/files/minifirewall | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43ddbf67..3c377089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: backup-server-state release 22.03.3 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld -* minifirewall: upstream release 22.03.2 and use includes directory +* minifirewall: upstream release 22.03.3 and use includes directory ### Fixed diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index 0367968a..9e8ff67f 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -28,7 +28,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.03.2" +VERSION="22.03.3" NAME="minifirewall" # shellcheck disable=SC2034 @@ -298,6 +298,11 @@ start() { ${IPT6} -A LOG_ACCEPT -j ACCEPT fi + # Source additional rules and commands + # * from legacy configuration file (/etc/default/minifirewall) + # * from configuration directory (/etc/minifirewall.d/*) + source_includes + # Trusted ip addresses ${IPT} -N ONLYTRUSTED ${IPT} -A ONLYTRUSTED -j LOG_DROP @@ -713,9 +718,6 @@ start() { source_file_or_error "${config_file}" fi - # Source files present in optional directory - source_includes - trap - INT TERM EXIT echo "...starting IPTables rules is now finish : OK" From c2f6ff5249becdef2302219fad59d2b76ecad8ae Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Tue, 22 Mar 2022 11:03:26 +0100 Subject: [PATCH 23/79] evocheck: upstream release 22.03.1 --- CHANGELOG.md | 2 +- evocheck/files/evocheck.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c377089..3945f94e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed -* evocheck: upstream release 22.03 +* evocheck: upstream release 22.03.1 * evolinux-base: backup-server-state release 22.03.3 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index 56805105..2f01afae 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -4,7 +4,7 @@ # Script to verify compliance of a Debian/OpenBSD server # powered by Evolix -VERSION="22.03" +VERSION="22.03.1" readonly VERSION # base functions @@ -570,7 +570,7 @@ check_network_interfaces() { # Verify if all if are in auto check_autoif() { if is_debian_stretch || is_debian_buster || is_debian_bullseye; then - interfaces=$(/sbin/ip address show up | grep "^[0-9]*:" | grep -E -v "(lo|vnet|docker|veth|tun|tap|macvtap|vrrp)" | cut -d " " -f 2 | tr -d : | cut -d@ -f1 | tr "\n" " ") + interfaces=$(/sbin/ip address show up | grep "^[0-9]*:" | grep -E -v "(lo|vnet|docker|veth|tun|tap|macvtap|vrrp|lxcbr)" | cut -d " " -f 2 | tr -d : | cut -d@ -f1 | tr "\n" " ") else interfaces=$(/sbin/ifconfig -s | tail -n +2 | grep -E -v "^(lo|vnet|docker|veth|tun|tap|macvtap|vrrp)" | cut -d " " -f 1 |tr "\n" " ") fi From ef832c9ab60544c10884a937c4631f2bf229eb29 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 22 Mar 2022 15:29:41 +0100 Subject: [PATCH 24/79] backup-server-state: also dump iptables rules without counters --- evolinux-base/files/backup-server-state.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 9bf16a59..a3d8e62b 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -434,7 +434,18 @@ backup_iptables() { debug "* nft found, skip iptables" else if [ -n "${iptables_bin}" ]; then - last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${backup_dir}/iptables.txt") + last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${backup_dir}/iptables-v.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* iptables -v OK" + else + debug "* iptables -v ERROR" + debug "${last_result}" + rc=10 + fi + + last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } >> "${backup_dir}/iptables.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then From 163d5abf7c2e1943ddb0634f89898404e7b53397 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 22 Mar 2022 15:30:18 +0100 Subject: [PATCH 25/79] backup-server-state: release 22.03.4 --- evolinux-base/files/backup-server-state.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index a3d8e62b..3c42695d 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="backup-server-state" -VERSION="22.03.3" +VERSION="22.03.4" readonly VERSION backup_dir= From 0d1ccc79c39f819eb6962643b508ed27810ddce2 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 22 Mar 2022 15:31:06 +0100 Subject: [PATCH 26/79] whitespace --- nginx/files/nginx/evolinux-defaults.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/nginx/files/nginx/evolinux-defaults.conf b/nginx/files/nginx/evolinux-defaults.conf index 4d300c4d..22eb7fef 100644 --- a/nginx/files/nginx/evolinux-defaults.conf +++ b/nginx/files/nginx/evolinux-defaults.conf @@ -1,4 +1,5 @@ # Evolix default customizations + server_tokens off; server_names_hash_max_size 512; server_names_hash_bucket_size 128; From b4f83e54d01ae09e58d119a95bf7397e7e7acbcc Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Wed, 23 Mar 2022 10:45:53 +0100 Subject: [PATCH 27/79] openvpn: use a subnet topology instead of the net30 default topology --- CHANGELOG.md | 1 + openvpn/templates/server.conf.j2 | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3945f94e..3423f57e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.3 and use includes directory +* openvpn: use a subnet topology instead of the net30 default topology ### Fixed diff --git a/openvpn/templates/server.conf.j2 b/openvpn/templates/server.conf.j2 index a89701e8..23ce3e2b 100644 --- a/openvpn/templates/server.conf.j2 +++ b/openvpn/templates/server.conf.j2 @@ -6,6 +6,7 @@ port 1194 proto udp dev tun mode server +topology subnet keepalive 10 120 tls-exit From 1646cc99bf460cef8d1634d576682233d4a6a79f Mon Sep 17 00:00:00 2001 From: Mathieu Trossevin Date: Wed, 23 Mar 2022 13:55:54 +0100 Subject: [PATCH 28/79] redis: Remount /usr with RW when adding nagios plugin --- CHANGELOG.md | 1 + redis/tasks/nrpe.yml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3423f57e..e6a0941d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * Repair keepalived role * generate-ldif: Correct generated entries for php-fpm in containers +* redis: Remount /usr with RW before adding nagios plugin ### Removed diff --git a/redis/tasks/nrpe.yml b/redis/tasks/nrpe.yml index b317c4e6..9e042479 100644 --- a/redis/tasks/nrpe.yml +++ b/redis/tasks/nrpe.yml @@ -79,6 +79,10 @@ - redis - nrpe +- name: "Remount /usr with RW for 'install check_redis instance'" + include_role: + name: evolix/remount-usr + - name: install check_redis_instances copy: src: check_redis_instances.sh From 42782b7f3d8f3a93fc396489adeda5ccb1a2167d Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 24 Mar 2022 17:57:58 +0100 Subject: [PATCH 29/79] evolinux-base: fix show_help in backup-server-state.sh * --uname and --no-uname options were not in help * --services and --no-services were in help whereas --systemctl and --no-systemctl are used in options parsing --- CHANGELOG.md | 1 + evolinux-base/files/backup-server-state.sh | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a0941d..6500c19b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * Repair keepalived role * generate-ldif: Correct generated entries for php-fpm in containers * redis: Remount /usr with RW before adding nagios plugin +* evolinux-base: fix show_help in backup-server-state.sh ### Removed diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh index 3c42695d..bc0eedd7 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/backup-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="backup-server-state" -VERSION="22.03.4" +VERSION="22.03.5" readonly VERSION backup_dir= @@ -46,6 +46,8 @@ Options --no-packages no backup copy of dpkg selections --processes backup copy of process list (default) --no-processes no backup copy of process list + --uname backup copy of uname (default) + --no-uname no backup copy of uname --uptime backup of uptime value (default) --no-uptime no backup of uptime value --netstat backup copy of netstat (default) @@ -70,8 +72,8 @@ Options --no-dmesg no backup copy of dmesg --mysql backup copy of mysql processes (default) --no-mysql no backup copy of mysql processes - --services backup copy of services states (default) - --no-services no backup copy of services states + --systemctl backup copy of services states (default) + --no-systemctl no backup copy of services states -v, --verbose print details about backup steps -V, --version print version and exit -h, --help print this message and exit From d2fa14fb4f0d565c0ff31b80aeb0f5dbf6bd95be Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 24 Mar 2022 18:15:56 +0100 Subject: [PATCH 30/79] backup-server-state: release 22.03.5 --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6500c19b..1afc4f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evocheck: upstream release 22.03.1 -* evolinux-base: backup-server-state release 22.03.3 +* evolinux-base: backup-server-state release 22.03.5 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.3 and use includes directory @@ -26,7 +26,6 @@ The **patch** part changes is incremented if multiple releases happen the same m * Repair keepalived role * generate-ldif: Correct generated entries for php-fpm in containers * redis: Remount /usr with RW before adding nagios plugin -* evolinux-base: fix show_help in backup-server-state.sh ### Removed From bbc1bae43754ede8882c95d81c92c6b4a6fdba55 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 25 Mar 2022 14:57:10 +0100 Subject: [PATCH 31/79] minifirewall: upstream release 22.03.4 --- CHANGELOG.md | 2 +- minifirewall/files/minifirewall | 42 ++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1afc4f9f..42247241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: backup-server-state release 22.03.5 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld -* minifirewall: upstream release 22.03.3 and use includes directory +* minifirewall: upstream release 22.03.4 * openvpn: use a subnet topology instead of the net30 default topology ### Fixed diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index 9e8ff67f..cb707673 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -28,7 +28,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.03.3" +VERSION="22.03.4" NAME="minifirewall" # shellcheck disable=SC2034 @@ -97,6 +97,21 @@ BACKUPSERVERS='' LEGACY_CONFIG='off' +## pseudo dry-run : +## Uncomment and call these functions instead of the real iptables and ip6tables commands +# IPT="fake_iptables" +# IPT6="fake_ip6tables" +# fake_iptables() { +# printf "DRY-RUN iptables %s\n" "$*" +# } +# fake_ip6tables() { +# printf "DRY-RUN ip6tables %s\n" "$*" +# } +## Beware that commands executed from included files are not modified by this trick. + +sort_values() { + echo "$*" | tr ' ' '\n' | sort -h +} is_ipv6_enabled() { test "${IPV6}" != "off" } @@ -303,6 +318,31 @@ start() { # * from configuration directory (/etc/minifirewall.d/*) source_includes + # IP/ports lists are sorted to have consistent ordering + # You can disable this feature by simply commenting the following lines + LOOPBACK=$(sort_values ${LOOPBACK}) + INTLAN=$(sort_values ${INTLAN}) + TRUSTEDIPS=$(sort_values ${TRUSTEDIPS}) + PRIVILEGIEDIPS=$(sort_values ${PRIVILEGIEDIPS}) + SERVICESTCP1p=$(sort_values ${SERVICESTCP1p}) + SERVICESUDP1p=$(sort_values ${SERVICESUDP1p}) + SERVICESTCP1=$(sort_values ${SERVICESTCP1}) + SERVICESUDP1=$(sort_values ${SERVICESUDP1}) + SERVICESTCP2=$(sort_values ${SERVICESTCP2}) + SERVICESUDP2=$(sort_values ${SERVICESUDP2}) + SERVICESTCP3=$(sort_values ${SERVICESTCP3}) + SERVICESUDP3=$(sort_values ${SERVICESUDP3}) + DNSSERVEURS=$(sort_values ${DNSSERVEURS}) + HTTPSITES=$(sort_values ${HTTPSITES}) + HTTPSSITES=$(sort_values ${HTTPSSITES}) + FTPSITES=$(sort_values ${FTPSITES}) + SSHOK=$(sort_values ${SSHOK}) + SMTPOK=$(sort_values ${SMTPOK}) + SMTPSECUREOK=$(sort_values ${SMTPSECUREOK}) + NTPOK=$(sort_values ${NTPOK}) + PROXYBYPASS=$(sort_values ${PROXYBYPASS}) + BACKUPSERVERS=$(sort_values ${BACKUPSERVERS}) + # Trusted ip addresses ${IPT} -N ONLYTRUSTED ${IPT} -A ONLYTRUSTED -j LOG_DROP From 85d429295ff2abe231772ec61547a36cc97197a2 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 25 Mar 2022 18:12:24 +0100 Subject: [PATCH 32/79] minifirewall: tail template follows symlinks --- CHANGELOG.md | 1 + minifirewall/tasks/tail.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42247241..1bccf9ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.4 +* minifirewall: tail template follows symlinks * openvpn: use a subnet topology instead of the net30 default topology ### Fixed diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index 199b4c7a..a1bfba64 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -4,6 +4,7 @@ src: "{{ item }}" dest: "/etc/minifirewall.d/{{ minifirewall_tail_file }}" force: "{{ minifirewall_tail_force | bool }}" + follow: yes loop: "{{ query('first_found', templates) }}" vars: templates: From 54bf9c1854f46dcf481f907ad4e3e57feb61642a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 27 Mar 2022 09:18:15 +0200 Subject: [PATCH 33/79] evolinux-base: rename backup-server-state to dump-server-state --- CHANGELOG.md | 2 +- ...p-server-state.sh => dump-server-state.sh} | 312 +++++++++--------- evolinux-base/tasks/utils.yml | 18 +- 3 files changed, 163 insertions(+), 169 deletions(-) rename evolinux-base/files/{backup-server-state.sh => dump-server-state.sh} (70%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bccf9ef..c1c90020 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evocheck: upstream release 22.03.1 -* evolinux-base: backup-server-state release 22.03.5 +* evolinux-base: rename backup-server-state to dump-server-state * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * generate-ldif: Add services check for bkctld * minifirewall: upstream release 22.03.4 diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/dump-server-state.sh similarity index 70% rename from evolinux-base/files/backup-server-state.sh rename to evolinux-base/files/dump-server-state.sh index bc0eedd7..bdc1e301 100644 --- a/evolinux-base/files/backup-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -1,11 +1,11 @@ #!/bin/sh -PROGNAME="backup-server-state" +PROGNAME="dump-server-state" -VERSION="22.03.5" +VERSION="22.03.6" readonly VERSION -backup_dir= +dump_dir= rc=0 # base functions @@ -15,7 +15,9 @@ show_version() { ${PROGNAME} version ${VERSION} Copyright 2018-2022 Evolix , - Jérémy Lecour + Jérémy Lecour , + Éric Morino , + Brice Waegeneire and others. ${PROGNAME} comes with ABSOLUTELY NO WARRANTY.This is free software, @@ -25,58 +27,38 @@ END } show_help() { cat < "${backup_dir}/apt-config.txt") + last_result=$(${apt_config_bin} dump > "${dump_dir}/apt-config.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -182,8 +164,8 @@ backup_apt_config() { fi } -backup_dpkg_full() { - debug "Backup DPkg full state" +do_dpkg_full() { + debug "## DPkg full state" dir_state_status="/var/lib/dpkg/status" @@ -195,7 +177,7 @@ backup_dpkg_full() { dpkg_dir=$(dirname "${dir_state_status}") - last_result=$(mkdir -p "${backup_dir}${dpkg_dir}" && chmod -R 755 "${backup_dir}${dpkg_dir}") + last_result=$(mkdir -p "${dump_dir}${dpkg_dir}" && chmod -R 755 "${dump_dir}${dpkg_dir}") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -209,7 +191,7 @@ backup_dpkg_full() { rsync_bin=$(command -v rsync) if [ -n "${rsync_bin}" ]; then - last_result=$(${rsync_bin} -ah --itemize-changes --exclude='*-old' "${dpkg_dir}/" "${backup_dir}${dpkg_dir}/") + last_result=$(${rsync_bin} -ah --itemize-changes --exclude='*-old' "${dpkg_dir}/" "${dump_dir}${dpkg_dir}/") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -222,7 +204,7 @@ backup_dpkg_full() { else debug "* rsync not found" - last_result=$(cp -r "${dpkg_dir}/*" "${backup_dir}${dpkg_dir}/" && rm -rf "${backup_dir}${dpkg_dir}/*-old") + last_result=$(cp -r "${dpkg_dir}/*" "${dump_dir}${dpkg_dir}/" && rm -rf "${dump_dir}${dpkg_dir}/*-old") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -235,8 +217,8 @@ backup_dpkg_full() { fi } -backup_dpkg_status() { - debug "Backup DPkg status" +do_dpkg_status() { + debug "## DPkg status" dir_state_status="/var/lib/dpkg/status" @@ -246,7 +228,7 @@ backup_dpkg_status() { eval "$(${apt_config_bin} shell dir_state_status Dir::State::status)" fi - last_result=$(cp "${dir_state_status}" "${backup_dir}/dpkg-status.txt") + last_result=$(cp "${dir_state_status}" "${dump_dir}/dpkg-status.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -258,13 +240,13 @@ backup_dpkg_status() { fi } -backup_packages() { - debug "Backup list of installed package" +do_packages() { + debug "## List of installed package" dpkg_bin=$(command -v dpkg) if [ -n "${dpkg_bin}" ]; then - last_result=$(${dpkg_bin} --get-selections "*" > "${backup_dir}/current_packages.txt") + last_result=$(${dpkg_bin} --get-selections "*" > "${dump_dir}/current_packages.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -279,10 +261,10 @@ backup_packages() { fi } -backup_uname() { - debug "Backup uname" +do_uname() { + debug "## uname" - last_result=$(uname -a > "${backup_dir}/uname.txt") + last_result=$(uname -a > "${dump_dir}/uname.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -294,10 +276,10 @@ backup_uname() { fi } -backup_uptime() { - debug "Backup uptime" +do_uptime() { + debug "## uptime" - last_result=$(uptime > "${backup_dir}/uptime.txt") + last_result=$(uptime > "${dump_dir}/uptime.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -309,10 +291,10 @@ backup_uptime() { fi } -backup_processes() { - debug "Backup process list" +do_processes() { + debug "## Process list" - last_result=$(ps fauxw > "${backup_dir}/ps.txt") + last_result=$(ps fauxw > "${dump_dir}/ps.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -326,7 +308,7 @@ backup_processes() { pstree_bin=$(command -v pstree) if [ -n "${pstree_bin}" ]; then - last_result=$(${pstree_bin} -pan > "${backup_dir}/pstree.txt") + last_result=$(${pstree_bin} -pan > "${dump_dir}/pstree.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -339,13 +321,13 @@ backup_processes() { fi } -backup_netstat() { - debug "Backup network status" +do_netstat() { + debug "## Network status" ss_bin=$(command -v ss) if [ -n "${ss_bin}" ]; then - last_result=$(${ss_bin} -tanpul > "${backup_dir}/netstat-ss.txt") + last_result=$(${ss_bin} -tanpul > "${dump_dir}/netstat-ss.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -362,7 +344,7 @@ backup_netstat() { netstat_bin=$(command -v netstat) if [ -n "${netstat_bin}" ]; then - last_result=$(netstat -laputen > "${backup_dir}/netstat-legacy.txt") + last_result=$(netstat -laputen > "${dump_dir}/netstat-legacy.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -377,13 +359,13 @@ backup_netstat() { fi } -backup_netcfg() { - debug "Backup network configuration" +do_netcfg() { + debug "## Network configuration" ip_bin=$(command -v ip) if [ -n "${ip_bin}" ]; then - last_result=$(${ip_bin} address show > "${backup_dir}/ip-address.txt") + last_result=$(${ip_bin} address show > "${dump_dir}/ip-address.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -394,7 +376,7 @@ backup_netcfg() { rc=10 fi - last_result=$(${ip_bin} route show > "${backup_dir}/ip-route.txt") + last_result=$(${ip_bin} route show > "${dump_dir}/ip-route.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -410,7 +392,7 @@ backup_netcfg() { ifconfig_bin=$(command -v ifconfig) if [ -n "${ifconfig_bin}" ]; then - last_result=$(${ifconfig_bin} > "${backup_dir}/ifconfig.txt") + last_result=$(${ifconfig_bin} > "${dump_dir}/ifconfig.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -426,8 +408,8 @@ backup_netcfg() { fi } -backup_iptables() { - debug "Backup iptables" +do_iptables() { + debug "## iptables" iptables_bin=$(command -v iptables) nft_bin=$(command -v nft) @@ -436,7 +418,7 @@ backup_iptables() { debug "* nft found, skip iptables" else if [ -n "${iptables_bin}" ]; then - last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${backup_dir}/iptables-v.txt") + last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${dump_dir}/iptables-v.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -447,7 +429,7 @@ backup_iptables() { rc=10 fi - last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } >> "${backup_dir}/iptables.txt") + last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } >> "${dump_dir}/iptables.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -464,7 +446,7 @@ backup_iptables() { iptables_save_bin=$(command -v iptables-save) if [ -n "${iptables_save_bin}" ]; then - last_result=$(${iptables_save_bin} > "${backup_dir}/iptables-save.txt") + last_result=$(${iptables_save_bin} > "${dump_dir}/iptables-save.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -480,13 +462,13 @@ backup_iptables() { fi } -backup_sysctl() { - debug "Backup sysctl values" +do_sysctl() { + debug "## sysctl values" sysctl_bin=$(command -v sysctl) if [ -n "${sysctl_bin}" ]; then - last_result=$(${sysctl_bin} -a --ignore 2>/dev/null | sort -h > "${backup_dir}/sysctl.txt") + last_result=$(${sysctl_bin} -a --ignore 2>/dev/null | sort -h > "${dump_dir}/sysctl.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -501,13 +483,13 @@ backup_sysctl() { fi } -backup_virsh() { - debug "Backup virsh list" +do_virsh() { + debug "## virsh list" virsh_bin=$(command -v virsh) if [ -n "${virsh_bin}" ]; then - last_result=$(${virsh_bin} list --all > "${backup_dir}/virsh-list.txt") + last_result=$(${virsh_bin} list --all > "${dump_dir}/virsh-list.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -522,13 +504,13 @@ backup_virsh() { fi } -backup_lxc() { - debug "Backup lxc list" +do_lxc() { + debug "## lxc list" lxc_ls_bin=$(command -v lxc-ls) if [ -n "${lxc_ls_bin}" ]; then - last_result=$(${lxc_ls_bin} --fancy > "${backup_dir}/lxc-list.txt") + last_result=$(${lxc_ls_bin} --fancy > "${dump_dir}/lxc-list.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -543,8 +525,8 @@ backup_lxc() { fi } -backup_disks() { - debug "Backup disks" +do_disks() { + debug "## Disks" lsblk_bin=$(command -v lsblk) awk_bin=$(command -v awk) @@ -554,7 +536,7 @@ backup_disks() { for disk in ${disks}; do dd_bin=$(command -v dd) if [ -n "${dd_bin}" ]; then - last_result=$(${dd_bin} if="/dev/${disk}" of="${backup_dir}/MBR-${disk}" bs=512 count=1 2>&1) + last_result=$(${dd_bin} if="/dev/${disk}" of="${dump_dir}/MBR-${disk}" bs=512 count=1 2>&1) last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -569,7 +551,7 @@ backup_disks() { fi fdisk_bin=$(command -v fdisk) if [ -n "${fdisk_bin}" ]; then - last_result=$(${fdisk_bin} -l "/dev/${disk}" > "${backup_dir}/partitions-${disk}" 2>&1) + last_result=$(${fdisk_bin} -l "/dev/${disk}" > "${dump_dir}/partitions-${disk}" 2>&1) last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -583,7 +565,7 @@ backup_disks() { debug "* fdisk not found" fi done - cat "${backup_dir}"/partitions-* > "${backup_dir}/partitions" + cat "${dump_dir}"/partitions-* > "${dump_dir}/partitions" else if [ -n "${lsblk_bin}" ]; then debug "* lsblk not found" @@ -594,13 +576,13 @@ backup_disks() { fi } -backup_mount() { - debug "Backup mount points" +do_mount() { + debug "## Mount points" findmnt_bin=$(command -v findmnt) if [ -n "${findmnt_bin}" ]; then - last_result=$(${findmnt_bin} > "${backup_dir}/mount.txt") + last_result=$(${findmnt_bin} > "${dump_dir}/mount.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -616,7 +598,7 @@ backup_mount() { mount_bin=$(command -v mount) if [ -n "${mount_bin}" ]; then - last_result=$(${mount_bin} > "${backup_dir}/mount.txt") + last_result=$(${mount_bin} > "${dump_dir}/mount.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -632,13 +614,13 @@ backup_mount() { fi } -backup_df() { - debug "Backup df" +do_df() { + debug "## df" df_bin=$(command -v df) if [ -n "${df_bin}" ]; then - last_result=$(${df_bin} --portability > "${backup_dir}/df.txt") + last_result=$(${df_bin} --portability > "${dump_dir}/df.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -653,13 +635,13 @@ backup_df() { fi } -backup_dmesg() { - debug "Backup dmesg" +do_dmesg() { + debug "## dmesg" dmesg_bin=$(command -v dmesg) if [ -n "${dmesg_bin}" ]; then - last_result=$(${dmesg_bin} > "${backup_dir}/dmesg.txt") + last_result=$(${dmesg_bin} > "${dump_dir}/dmesg.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -674,15 +656,15 @@ backup_dmesg() { fi } -backup_mysql_processes() { - debug "Backup mysql processes" +do_mysql_processes() { + debug "## MySQL processes" mysqladmin_bin=$(command -v mysqladmin) if [ -n "${mysqladmin_bin}" ]; then # Look for local MySQL or MariaDB process if pgrep mysqld > /dev/null || pgrep mariadbd > /dev/null; then - last_result=$(${mysqladmin_bin} --verbose processlist > "${backup_dir}/mysql-processlist.txt") + last_result=$(${mysqladmin_bin} --verbose processlist > "${dump_dir}/mysql-processlist.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -700,13 +682,13 @@ backup_mysql_processes() { fi } -backup_systemctl() { - debug "Backup services" +do_systemctl() { + debug "## Systemd services" systemctl_bin=$(command -v systemctl) if [ -n "${systemctl_bin}" ]; then - last_result=$(${systemctl_bin} --no-legend --state=failed --type=service > "${backup_dir}/systemctl-failed-services.txt") + last_result=$(${systemctl_bin} --no-legend --state=failed --type=service > "${dump_dir}/systemctl-failed-services.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -723,86 +705,86 @@ backup_systemctl() { main() { - if [ -z "${backup_dir}" ]; then - echo "ERROR: You must provide the --backup-dir argument" >&2 + if [ -z "${dump_dir}" ]; then + echo "ERROR: You must provide the --dump-dir argument" >&2 exit 1 fi - if [ -d "${backup_dir}" ]; then + if [ -d "${dump_dir}" ]; then if [ "${FORCE}" != "1" ]; then - echo "ERROR: The backup directory ${backup_dir} already exists. Delete it first." >&2 + echo "ERROR: The dump directory ${dump_dir} already exists. Delete it first." >&2 exit 2 fi else - create_backup_dir + create_dump_dir fi if [ "${DO_ETC}" -eq 1 ]; then - backup_etc + do_etc fi if [ "${DO_DPKG_FULL}" -eq 1 ]; then - backup_dpkg_full + do_dpkg_full fi if [ "${DO_DPKG_STATUS}" -eq 1 ]; then - backup_dpkg_status + do_dpkg_status fi if [ "${DO_APT_STATES}" -eq 1 ]; then - backup_apt_states + do_apt_states fi if [ "${DO_APT_CONFIG}" -eq 1 ]; then - backup_apt_config + do_apt_config fi if [ "${DO_PACKAGES}" -eq 1 ]; then - backup_packages + do_packages fi if [ "${DO_PROCESSES}" -eq 1 ]; then - backup_processes + do_processes fi if [ "${DO_UPTIME}" -eq 1 ]; then - backup_uptime + do_uptime fi if [ "${DO_UNAME}" -eq 1 ]; then - backup_uname + do_uname fi if [ "${DO_NETSTAT}" -eq 1 ]; then - backup_netstat + do_netstat fi if [ "${DO_NETCFG}" -eq 1 ]; then - backup_netcfg + do_netcfg fi if [ "${DO_IPTABLES}" -eq 1 ]; then - backup_iptables + do_iptables fi if [ "${DO_SYSCTL}" -eq 1 ]; then - backup_sysctl + do_sysctl fi if [ "${DO_VIRSH}" -eq 1 ]; then - backup_virsh + do_virsh fi if [ "${DO_LXC}" -eq 1 ]; then - backup_lxc + do_lxc fi if [ "${DO_DISKS}" -eq 1 ]; then - backup_disks + do_disks fi if [ "${DO_MOUNT}" -eq 1 ]; then - backup_mount + do_mount fi if [ "${DO_DF}" -eq 1 ]; then - backup_df + do_df fi if [ "${DO_DMESG}" -eq 1 ]; then - backup_dmesg + do_dmesg fi if [ "${DO_MYSQL_PROCESSES}" -eq 1 ]; then - backup_mysql_processes + do_mysql_processes fi if [ "${DO_SYSTEMCTL}" -eq 1 ]; then - backup_systemctl + do_systemctl fi - debug "=> Your backup is available at ${backup_dir}" + debug "=> Your dump is available at ${dump_dir}" exit ${rc} } @@ -826,23 +808,23 @@ while :; do FORCE=1 ;; - -d|--backup-dir) + -d|--dump-dir|--backup-dir) # with value separated by space if [ -n "$2" ]; then - backup_dir=$2 + dump_dir=$2 shift else - printf 'ERROR: "-d|--backup-dir" requires a non-empty option argument.\n' >&2 + printf 'ERROR: "-d|--dump-dir|--backup-dir" requires a non-empty option argument.\n' >&2 exit 1 fi ;; - --backup-dir=?*) + --dump-dir=?*|--backup-dir=?*) # with value speparated by = - backup_dir=${1#*=} + dump_dir=${1#*=} ;; - --backup-dir=) + --dump-dir=|--backup-dir=) # without value - printf 'ERROR: "--backup-dir" requires a non-empty option argument.\n' >&2 + printf 'ERROR: "--dump-dir|--backup-dir" requires a non-empty option argument.\n' >&2 exit 1 ;; diff --git a/evolinux-base/tasks/utils.yml b/evolinux-base/tasks/utils.yml index a5ff56fa..bf1ef7db 100644 --- a/evolinux-base/tasks/utils.yml +++ b/evolinux-base/tasks/utils.yml @@ -3,10 +3,22 @@ - include_role: name: evolix/remount-usr -- name: backup-server-state script is present - copy: - src: "backup-server-state.sh" +- name: move backup-server-state to dump-server-state if present + command: mv /usr/local/sbin/backup-server-state /usr/local/sbin/dump-server-state + args: + creates: /usr/local/sbin/dump-server-state + +- name: symlink backup-server-state to dump-server-state + file: + src: /usr/local/sbin/dump-server-state dest: /usr/local/sbin/backup-server-state + state: link + force: yes + +- name: dump-server-state script is present + copy: + src: "dump-server-state.sh" + dest: /usr/local/sbin/dump-server-state force: True owner: root group: root From f0b23ffa504bc2860de5383d1fb5fea0b22c6fa7 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 27 Mar 2022 09:31:06 +0200 Subject: [PATCH 34/79] dump-server-state: split backup-dir and dump-dir options parsing --- evolinux-base/files/dump-server-state.sh | 49 +++++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index bdc1e301..45db7788 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -2,7 +2,7 @@ PROGNAME="dump-server-state" -VERSION="22.03.6" +VERSION="22.03.7" readonly VERSION dump_dir= @@ -808,26 +808,63 @@ while :; do FORCE=1 ;; - -d|--dump-dir|--backup-dir) + -d|--dump-dir) # with value separated by space if [ -n "$2" ]; then dump_dir=$2 shift else - printf 'ERROR: "-d|--dump-dir|--backup-dir" requires a non-empty option argument.\n' >&2 + printf 'ERROR: "-d|--dump-dir" requires a non-empty option argument.\n' >&2 exit 1 fi ;; - --dump-dir=?*|--backup-dir=?*) + --dump-dir=?*) # with value speparated by = dump_dir=${1#*=} ;; - --dump-dir=|--backup-dir=) + --dump-dir=) # without value - printf 'ERROR: "--dump-dir|--backup-dir" requires a non-empty option argument.\n' >&2 + printf 'ERROR: "--dump-dir" requires a non-empty option argument.\n' >&2 exit 1 ;; + --backup-dir) + printf 'WARNING: "--backup-dir" is deprecated in favor of "--dump-dir".\n' + if [ -n "${dump_dir}" ]; then + debug "Dump directory is already set, let's ignore this one." + else + debug "Dump directory is not set already, let's stay backward compatible." + # with value separated by space + if [ -n "$2" ]; then + dump_dir=$2 + shift + else + printf 'ERROR: "--backup-dir" requires a non-empty option argument.\n' >&2 + exit 1 + fi + fi + ;; + --backup-dir=?*) + # with value speparated by = + printf 'WARNING: "--backup-dir" is deprecated in favor of "--dump-dir".\n' + if [ -n "${dump_dir}" ]; then + debug "Dump directory is already set, let's ignore this one." + else + debug "Dump directory is not set already, let's stay backward compatible." + dump_dir=${1#*=} + fi + ;; + --backup-dir=) + # without value + printf 'WARNING: "--backup-dir" is deprecated in favor of "--dump-dir".\n' + if [ -n "${dump_dir}" ]; then + debug "Dump directory is already set, let's ignore this one." + else + printf 'ERROR: "--backup-dir" requires a non-empty option argument.\n' >&2 + exit 1 + fi + ;; + --etc) DO_ETC=1 ;; From d0f8e6c75364e1d2fcedaae4c2219f5a8f9448fd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 27 Mar 2022 10:08:20 +0200 Subject: [PATCH 35/79] dump-server-state: upstream release 22.03.8 --- evolinux-base/files/dump-server-state.sh | 63 +++++++++++++----------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 45db7788..7adde4e4 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -1,8 +1,9 @@ #!/bin/sh PROGNAME="dump-server-state" +REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.03.7" +VERSION="22.03.8" readonly VERSION dump_dir= @@ -20,6 +21,8 @@ Copyright 2018-2022 Evolix , Brice Waegeneire and others. +${REPOSITORY} + ${PROGNAME} comes with ABSOLUTELY NO WARRANTY.This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public License v3.0 for details. @@ -31,34 +34,36 @@ ${PROGNAME} is dumping information related to the state of the server. Usage: ${PROGNAME} --dump-dir=/path/to/dump/directory [OPTIONS] -Options - -d, --dump-dir path to the directory where data will be stored - --backup-dir legacy option for dump directory - -f, --force keep existing dump directory and its content - --[no-]etc copy of /etc (default: no) - --[no-]dpkg-full copy of /var/lib/dpkg (default: no) - --[no-]dpkg-status copy of /var/lib/dpkg/status (default: yes) - --[no-]apt-states copy of apt extended states (default: yes) - --[no-]apt-config copy of apt configuration (default: yes) - --[no-]packages copy of dpkg selections (default: yes) - --[no-]processes copy of process list (default: yes) - --[no-]uname copy of uname value (default: yes) - --[no-]uptime copy of uptime value (default: yes) - --[no-]netstat copy of netstat (default: yes) - --[no-]netcfg copy of network configuration (default: yes) - --[no-]iptables copy of iptables (default: yes) - --[no-]sysctl copy of sysctl values (default: yes) - --[no-]virsh copy of virsh list (default: yes) - --[no-]lxc copy of lxc list (default: yes) - --[no-]disks copy of MBR and partitions (default: yes) - --[no-]mount copy of mount points (default: yes) - --[no-]df copy of disk usage (default: yes) - --[no-]dmesg copy of dmesg (default: yes) - --[no-]mysql copy of mysql processes (default: yes) - --[no-]systemctl copy of systemd services states (default: yes) - -v, --verbose print details about each step - -V, --version print version and exit - -h, --help print this message and exit +Main options + -d, --dump-dir path to the directory where data will be stored + --backup-dir legacy option for dump directory + -f, --force keep existing dump directory and its content + -v, --verbose print details about each step + -V, --version print version and exit + -h, --help print this message and exit + +Dump options + --[no-]etc copy of /etc (default: no) + --[no-]dpkg-full copy of /var/lib/dpkg (default: no) + --[no-]dpkg-status copy of /var/lib/dpkg/status (default: yes) + --[no-]apt-states copy of apt extended states (default: yes) + --[no-]apt-config copy of apt configuration (default: yes) + --[no-]packages copy of dpkg selections (default: yes) + --[no-]processes copy of process list (default: yes) + --[no-]uname copy of uname value (default: yes) + --[no-]uptime copy of uptime value (default: yes) + --[no-]netstat copy of netstat (default: yes) + --[no-]netcfg copy of network configuration (default: yes) + --[no-]iptables copy of iptables (default: yes) + --[no-]sysctl copy of sysctl values (default: yes) + --[no-]virsh copy of virsh list (default: yes) + --[no-]lxc copy of lxc list (default: yes) + --[no-]disks copy of MBR and partitions (default: yes) + --[no-]mount copy of mount points (default: yes) + --[no-]df copy of disk usage (default: yes) + --[no-]dmesg copy of dmesg (default: yes) + --[no-]mysql copy of mysql processes (default: yes) + --[no-]systemctl copy of systemd services states (default: yes) END } debug() { From 214b6e0d6a342b11d610f03e763b19eed31c28dd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 27 Mar 2022 10:40:52 +0200 Subject: [PATCH 36/79] dump-server-state: upstream release 22.03.9 --- evolinux-base/files/dump-server-state.sh | 367 +++++++++++++---------- 1 file changed, 215 insertions(+), 152 deletions(-) diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 7adde4e4..0a779d3a 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.03.8" +VERSION="22.03.9" readonly VERSION dump_dir= @@ -38,11 +38,13 @@ Main options -d, --dump-dir path to the directory where data will be stored --backup-dir legacy option for dump directory -f, --force keep existing dump directory and its content - -v, --verbose print details about each step + -v, --verbose print details about each task -V, --version print version and exit -h, --help print this message and exit -Dump options +Tasks options + --all reset options to execute all tasks + --none reset options to execute no task --[no-]etc copy of /etc (default: no) --[no-]dpkg-full copy of /var/lib/dpkg (default: no) --[no-]dpkg-status copy of /var/lib/dpkg/status (default: yes) @@ -64,6 +66,12 @@ Dump options --[no-]dmesg copy of dmesg (default: yes) --[no-]mysql copy of mysql processes (default: yes) --[no-]systemctl copy of systemd services states (default: yes) + +Tasks options order matters. They are evaluated from left to right. +Examples : +* "[…] --none --uname" will do only the uname task +* "[…] --all --no-etc" will do everything but the etc task +* "[…] --etc --none --mysql" will do only the mysql task END } debug() { @@ -73,7 +81,7 @@ debug() { } create_dump_dir() { - debug "## Create ${dump_dir}" + debug "Task: Create ${dump_dir}" last_result=$(mkdir -p "${dump_dir}" && chmod -R 755 "${dump_dir}") last_rc=$? @@ -87,8 +95,8 @@ create_dump_dir() { fi } -do_etc() { - debug "## /etc" +task_etc() { + debug "Task: /etc" rsync_bin=$(command -v rsync) @@ -118,7 +126,7 @@ do_etc() { fi } -do_apt_states() { +task_apt_states() { apt_dir="/" apt_dir_state="var/lib/apt" apt_dir_state_extended_states="extended_states" @@ -133,7 +141,7 @@ do_apt_states() { extended_states="${apt_dir}/${apt_dir_state}/${apt_dir_state_extended_states}" if [ -f "${extended_states}" ]; then - debug "## APT states" + debug "Task: APT states" last_result=$(cp -r "${extended_states}" "${dump_dir}/apt-extended-states.txt") last_rc=$? @@ -148,8 +156,8 @@ do_apt_states() { fi } -do_apt_config() { - debug "## APT config" +task_apt_config() { + debug "Task: APT config" apt_config_bin=$(command -v apt-config) @@ -169,8 +177,8 @@ do_apt_config() { fi } -do_dpkg_full() { - debug "## DPkg full state" +task_dpkg_full() { + debug "Task: DPkg full state" dir_state_status="/var/lib/dpkg/status" @@ -222,8 +230,8 @@ do_dpkg_full() { fi } -do_dpkg_status() { - debug "## DPkg status" +task_dpkg_status() { + debug "Task: DPkg status" dir_state_status="/var/lib/dpkg/status" @@ -245,8 +253,8 @@ do_dpkg_status() { fi } -do_packages() { - debug "## List of installed package" +task_packages() { + debug "Task: List of installed package" dpkg_bin=$(command -v dpkg) @@ -266,8 +274,8 @@ do_packages() { fi } -do_uname() { - debug "## uname" +task_uname() { + debug "Task: uname" last_result=$(uname -a > "${dump_dir}/uname.txt") last_rc=$? @@ -281,8 +289,8 @@ do_uname() { fi } -do_uptime() { - debug "## uptime" +task_uptime() { + debug "Task: uptime" last_result=$(uptime > "${dump_dir}/uptime.txt") last_rc=$? @@ -296,8 +304,8 @@ do_uptime() { fi } -do_processes() { - debug "## Process list" +task_processes() { + debug "Task: Process list" last_result=$(ps fauxw > "${dump_dir}/ps.txt") last_rc=$? @@ -326,8 +334,8 @@ do_processes() { fi } -do_netstat() { - debug "## Network status" +task_netstat() { + debug "Task: Network status" ss_bin=$(command -v ss) @@ -364,8 +372,8 @@ do_netstat() { fi } -do_netcfg() { - debug "## Network configuration" +task_netcfg() { + debug "Task: Network configuration" ip_bin=$(command -v ip) @@ -413,8 +421,8 @@ do_netcfg() { fi } -do_iptables() { - debug "## iptables" +task_iptables() { + debug "Task: iptables" iptables_bin=$(command -v iptables) nft_bin=$(command -v nft) @@ -467,8 +475,8 @@ do_iptables() { fi } -do_sysctl() { - debug "## sysctl values" +task_sysctl() { + debug "Task: sysctl values" sysctl_bin=$(command -v sysctl) @@ -488,8 +496,8 @@ do_sysctl() { fi } -do_virsh() { - debug "## virsh list" +task_virsh() { + debug "Task: virsh list" virsh_bin=$(command -v virsh) @@ -509,8 +517,8 @@ do_virsh() { fi } -do_lxc() { - debug "## lxc list" +task_lxc() { + debug "Task: lxc list" lxc_ls_bin=$(command -v lxc-ls) @@ -530,8 +538,8 @@ do_lxc() { fi } -do_disks() { - debug "## Disks" +task_disks() { + debug "Task: Disks" lsblk_bin=$(command -v lsblk) awk_bin=$(command -v awk) @@ -581,8 +589,8 @@ do_disks() { fi } -do_mount() { - debug "## Mount points" +task_mount() { + debug "Task: Mount points" findmnt_bin=$(command -v findmnt) @@ -619,8 +627,8 @@ do_mount() { fi } -do_df() { - debug "## df" +task_df() { + debug "Task: df" df_bin=$(command -v df) @@ -640,8 +648,8 @@ do_df() { fi } -do_dmesg() { - debug "## dmesg" +task_dmesg() { + debug "Task: dmesg" dmesg_bin=$(command -v dmesg) @@ -661,8 +669,8 @@ do_dmesg() { fi } -do_mysql_processes() { - debug "## MySQL processes" +task_mysql_processes() { + debug "Task: MySQL processes" mysqladmin_bin=$(command -v mysqladmin) @@ -687,8 +695,8 @@ do_mysql_processes() { fi } -do_systemctl() { - debug "## Systemd services" +task_systemctl() { + debug "Task: Systemd services" systemctl_bin=$(command -v systemctl) @@ -708,7 +716,6 @@ do_systemctl() { fi } - main() { if [ -z "${dump_dir}" ]; then echo "ERROR: You must provide the --dump-dir argument" >&2 @@ -724,68 +731,68 @@ main() { create_dump_dir fi - if [ "${DO_ETC}" -eq 1 ]; then - do_etc + if [ "${TASK_ETC}" -eq 1 ]; then + task_etc fi - if [ "${DO_DPKG_FULL}" -eq 1 ]; then - do_dpkg_full + if [ "${TASK_DPKG_FULL}" -eq 1 ]; then + task_dpkg_full fi - if [ "${DO_DPKG_STATUS}" -eq 1 ]; then - do_dpkg_status + if [ "${TASK_DPKG_STATUS}" -eq 1 ]; then + task_dpkg_status fi - if [ "${DO_APT_STATES}" -eq 1 ]; then - do_apt_states + if [ "${TASK_APT_STATES}" -eq 1 ]; then + task_apt_states fi - if [ "${DO_APT_CONFIG}" -eq 1 ]; then - do_apt_config + if [ "${TASK_APT_CONFIG}" -eq 1 ]; then + task_apt_config fi - if [ "${DO_PACKAGES}" -eq 1 ]; then - do_packages + if [ "${TASK_PACKAGES}" -eq 1 ]; then + task_packages fi - if [ "${DO_PROCESSES}" -eq 1 ]; then - do_processes + if [ "${TASK_PROCESSES}" -eq 1 ]; then + task_processes fi - if [ "${DO_UPTIME}" -eq 1 ]; then - do_uptime + if [ "${TASK_UPTIME}" -eq 1 ]; then + task_uptime fi - if [ "${DO_UNAME}" -eq 1 ]; then - do_uname + if [ "${TASK_UNAME}" -eq 1 ]; then + task_uname fi - if [ "${DO_NETSTAT}" -eq 1 ]; then - do_netstat + if [ "${TASK_NETSTAT}" -eq 1 ]; then + task_netstat fi - if [ "${DO_NETCFG}" -eq 1 ]; then - do_netcfg + if [ "${TASK_NETCFG}" -eq 1 ]; then + task_netcfg fi - if [ "${DO_IPTABLES}" -eq 1 ]; then - do_iptables + if [ "${TASK_IPTABLES}" -eq 1 ]; then + task_iptables fi - if [ "${DO_SYSCTL}" -eq 1 ]; then - do_sysctl + if [ "${TASK_SYSCTL}" -eq 1 ]; then + task_sysctl fi - if [ "${DO_VIRSH}" -eq 1 ]; then - do_virsh + if [ "${TASK_VIRSH}" -eq 1 ]; then + task_virsh fi - if [ "${DO_LXC}" -eq 1 ]; then - do_lxc + if [ "${TASK_LXC}" -eq 1 ]; then + task_lxc fi - if [ "${DO_DISKS}" -eq 1 ]; then - do_disks + if [ "${TASK_DISKS}" -eq 1 ]; then + task_disks fi - if [ "${DO_MOUNT}" -eq 1 ]; then - do_mount + if [ "${TASK_MOUNT}" -eq 1 ]; then + task_mount fi - if [ "${DO_DF}" -eq 1 ]; then - do_df + if [ "${TASK_DF}" -eq 1 ]; then + task_df fi - if [ "${DO_DMESG}" -eq 1 ]; then - do_dmesg + if [ "${TASK_DMESG}" -eq 1 ]; then + task_dmesg fi - if [ "${DO_MYSQL_PROCESSES}" -eq 1 ]; then - do_mysql_processes + if [ "${TASK_MYSQL_PROCESSES}" -eq 1 ]; then + task_mysql_processes fi - if [ "${DO_SYSTEMCTL}" -eq 1 ]; then - do_systemctl + if [ "${TASK_SYSTEMCTL}" -eq 1 ]; then + task_systemctl fi @@ -870,151 +877,207 @@ while :; do fi ;; + --all) + for option in \ + TASK_ETC \ + TASK_DPKG_FULL \ + TASK_DPKG_STATUS \ + TASK_APT_STATES \ + TASK_APT_CONFIG \ + TASK_PACKAGES \ + TASK_PROCESSES \ + TASK_UNAME \ + TASK_UPTIME \ + TASK_NETSTAT \ + TASK_NETCFG \ + TASK_IPTABLES \ + TASK_SYSCTL \ + TASK_VIRSH \ + TASK_LXC \ + TASK_DISKS \ + TASK_MOUNT \ + TASK_DF \ + TASK_DMESG \ + TASK_MYSQL_PROCESSES \ + TASK_SYSTEMCTL + do + eval "${option}=1" + done + ;; + + --none) + for option in \ + TASK_ETC \ + TASK_DPKG_FULL \ + TASK_DPKG_STATUS \ + TASK_APT_STATES \ + TASK_APT_CONFIG \ + TASK_PACKAGES \ + TASK_PROCESSES \ + TASK_UNAME \ + TASK_UPTIME \ + TASK_NETSTAT \ + TASK_NETCFG \ + TASK_IPTABLES \ + TASK_SYSCTL \ + TASK_VIRSH \ + TASK_LXC \ + TASK_DISKS \ + TASK_MOUNT \ + TASK_DF \ + TASK_DMESG \ + TASK_MYSQL_PROCESSES \ + TASK_SYSTEMCTL + do + eval "${option}=0" + done + ;; + --etc) - DO_ETC=1 + TASK_ETC=1 ;; --no-etc) - DO_ETC=0 + TASK_ETC=0 ;; --dpkg-full) - DO_DPKG_FULL=1 + TASK_DPKG_FULL=1 ;; --no-dpkg-full) - DO_DPKG_FULL=0 + TASK_DPKG_FULL=0 ;; --dpkg-status) - DO_DPKG_STATUS=1 + TASK_DPKG_STATUS=1 ;; --no-dpkg-status) - DO_DPKG_STATUS=0 + TASK_DPKG_STATUS=0 ;; --apt-states) - DO_APT_STATES=1 + TASK_APT_STATES=1 ;; --no-apt-states) - DO_APT_STATES=0 + TASK_APT_STATES=0 ;; --apt-config) - DO_APT_CONFIG=1 + TASK_APT_CONFIG=1 ;; --no-apt-config) - DO_APT_CONFIG=0 + TASK_APT_CONFIG=0 ;; --packages) - DO_PACKAGES=1 + TASK_PACKAGES=1 ;; --no-packages) - DO_PACKAGES=0 + TASK_PACKAGES=0 ;; --processes) - DO_PROCESSES=1 + TASK_PROCESSES=1 ;; --no-processes) - DO_PROCESSES=0 + TASK_PROCESSES=0 ;; --uptime) - DO_UPTIME=1 + TASK_UPTIME=1 ;; --no-uptime) - DO_UPTIME=0 + TASK_UPTIME=0 ;; --uname) - DO_UNAME=1 + TASK_UNAME=1 ;; --no-uname) - DO_UNAME=0 + TASK_UNAME=0 ;; --netstat) - DO_NETSTAT=1 + TASK_NETSTAT=1 ;; --no-netstat) - DO_NETSTAT=0 + TASK_NETSTAT=0 ;; --netcfg) - DO_NETCFG=1 + TASK_NETCFG=1 ;; --no-netcfg) - DO_NETCFG=0 + TASK_NETCFG=0 ;; --iptables) - DO_IPTABLES=1 + TASK_IPTABLES=1 ;; --no-iptables) - DO_IPTABLES=0 + TASK_IPTABLES=0 ;; --sysctl) - DO_SYSCTL=1 + TASK_SYSCTL=1 ;; --no-sysctl) - DO_SYSCTL=0 + TASK_SYSCTL=0 ;; --virsh) - DO_VIRSH=1 + TASK_VIRSH=1 ;; --no-virsh) - DO_VIRSH=0 + TASK_VIRSH=0 ;; --lxc) - DO_LXC=1 + TASK_LXC=1 ;; --no-lxc) - DO_LXC=0 + TASK_LXC=0 ;; --disks) - DO_DISKS=1 + TASK_DISKS=1 ;; --no-disks) - DO_DISKS=0 + TASK_DISKS=0 ;; --mount) - DO_MOUNT=1 + TASK_MOUNT=1 ;; --no-mount) - DO_MOUNT=0 + TASK_MOUNT=0 ;; --df) - DO_DF=1 + TASK_DF=1 ;; --no-df) - DO_DF=0 + TASK_DF=0 ;; --dmesg) - DO_DMESG=1 + TASK_DMESG=1 ;; --no-dmesg) - DO_DMESG=0 + TASK_DMESG=0 ;; --mysql-processes) - DO_MYSQL_PROCESSES=1 + TASK_MYSQL_PROCESSES=1 ;; --no-mysql-processes) - DO_MYSQL_PROCESSES=0 + TASK_MYSQL_PROCESSES=0 ;; --systemctl) - DO_SYSTEMCTL=1 + TASK_SYSTEMCTL=1 ;; --no-systemctl) - DO_SYSTEMCTL=0 + TASK_SYSTEMCTL=0 ;; --) @@ -1039,27 +1102,27 @@ done # Default values : "${VERBOSE:=0}" : "${FORCE:=0}" -: "${DO_ETC:=0}" -: "${DO_DPKG_FULL:=0}" -: "${DO_DPKG_STATUS:=1}" -: "${DO_APT_STATES:=1}" -: "${DO_APT_CONFIG:=1}" -: "${DO_PACKAGES:=1}" -: "${DO_PROCESSES:=1}" -: "${DO_UNAME:=1}" -: "${DO_UPTIME:=1}" -: "${DO_NETSTAT:=1}" -: "${DO_NETCFG:=1}" -: "${DO_IPTABLES:=1}" -: "${DO_SYSCTL:=1}" -: "${DO_VIRSH:=1}" -: "${DO_LXC:=1}" -: "${DO_DISKS:=1}" -: "${DO_MOUNT:=1}" -: "${DO_DF:=1}" -: "${DO_DMESG:=1}" -: "${DO_MYSQL_PROCESSES:=1}" -: "${DO_SYSTEMCTL:=1}" +: "${TASK_ETC:=0}" +: "${TASK_DPKG_FULL:=0}" +: "${TASK_DPKG_STATUS:=1}" +: "${TASK_APT_STATES:=1}" +: "${TASK_APT_CONFIG:=1}" +: "${TASK_PACKAGES:=1}" +: "${TASK_PROCESSES:=1}" +: "${TASK_UNAME:=1}" +: "${TASK_UPTIME:=1}" +: "${TASK_NETSTAT:=1}" +: "${TASK_NETCFG:=1}" +: "${TASK_IPTABLES:=1}" +: "${TASK_SYSCTL:=1}" +: "${TASK_VIRSH:=1}" +: "${TASK_LXC:=1}" +: "${TASK_DISKS:=1}" +: "${TASK_MOUNT:=1}" +: "${TASK_DF:=1}" +: "${TASK_DMESG:=1}" +: "${TASK_MYSQL_PROCESSES:=1}" +: "${TASK_SYSTEMCTL:=1}" export LC_ALL=C From 6ab0cb4fd1b3a044207c8b6bbd2b92636f5ef20c Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Mon, 28 Mar 2022 11:56:03 +0200 Subject: [PATCH 37/79] =?UTF-8?q?evolinux-base:=20Fix=20utils.yml=20->=20N?= =?UTF-8?q?e=20pas=20d=C3=A9placer=20inutilement=20le=20script=20qu'on=20v?= =?UTF-8?q?a=20de=20toute=20fa=C3=A7on=20=C3=A9craser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + Correction du cas d'une machine n'ayant pas le script (fail du mv initial) --- evolinux-base/tasks/utils.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/evolinux-base/tasks/utils.yml b/evolinux-base/tasks/utils.yml index bf1ef7db..084f8b35 100644 --- a/evolinux-base/tasks/utils.yml +++ b/evolinux-base/tasks/utils.yml @@ -3,18 +3,6 @@ - include_role: name: evolix/remount-usr -- name: move backup-server-state to dump-server-state if present - command: mv /usr/local/sbin/backup-server-state /usr/local/sbin/dump-server-state - args: - creates: /usr/local/sbin/dump-server-state - -- name: symlink backup-server-state to dump-server-state - file: - src: /usr/local/sbin/dump-server-state - dest: /usr/local/sbin/backup-server-state - state: link - force: yes - - name: dump-server-state script is present copy: src: "dump-server-state.sh" @@ -24,6 +12,13 @@ group: root mode: "0750" +- name: symlink backup-server-state to dump-server-state + file: + src: /usr/local/sbin/dump-server-state + dest: /usr/local/sbin/backup-server-state + state: link + force: yes + - name: "/sbin/deny script is present" copy: src: deny.sh From 1ae978c74a06f14426ccd192776bbe12850a5404 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Mar 2022 13:27:19 +0200 Subject: [PATCH 38/79] minifirewall: restore "force-restart" and fix "restart-if-needed" --- minifirewall/tasks/config.yml | 13 +------------ minifirewall/tasks/install.yml | 2 ++ minifirewall/tasks/main.yml | 8 ++++---- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index c0afd2b1..57fea0f1 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -193,24 +193,13 @@ register: minifirewall_after - name: restart minifirewall - # service: - # name: minifirewall - # state: restarted command: /etc/init.d/minifirewall restart register: minifirewall_init_restart failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" when: - minifirewall_restart_if_needed | bool - minifirewall_is_running.rc == 0 - - minifirewall_before.stat.checksum != minifirewall_after.stat.checksum - -- name: restart minifirewall (noop) - meta: noop - register: minifirewall_init_restart - failed_when: False - changed_when: False - when: not (minifirewall_restart_if_needed | bool) + - minifirewall_before.stat.checksum != minifirewall_after.stat.checksum or minifirewall_upgrade_script is changed or minifirewall_upgrade_config is changed - debug: var: minifirewall_init_restart diff --git a/minifirewall/tasks/install.yml b/minifirewall/tasks/install.yml index 5eeed116..9c0483b9 100644 --- a/minifirewall/tasks/install.yml +++ b/minifirewall/tasks/install.yml @@ -13,6 +13,7 @@ mode: "0700" owner: root group: root + register: minifirewall_upgrade_script - name: configuration is copied copy: @@ -22,6 +23,7 @@ mode: "0600" owner: root group: root + register: minifirewall_upgrade_config - name: includes directory is present file: diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index 5f442eb1..0fbb3ad6 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -22,7 +22,7 @@ when: minifirewall_tail_included | bool - name: Force restart minifirewall - command: /bin/true - notify: restart minifirewall - changed_when: False - when: minifirewall_restart_force | bool + command: /etc/init.d/minifirewall restart + register: minifirewall_init_restart + failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + when: minifirewall_restart_force | bool \ No newline at end of file From 3feacd0c6d7748ef108413d9704722ea41b3003a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Mar 2022 13:28:48 +0200 Subject: [PATCH 39/79] update CHANGELOG --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1c90020..b5c3aa01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,11 +15,12 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed * evocheck: upstream release 22.03.1 -* evolinux-base: rename backup-server-state to dump-server-state * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware +* evolinux-base: rename backup-server-state to dump-server-state * generate-ldif: Add services check for bkctld -* minifirewall: upstream release 22.03.4 +* minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks +* minifirewall: upstream release 22.03.4 * openvpn: use a subnet topology instead of the net30 default topology ### Fixed From 75459baa35499591e80daa5005c35af46d653ade Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 29 Mar 2022 09:11:35 +0200 Subject: [PATCH 40/79] dump-server-state: upstream release 22.03.10 --- CHANGELOG.md | 1 + evolinux-base/files/dump-server-state.sh | 97 ++++++++++++++---------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5c3aa01..7243ecf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evocheck: upstream release 22.03.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state +* dump-server-state: upstream release 22.03.10 * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 0a779d3a..1da5bf2f 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.03.9" +VERSION="22.03.10" readonly VERSION dump_dir= @@ -425,52 +425,65 @@ task_iptables() { debug "Task: iptables" iptables_bin=$(command -v iptables) + + if [ -n "${iptables_bin}" ]; then + last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } > "${dump_dir}/iptables-v.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* iptables -v OK" + else + debug "* iptables -v ERROR" + debug "${last_result}" + # Ignore errors because we don't know if this is nft related or a real error + # rc=10 + fi + + last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } > "${dump_dir}/iptables.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* iptables OK" + else + debug "* iptables ERROR" + debug "${last_result}" + # Ignore errors because we don't know if this is nft related or a real error + # rc=10 + fi + else + debug "* iptables not found" + fi + + iptables_save_bin=$(command -v iptables-save) + + if [ -n "${iptables_save_bin}" ]; then + last_result=$(${iptables_save_bin} > "${dump_dir}/iptables-save.txt") + last_rc=$? + + if [ ${last_rc} -eq 0 ]; then + debug "* iptables-save OK" + else + debug "* iptables-save ERROR" + debug "${last_result}" + # Ignore errors because we don't know if this is nft related or a real error + # rc=10 + fi + else + debug "* iptables-save not found" + fi + nft_bin=$(command -v nft) if [ -n "${nft_bin}" ]; then - debug "* nft found, skip iptables" - else - if [ -n "${iptables_bin}" ]; then - last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } >> "${dump_dir}/iptables-v.txt") - last_rc=$? + last_result=$(${nft_bin} list ruleset > "${dump_dir}/nft-ruleset.txt") + last_rc=$? - if [ ${last_rc} -eq 0 ]; then - debug "* iptables -v OK" - else - debug "* iptables -v ERROR" - debug "${last_result}" - rc=10 - fi - - last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } >> "${dump_dir}/iptables.txt") - last_rc=$? - - if [ ${last_rc} -eq 0 ]; then - debug "* iptables OK" - else - debug "* iptables ERROR" - debug "${last_result}" - rc=10 - fi + if [ ${last_rc} -eq 0 ]; then + debug "* nft ruleset OK" else - debug "* iptables not found" - fi - - iptables_save_bin=$(command -v iptables-save) - - if [ -n "${iptables_save_bin}" ]; then - last_result=$(${iptables_save_bin} > "${dump_dir}/iptables-save.txt") - last_rc=$? - - if [ ${last_rc} -eq 0 ]; then - debug "* iptables-save OK" - else - debug "* iptables-save ERROR" - debug "${last_result}" - rc=10 - fi - else - debug "* iptables-save not found" + debug "* nft ruleset ERROR" + debug "${last_result}" + rc=10 fi fi } From 20abe0e09aa43bbe6385a6592bb3e3cc367a0889 Mon Sep 17 00:00:00 2001 From: Mathieu Trossevin Date: Tue, 29 Mar 2022 16:06:12 +0200 Subject: [PATCH 41/79] postfix: Skip milters after amavis (in packmail) Otherwise opendkim will sign local mails twice AND sign external mails (pretending to be) from local domains as if they were local mails. --- CHANGELOG.md | 1 + postfix/templates/packmail_master.cf.j2 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7243ecf6..9ce3eaf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * Repair keepalived role * generate-ldif: Correct generated entries for php-fpm in containers * redis: Remount /usr with RW before adding nagios plugin +* postfix: Do not send mails through milters a second time after amavis (in packmail) ### Removed diff --git a/postfix/templates/packmail_master.cf.j2 b/postfix/templates/packmail_master.cf.j2 index 50aeeec4..9627fcb3 100644 --- a/postfix/templates/packmail_master.cf.j2 +++ b/postfix/templates/packmail_master.cf.j2 @@ -158,7 +158,7 @@ smtp-amavis unix - - y - 2 lmtp -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 - -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks + -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters pre-cleanup unix n - n - 0 cleanup -o virtual_alias_maps= From 31c2629d313889fb91f86169772fe4d7125367c2 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 30 Mar 2022 09:42:54 +0200 Subject: [PATCH 42/79] minifirewall: configure proxy/backup/sysctl values --- CHANGELOG.md | 2 + minifirewall/defaults/main.yml | 16 +++++ minifirewall/tasks/config.yml | 106 ++++++++++++++++++++++++++++++--- 3 files changed, 116 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ce3eaf0..49307328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Added +* minifirewall: configure proxy/backup/sysctl values + ### Changed * evocheck: upstream release 22.03.1 diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml index 51d169cb..faedfa6b 100644 --- a/minifirewall/defaults/main.yml +++ b/minifirewall/defaults/main.yml @@ -47,6 +47,22 @@ minifirewall_smtp_ok: Null minifirewall_smtp_secure_ok: Null minifirewall_ntp_ok: Null +minifirewall_proxy: "off" +minifirewall_proxyport: 8888 +minifirewall_proxybypass: + - "${INTLAN}" + - "127.0.0.0/8" + - "::1/128" +minifirewall_backupservers: Null + +minifirewall_sysctl_icmp_echo_ignore_broadcasts : Null +minifirewall_sysctl_icmp_ignore_bogus_error_responses : Null +minifirewall_sysctl_accept_source_route : Null +minifirewall_sysctl_tcp_syncookies : Null +minifirewall_sysctl_icmp_redirects : Null +minifirewall_sysctl_rp_filter : Null +minifirewall_sysctl_log_martians : Null + minifirewall_autostart: False minifirewall_restart_if_needed: True minifirewall_restart_force: False diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 57fea0f1..82b5263a 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -127,7 +127,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "DNSSERVEURS='{{ minifirewall_dns_servers | join(' ') }}'" - regexp: "DNSSERVEURS='.*'" + regexp: "DNSSERVEURS=('|\").*('|\")" create: no when: minifirewall_dns_servers is not none @@ -135,7 +135,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "HTTPSITES='{{ minifirewall_http_sites | join(' ') }}'" - regexp: "HTTPSITES='.*'" + regexp: "HTTPSITES=('|\").*('|\")" create: no when: minifirewall_http_sites is not none @@ -143,7 +143,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "HTTPSSITES='{{ minifirewall_https_sites | join(' ') }}'" - regexp: "HTTPSSITES='.*'" + regexp: "HTTPSSITES=('|\").*('|\")" create: no when: minifirewall_https_sites is not none @@ -151,7 +151,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "FTPSITES='{{ minifirewall_ftp_sites | join(' ') }}'" - regexp: "FTPSITES='.*'" + regexp: "FTPSITES=('|\").*('|\")" create: no when: minifirewall_ftp_sites is not none @@ -159,7 +159,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "SSHOK='{{ minifirewall_ssh_ok | join(' ') }}'" - regexp: "SSHOK='.*'" + regexp: "SSHOK=('|\").*('|\")" create: no when: minifirewall_ssh_ok is not none @@ -167,7 +167,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "SMTPOK='{{ minifirewall_smtp_ok | join(' ') }}'" - regexp: "SMTPOK='.*'" + regexp: "SMTPOK=('|\").*('|\")" create: no when: minifirewall_smtp_ok is not none @@ -175,7 +175,7 @@ lineinfile: dest: "/etc/default/minifirewall" line: "SMTPSECUREOK='{{ minifirewall_smtp_secure_ok | join(' ') }}'" - regexp: "SMTPSECUREOK='.*'" + regexp: "SMTPSECUREOK=('|\").*('|\")" create: no when: minifirewall_smtp_secure_ok is not none @@ -183,10 +183,100 @@ lineinfile: dest: "/etc/default/minifirewall" line: "NTPOK='{{ minifirewall_ntp_ok | join(' ') }}'" - regexp: "NTPOK='.*'" + regexp: "NTPOK=('|\").*('|\")" create: no when: minifirewall_ntp_ok is not none +- name: Configure PROXY + lineinfile: + dest: "/etc/default/minifirewall" + line: "PROXY='{{ minifirewall_proxy }}'" + regexp: "PROXY=('|\").*('|\")" + create: no + when: minifirewall_proxy is not none + +- name: Configure PROXYPORT + lineinfile: + dest: "/etc/default/minifirewall" + line: "PROXYPORT='{{ minifirewall_proxyport }}'" + regexp: "PROXYPORT=('|\").*('|\")" + create: no + when: minifirewall_proxyport is not none + +# Warning: keep double quotes for the value, +# since we often reference a shell variable that needs to be interpolated +- name: Configure PROXYBYPASS + lineinfile: + dest: "/etc/default/minifirewall" + line: "PROXYBYPASS=\"{{ minifirewall_proxybypass | join(' ') }}\"" + regexp: "PROXYBYPASS=('|\").*('|\")" + create: no + when: minifirewall_proxybypass is not none + +- name: Configure BACKUPSERVERS + lineinfile: + dest: "/etc/default/minifirewall" + line: "BACKUPSERVERS='{{ minifirewall_backupservers | join(' ') }}'" + regexp: "BACKUPSERVERS=('|\").*('|\")" + create: no + when: minifirewall_backupservers is not none + +- name: Configure SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS='{{ minifirewall_sysctl_icmp_echo_ignore_broadcasts }}'" + regexp: "SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS=('|\").*('|\")" + create: no + when: minifirewall_sysctl_icmp_echo_ignore_broadcasts is not none + +- name: Configure SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES='{{ minifirewall_sysctl_icmp_ignore_bogus_error_responses }}'" + regexp: "SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=('|\").*('|\")" + create: no + when: minifirewall_sysctl_icmp_ignore_bogus_error_responses is not none + +- name: Configure SYSCTL_ACCEPT_SOURCE_ROUTE + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_ACCEPT_SOURCE_ROUTE='{{ minifirewall_sysctl_accept_source_route }}'" + regexp: "SYSCTL_ACCEPT_SOURCE_ROUTE=('|\").*('|\")" + create: no + when: minifirewall_sysctl_accept_source_route is not none + +- name: Configure SYSCTL_TCP_SYNCOOKIES + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_TCP_SYNCOOKIES='{{ minifirewall_sysctl_tcp_syncookies }}'" + regexp: "SYSCTL_TCP_SYNCOOKIES=('|\").*('|\")" + create: no + when: minifirewall_sysctl_tcp_syncookies is not none + +- name: Configure SYSCTL_ICMP_REDIRECTS + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_ICMP_REDIRECTS='{{ minifirewall_sysctl_icmp_redirects }}'" + regexp: "SYSCTL_ICMP_REDIRECTS=('|\").*('|\")" + create: no + when: minifirewall_sysctl_icmp_redirects is not none + +- name: Configure SYSCTL_RP_FILTER + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_RP_FILTER='{{ minifirewall_sysctl_rp_filter }}'" + regexp: "SYSCTL_RP_FILTER=('|\").*('|\")" + create: no + when: minifirewall_sysctl_rp_filter is not none + +- name: Configure SYSCTL_LOG_MARTIANS + lineinfile: + dest: "/etc/default/minifirewall" + line: "SYSCTL_LOG_MARTIANS='{{ minifirewall_sysctl_log_martians }}'" + regexp: "SYSCTL_LOG_MARTIANS=('|\").*('|\")" + create: no + when: minifirewall_sysctl_log_martians is not none + - name: Stat minifirewall config file (after) stat: path: "/etc/default/minifirewall" From 5dc6a1d36b15bd126d9bbf793c559c8035ea10a1 Mon Sep 17 00:00:00 2001 From: Mathieu Trossevin Date: Wed, 23 Mar 2022 15:07:32 +0100 Subject: [PATCH 43/79] etc-git: Commit changes to /etc in containers --- CHANGELOG.md | 1 + etc-git/tasks/commit.yml | 27 +++++++++++++++++++++++++++ etc-git/tasks/lxc_commit.yml | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 etc-git/tasks/lxc_commit.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 49307328..379c0c10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Added * minifirewall: configure proxy/backup/sysctl values +* etc-git: Commit /etc in lxc containers when they are git repositories ### Changed diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml index 3f993771..2098aeeb 100644 --- a/etc-git/tasks/commit.yml +++ b/etc-git/tasks/commit.yml @@ -50,3 +50,30 @@ when: - _usr_share_scripts_git.stat.exists - _usr_share_scripts_git.stat.isdir + +- name: Check if there are lxc containers + stat: + path: /var/lib/lxc + get_attributes: no + get_checksum: no + get_mime: no + register: _var_lib_lxc + +- name: Get lxc containers and commit their /etc when needed + block: + - name: Get all lxc containers + find: + paths: /var/lib/lxc + recurse: no + file_type: directory + register: _lxc_containers + + - name: "Commit /etc in all containers" + include_tasks: + file: lxc_commit.yml + loop: "{{ _lxc_containers.files | map(attribute='path') | map('basename') }}" + loop_control: + loop_var: container + when: + - _var_lib_lxc.stat.exists + - _var_lib_lxc.stat.isdir or _var_lib_lxc.stat.islnk diff --git a/etc-git/tasks/lxc_commit.yml b/etc-git/tasks/lxc_commit.yml new file mode 100644 index 00000000..26fc8738 --- /dev/null +++ b/etc-git/tasks/lxc_commit.yml @@ -0,0 +1,35 @@ +--- +- name: "Assert that we have been called with `container` defined" + assert: + that: + - container is defined + +- name: "Define path to /etc in {{ container }} container" + set_fact: + container_etc: "{{ ('/var/lib/lxc', container, 'rootfs/etc') | path_join }}" + +- name: "Check if /etc is a git repository in {{ container }}" + stat: + path: "{{ (container_etc, '.git') | path_join }}" + get_attributes: no + get_checksum: no + get_mime: no + register: "container_etc_git" + +- name: "Evocommit /etc of {{ container }}" + command: + argv: + - /usr/local/bin/evocommit + - '--ansible' + - '--repository' + - "{{ container_etc }}" + - '--message' + - "{{ commit_message | mandatory }}" + changed_when: + - "container_etc_git_commit.stdout" + - "'CHANGED:' in container_etc_git_commit.stdout" + ignore_errors: yes + register: "container_etc_git_commit" + when: + - "container_etc_git.stat.exists" + - "container_etc_git.stat.isdir" From ed6ca9a85a924a9cdc2429783c51bf09ccb2f47c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 30 Mar 2022 22:45:09 +0200 Subject: [PATCH 44/79] minifirewall: upstream release 22.03.5 --- CHANGELOG.md | 2 +- minifirewall/files/minifirewall | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 379c0c10..9d1ca0d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks -* minifirewall: upstream release 22.03.4 +* minifirewall: upstream release 22.03.5 * openvpn: use a subnet topology instead of the net30 default topology ### Fixed diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index cb707673..f8729f79 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -28,7 +28,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.03.4" +VERSION="22.03.5" NAME="minifirewall" # shellcheck disable=SC2034 @@ -251,7 +251,7 @@ start() { if [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "1" ] || [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "0" ]; then for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do - echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = > "${proc_sys_file}" + echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" > "${proc_sys_file}" done else echo "Invalid SYSCTL_ACCEPT_SOURCE_ROUTE value '${SYSCTL_ACCEPT_SOURCE_ROUTE}', must be '0' or '1'." >&2 From f8a146d3ac4b9ca677836cfb9c62110d9c275809 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 31 Mar 2022 09:50:31 +0200 Subject: [PATCH 45/79] =?UTF-8?q?ajout=20IPv6=20par=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minifirewall/defaults/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml index faedfa6b..4c084154 100644 --- a/minifirewall/defaults/main.yml +++ b/minifirewall/defaults/main.yml @@ -23,8 +23,8 @@ minifirewall_docker: "off" minifirewall_default_trusted_ips: [] minifirewall_additional_trusted_ips: [] -# and default to ['0.0.0.0/0'] if the result is still empty -minifirewall_trusted_ips: "{{ minifirewall_default_trusted_ips | union(minifirewall_additional_trusted_ips) | unique | default(['0.0.0.0/0'], true) }}" +# and default to ['0.0.0.0/0', '::/0'] if the result is still empty +minifirewall_trusted_ips: "{{ minifirewall_default_trusted_ips | union(minifirewall_additional_trusted_ips) | unique | default(['0.0.0.0/0', '::/0'], true) }}" minifirewall_privilegied_ips: [] minifirewall_protected_ports_tcp: [22] From 6434adcc62b62b8edd8e208793282c097cbb0170 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 31 Mar 2022 15:59:38 +0200 Subject: [PATCH 46/79] nagios-nrpe: Add a check dhcp_pool --- CHANGELOG.md | 1 + nagios-nrpe/files/plugins/check_dhcp_pool | 223 ++++++++++++++++++++++ nagios-nrpe/templates/evolix.cfg.j2 | 3 +- 3 files changed, 226 insertions(+), 1 deletion(-) create mode 100755 nagios-nrpe/files/plugins/check_dhcp_pool diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d1ca0d5..2c22a6fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * minifirewall: configure proxy/backup/sysctl values * etc-git: Commit /etc in lxc containers when they are git repositories +* nagios-nrpe: Add a check dhcp_pool ### Changed diff --git a/nagios-nrpe/files/plugins/check_dhcp_pool b/nagios-nrpe/files/plugins/check_dhcp_pool new file mode 100755 index 00000000..29157c2e --- /dev/null +++ b/nagios-nrpe/files/plugins/check_dhcp_pool @@ -0,0 +1,223 @@ +#!/usr/bin/perl -w +# +# Copyright (C) 2008 Rien Broekstra +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 dated June, +# 1991. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Configuration variables: +# +# conffile - path to dhcpd's configuration file (default "/etc/dhcpd.conf") +# leasefile - path to dhcpd's leases file (default "/var/lib/dhcp/dhcpd.leases") +# + +use POSIX; +use Time::Local; +use strict; + +my $CONFFILE = exists $ENV{'conffile'} ? $ENV{'conffile'} : "/etc/dhcp/dhcpd.conf"; +my $LEASEFILE = exists $ENV{'leasefile'} ? $ENV{'leasefile'} : "/var/lib/dhcp/dhcpd.leases"; +my $WARNING_LEVEL = 70; +my $CRITICAL_LEVEL = 90; + +my (@activeleases, %dhcp_pools, $pool_start, $pool_end, $pool_size, $pool_free, $pool_usage, $pool_status, $label, $lease, $nagios_return_code, $nagios_ok, $nagios_warning, $nagios_critical, @nagios_text, @nagios_perfdata); + +# Determine all leased IP addresses +@activeleases = determine_active_leases(); + +# Determine the available IP pools +%dhcp_pools = determine_pools(); + +# Nagios return code +$nagios_return_code = 0; +$nagios_ok = 0; +$nagios_warning = 0; +$nagios_critical = 0; + +# For each pool, count how many leases from that pool are currently active +foreach $pool_start (keys %dhcp_pools) { + $pool_size = $dhcp_pools{$pool_start}; + $pool_end = $pool_start+$pool_size-1; + $pool_free = $pool_size; + + foreach $lease (@activeleases) { + if ($lease >= $pool_start && $lease <= $pool_end) { + $pool_free--; + } + } + + $label = ip2string($pool_start)."-".ip2string($pool_end); + $pool_usage = sprintf("%.1f", 100*($pool_size-$pool_free)/$pool_size); + + if ($pool_usage >= $CRITICAL_LEVEL) { + $nagios_return_code = 2; + $nagios_critical++; + $pool_status = "CRITICAL"; + } elsif ($pool_usage >= $WARNING_LEVEL) { + if ($nagios_return_code == 0 ) { + $nagios_return_code = 1; + } + $nagios_warning++; + $pool_status = "WARNING"; + } + else { + $nagios_ok++; + $pool_status = "OK"; + } + + push(@nagios_text, "$pool_status : $label - $pool_usage \n"); + push(@nagios_perfdata, "$label=$pool_usage%;$WARNING_LEVEL%;$CRITICAL_LEVEL%;;" ); + # 'label'=value[UOM];[warn];[crit];; + +} + + +print nagios_code_2_txt($nagios_return_code)." - ".$nagios_critical." CRIT / ".$nagios_warning." WARN / ".$nagios_ok." OK \n\n"; + +print grep(/CRITICAL/, @nagios_text); +print grep(/WARNING/, @nagios_text); +print grep(/OK/, @nagios_text); + +print "|@nagios_perfdata"; + +exit $nagios_return_code; + + +################ +###### FUNCTIONS + +# Parse dhcpd.conf for range statements. +# +# Returns a hash with start IP -> size +sub determine_pools { + my (%pools, @conffile, $line, $start, $end, $size); + + open(CONFFILE, "<${CONFFILE}") || exit -1; + @conffile = ; + close (CONFFILE); + + foreach $line (@conffile) { + next if $line =~ /^\s*#/; + + if ($line =~ /range[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)/) { + $start = string2ip($1); + $end = string2ip($2); + + defined($start) || next; + defined($end) || next; + + # The range statement gives the lowest and highest IP addresses in a range. + $size = $end - $start + 1; + + $pools{$start} = $size; + } + } + return %pools; +} + +# Very simple parser for dhcpd.leases. This will break very easily if dhcpd decides to +# format the file differently. Ideally a simple recursive-descent parser should be used. +# +# Returns an array with currently leased IP's +sub determine_active_leases { + my (@leasefile, $startdate, $enddate, $lease, @activeleases, $mytz, $line, %saw); + + open(LEASEFILE, "<${LEASEFILE}") || exit -1; + @leasefile = ; + close (LEASEFILE); + + @activeleases = (); + + # Portable way of converting a GMT date/time string to timestamp is setting TZ to UTC, and then calling mktime() + $mytz = $ENV{'TZ'}; + $ENV{'TZ'} = 'UTC 0'; + tzset(); + + foreach $line (@leasefile) { + if ($line =~ /lease ([\d]+\.[\d]+\.[\d]+\.[\d]+)/) { + $lease = string2ip($1); + defined($lease) || next; + + undef $startdate; + undef $enddate; + } + elsif ($line =~ /starts \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) { + $startdate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0); + } + elsif ($line =~ /ends \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) { + $enddate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0); + } + elsif ($line =~ /binding state active/) { + if (defined($enddate) && defined($startdate) && defined($lease)) { + if ($startdate < time() && $enddate > time()) { + push (@activeleases, $lease); + } + } + } + + } + + # Set TZ back to its original setting + if (defined($mytz)) { + $ENV{'TZ'} = $mytz; + } + else { + delete $ENV{'TZ'}; + } + tzset(); + + # Sort the array, strip doubles, and return + return grep(!$saw{$_}++, @activeleases); +} + +# +# Helper routine to convert an IP address a.b.c.d into an integer +# +# Returns an integer representation of an IP address +sub string2ip { + my $string = shift; + defined($string) || return undef; + if ($string =~ /([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)/) { + if ($1 < 0 || $1 > 255 || $2 < 0 || $2 > 255 || $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255) { + return undef; + } + else { + return $1 << 24 | $2 << 16 | $3 << 8 | $4; + } + } + return undef; +} + +# +# Returns a dotted quad notation of an +# +sub ip2string { + my $ip = shift; + defined ($ip) || return undef; + return sprintf ("%d.%d.%d.%d", ($ip >> 24) & 0xff, ($ip >> 16) & 0xff, ($ip >> 8) & 0xff, $ip & 0xff); +} + + +# +# Return textual status of return code +# +sub nagios_code_2_txt{ + my $code = shift; + defined ($code) || return undef; + + if($code == 0 ) { return "OK" } + elsif( $code == 1 ) { return "WARNING" } + elsif( $code == 2 ) { return "CRITICAL" } +} diff --git a/nagios-nrpe/templates/evolix.cfg.j2 b/nagios-nrpe/templates/evolix.cfg.j2 index 80eaaaf2..be42c97a 100644 --- a/nagios-nrpe/templates/evolix.cfg.j2 +++ b/nagios-nrpe/templates/evolix.cfg.j2 @@ -57,6 +57,7 @@ command[check_bkctld_jails]=sudo /usr/sbin/bkctld check-jails command[check_bkctld]=sudo /usr/sbin/bkctld check command[check_postgrey]=/usr/lib/nagios/plugins/check_tcp -p10023 command[check_influxdb]=/usr/lib/nagios/plugins/check_http -I 127.0.0.1 -u /health -p 8086 -r '"status":"pass"' +command[check_dhcpd]=/usr/lib/nagios/plugins/check_procs -c1:1 -C dhcpd -t 60 # Local checks (not packaged) command[check_mem]={{ nagios_plugins_directory }}/check_mem -f -C -w 20 -c 10 @@ -82,7 +83,7 @@ command[check_php-fpm74]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi command[check_php-fpm80]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php80/rootfs/etc/php/8.0/fpm/pool.d/ command[check_php-fpm81]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php81/rootfs/etc/php/8.1/fpm/pool.d/ command[check_ipmi_sensors]=sudo /usr/lib/nagios/plugins/check_ipmi_sensor -command[check_raid_status]=/usr/lib/nagios/plugins/check_raid +command[check_raid_status]={{ nagios_plugins_directory }}/check_dhcp_pool # Check HTTP "many". Use this to check many websites (http, https, ports, sockets and SSL certificates). # Beware! All checks must not take more than 10s! From 726735d269e11212bd0a1b51bb14162877935c75 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Fri, 1 Apr 2022 15:47:44 +0200 Subject: [PATCH 47/79] etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ --- CHANGELOG.md | 1 + etc-git/files/etc-git-optimize | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c22a6fd..65b32df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * generate-ldif: Correct generated entries for php-fpm in containers * redis: Remount /usr with RW before adding nagios plugin * postfix: Do not send mails through milters a second time after amavis (in packmail) +* etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ ### Removed diff --git a/etc-git/files/etc-git-optimize b/etc-git/files/etc-git-optimize index 3d4932ee..56967e8f 100644 --- a/etc-git/files/etc-git-optimize +++ b/etc-git/files/etc-git-optimize @@ -6,6 +6,12 @@ repositories="/etc /etc/bind/ /usr/share/scripts" for repository in ${repositories}; do if [ -d "${repository}/.git" ]; then + if [ ${repository} = "/usr/share/scripts" ]; then + mount -o remount,rw /usr + fi git --git-dir="${repository}/.git" gc --quiet + if [ ${repository} = "/usr/share/scripts" ]; then + mount -o remount /usr + fi fi done From e71201ab46339aa26919936bbe23e06900bcaadd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 3 Apr 2022 11:18:41 +0200 Subject: [PATCH 48/79] dump-server-state: upstream release 22.04 --- CHANGELOG.md | 2 +- evolinux-base/files/dump-server-state.sh | 33 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65b32df0..70600d04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evocheck: upstream release 22.03.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state -* dump-server-state: upstream release 22.03.10 +* dump-server-state: upstream release 22.04 * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 1da5bf2f..3b66f230 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.03.10" +VERSION="22.04" readonly VERSION dump_dir= @@ -425,9 +425,23 @@ task_iptables() { debug "Task: iptables" iptables_bin=$(command -v iptables) + ip6tables_bin=$(command -v ip6tables) if [ -n "${iptables_bin}" ]; then - last_result=$({ ${iptables_bin} -L -n -v; ${iptables_bin} -t filter -L -n -v; } > "${dump_dir}/iptables-v.txt") + last_result=$({ + printf "#### iptables --list ###############################\n" + ${iptables_bin} --list --numeric --verbose --line-numbers + printf "\n### iptables --table nat --list ####################\n" + ${iptables_bin} --table nat --list --numeric --verbose --line-numbers + printf "\n#### iptables --table mangle --list ################\n" + ${iptables_bin} --table mangle --list --numeric --verbose --line-numbers + if [ -n "${ip6tables_bin}" ]; then + printf "\n#### ip6tables --list ##############################\n" + ${ip6tables_bin} --list --numeric --verbose --line-numbers + printf "\n#### ip6tables --table mangle --list ###############\n" + ${ip6tables_bin} --table mangle --list --numeric --verbose --line-numbers + fi + } > "${dump_dir}/iptables-v.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then @@ -439,7 +453,20 @@ task_iptables() { # rc=10 fi - last_result=$({ ${iptables_bin} -L -n; ${iptables_bin} -t filter -L -n; } > "${dump_dir}/iptables.txt") + last_result=$({ + printf "#### iptables --list ###############################\n" + ${iptables_bin} --list --numeric + printf "\n### iptables --table nat --list ####################\n" + ${iptables_bin} --table nat --list --numeric + printf "\n#### iptables --table mangle --list ################\n" + ${iptables_bin} --table mangle --list --numeric + if [ -n "${ip6tables_bin}" ]; then + printf "\n#### ip6tables --list ##############################\n" + ${ip6tables_bin} --list --numeric + printf "\n#### ip6tables --table mangle --list ###############\n" + ${ip6tables_bin} --table mangle --list --numeric + fi + } > "${dump_dir}/iptables.txt") last_rc=$? if [ ${last_rc} -eq 0 ]; then From 5b2fecb49cb0a26aba71cceb91766ddfda540b89 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 7 Apr 2022 10:18:08 +0200 Subject: [PATCH 49/79] Make evocommit fully compatible with OpenBSD --- CHANGELOG.md | 1 + etc-git/files/evocommit | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70600d04..58426028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * redis: Remount /usr with RW before adding nagios plugin * postfix: Do not send mails through milters a second time after amavis (in packmail) * etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ +* etc-git: Make evocommit fully compatible with OpenBSD ### Removed diff --git a/etc-git/files/evocommit b/etc-git/files/evocommit index 36050d02..0053784b 100644 --- a/etc-git/files/evocommit +++ b/etc-git/files/evocommit @@ -2,7 +2,7 @@ set -u -VERSION="21.10" +VERSION="22.04" show_version() { cat </dev/null + syslog "Re-mount ${mountpoint} as read-write to commit in repository $1" else mountpoint=$(stat -c '%m' $1) mount -o remount,rw ${mountpoint} @@ -73,6 +74,7 @@ remount_repository_readonly() { if [ "$(get_system)" = "OpenBSD" ]; then partition=$(stat -f '%Sd' $1) mount -u -r /dev/${partition} 2>/dev/null + syslog "Re-mount ${mountpoint} as read-only after commit to repository $1" else mountpoint=$(stat -c '%m' $1) mount -o remount,ro ${mountpoint} 2>/dev/null @@ -92,8 +94,12 @@ main() { rc=0 lock="${GIT_DIR}/index.lock" if [ -f "${lock}" ]; then - limit=$(date +"%s" -d "now - 1 hour") - updated_at=$(stat -c "%Y" "${lock}") + limit=$(($(date +"%s") - (1 * 60 * 60))) + if [ "$(get_system)" = "OpenBSD" ]; then + updated_at=$(stat -f "%m" "${lock}") + else + updated_at=$(stat -c "%Y" "${lock}") + fi if [ "$updated_at" -lt "$limit" ]; then rm -f "${lock}" fi @@ -262,4 +268,4 @@ if [ -d "${GIT_DIR}" ]; then else echo "There is no Git repository in '${REPOSITORY}'" >&2 exit 1 -fi \ No newline at end of file +fi From fca895a231be0572a3d77aec7df9e3afd053d55c Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Fri, 8 Apr 2022 11:05:46 +0200 Subject: [PATCH 50/79] nagios-nrpe: fix copy/paste error --- nagios-nrpe/templates/evolix.cfg.j2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nagios-nrpe/templates/evolix.cfg.j2 b/nagios-nrpe/templates/evolix.cfg.j2 index be42c97a..d3d102f0 100644 --- a/nagios-nrpe/templates/evolix.cfg.j2 +++ b/nagios-nrpe/templates/evolix.cfg.j2 @@ -83,7 +83,8 @@ command[check_php-fpm74]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi command[check_php-fpm80]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php80/rootfs/etc/php/8.0/fpm/pool.d/ command[check_php-fpm81]=sudo {{ nagios_plugins_directory }}/check_phpfpm_multi /var/lib/lxc/php81/rootfs/etc/php/8.1/fpm/pool.d/ command[check_ipmi_sensors]=sudo /usr/lib/nagios/plugins/check_ipmi_sensor -command[check_raid_status]={{ nagios_plugins_directory }}/check_dhcp_pool +command[check_raid_status]=/usr/lib/nagios/plugins/check_raid +command[check_dhcp_pool]={{ nagios_plugins_directory }}/check_dhcp_pool # Check HTTP "many". Use this to check many websites (http, https, ports, sockets and SSL certificates). # Beware! All checks must not take more than 10s! From 84178d6b24225acf9d3965e0adcb03f76f526bc8 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 8 Apr 2022 11:57:33 +0200 Subject: [PATCH 51/79] Tomcat 9 by default with Debian 11 --- CHANGELOG.md | 1 + tomcat/tasks/packages.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58426028..2251ea66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * minifirewall: tail template follows symlinks * minifirewall: upstream release 22.03.5 * openvpn: use a subnet topology instead of the net30 default topology +* tomcat: Tomcat 9 by default with Debian 11 ### Fixed diff --git a/tomcat/tasks/packages.yml b/tomcat/tasks/packages.yml index 9b7995cc..f1b968cc 100644 --- a/tomcat/tasks/packages.yml +++ b/tomcat/tasks/packages.yml @@ -21,9 +21,9 @@ - ansible_distribution_release == "buster" - tomcat_version is not defined -- name: Set Tomcat version to 10 on Debian 11 if missing +- name: Set Tomcat version to 9 on Debian 11 if missing set_fact: - tomcat_version: 10 + tomcat_version: 9 when: - ansible_distribution_release == "bullseye" - tomcat_version is not defined From e3a75b9584a663607eef45730cd7450f4b22ade4 Mon Sep 17 00:00:00 2001 From: Gregory Colpart Date: Mon, 11 Apr 2022 16:34:39 +0200 Subject: [PATCH 52/79] detect OOM --- evolinux-base/handlers/main.yml | 5 +++++ evolinux-base/tasks/log2mail.yml | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/evolinux-base/handlers/main.yml b/evolinux-base/handlers/main.yml index 80b7378e..7331a245 100644 --- a/evolinux-base/handlers/main.yml +++ b/evolinux-base/handlers/main.yml @@ -72,3 +72,8 @@ name: postfix state: reloaded +- name: restart log2mail + service: + name: log2mail + state: restarted + diff --git a/evolinux-base/tasks/log2mail.yml b/evolinux-base/tasks/log2mail.yml index e6f624c1..35ce19cf 100644 --- a/evolinux-base/tasks/log2mail.yml +++ b/evolinux-base/tasks/log2mail.yml @@ -16,3 +16,20 @@ daemon-reload: yes state: started enabled: yes + +- name: log2mail config is present + blockinfile: + dest: /etc/log2mail/config/default + owner: log2mail + group: adm + mode: "0640" + marker: "# {mark} ANSIBLE MANAGED RULES FOR DEFAULT INSTANCE" + block: | + file = /var/log/syslog + pattern = "Out of memory: Kill" + mailto = {{ log2mail_alert_email or general_alert_email | mandatory }} + template = /etc/log2mail/mail + notify: restart log2mail + tags: + - log2mail + From 959d6a857986678972c2da8778d057875d0efff9 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 12 Apr 2022 11:27:46 +0200 Subject: [PATCH 53/79] redis : Activate overcommit sysctl --- CHANGELOG.md | 3 ++- redis/tasks/main.yml | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2251ea66..ba1a6561 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,9 +12,10 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Added -* minifirewall: configure proxy/backup/sysctl values * etc-git: Commit /etc in lxc containers when they are git repositories +* minifirewall: configure proxy/backup/sysctl values * nagios-nrpe: Add a check dhcp_pool +* redis : Activate overcommit sysctl ### Changed diff --git a/redis/tasks/main.yml b/redis/tasks/main.yml index 90f0aa12..10598aa6 100644 --- a/redis/tasks/main.yml +++ b/redis/tasks/main.yml @@ -22,6 +22,14 @@ - packages when: redis_sentinel_install | bool +- name: Linux kernel overcommit memory setting is enabled + sysctl: + name: "vm.overcommit_memory" + value: "1" + sysctl_file: "/etc/sysctl.d/evolinux-redis.conf" + state: present + reload: yes + - name: Get Redis version shell: "redis-server -v | grep -Eo '(v=\\S+)' | cut -d'=' -f 2 | grep -E '^([0-9]|\\.)+$'" changed_when: false From 4bf14b9a2292acb51cd37e7492837cbd81188ad0 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 14 Apr 2022 10:45:24 +0200 Subject: [PATCH 54/79] munin: Add possibility to install local plugins, and install dhcp_pool plugin --- CHANGELOG.md | 1 + munin/files/plugins/dhcp_pool | 213 ++++++++++++++++++++++++++++++++++ munin/tasks/main.yml | 9 ++ 3 files changed, 223 insertions(+) create mode 100644 munin/files/plugins/dhcp_pool diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1a6561..4c4f480d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * minifirewall: configure proxy/backup/sysctl values * nagios-nrpe: Add a check dhcp_pool * redis : Activate overcommit sysctl +* munin: Add possibility to install local plugins, and install dhcp_pool plugin ### Changed diff --git a/munin/files/plugins/dhcp_pool b/munin/files/plugins/dhcp_pool new file mode 100644 index 00000000..c33da5a7 --- /dev/null +++ b/munin/files/plugins/dhcp_pool @@ -0,0 +1,213 @@ +#!/usr/bin/perl -w +# +# Copyright (C) 2008 Rien Broekstra +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 dated June, +# 1991. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Munin plugin to measure saturation of DHCP pools. +# +# Configuration variables: +# +# conffile - path to dhcpd's configuration file (default "/etc/dhcpd.conf") +# leasefile - path to dhcpd's leases file (default "/var/lib/dhcp/dhcpd.leases") +# +# Parameters: +# +# config (required) +# +# Version 1.0, 2-12-2008 +# +#%# family=auto +#%# capabilities=autoconf + +use POSIX; +use Time::Local; +use strict; + +my $CONFFILE = exists $ENV{'conffile'} ? $ENV{'conffile'} : "/etc/dhcp/dhcpd.conf"; +my $LEASEFILE = exists $ENV{'leasefile'} ? $ENV{'leasefile'} : "/var/lib/dhcp/dhcpd.leases"; + +if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) { + if (-e ${CONFFILE} and -e ${LEASEFILE}) { + my %pools; + %pools = determine_pools(); + if (%pools) { + print "yes\n"; + } else { + print "no (no pools defined in config)\n"; + } + } else { + print "no (no config or lease file)\n"; + } +} +elsif ( defined $ARGV[0] and $ARGV[0] eq "config" ) { + my (%pools, $start, $label); + + # Print general information + print "graph_title DHCP pool usage (in %)\n"; + print "graph_args --upper-limit 100 -l 0\n"; + print "graph_vlabel %\n"; +#___ORI___# print "graph_category network\n"; + print "graph_category dhcpd\n"; + + # Determine the available IP pools + %pools = determine_pools(); + + # Print a label for each pool + foreach $start (sort (keys %pools)) { + $label = ip2string($start); + $label =~ s/\./\_/g; + print "_$label.label Pool " . ip2string($start) . " - " . ip2string($start + $pools{$start} - 1) . "\n"; + print "_$label.warning 90\n"; + print "_$label.critical 100\n"; + } +} +else { + my (@activeleases, %pools, $start, $end, $size, $free, $label, $lease); + + # Determine all leased IP addresses + @activeleases = determine_active_leases(); + + # Determine the available IP pools + %pools = determine_pools(); + + # For each pool, count how many leases from that pool are currently active + foreach $start (keys %pools) { + $size = $pools{$start}; + $end = $start+$size-1; + $free = $size; + + foreach $lease (@activeleases) { + if ($lease >= $start && $lease <= $end) { + $free--; + } + } + $label = ip2string($start); + $label =~ s/\./\_/g; + print "_$label.value ".sprintf("%.1f", 100*($size-$free)/$size)."\n"; + } +} + +# Parse dhcpd.conf for range statements. +# +# Returns a hash with start IP -> size +sub determine_pools { + my (%pools, @conffile, $line, $start, $end, $size); + + open(CONFFILE, "<${CONFFILE}") || exit -1; + @conffile = ; + close (CONFFILE); + + foreach $line (@conffile) { + next if $line =~ /^\s*#/; + + if ($line =~ /range[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)/) { + $start = string2ip($1); + $end = string2ip($2); + + defined($start) || next; + defined($end) || next; + + # The range statement gives the lowest and highest IP addresses in a range. + $size = $end - $start + 1; + + $pools{$start} = $size; + } + } + return %pools; +} + +# Very simple parser for dhcpd.leases. This will break very easily if dhcpd decides to +# format the file differently. Ideally a simple recursive-descent parser should be used. +# +# Returns an array with currently leased IP's +sub determine_active_leases { + my (@leasefile, $startdate, $enddate, $lease, @activeleases, $mytz, $line, %saw); + + open(LEASEFILE, "<${LEASEFILE}") || exit -1; + @leasefile = ; + close (LEASEFILE); + + @activeleases = (); + + # Portable way of converting a GMT date/time string to timestamp is setting TZ to UTC, and then calling mktime() + $mytz = $ENV{'TZ'}; + $ENV{'TZ'} = 'UTC 0'; + tzset(); + + foreach $line (@leasefile) { + if ($line =~ /lease ([\d]+\.[\d]+\.[\d]+\.[\d]+)/) { + $lease = string2ip($1); + defined($lease) || next; + + undef $startdate; + undef $enddate; + } + elsif ($line =~ /starts \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) { + $startdate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0); + } + elsif ($line =~ /ends \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) { + $enddate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0); + } + elsif ($line =~ /binding state active/) { + if (defined($enddate) && defined($startdate) && defined($lease)) { + if ($startdate < time() && $enddate > time()) { + push (@activeleases, $lease); + } + } + } + + } + + # Set TZ back to its original setting + if (defined($mytz)) { + $ENV{'TZ'} = $mytz; + } + else { + delete $ENV{'TZ'}; + } + tzset(); + + # Sort the array, strip doubles, and return + return grep(!$saw{$_}++, @activeleases); +} + +# +# Helper routine to convert an IP address a.b.c.d into an integer +# +# Returns an integer representation of an IP address +sub string2ip { + my $string = shift; + defined($string) || return undef; + if ($string =~ /([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)/) { + if ($1 < 0 || $1 > 255 || $2 < 0 || $2 > 255 || $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255) { + return undef; + } + else { + return $1 << 24 | $2 << 16 | $3 << 8 | $4; + } + } + return undef; +} + +# +# Returns a dotted quad notation of an +# +sub ip2string { + my $ip = shift; + defined ($ip) || return undef; + return sprintf ("%d.%d.%d.%d", ($ip >> 24) & 0xff, ($ip >> 16) & 0xff, ($ip >> 8) & 0xff, $ip & 0xff); +} diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml index d7cf8e2a..c4eee575 100644 --- a/munin/tasks/main.yml +++ b/munin/tasks/main.yml @@ -31,6 +31,15 @@ tags: - munin +- name: Install some Munin plugins (disabled) + copy: + src: 'plugins/{{ item }}' + dest: '/usr/share/munin/plugins/{{ item }}' + loop: + - dhcp_pool + tags: + - munin + - name: Ensure some Munin plugins are disabled file: path: '/etc/munin/plugins/{{ item }}' From 9161fae0c415ae3a912baf162e94478d4a385acf Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 14 Apr 2022 16:34:43 +0200 Subject: [PATCH 55/79] openvpn: use a local copy of files instead of cloning an external git repository --- CHANGELOG.md | 1 + openvpn/files/shellpki/cert-expirations.sh | 26 + openvpn/files/shellpki/openssl.cnf | 58 + openvpn/files/shellpki/shellpki | 1106 ++++++++++++++++++++ openvpn/tasks/debian.yml | 43 +- openvpn/tasks/openbsd.yml | 40 +- 6 files changed, 1199 insertions(+), 75 deletions(-) create mode 100644 openvpn/files/shellpki/cert-expirations.sh create mode 100644 openvpn/files/shellpki/openssl.cnf create mode 100755 openvpn/files/shellpki/shellpki diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4f480d..15d5e347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * minifirewall: upstream release 22.03.5 * openvpn: use a subnet topology instead of the net30 default topology * tomcat: Tomcat 9 by default with Debian 11 +* openvpn: use a local copy of files instead of cloning an external git repository ### Fixed diff --git a/openvpn/files/shellpki/cert-expirations.sh b/openvpn/files/shellpki/cert-expirations.sh new file mode 100644 index 00000000..9e27dcc7 --- /dev/null +++ b/openvpn/files/shellpki/cert-expirations.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +carp=$(/sbin/ifconfig carp0 2>/dev/null | grep 'status' | cut -d' ' -f2) + +if [ "$carp" = "backup" ]; then + exit 0 +fi + +echo "Warning : all times are in UTC !\n" + +echo "CA certificate:" +openssl x509 -enddate -noout -in /etc/shellpki/cacert.pem \ + | cut -d '=' -f 2 \ + | sed -e "s/^\(.*\)\ \(20..\).*/- \2 \1/" + +echo "" + +echo "Client certificates:" +cat /etc/shellpki/index.txt \ + | grep ^V \ + | awk -F "/" '{print $1,$5}' \ + | awk '{print $2,$5}' \ + | sed 's/CN=//' \ + | sed -E 's/([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})Z (.*)/- 20\1 \2 \3 \4:\5:\6 \7/' \ + | awk '{if ($3 == "01") $3="Jan"; else if ($3 == "02") $3="Feb"; else if ($3 == "03") $3="Mar"; else if ($3 == "04") $3="Apr"; else if ($3 == "05") $3="May"; else if ($3 == "06") $3="Jun"; else if ($3 == "07") $3="Jul"; else if ($3 == "08") $3="Aug"; else if ($3 == "09") $3="Sep"; else if ($3 == "10") $3="Oct"; else if ($3 == "11") $3="Nov"; else if ($3 == "12") $3="Dec"; print $0;}' \ + | sort -n -k 2 -k 3M -k 4 diff --git a/openvpn/files/shellpki/openssl.cnf b/openvpn/files/shellpki/openssl.cnf new file mode 100644 index 00000000..2c87f10d --- /dev/null +++ b/openvpn/files/shellpki/openssl.cnf @@ -0,0 +1,58 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = /etc/shellpki +certs = $dir/certs +new_certs_dir = $dir/tmp +database = $dir/index.txt +certificate = $dir/cacert.pem +serial = $dir/serial +crl = $dir/crl.pem +private_key = $dir/cakey.key +RANDFILE = $dir/.rand +default_days = 365 +default_crl_days= 365 +default_md = sha256 +preserve = no +policy = policy_match + +[ policy_match ] +countryName = supplied +stateOrProvinceName = supplied +organizationName = supplied +organizationalUnitName = optional +commonName = supplied +emailAddress = supplied + +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = CA:true + +[ v3_ocsp ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = OCSPSigning + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = FR +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province +stateOrProvinceName_default = 13 +localityName = Locality Name (eg, city) +localityName_default = Marseille +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Evolix +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (eg, your name or your server\'s hostname) +commonName_max = 64 +emailAddress = Email Address +emailAddress_default = security@evolix.net +emailAddress_max = 40 diff --git a/openvpn/files/shellpki/shellpki b/openvpn/files/shellpki/shellpki new file mode 100755 index 00000000..5d139866 --- /dev/null +++ b/openvpn/files/shellpki/shellpki @@ -0,0 +1,1106 @@ +#!/bin/sh +# +# shellpki is a wrapper around OpenSSL to manage a small PKI +# + +set -u + +VERSION="22.04" + +show_version() { + cat <, + Thomas Martin , + Gregory Colpart , + Romain Dessort , + Benoit Série , + Victor Laborie , + Daniel Jakots , + Patrick Marchand , + Jérémy Lecour , + Jérémy Dubois + and others. + +shellpki comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to redistribute it under certain conditions. +See the MIT Licence for details. +END +} + +show_usage() { + cat < [options] [CommonName] +Warning: [options] always must be before [CommonName] and after + +EOF +show_usage_init +show_usage_create +show_usage_revoke +show_usage_list +show_usage_check +show_usage_ocsp + + cat < + + Options + --non-interactive do not prompt the user, and exit if an error occurs + +EOF +} + +show_usage_create() { + cat < + + Options + -f, --file, --csr-file create a client certificate from a CSR (doesn't need key) + -p, --password prompt the user for a password to set on the client key + --password-file if provided with a path to a readable file, the first line is read and set as password on the client key + --days specify how many days the certificate should be valid + --end-date specify until which date the certificate should be valid, in "YYYY/MM/DD hh:mm:ss" format, UTC +0 + --non-interactive do not prompt the user, and exit if an error occurs + --replace-existing if the certificate already exists, revoke it before creating a new one + +EOF +} + +show_usage_revoke() { + cat < + + Options + --non-interactive do not prompt the user, and exit if an error occurs + +EOF +} + +show_usage_list() { + cat < + + Options + -a, --all list all certificates: valid and revoked ones + -v, --valid list all valid certificates + -r, --revoked list all revoked certificates + +EOF +} + +show_usage_check() { + cat < + +EOF +} + +error() { + echo "${1}" >&2 + exit 1 +} + +warning() { + echo "${1}" >&2 +} + +verify_ca_password() { + "${OPENSSL_BIN}" rsa \ + -in "${CA_KEY}" \ + -passin pass:"${CA_PASSWORD}" \ + >/dev/null 2>&1 +} +get_real_path() { + # --canonicalize is supported on Linux + # -f is supported on Linux and OpenBSD + readlink -f -- "${1}" +} + +ask_ca_password() { + attempt=${1:-0} + max_attempts=3 + + trap 'unset CA_PASSWORD' 0 + + if [ ! -f "${CA_KEY}" ]; then + error "You must initialize your PKI with \`shellpki init' !" + fi + if [ "${attempt}" -gt 0 ]; then + warning "Invalid password, retry." + fi + if [ "${attempt}" -ge "${max_attempts}" ]; then + error "Maximum number of attempts reached (${max_attempts})." + fi + if [ -z "${CA_PASSWORD:-}" ]; then + if [ "${non_interactive}" -eq 1 ]; then + error "In non-interactive mode, you must pass CA_PASSWORD as environment variable" + fi + stty -echo + printf "Password for CA key: " + read -r CA_PASSWORD + stty echo + printf "\n" + fi + if [ -z "${CA_PASSWORD:-}" ] || ! verify_ca_password; then + unset CA_PASSWORD + attempt=$(( attempt + 1 )) + ask_ca_password "${attempt}" + fi +} +ask_user_password() { + trap 'unset PASSWORD' 0 + + if [ -z "${PASSWORD:-}" ]; then + if [ "${non_interactive}" -eq 1 ]; then + error "In non-interactive mode, you must pass PASSWORD as environment variable or use --password-file" + fi + stty -echo + printf "Password for user key: " + read -r PASSWORD + stty echo + printf "\n" + fi + if [ -z "${PASSWORD:-}" ]; then + warning "Warning: empty password from input" + fi +} +replace_existing_or_abort() { + cn=${1:?} + if [ "${non_interactive}" -eq 1 ]; then + if [ "${replace_existing}" -eq 1 ]; then + revoke --non-interactive "${cn}" + else + error "${cn} already exists, use \`--replace-existing' to force" + fi + else + if [ "${replace_existing}" -eq 1 ]; then + revoke "${cn}" + else + printf "%s already exists, do you want to revoke and recreate it ? [y/N] " "${cn}" + read -r REPLY + resp=$(echo "${REPLY}" | tr 'Y' 'y') + + if [ "${resp}" = "y" ]; then + revoke "${cn}" + else + error "Aborted" + fi + fi + fi +} + +init() { + umask 0177 + + [ -d "${CA_DIR}" ] || mkdir -m 0750 "${CA_DIR}" + [ -d "${CRT_DIR}" ] || mkdir -m 0750 "${CRT_DIR}" + [ -f "${INDEX_FILE}" ] || touch "${INDEX_FILE}" + [ -f "${CRL}" ] || touch "${CRL}" + [ -f "${SERIAL}" ] || echo "01" > "${SERIAL}" + + non_interactive=0 + + # Parse options + # based on https://gist.github.com/deshion/10d3cb5f88a21671e17a + while :; do + case ${1:-} in + --non-interactive) + non_interactive=1 + ;; + --) + # End of all options. + shift + break + ;; + -?*) + # ignore unknown options + warning "Warning: unknown option (ignored): \`$1'" + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift + done + + cn="${1:-}" + if [ -z "${cn}" ]; then + show_usage_init >&2 + exit 1 + fi + + if [ -f "${CA_KEY}" ]; then + if [ "${non_interactive}" -eq 1 ]; then + error "${CA_KEY} already exists, erase it manually if you want to start over." + else + printf "%s already exists, do you really want to erase it ? [y/N] " "${CA_KEY}" + read -r REPLY + resp=$(echo "${REPLY}" | tr 'Y' 'y') + if [ "${resp}" = "y" ]; then + rm -f "${CA_KEY}" "${CA_CERT}" + fi + fi + fi + + passout_arg="" + if [ -n "${CA_PASSWORD:-}" ]; then + passout_arg="-passout pass:${CA_PASSWORD}" + elif [ "${non_interactive}" -eq 1 ]; then + error "In non-interactive mode, you must pass CA_PASSWORD as environment variable." + fi + + if [ ! -f "${CA_KEY}" ]; then + "${OPENSSL_BIN}" genrsa \ + -out "${CA_KEY}" \ + ${passout_arg} \ + -aes256 \ + "${CA_KEY_LENGTH}" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Error generating the CA key" + fi + fi + + if [ -f "${CA_CERT}" ]; then + if [ "${non_interactive}" -eq 1 ]; then + error "${CA_CERT} already exists, erase it manually if you want to start over." + else + printf "%s already exists, do you really want to erase it ? [y/N] " "${CA_CERT}" + read -r REPLY + resp=$(echo "${REPLY}" | tr 'Y' 'y') + if [ "${resp}" = "y" ]; then + rm "${CA_CERT}" + fi + fi + fi + + if [ ! -f "${CA_CERT}" ]; then + ask_ca_password 0 + fi + + if [ ! -f "${CA_CERT}" ]; then + "${OPENSSL_BIN}" req \ + -new \ + -batch \ + -sha512 \ + -x509 \ + -days 3650 \ + -extensions v3_ca \ + -passin pass:"${CA_PASSWORD}" \ + -key "${CA_KEY}" \ + -out "${CA_CERT}" \ + -config /dev/stdin <&2 + exit 1 + fi + ocsp_csr_file="${CSR_DIR}/ocsp.csr" + + url=$(echo "${ocsp_uri}" | cut -d':' -f1) + port=$(echo "${ocsp_uri}" | cut -d':' -f2) + + if [ ! -f "${OCSP_KEY}" ]; then + "${OPENSSL_BIN}" genrsa \ + -out "${OCSP_KEY}" \ + "${KEY_LENGTH}" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Error generating the OCSP key" + fi + fi + + "${OPENSSL_BIN}" req \ + -batch \ + -new \ + -key "${OCSP_KEY}" \ + -out "${ocsp_csr_file}" \ + -config /dev/stdin < /dev/null) + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Invalid end date format: \`${end_date}' can't be parsed by date(1). Expected format: YYYY/MM/DD [hh[:mm[:ss]]]." + else + crt_expiration_arg="-enddate ${cert_end_date}" + fi + elif [ "${SYSTEM}" = "openbsd" ]; then + cert_end_date=$(TZ=:Zulu date -f "%C%y/%m/%d %H:%M:%S" -j "${end_date}" +"%Y%m%d%H%M%SZ" 2> /dev/null) + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Invalid end date format: \`${end_date}' can't be parsed by date(1). Expected format: YYYY/MM/DD hh:mm:ss." + else + crt_expiration_arg="-enddate ${cert_end_date}" + fi + else + error "System ${SYSTEM} not supported." + fi + fi + if [ "${non_interactive}" -eq 1 ]; then + batch_arg="-batch" + else + batch_arg="" + fi + + if [ "${from_csr}" -eq 1 ]; then + if [ "${ask_pass}" -eq 1 ]; then + warning "Warning: -p|--password is ignored with -f|--file|--crt-file" + fi + if [ -n "${password_file:-}" ]; then + warning "Warning: --password-file is ignored with -f|--file|--crt-file" + fi + + crt_file="${CRT_DIR}/${cn}.crt" + + # ask for CA passphrase + ask_ca_password 0 + + # check if csr_file is a CSR + "${OPENSSL_BIN}" req \ + -noout \ + -subject \ + -in "${csr_file}" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "${csr_file} is not a valid CSR !" + fi + + # check if csr_file contain a CN + "${OPENSSL_BIN}" req \ + -noout \ + -subject \ + -in "${csr_file}" \ + | grep -Eo "CN\s*=[^,/]*" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "${csr_file} doesn't contain a CommonName !" + fi + + # get CN from CSR + cn=$("${OPENSSL_BIN}" req -noout -subject -in "${csr_file}" | grep -Eo "CN\s*=[^,/]*" | cut -d'=' -f2 | xargs) + + # check if CN already exists + if [ -f "${crt_file}" ]; then + replace_existing_or_abort "${cn}" + fi + + # ca sign and generate cert + if [ "${non_interactive}" -eq 1 ]; then + batch_arg="-batch" + else + batch_arg="" + fi + "${OPENSSL_BIN}" ca \ + ${batch_arg} \ + -config "${CONF_FILE}" \ + -in "${csr_file}" \ + -passin pass:"${CA_PASSWORD}" \ + -out "${crt_file}" \ + ${crt_expiration_arg} + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Error generating the certificate" + else + echo "The certificate file is available at \`${crt_file}'" + fi + else + if [ -z "${cn}" ]; then + show_usage_create >&2 + exit 1 + fi + csr_file="${CSR_DIR}/${cn}-${SUFFIX}.csr" + crt_file="${CRT_DIR}/${cn}.crt" + key_file="${KEY_DIR}/${cn}-${SUFFIX}.key" + ovpn_file="${OVPN_DIR}/${cn}-${SUFFIX}.ovpn" + pkcs12_file="${PKCS12_DIR}/${cn}-${SUFFIX}.p12" + + # ask for CA passphrase + ask_ca_password 0 + + if [ "${ask_pass}" -eq 1 ]; then + ask_user_password + fi + + # check if CN already exists + if [ -f "${crt_file}" ]; then + replace_existing_or_abort "${cn}" + fi + + # generate private key + pass_args="" + if [ -n "${password_file:-}" ]; then + pass_args="-aes256 -passout file:${password_file}" + elif [ -n "${PASSWORD:-}" ]; then + pass_args="-aes256 -passout pass:${PASSWORD}" + fi + "${OPENSSL_BIN}" genrsa \ + -out "${key_file}" \ + ${pass_args} \ + "${KEY_LENGTH}" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -eq 0 ]; then + echo "The KEY file is available at \`${key_file}'" + else + error "Error generating the private key" + fi + + # generate csr req + pass_args="" + if [ -n "${password_file:-}" ]; then + pass_args="-passin file:${password_file}" + elif [ -n "${PASSWORD:-}" ]; then + pass_args="-passin pass:${PASSWORD}" + fi + "${OPENSSL_BIN}" req \ + -batch \ + -new \ + -key "${key_file}" \ + -out "${csr_file}" \ + ${pass_args} \ + -config /dev/stdin </dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + rm -f "${crt_file}" + fi + if [ ! -f "${crt_file}" ]; then + error "Error in CSR creation" + fi + + chmod 640 "${crt_file}" + + echo "The CRT file is available in ${crt_file}" + + # generate pkcs12 format + pass_args="" + if [ -n "${password_file:-}" ]; then + # Hack for pkcs12 : + # If passin and passout files are the same path, it expects 2 lines + # so we make a temporary copy of the password file + password_file_out=$(mktemp) + cp "${password_file}" "${password_file_out}" + pass_args="-passin file:${password_file} -passout file:${password_file_out}" + elif [ -n "${PASSWORD:-}" ]; then + pass_args="-passin pass:${PASSWORD} -passout pass:${PASSWORD}" + else + pass_args="-passout pass:" + fi + "${OPENSSL_BIN}" pkcs12 \ + -export \ + -nodes \ + -inkey "${key_file}" \ + -in "${crt_file}" \ + -out "${pkcs12_file}" \ + ${pass_args} + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "Error generating the pkcs12 file" + fi + + if [ -n "${password_file_out:-}" ]; then + # Hack for pkcs12 : + # Destroy the temporary file + rm -f "${password_file_out}" + fi + + chmod 640 "${pkcs12_file}" + echo "The PKCS12 config file is available at \`${pkcs12_file}'" + + # generate openvpn format + if [ -e "${CA_DIR}/ovpn.conf" ]; then + cat "${CA_DIR}/ovpn.conf" - > "${ovpn_file}" < +$(cat "${CA_CERT}") + + + +$(cat "${crt_file}") + + + +$(cat "${key_file}") + +EOF + chmod 640 "${ovpn_file}" + echo "The OpenVPN config file is available at \`${ovpn_file}'" + fi + + # Copy files if destination exists + if [ -d "${COPY_DIR}" ]; then + for file in "${crt_file}" "${key_file}" "${pkcs12_file}" "${ovpn_file}"; do + if [ -f "${file}" ]; then + new_file="${COPY_DIR}/$(basename "${file}")" + if [ "${replace_existing}" -eq 1 ]; then + cp -f "${file}" "${COPY_DIR}/" + else + if [ "${non_interactive}" -eq 1 ]; then + if [ -f "${new_file}" ]; then + echo "File \`${file}' has not been copied to \`${new_file}', it already exists" >&2 + continue + else + cp "${file}" "${COPY_DIR}/" + fi + else + cp -i "${file}" "${COPY_DIR}/" + fi + fi + echo "File \`${file}' has been copied to \`${new_file}'" + fi + done + + # shellcheck disable=SC2086 + chown -R ${PKI_USER}:${PKI_USER} "${COPY_DIR}/" + chmod -R u=rwX,g=rwX,o= "${COPY_DIR}/" + fi + fi +} + +revoke() { + non_interactive=0 + + # Parse options + # based on https://gist.github.com/deshion/10d3cb5f88a21671e17a + while :; do + case ${1:-} in + --non-interactive) + non_interactive=1 + ;; + --) + # End of all options. + shift + break + ;; + -?*) + # ignore unknown options + warning "Warning: unknown option (ignored): \`$1'" + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift + done + + # The name of the certificate + cn="${1:-}" + + if [ -z "${cn}" ]; then + show_usage_revoke >&2 + exit 1 + fi + + crt_file="${CRT_DIR}/${cn}.crt" + # check if CRT exists + if [ ! -f "${crt_file}" ]; then + error "Unknow CN: ${cn} (\`${crt_file}' not found)" + fi + + # check if CRT is a valid + "${OPENSSL_BIN}" x509 \ + -noout \ + -subject \ + -in "${crt_file}" \ + >/dev/null 2>&1 + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + error "${crt_file} is not a valid CRT, you must delete it !" + fi + + # ask for CA passphrase + ask_ca_password 0 + + echo "Revoke certificate ${crt_file} :" + "${OPENSSL_BIN}" ca \ + -config "${CONF_FILE}" \ + -passin pass:"${CA_PASSWORD}" \ + -revoke "${crt_file}" + # shellcheck disable=SC2181 + if [ "$?" -eq 0 ]; then + rm "${crt_file}" + fi + + "${OPENSSL_BIN}" ca \ + -config "${CONF_FILE}" \ + -passin pass:"${CA_PASSWORD}" \ + -gencrl \ + -out "${CRL}" +} + +list() { + if [ ! -f "${INDEX_FILE}" ]; then + exit 0 + fi + + if [ -z "${1:-}" ]; then + show_usage_list >&2 + exit 1 + fi + + while :; do + case "${1:-}" in + -a|--all) + list_valid=0 + list_revoked=0 + ;; + -v|--valid) + list_valid=0 + list_revoked=1 + ;; + -r|--revoked) + list_valid=1 + list_revoked=0 + ;; + -?*) + warning "unknow option ${1} (ignored)" + ;; + *) + break + ;; + esac + shift + done + + if [ "${list_valid}" -eq 0 ]; then + certs=$(grep "^V" "${INDEX_FILE}") + fi + + if [ "${list_revoked}" -eq 0 ]; then + certs=$(grep "^R" "${INDEX_FILE}") + fi + + if [ "${list_valid}" -eq 0 ] && [ "${list_revoked}" -eq 0 ]; then + certs=$(cat "${INDEX_FILE}") + fi + + echo "${certs}" | grep -Eo "CN\s*=[^,/]*" | cut -d'=' -f2 | xargs -n1 +} + +cert_end_date() { + "${OPENSSL_BIN}" x509 -noout -enddate -in "${1}" | cut -d'=' -f2 +} + +check() { + # default expiration alert + # TODO: permit override with parameters + min_day=90 + cur_epoch=$(date -u +'%s') + + for cert in "${CRT_DIR}"/*; do + end_date=$(cert_end_date "${cert}") + end_epoch=$(date -ud "${end_date}" +'%s') + diff_epoch=$(( end_epoch - cur_epoch )) + diff_day=$(( diff_epoch / 60 / 60 / 24 )) + if [ "${diff_day}" -lt "${min_day}" ]; then + if [ "${diff_day}" -le 0 ]; then + echo "${cert} has expired" + else + echo "${cert} expire in ${diff_day} days" + fi + fi + done +} + +is_user() { + getent passwd "${1}" >/dev/null +} +is_group() { + getent group "${1}" >/dev/null +} + +main() { + # Know what system we are on, because OpenBSD and Linux do not implement date(1) in the same way + SYSTEM=$(uname | tr '[:upper:]' '[:lower:]') + + # default config + # TODO: override with /etc/default/shellpki + CONF_FILE="/etc/shellpki/openssl.cnf" + + if [ "$(uname)" = "OpenBSD" ]; then + PKI_USER="_shellpki" + else + PKI_USER="shellpki" + fi + + if [ "${USER}" != "root" ] && [ "${USER}" != "${PKI_USER}" ]; then + error "Please become root before running ${0} !" + fi + + # retrieve CA path from config file + CA_DIR=$(grep -E "^dir" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1) + CA_KEY=$(grep -E "^private_key" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + CA_CERT=$(grep -E "^certificate" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + OCSP_KEY="${CA_DIR}/ocsp.key" + OCSP_CERT="${CA_DIR}/ocsp.pem" + CRT_DIR=$(grep -E "^certs" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + TMP_DIR=$(grep -E "^new_certs_dir" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + INDEX_FILE=$(grep -E "^database" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + SERIAL=$(grep -E "^serial" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + CRL=$(grep -E "^crl" "${CONF_FILE}" | cut -d'=' -f2 | xargs -n1 | sed "s~\$dir~${CA_DIR}~") + + # directories for clients key, csr, crt + KEY_DIR="${CA_DIR}/private" + CSR_DIR="${CA_DIR}/requests" + PKCS12_DIR="${CA_DIR}/pkcs12" + OVPN_DIR="${CA_DIR}/openvpn" + + COPY_DIR="$(dirname "${CONF_FILE}")/copy_output" + + CA_KEY_LENGTH=4096 + if [ "${CA_KEY_LENGTH}" -lt 4096 ]; then + error "CA key must be at least 4096 bits long." + fi + KEY_LENGTH=2048 + if [ "${KEY_LENGTH}" -lt 2048 ]; then + error "User key must be at least 2048 bits long." + fi + + OPENSSL_BIN=$(command -v openssl) + SUFFIX=$(TZ=:Zulu /bin/date +"%Y%m%d%H%M%SZ") + + if ! is_user "${PKI_USER}" || ! is_group "${PKI_USER}"; then + error "You must create ${PKI_USER} user and group !" + fi + + if [ ! -e "${CONF_FILE}" ]; then + error "${CONF_FILE} is missing" + fi + + mkdir -p "${CA_DIR}" "${CRT_DIR}" "${KEY_DIR}" "${CSR_DIR}" "${PKCS12_DIR}" "${OVPN_DIR}" "${TMP_DIR}" + + command=${1:-help} + + case "${command}" in + init) + shift + init "$@" + ;; + + ocsp) + shift + ocsp "$@" + ;; + + create) + shift + create "$@" + ;; + + revoke) + shift + revoke "$@" + ;; + + list) + shift + list "$@" + ;; + + check) + shift + check "$@" + ;; + + version|--version) + show_version + exit 0 + ;; + + help|--help) + show_usage + exit 0 + ;; + + *) + show_usage >&2 + exit 1 + ;; + esac + + # fix right + chown -R "${PKI_USER}":"${PKI_USER}" "${CA_DIR}" + chmod 750 "${CA_DIR}" "${CRT_DIR}" "${KEY_DIR}" "${CSR_DIR}" "${PKCS12_DIR}" "${OVPN_DIR}" "${TMP_DIR}" + chmod 600 "${INDEX_FILE}"* "${SERIAL}"* "${CA_KEY}" "${CRL}" + chmod 640 "${CA_CERT}" +} + +main "$@" diff --git a/openvpn/tasks/debian.yml b/openvpn/tasks/debian.yml index f94e19b6..3ace1f4c 100644 --- a/openvpn/tasks/debian.yml +++ b/openvpn/tasks/debian.yml @@ -12,11 +12,6 @@ - client - server -- name: Clone shellpki repo - git: - repo: "https://gitea.evolix.org/evolix/shellpki.git" - dest: /root/shellpki - - name: Create the shellpki user user: name: shellpki @@ -38,30 +33,14 @@ - name: Copy shellpki files copy: - src: "{{ item.source }}" + src: "shellpki/{{ item.source }}" dest: "{{ item.destination }}" - remote_src: yes - with_items: - - { source: "/root/shellpki/openssl.cnf", destination: "/etc/shellpki/openssl.cnf" } - - { source: "/root/shellpki/shellpki", destination: "/usr/local/sbin/shellpki" } - -- include_role: - name: evolix/remount-usr - -- name: Change files permissions - file: - dest: "{{ item.dest }}" mode: "{{ item.mode }}" owner: "{{ item.owner }}" group: "{{ item.group }}" with_items: - - { dest: "/etc/shellpki/openssl.cnf", mode: "0640", owner: "shellpki", group: "shellpki" } - - { dest: "/usr/local/sbin/shellpki", mode: "0755", owner: "root", group: "root" } - -- name: Delete local shellpki repo - file: - state: absent - dest: "/root/shellpki" + - { source: "openssl.cnf", destination: "/etc/shellpki/openssl.cnf", mode: "0640", owner: "shellpki", group: "shellpki" } + - { source: "shellpki", destination: "/usr/local/sbin/shellpki", mode: "0755", owner: "root", group: "root" } - name: Add sudo rights lineinfile: @@ -251,30 +230,16 @@ notify: restart nagios-nrpe-server when: nrpe_evolix_config.stat.exists -# BEGIN TODO : Get this script from master branch when cloning it at the beginning when dev branch is merged with master (this script is currently not available on master branch) -- name: Clone dev branch of shellpki repo - git: - repo: "https://gitea.evolix.org/evolix/shellpki.git" - dest: /root/shellpki-dev - version: dev - - include_role: name: evolix/remount-usr - name: Copy shellpki script copy: - src: "/root/shellpki-dev/cert-expirations.sh" + src: "shellpki/cert-expirations.sh" dest: "/usr/share/scripts/cert-expirations.sh" mode: "0700" owner: root group: root - remote_src: yes - -- name: Delete local shellpki-dev repo - file: - state: absent - dest: "/root/shellpki-dev" -# END TODO - name: Install cron to warn about certificates expiration cron: diff --git a/openvpn/tasks/openbsd.yml b/openvpn/tasks/openbsd.yml index 2edbec70..18cd0156 100644 --- a/openvpn/tasks/openbsd.yml +++ b/openvpn/tasks/openbsd.yml @@ -13,11 +13,6 @@ group: wheel mode: "0755" -- name: Clone shellpki repo - git: - repo: "https://gitea.evolix.org/evolix/shellpki.git" - dest: /root/shellpki - - name: Create the shellpki user user: name: _shellpki @@ -36,27 +31,14 @@ - name: Copy shellpki files copy: - src: "{{ item.source }}" + src: "shellpki/{{ item.source }}" dest: "{{ item.destination }}" - remote_src: yes - with_items: - - { source: "/root/shellpki/openssl.cnf", destination: "/etc/shellpki/openssl.cnf" } - - { source: "/root/shellpki/shellpki", destination: "/usr/local/sbin/shellpki" } - -- name: Change files permissions - file: - dest: "{{ item.dest }}" mode: "{{ item.mode }}" owner: "{{ item.owner }}" group: "{{ item.group }}" with_items: - - { dest: "/etc/shellpki/openssl.cnf", mode: "0640", owner: "_shellpki", group: "_shellpki"} - - { dest: "/usr/local/sbin/shellpki", mode: "0755", owner: "root", group: "wheel" } - -- name: Delete local shellpki repo - file: - state: absent - dest: "/root/shellpki" + - { source: "openssl.cnf", destination: "/etc/shellpki/openssl.cnf", mode: "0640", owner: "_shellpki", group: "_shellpki" } + - { source: "shellpki", destination: "/usr/local/sbin/shellpki", mode: "0755", owner: "root", group: "wheel" } - name: Add sudo rights lineinfile: @@ -193,27 +175,13 @@ notify: restart nrpe when: nrpe_evolix_config.stat.exists -# BEGIN TODO : Get this script from master branch when cloning it at the beginning when dev branch is merged with master (this script is currently not available on master branch) -- name: Clone dev branch of shellpki repo - git: - repo: "https://gitea.evolix.org/evolix/shellpki.git" - dest: /root/shellpki-dev - version: dev - - name: Copy shellpki script copy: - src: "/root/shellpki-dev/cert-expirations.sh" + src: "shellpki/cert-expirations.sh" dest: "/usr/share/scripts/cert-expirations.sh" mode: "0700" owner: root group: wheel - remote_src: yes - -- name: Delete local shellpki-dev repo - file: - state: absent - dest: "/root/shellpki-dev" -# END TODO - name: Install cron to warn about certificates expiration cron: From d66248e9f0bf4bbf8ae992b94d4ff05fec77e6ea Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Thu, 14 Apr 2022 16:38:43 +0200 Subject: [PATCH 56/79] openvpn: update README --- openvpn/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvpn/README.md b/openvpn/README.md index 27b507d4..ddaffcce 100644 --- a/openvpn/README.md +++ b/openvpn/README.md @@ -23,6 +23,6 @@ Then, you can use `shellpki` to generate client certificates. * `openvpn_netmask`: netmask of the network to use for OpenVPN * `openvpn_netmask_cidr`: automatically generated prefix length of the netmask, in CIDR notation -## TODO +## Dependencies -* See TODO tasks in tasks/*.yml +* Files in `files/shellpki/*` are gotten from the upstream [shellpki](https://gitea.evolix.org/evolix/shellpki) and must be updated when the upstream is. From 5f4f885556868075f5b2a5427d0c2181636c912c Mon Sep 17 00:00:00 2001 From: David Prevot Date: Tue, 19 Apr 2022 16:47:22 +0200 Subject: [PATCH 57/79] munin: Ensure /usr is writable --- munin/tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml index c4eee575..8c6ec525 100644 --- a/munin/tasks/main.yml +++ b/munin/tasks/main.yml @@ -12,6 +12,10 @@ - munin - packages +- name: Ensure /usr is still writable + include_role: + name: evolix/remount-usr + - block: - name: Replace localdomain in Munin config replace: From a5bae6645e10126b9c862cab87e8f10de95a5647 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 20 Apr 2022 11:07:20 +0200 Subject: [PATCH 58/79] dump-server-state: upstream release 22.04.1 --- CHANGELOG.md | 2 +- evolinux-base/files/dump-server-state.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15d5e347..8582054f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evocheck: upstream release 22.03.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state -* dump-server-state: upstream release 22.04 +* dump-server-state: upstream release 22.04.1 * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 3b66f230..b2560e20 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.04" +VERSION="22.04.1" readonly VERSION dump_dir= @@ -673,7 +673,7 @@ task_df() { df_bin=$(command -v df) if [ -n "${df_bin}" ]; then - last_result=$(${df_bin} --portability > "${dump_dir}/df.txt") + last_result=$(${df_bin} --portability > "${dump_dir}/df.txt 2>&1") last_rc=$? if [ ${last_rc} -eq 0 ]; then From 4214db4ad6e4a3e717a3ee6d5a66741b32c1a0c8 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 20 Apr 2022 11:14:02 +0200 Subject: [PATCH 59/79] fix dump-server-state quote error --- evolinux-base/files/dump-server-state.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index b2560e20..1b80bd0a 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -673,7 +673,7 @@ task_df() { df_bin=$(command -v df) if [ -n "${df_bin}" ]; then - last_result=$(${df_bin} --portability > "${dump_dir}/df.txt 2>&1") + last_result=$(${df_bin} --portability > "${dump_dir}/df.txt" 2>&1) last_rc=$? if [ ${last_rc} -eq 0 ]; then From 58909bc3956dbf0f5b51bd0dc2b5dd59ef24977e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 22 Apr 2022 09:32:37 +0200 Subject: [PATCH 60/79] vrrpd: Store sysctl values in specific file --- CHANGELOG.md | 1 + vrrpd/tasks/main.yml | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8582054f..ddaa426f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * openvpn: use a subnet topology instead of the net30 default topology * tomcat: Tomcat 9 by default with Debian 11 * openvpn: use a local copy of files instead of cloning an external git repository +* vrrpd: Store sysctl values in specific file ### Fixed diff --git a/vrrpd/tasks/main.yml b/vrrpd/tasks/main.yml index 74dfa5c2..5804cb39 100644 --- a/vrrpd/tasks/main.yml +++ b/vrrpd/tasks/main.yml @@ -3,6 +3,8 @@ include_role: name: evolix/apt tasks_from: evolix_public.yml + tags: + - vrrpd - name: Install vrrpd packages apt: @@ -10,12 +12,13 @@ allow_unauthenticated: yes state: present tags: - - vrrpd + - vrrpd - name: Adjust sysctl config sysctl: name: "{{ item.name }}" value: "{{ item.value }}" + sysctl_file: /etc/sysctl.d/vrrpd.conf sysctl_set: yes state: present loop: @@ -26,4 +29,4 @@ - { name: 'net.ipv4.conf.all.arp_announce', value: 2 } - { name: 'net.ipv4.ip_nonlocal_bind', value: 1 } tags: - - vrrpd + - vrrpd From 5935d9d4a3c82d12891da3063507ad5518f2178a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 25 Apr 2022 09:58:07 +0200 Subject: [PATCH 61/79] evocheck: upstream release 22.04 --- CHANGELOG.md | 2 +- evocheck/files/evocheck.sh | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddaa426f..383e021b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed -* evocheck: upstream release 22.03.1 +* evocheck: upstream release 22.04 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state * dump-server-state: upstream release 22.04.1 diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index 2f01afae..07ec97f7 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -4,7 +4,7 @@ # Script to verify compliance of a Debian/OpenBSD server # powered by Evolix -VERSION="22.03.1" +VERSION="22.04" readonly VERSION # base functions @@ -234,7 +234,8 @@ check_syslogconf() { check_debiansecurity() { if is_debian_bullseye; then # https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.html#security-archive - pattern="^deb https://deb\.debian\.org/debian-security/? bullseye-security main" + # https://www.debian.org/security/ + pattern="^deb https://(deb|security)\.debian\.org/debian-security/? bullseye-security main" elif is_debian_buster; then pattern="^deb http://security\.debian\.org/debian-security/? buster/updates main" elif is_debian_stretch; then @@ -600,7 +601,11 @@ check_evobackup_exclude_mount() { # shellcheck disable=SC2044 for evobackup_file in $(find /etc/cron* -name '*evobackup*' | grep -v -E ".disabled$"); do - grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}" + # If rsync is not limited by "one-file-system" + # then we verify that every mount is excluded + grep -q -- "^\s*--one-file-system" "${evobackup_file}" \ + || grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' \ + > "${excludes_file}" not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}") for mount in ${not_excluded}; do failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script" @@ -1374,7 +1379,7 @@ download_versions() { elif is_openbsd; then versions_url="https://upgrades.evolix.org/versions-${OPENBSD_RELEASE}" else - failed "IS_VERSIONS_CHECK" "error determining os release" + failed "IS_CHECK_VERSIONS" "error determining os release" fi # fetch timeout, in seconds @@ -1387,9 +1392,9 @@ download_versions() { elif command -v GET; then GET -t ${timeout}s "${versions_url}" > "${versions_file}" else - failed "IS_VERSIONS_CHECK" "failed to find curl, wget or GET" + failed "IS_CHECK_VERSIONS" "failed to find curl, wget or GET" fi - test "$?" -eq 0 || failed "IS_VERSIONS_CHECK" "failed to download ${versions_url} to ${versions_file}" + test "$?" -eq 0 || failed "IS_CHECK_VERSIONS" "failed to download ${versions_url} to ${versions_file}" } get_command() { local program @@ -1451,11 +1456,11 @@ check_version() { actual_version=$(get_version "${program}" "${command}") # printf "program:%s expected:%s actual:%s\n" "${program}" "${expected_version}" "${actual_version}" if [ -z "${actual_version}" ]; then - failed "IS_VERSIONS_CHECK" "failed to lookup actual version of ${program}" + failed "IS_CHECK_VERSIONS" "failed to lookup actual version of ${program}" elif dpkg --compare-versions "${actual_version}" lt "${expected_version}"; then - failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is older than expected version ${expected_version}" + failed "IS_CHECK_VERSIONS" "${program} version ${actual_version} is older than expected version ${expected_version}" elif dpkg --compare-versions "${actual_version}" gt "${expected_version}"; then - failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is newer than expected version ${expected_version}, you should update tour index." + failed "IS_CHECK_VERSIONS" "${program} version ${actual_version} is newer than expected version ${expected_version}, you should update your index." else : # Version check OK fi @@ -1484,7 +1489,7 @@ check_versions() { if [ -n "${version}" ]; then check_version "${program}" "${version}" else - failed "IS_VERSIONS_CHECK" "failed to lookup expected version for ${program}" + failed "IS_CHECK_VERSIONS" "failed to lookup expected version for ${program}" fi fi done From daa54cac8fe03d69ed41e1bafbe90f34f7f58a6d Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 25 Apr 2022 10:33:33 +0200 Subject: [PATCH 62/79] evocheck: upstream release 22.04.1 --- CHANGELOG.md | 2 +- evocheck/files/evocheck.sh | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 383e021b..0626cd38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Changed -* evocheck: upstream release 22.04 +* evocheck: upstream release 22.04.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state * dump-server-state: upstream release 22.04.1 diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index 07ec97f7..4f24ae79 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -4,7 +4,7 @@ # Script to verify compliance of a Debian/OpenBSD server # powered by Evolix -VERSION="22.04" +VERSION="22.04.1" readonly VERSION # base functions @@ -596,20 +596,20 @@ check_evobackup() { } # Vérification de l'exclusion des montages (NFS) dans les sauvegardes check_evobackup_exclude_mount() { - excludes_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.evobackup_exclude_mount.XXXXX") + excludes_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.evobackup_exclude_mount.XXXXX") files_to_cleanup="${files_to_cleanup} ${excludes_file}" # shellcheck disable=SC2044 for evobackup_file in $(find /etc/cron* -name '*evobackup*' | grep -v -E ".disabled$"); do # If rsync is not limited by "one-file-system" # then we verify that every mount is excluded - grep -q -- "^\s*--one-file-system" "${evobackup_file}" \ - || grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' \ - > "${excludes_file}" - not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}") - for mount in ${not_excluded}; do - failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script" - done + if ! grep -q -- "^\s*--one-file-system" "${evobackup_file}"; then + grep -- "--exclude " "${evobackup_file}" | grep -E -o "\"[^\"]+\"" | tr -d '"' > "${excludes_file}" + not_excluded=$(findmnt --type nfs,nfs4,fuse.sshfs, -o target --noheadings | grep -v -f "${excludes_file}") + for mount in ${not_excluded}; do + failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script" + done + fi done } # Verification de la presence du userlogrotate @@ -1074,7 +1074,7 @@ check_duplicate_fs_label() { # Do it only if thereis blkid binary BLKID_BIN=$(command -v blkid) if [ -n "$BLKID_BIN" ]; then - tmpFile=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.duplicate_fs_label.XXXXX") + tmpFile=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.duplicate_fs_label.XXXXX") files_to_cleanup="${files_to_cleanup} ${tmpFile}" parts=$($BLKID_BIN -c /dev/null | grep -ve raid_member -e EFI_SYSPART | grep -Eo ' LABEL=".*"' | cut -d'"' -f2) @@ -1473,7 +1473,7 @@ add_to_path() { echo "$PATH" | grep -qF "${new_path}" || export PATH="${PATH}:${new_path}" } check_versions() { - versions_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.versions.XXXXX") + versions_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.versions.XXXXX") files_to_cleanup="${files_to_cleanup} ${versions_file}" download_versions "${versions_file}" @@ -1501,7 +1501,7 @@ main() { # Detect operating system name, version and release detect_os - main_output_file=$(mktemp --tmpdir=${TMPDIR:-/tmp} "evocheck.main.XXXXX") + main_output_file=$(mktemp --tmpdir="${TMPDIR:-/tmp}" "evocheck.main.XXXXX") files_to_cleanup="${files_to_cleanup} ${main_output_file}" #----------------------------------------------------------- @@ -1733,7 +1733,9 @@ main() { fi if [ -f "${main_output_file}" ]; then - if [ $(cat "${main_output_file}" | wc -l) -gt 0 ]; then + lines_found=$(wc -l < "${main_output_file}") + # shellcheck disable=SC2086 + if [ ${lines_found} -gt 0 ]; then cat "${main_output_file}" 2>&1 fi From 55356857b2228e3f7c334c574146533e2eb4c10e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 26 Apr 2022 09:56:47 +0200 Subject: [PATCH 63/79] dump-server-state: upstream release 22.04.2 --- CHANGELOG.md | 2 +- evolinux-base/files/dump-server-state.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0626cd38..6dd72cf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evocheck: upstream release 22.04.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state -* dump-server-state: upstream release 22.04.1 +* dump-server-state: upstream release 22.04.2 * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 1b80bd0a..5bb3cd4e 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.04.1" +VERSION="22.04.2" readonly VERSION dump_dir= @@ -725,7 +725,8 @@ task_mysql_processes() { else debug "* mysqladmin ERROR" debug "${last_result}" - rc=10 + # Ignore errors because we don't know how to deal with multiple instances + # rc=10 fi else debug "* no mysqld or mariadbd process is running" From 49e4e67c2c5401274a33fa432b37f4c7582e39fc Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 26 Apr 2022 11:26:15 +0200 Subject: [PATCH 64/79] fix copyright evocommit --- etc-git/files/evocommit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc-git/files/evocommit b/etc-git/files/evocommit index 0053784b..5a7f798b 100644 --- a/etc-git/files/evocommit +++ b/etc-git/files/evocommit @@ -8,7 +8,7 @@ show_version() { cat <, +Copyright 2022 Evolix , Jérémy Lecour and others. From 381a71aca1648a76f590f67e7aeb08e663c5cbcd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 26 Apr 2022 18:21:42 +0200 Subject: [PATCH 65/79] dump-server-state: upstream release 22.04.3 --- CHANGELOG.md | 2 +- evolinux-base/files/dump-server-state.sh | 25 ++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dd72cf3..4735e3cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * evocheck: upstream release 22.04.1 * evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware * evolinux-base: rename backup-server-state to dump-server-state -* dump-server-state: upstream release 22.04.2 +* dump-server-state: upstream release 22.04.3 * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks diff --git a/evolinux-base/files/dump-server-state.sh b/evolinux-base/files/dump-server-state.sh index 5bb3cd4e..5f76413f 100644 --- a/evolinux-base/files/dump-server-state.sh +++ b/evolinux-base/files/dump-server-state.sh @@ -3,7 +3,7 @@ PROGNAME="dump-server-state" REPOSITORY="https://gitea.evolix.org/evolix/dump-server-state" -VERSION="22.04.2" +VERSION="22.04.3" readonly VERSION dump_dir= @@ -76,7 +76,8 @@ END } debug() { if [ "${VERBOSE}" = "1" ]; then - echo "$1" + msg="${1:-$(cat /dev/stdin)}" + echo "${msg}" fi } @@ -717,16 +718,20 @@ task_mysql_processes() { if [ -n "${mysqladmin_bin}" ]; then # Look for local MySQL or MariaDB process if pgrep mysqld > /dev/null || pgrep mariadbd > /dev/null; then - last_result=$(${mysqladmin_bin} --verbose processlist > "${dump_dir}/mysql-processlist.txt") - last_rc=$? + if ${mysqladmin_bin} ping > /dev/null 2>&1; then + ${mysqladmin_bin} --verbose processlist > "${dump_dir}/mysql-processlist.txt" 2> "${dump_dir}/mysql-processlist.err" + last_rc=$? - if [ ${last_rc} -eq 0 ]; then - debug "* mysqladmin OK" + if [ ${last_rc} -eq 0 ]; then + debug "* mysqladmin OK" + else + debug "* mysqladmin ERROR" + debug < "${dump_dir}/mysql-processlist.err" + rm "${dump_dir}/mysql-processlist.err" + rc=10 + fi else - debug "* mysqladmin ERROR" - debug "${last_result}" - # Ignore errors because we don't know how to deal with multiple instances - # rc=10 + debug "* unable to ping with mysqladmin" fi else debug "* no mysqld or mariadbd process is running" From 805a8ecb3ab644d3dcd7cd8af5ac55a791117c61 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 27 Apr 2022 14:22:59 +0200 Subject: [PATCH 66/79] etc-git: use "ansible-commit" to efficiently commit all available repositories (including /etc inside LXC) from Ansible --- CHANGELOG.md | 2 +- etc-git/defaults/main.yml | 1 + etc-git/files/ansible-commit | 183 +++++++++++++++++++++++++++++++++ etc-git/tasks/commit.yml | 82 ++------------- etc-git/tasks/main.yml | 105 +------------------ etc-git/tasks/repositories.yml | 37 +++++++ etc-git/tasks/utils.yml | 93 +++++++++++++++++ 7 files changed, 326 insertions(+), 177 deletions(-) create mode 100644 etc-git/files/ansible-commit create mode 100644 etc-git/tasks/repositories.yml create mode 100644 etc-git/tasks/utils.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 4735e3cc..7b6bb7f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Added -* etc-git: Commit /etc in lxc containers when they are git repositories +* etc-git: use "ansible-commit" to efficiently commit all available repositories (including /etc inside LXC) from Ansible * minifirewall: configure proxy/backup/sysctl values * nagios-nrpe: Add a check dhcp_pool * redis : Activate overcommit sysctl diff --git a/etc-git/defaults/main.yml b/etc-git/defaults/main.yml index d0da5e7d..01b83bfd 100644 --- a/etc-git/defaults/main.yml +++ b/etc-git/defaults/main.yml @@ -4,3 +4,4 @@ etc_git_default_commit_message: Ansible run etc_git_monitor_status: True etc_git_purge_index_lock_enabled: True etc_git_purge_index_lock_age: 86400 +etc_git_config_repositories: True diff --git a/etc-git/files/ansible-commit b/etc-git/files/ansible-commit new file mode 100644 index 00000000..c47375f8 --- /dev/null +++ b/etc-git/files/ansible-commit @@ -0,0 +1,183 @@ +#!/bin/sh + +set -u + +VERSION="22.04" + +show_version() { + cat <, + Jérémy Lecour + and others. + +ansible-commit comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to redistribute it under certain conditions. +See the GNU General Public Licence for details. +END +} + +show_help() { + cat <&2 + exit 1 + fi + ;; + --message=?*) + # message options, with value speparated by = + MESSAGE=${1#*=} + ;; + --message=) + # message options, without value + printf 'FAILED: "--message" requires a non-empty option argument.\n' >&2 + exit 1 + ;; + -n|--dry-run) + # disable actual commands + DRY_RUN=1 + ;; + -v|--verbose) + # print verbose information + VERBOSE=1 + ;; + --) + # End of all options. + shift + break + ;; + -?*|[[:alnum:]]*) + # ignore unknown options + printf 'FAILED: Unknown option (ignored): %s\n' "$1" >&2 + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift +done + +if [ -z "${MESSAGE}" ]; then + echo "FAILED: missing message parameter" >&2 + show_usage + exit 1 +fi +DRY_RUN=${DRY_RUN:-0} +VERBOSE=${VERBOSE:-0} + +evocommit_bin=$(command -v evocommit) +if [ -z "${evocommit_bin}" ]; then + echo "FAILED: evocommit not found" >&2 + exit 1 +fi + +lxc_ls_bin=$(command -v lxc-ls) +lxc_config_bin=$(command -v lxc-config) + +main \ No newline at end of file diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml index 2098aeeb..c92e3c6a 100644 --- a/etc-git/tasks/commit.yml +++ b/etc-git/tasks/commit.yml @@ -1,79 +1,9 @@ --- -# /etc -- name: Is /etc a git repository - stat: - path: /etc/.git - register: _etc_git - -- name: "evocommit /etc" - command: "/usr/local/bin/evocommit --ansible --repository /etc --message \"{{ commit_message | mandatory }}\"" +- name: "Execute ansible-commit" + command: "/usr/local/bin/ansible-commit --verbose --message \"{{ commit_message | mandatory }}\"" changed_when: - - _etc_git_commit.stdout - - "'CHANGED:' in _etc_git_commit.stdout" - ignore_errors: yes - register: _etc_git_commit - when: - - _etc_git.stat.exists - - _etc_git.stat.isdir - -# /etc/bind -- name: Is /etc/bind a git repository - stat: - path: /etc/bind/.git - register: _etc_bind_git - -- name: "evocommit /etc/bind" - command: "/usr/local/bin/evocommit --ansible --repository /etc/bind --message \"{{ commit_message | mandatory }}\"" - changed_when: - - _etc_bind_git_commit.stdout - - "'CHANGED:' in _etc_bind_git_commit.stdout" - ignore_errors: yes - register: _etc_bind_git_commit - when: - - _etc_bind_git.stat.exists - - _etc_bind_git.stat.isdir - -# /usr/share/scripts -- name: Is /usr/share/scripts a git repository - stat: - path: /usr/share/scripts/.git - register: _usr_share_scripts_git - -- name: "evocommit /usr/share/scripts" - command: "/usr/local/bin/evocommit --ansible --repository /usr/share/scripts --message \"{{ commit_message | mandatory }}\"" - changed_when: - - _usr_share_scripts_git_commit.stdout - - "'CHANGED:' in _usr_share_scripts_git_commit.stdout" - ignore_errors: yes - register: _usr_share_scripts_git_commit - when: - - _usr_share_scripts_git.stat.exists - - _usr_share_scripts_git.stat.isdir - -- name: Check if there are lxc containers - stat: - path: /var/lib/lxc - get_attributes: no - get_checksum: no - get_mime: no - register: _var_lib_lxc - -- name: Get lxc containers and commit their /etc when needed - block: - - name: Get all lxc containers - find: - paths: /var/lib/lxc - recurse: no - file_type: directory - register: _lxc_containers - - - name: "Commit /etc in all containers" - include_tasks: - file: lxc_commit.yml - loop: "{{ _lxc_containers.files | map(attribute='path') | map('basename') }}" - loop_control: - loop_var: container - when: - - _var_lib_lxc.stat.exists - - _var_lib_lxc.stat.isdir or _var_lib_lxc.stat.islnk + - _ansible_commit.stdout + - "'CHANGED:' in _ansible_commit.stdout" + ignore_errors: True + register: _ansible_commit \ No newline at end of file diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index 34c4a1ca..f71ba552 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -9,108 +9,13 @@ when: - ansible_distribution == "Debian" -- include_role: - name: evolix/remount-usr - -- name: "evocommit script is installed" - copy: - src: evocommit - dest: /usr/local/bin/evocommit - mode: "0755" - force: yes +- name: Install and configure utilities + include: utils.yml tags: - etc-git -- include: repository.yml - vars: - repository_path: "/etc" - gitignore_items: - - "aliases.db" - - "*.swp" - - "postfix/sa-blacklist.access" - - "postfix/*.db" - - "postfix/spamd.cidr" - - "evobackup/.keep-*" - - "letsencrypt/.certbot.lock" - -- name: verify /usr/share/scripts presence - stat: - path: /usr/share/scripts - register: _usr_share_scripts - -- include: repository.yml - vars: - repository_path: "/usr/share/scripts" - gitignore_items: [] - when: - - _usr_share_scripts.stat.isdir - - ansible_distribution_major_version is version('10', '>=') - -- name: "etc-git-optimize script is installed" - copy: - src: etc-git-optimize - dest: /usr/share/scripts/etc-git-optimize - mode: "0755" - force: yes +- name: Configure repositories + include: repositories.yml tags: - etc-git - -- name: "etc-git-status script is installed" - copy: - src: etc-git-status - dest: /usr/share/scripts/etc-git-status - mode: "0755" - force: yes - tags: - - etc-git - -- name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" - args: - executable: /bin/bash - failed_when: False - changed_when: False - check_mode: no - register: is_cron_installed - -- block: - - name: Legacy cron jobs for /etc/.git status are absent - file: - dest: "{{ item }}" - state: absent - loop: - - /etc/cron.monthly/optimize-etc-git - - /etc/cron.d/etc-git-status - - - name: Cron job for monthly git optimization - cron: - name: "Monthly optimization" - cron_file: etc-git - special_time: "monthly" - user: root - job: "/usr/share/scripts/etc-git-optimize" - - - name: Cron job for hourly git status - cron: - name: "Hourly warning for unclean Git repository if nobody is connected" - cron_file: etc-git - special_time: "hourly" - user: root - job: "who > /dev/null || /usr/share/scripts/etc-git-status" - state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}" - - - name: Cron job for daily git status - cron: - name: "Daily warning for unclean Git repository" - cron_file: etc-git - user: root - job: "/usr/share/scripts/etc-git-status" - minute: "21" - hour: "21" - weekday: "*" - day: "*" - month: "*" - state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}" - when: is_cron_installed.rc == 0 - tags: - - etc-git \ No newline at end of file + when: etc_git_config_repositories | bool \ No newline at end of file diff --git a/etc-git/tasks/repositories.yml b/etc-git/tasks/repositories.yml new file mode 100644 index 00000000..71ff0665 --- /dev/null +++ b/etc-git/tasks/repositories.yml @@ -0,0 +1,37 @@ +--- + +- include: repository.yml + vars: + repository_path: "/etc" + gitignore_items: + - "aliases.db" + - "*.swp" + - "postfix/sa-blacklist.access" + - "postfix/*.db" + - "postfix/spamd.cidr" + - "evobackup/.keep-*" + - "letsencrypt/.certbot.lock" + tags: + - etc-git + +- name: verify /usr/share/scripts presence + stat: + path: /usr/share/scripts + register: _usr_share_scripts + tags: + - etc-git + +- include_role: + name: evolix/remount-usr + when: + - _usr_share_scripts.stat.isdir + +- include: repository.yml + vars: + repository_path: "/usr/share/scripts" + gitignore_items: [] + when: + - _usr_share_scripts.stat.isdir + - ansible_distribution_major_version is version('10', '>=') + tags: + - etc-git \ No newline at end of file diff --git a/etc-git/tasks/utils.yml b/etc-git/tasks/utils.yml new file mode 100644 index 00000000..cd060de1 --- /dev/null +++ b/etc-git/tasks/utils.yml @@ -0,0 +1,93 @@ +--- + +- include_role: + name: evolix/remount-usr + tags: + - etc-git + +- name: "evocommit script is installed" + copy: + src: evocommit + dest: /usr/local/bin/evocommit + mode: "0755" + force: yes + tags: + - etc-git + +- name: "ansible-commit script is installed" + copy: + src: ansible-commit + dest: /usr/local/bin/ansible-commit + mode: "0755" + force: yes + tags: + - etc-git + +- name: "etc-git-optimize script is installed" + copy: + src: etc-git-optimize + dest: /usr/share/scripts/etc-git-optimize + mode: "0755" + force: yes + tags: + - etc-git + +- name: "etc-git-status script is installed" + copy: + src: etc-git-status + dest: /usr/share/scripts/etc-git-status + mode: "0755" + force: yes + tags: + - etc-git + +- name: Check if cron is installed + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + failed_when: False + changed_when: False + check_mode: no + register: is_cron_installed + +- block: + - name: Legacy cron jobs for /etc/.git status are absent + file: + dest: "{{ item }}" + state: absent + loop: + - /etc/cron.monthly/optimize-etc-git + - /etc/cron.d/etc-git-status + + - name: Cron job for monthly git optimization + cron: + name: "Monthly optimization" + cron_file: etc-git + special_time: "monthly" + user: root + job: "/usr/share/scripts/etc-git-optimize" + + - name: Cron job for hourly git status + cron: + name: "Hourly warning for unclean Git repository if nobody is connected" + cron_file: etc-git + special_time: "hourly" + user: root + job: "who > /dev/null || /usr/share/scripts/etc-git-status" + state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}" + + - name: Cron job for daily git status + cron: + name: "Daily warning for unclean Git repository" + cron_file: etc-git + user: root + job: "/usr/share/scripts/etc-git-status" + minute: "21" + hour: "21" + weekday: "*" + day: "*" + month: "*" + state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}" + when: is_cron_installed.rc == 0 + tags: + - etc-git \ No newline at end of file From 666487e00c9e822b385fec3166a0f3a36ecee02f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 27 Apr 2022 15:12:02 +0200 Subject: [PATCH 67/79] fix ansible-commit --help --- etc-git/files/ansible-commit | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/etc-git/files/ansible-commit b/etc-git/files/ansible-commit index c47375f8..20ab3a92 100644 --- a/etc-git/files/ansible-commit +++ b/etc-git/files/ansible-commit @@ -2,7 +2,7 @@ set -u -VERSION="22.04" +VERSION="22.04.1" show_version() { cat < Date: Wed, 27 Apr 2022 18:00:18 +0200 Subject: [PATCH 68/79] munin: remount /usr before writing --- munin/tasks/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml index 8c6ec525..4720fbe5 100644 --- a/munin/tasks/main.yml +++ b/munin/tasks/main.yml @@ -35,6 +35,9 @@ tags: - munin +- include_role: + name: evolix/remount-usr + - name: Install some Munin plugins (disabled) copy: src: 'plugins/{{ item }}' From a53159c93b0a38fa31920816019e6183b4385dfb Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 28 Apr 2022 12:40:02 +0200 Subject: [PATCH 69/79] minifirewall: compatibility with "legacy" version of minifirewall --- CHANGELOG.md | 1 + minifirewall/defaults/main.yml | 17 +- minifirewall/files/minifirewall.legacy.conf | 106 ++++ minifirewall/tasks/config.legacy.yml | 218 ++++++++ minifirewall/tasks/install.legacy.yml | 24 + minifirewall/tasks/install.yml | 20 - minifirewall/tasks/main.yml | 104 +++- minifirewall/tasks/tail.legacy.yml | 50 ++ minifirewall/tasks/tail.yml | 5 +- minifirewall/tasks/utils.yml | 21 + minifirewall/templates/minifirewall.legacy.j2 | 492 ++++++++++++++++++ squid/defaults/main.yml | 1 - squid/tasks/minifirewall.legacy.yml | 43 ++ squid/tasks/minifirewall.yml | 32 +- 14 files changed, 1085 insertions(+), 49 deletions(-) create mode 100644 minifirewall/files/minifirewall.legacy.conf create mode 100644 minifirewall/tasks/config.legacy.yml create mode 100644 minifirewall/tasks/install.legacy.yml create mode 100644 minifirewall/tasks/tail.legacy.yml create mode 100644 minifirewall/tasks/utils.yml create mode 100644 minifirewall/templates/minifirewall.legacy.j2 create mode 100644 squid/tasks/minifirewall.legacy.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b6bb7f8..70e058ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * etc-git: use "ansible-commit" to efficiently commit all available repositories (including /etc inside LXC) from Ansible * minifirewall: configure proxy/backup/sysctl values +* minifirewall: compatibility with "legacy" version of minifirewall * nagios-nrpe: Add a check dhcp_pool * redis : Activate overcommit sysctl * munin: Add possibility to install local plugins, and install dhcp_pool plugin diff --git a/minifirewall/defaults/main.yml b/minifirewall/defaults/main.yml index 4c084154..18d7d5b3 100644 --- a/minifirewall/defaults/main.yml +++ b/minifirewall/defaults/main.yml @@ -1,9 +1,14 @@ --- -# Deprecated variable -# minifirewall_main_file: /etc/default/minifirewall +# possible values: Null (default), modern or legacy +minifirewall_install_mode: Null -minifirewall_tail_file: zzz-tail +# BEGIN legacy variables +minifirewall_legacy_main_file: /etc/default/minifirewall +minifirewall_legacy_tail_file: /etc/default/minifirewall.tail +# END legacy variabes + +minifirewall_tail_file: /etc/minifirewall.d/zzz-tail minifirewall_tail_included: False minifirewall_tail_force: True @@ -14,17 +19,17 @@ minifirewall_force_upgrade_config: False # Update specific values in configuration minifirewall_update_config: True -minifirewall_git_url: "https://forge.evolix.org/minifirewall.git" -minifirewall_checkout_path: "/tmp/minifirewall" minifirewall_int: "{{ ansible_default_ipv4.interface }}" minifirewall_ipv6: "on" minifirewall_intlan: "{{ ansible_default_ipv4.address }}/32" minifirewall_docker: "off" minifirewall_default_trusted_ips: [] +minifirewall_legacy_fallback_trusted_ips: ['0.0.0.0/0'] +minifirewall_fallback_trusted_ips: ['0.0.0.0/0', '::/0'] minifirewall_additional_trusted_ips: [] # and default to ['0.0.0.0/0', '::/0'] if the result is still empty -minifirewall_trusted_ips: "{{ minifirewall_default_trusted_ips | union(minifirewall_additional_trusted_ips) | unique | default(['0.0.0.0/0', '::/0'], true) }}" +minifirewall_trusted_ips: "{{ minifirewall_default_trusted_ips | union(minifirewall_additional_trusted_ips) | unique }}" minifirewall_privilegied_ips: [] minifirewall_protected_ports_tcp: [22] diff --git a/minifirewall/files/minifirewall.legacy.conf b/minifirewall/files/minifirewall.legacy.conf new file mode 100644 index 00000000..47be78bf --- /dev/null +++ b/minifirewall/files/minifirewall.legacy.conf @@ -0,0 +1,106 @@ +# Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall +# Version 20.12 — 2020-12-01 22:55:35 + +# Main interface +INT='eth0' + +# IPv6 +IPV6=on + +# Docker Mode +# Changes the behaviour of minifirewall to not break the containers' network +# For instance, turning it on will disable nat table purge +# Also, we'll add the DOCKER-USER chain, in iptable +DOCKER='off' + +# Trusted IPv4 local network +# ...will be often IP/32 if you don't trust anything +INTLAN='192.168.0.2/32' + +# Trusted IPv4 addresses for private and semi-public services +TRUSTEDIPS='31.170.9.129 62.212.121.90 31.170.8.4 82.65.34.85 54.37.106.210 51.210.84.146' + +# Privilegied IPv4 addresses for semi-public services +# (no need to add again TRUSTEDIPS) +PRIVILEGIEDIPS='' + + +# Local services IPv4/IPv6 restrictions +####################################### + +# Protected services +# (add also in Public services if needed) +SERVICESTCP1p='22222' +SERVICESUDP1p='' + +# Public services (IPv4/IPv6) +SERVICESTCP1='22222' +SERVICESUDP1='' + +# Semi-public services (IPv4) +SERVICESTCP2='22' +SERVICESUDP2='' + +# Private services (IPv4) +SERVICESTCP3='5666' +SERVICESUDP3='' + +# Standard output IPv4 access restrictions +########################################## + +# DNS authorizations +# (if you have local DNS server, set 0.0.0.0/0) +DNSSERVEURS='0.0.0.0/0' + +# HTTP authorizations +# (you can use DNS names but set cron to reload minifirewall regularly) +# (if you have HTTP proxy, set 0.0.0.0/0) +# HTTPSITES='security.debian.org pub.evolix.net security-cdn.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org ocsp.int-x3.letsencrypt.org' +HTTPSITES='0.0.0.0/0' + +# HTTPS authorizations +HTTPSSITES='0.0.0.0/0' + +# FTP authorizations +FTPSITES='' + +# SSH authorizations +SSHOK='0.0.0.0/0' + +# SMTP authorizations +SMTPOK='0.0.0.0/0' + +# SMTP secure authorizations (ports TCP/465 and TCP/587) +SMTPSECUREOK='' + +# NTP authorizations +NTPOK='0.0.0.0/0' + + +# IPv6 Specific rules +##################### + +# Example: allow SSH from Trusted IPv6 addresses +/sbin/ip6tables -A INPUT -i $INT -p tcp --dport 22 -s 2a01:9500:37:129::/64 -j ACCEPT + +# Example: allow outgoing SSH/HTTP/HTTPS/SMTP/DNS traffic +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 22 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT + +# Example: allow output DNS, NTP and traceroute traffic +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT +#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + +# Example: allow DHCPv6 +/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT + +# IPv4 Specific rules +##################### + +# /sbin/iptables ... diff --git a/minifirewall/tasks/config.legacy.yml b/minifirewall/tasks/config.legacy.yml new file mode 100644 index 00000000..8a7f5990 --- /dev/null +++ b/minifirewall/tasks/config.legacy.yml @@ -0,0 +1,218 @@ +--- + +- debug: + var: minifirewall_trusted_ips + verbosity: 1 +- debug: + var: minifirewall_privilegied_ips + verbosity: 1 + +- name: Stat minifirewall config file (before) + stat: + path: "{{ minifirewall_main_file }}" + register: minifirewall_before + +- name: Check if minifirewall is running + shell: /sbin/iptables -L -n | grep -E "^(DROP\s+udp|ACCEPT\s+icmp)\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$" + changed_when: False + failed_when: False + check_mode: no + register: minifirewall_is_running + +- debug: + var: minifirewall_is_running + verbosity: 1 + +- name: Begin marker for IP addresses + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "# BEGIN ANSIBLE MANAGED BLOCK FOR IPS" + insertbefore: '^# Main interface' + create: no + +- name: End marker for IP addresses + lineinfile: + dest: "{{ minifirewall_main_file }}" + create: no + line: "# END ANSIBLE MANAGED BLOCK FOR IPS" + insertafter: '^PRIVILEGIEDIPS=' + +- name: Verify that at least 1 trusted IP is provided + assert: + that: minifirewall_trusted_ips | length > 0 + msg: You must provide at least 1 trusted IP + +- debug: + msg: "Warning: minifirewall_trusted_ips='0.0.0.0/0', the firewall is useless!" + when: minifirewall_trusted_ips == ["0.0.0.0/0"] + +- name: Configure IP addresses + blockinfile: + dest: "{{ minifirewall_main_file }}" + marker: "# {mark} ANSIBLE MANAGED BLOCK FOR IPS" + block: | + # Main interface + INT='{{ minifirewall_int }}' + + # IPv6 + IPV6='{{ minifirewall_ipv6 }}' + + # Docker Mode + # Changes the behaviour of minifirewall to not break the containers' network + # For instance, turning it on will disable nat table purge + # Also, we'll add the DOCKER-USER chain, in iptable + DOCKER='{{ minifirewall_docker }}' + + # Trusted IPv4 local network + # ...will be often IP/32 if you don't trust anything + INTLAN='{{ minifirewall_intlan }}' + + # Trusted IPv4 addresses for private and semi-public services + TRUSTEDIPS='{{ minifirewall_trusted_ips | join(' ') }}' + + # Privilegied IPv4 addresses for semi-public services + # (no need to add again TRUSTEDIPS) + PRIVILEGIEDIPS='{{ minifirewall_privilegied_ips | join(' ') }}' + create: no + register: minifirewall_config_ips + +- name: Begin marker for ports + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "# BEGIN ANSIBLE MANAGED BLOCK FOR PORTS" + insertbefore: '^# Protected services' + create: no + +- name: End marker for ports + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "# END ANSIBLE MANAGED BLOCK FOR PORTS" + insertafter: '^SERVICESUDP3=' + create: no + +- name: Configure ports + blockinfile: + dest: "{{ minifirewall_main_file }}" + marker: "# {mark} ANSIBLE MANAGED BLOCK FOR PORTS" + block: | + # Protected services + # (add also in Public services if needed) + SERVICESTCP1p='{{ minifirewall_protected_ports_tcp | join(' ') }}' + SERVICESUDP1p='{{ minifirewall_protected_ports_udp | join(' ') }}' + + # Public services (IPv4/IPv6) + SERVICESTCP1='{{ minifirewall_public_ports_tcp | join(' ') }}' + SERVICESUDP1='{{ minifirewall_public_ports_udp | join(' ') }}' + + # Semi-public services (IPv4) + SERVICESTCP2='{{ minifirewall_semipublic_ports_tcp | join(' ') }}' + SERVICESUDP2='{{ minifirewall_semipublic_ports_udp | join(' ') }}' + + # Private services (IPv4) + SERVICESTCP3='{{ minifirewall_private_ports_tcp | join(' ') }}' + SERVICESUDP3='{{ minifirewall_private_ports_udp | join(' ') }}' + create: no + register: minifirewall_config_ports + +- name: Configure DNSSERVEURS + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "DNSSERVEURS='{{ minifirewall_dns_servers | join(' ') }}'" + regexp: "DNSSERVEURS='.*'" + create: no + when: minifirewall_dns_servers is not none + +- name: Configure HTTPSITES + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "HTTPSITES='{{ minifirewall_http_sites | join(' ') }}'" + regexp: "HTTPSITES='.*'" + create: no + when: minifirewall_http_sites is not none + +- name: Configure HTTPSSITES + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "HTTPSSITES='{{ minifirewall_https_sites | join(' ') }}'" + regexp: "HTTPSSITES='.*'" + create: no + when: minifirewall_https_sites is not none + +- name: Configure FTPSITES + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "FTPSITES='{{ minifirewall_ftp_sites | join(' ') }}'" + regexp: "FTPSITES='.*'" + create: no + when: minifirewall_ftp_sites is not none + +- name: Configure SSHOK + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "SSHOK='{{ minifirewall_ssh_ok | join(' ') }}'" + regexp: "SSHOK='.*'" + create: no + when: minifirewall_ssh_ok is not none + +- name: Configure SMTPOK + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "SMTPOK='{{ minifirewall_smtp_ok | join(' ') }}'" + regexp: "SMTPOK='.*'" + create: no + when: minifirewall_smtp_ok is not none + +- name: Configure SMTPSECUREOK + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "SMTPSECUREOK='{{ minifirewall_smtp_secure_ok | join(' ') }}'" + regexp: "SMTPSECUREOK='.*'" + create: no + when: minifirewall_smtp_secure_ok is not none + +- name: Configure NTPOK + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "NTPOK='{{ minifirewall_ntp_ok | join(' ') }}'" + regexp: "NTPOK='.*'" + create: no + when: minifirewall_ntp_ok is not none + +- name: evomaintenance + lineinfile: + dest: "{{ minifirewall_main_file }}" + line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT" + insertafter: "^# EvoMaintenance" + loop: "{{ evomaintenance_hosts }}" + +- name: remove minifirewall example rule for the evomaintenance + lineinfile: + dest: "{{ minifirewall_main_file }}" + regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)' + state: absent + when: evomaintenance_hosts | length > 0 + +- name: Stat minifirewall config file (after) + stat: + path: "{{ minifirewall_main_file }}" + register: minifirewall_after + +- name: restart minifirewall + command: /etc/init.d/minifirewall restart + register: minifirewall_init_restart + failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + when: + - minifirewall_restart_if_needed | bool + - minifirewall_is_running.rc == 0 + - minifirewall_before.stat.checksum != minifirewall_after.stat.checksum + +- name: restart minifirewall (noop) + meta: noop + register: minifirewall_init_restart + failed_when: False + changed_when: False + when: not (minifirewall_restart_if_needed | bool) + +- debug: + var: minifirewall_init_restart + verbosity: 2 diff --git a/minifirewall/tasks/install.legacy.yml b/minifirewall/tasks/install.legacy.yml new file mode 100644 index 00000000..323426b5 --- /dev/null +++ b/minifirewall/tasks/install.legacy.yml @@ -0,0 +1,24 @@ +--- + +- name: dependencies are satisfied + apt: + name: iptables + state: present + +- name: init script is copied + template: + src: minifirewall.legacy.j2 + dest: /etc/init.d/minifirewall + force: "{{ minifirewall_force_upgrade_script | default('no') }}" + mode: "0700" + owner: root + group: root + +- name: configuration is copied + copy: + src: minifirewall.legacy.conf + dest: "{{ minifirewall_main_file }}" + force: "{{ minifirewall_force_upgrade_config | default('no') }}" + mode: "0600" + owner: root + group: root diff --git a/minifirewall/tasks/install.yml b/minifirewall/tasks/install.yml index 9c0483b9..daac6f81 100644 --- a/minifirewall/tasks/install.yml +++ b/minifirewall/tasks/install.yml @@ -41,23 +41,3 @@ mode: "0600" owner: root group: root - -- include_role: - name: evolix/remount-usr - -- name: /usr/share/scripts exists - file: - dest: /usr/share/scripts - mode: "0700" - owner: root - group: root - state: directory - -- name: blacklist-countries.sh is copied - copy: - src: blacklist-countries.sh - dest: /usr/share/scripts/blacklist-countries.sh - force: "no" - mode: "0700" - owner: root - group: root diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index 0fbb3ad6..e8355ceb 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -4,25 +4,107 @@ set_fact: minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" -- name: Fail if minifirewall_main_file is defined +# Legacy or modern mode? ############################################## + +- name: Check minifirewall + stat: + path: /etc/init.d/minifirewall + register: _minifirewall_check + +# Legacy versions of minifirewall don't define the VERSION variable +- name: Look for minifirewall version + shell: "grep -E '^\\s*VERSION=' /etc/init.d/minifirewall" + failed_when: False + changed_when: False + check_mode: False + register: _minifirewall_version_check + +- name: Set install mode to legacy if needed + set_fact: + minifirewall_install_mode: legacy + minifirewall_main_file: "{{ minifirewall_legacy_main_file }}" + minifirewall_tail_file: "{{ minifirewall_legacy_tail_file }}" + when: + - minifirewall_install_mode != 'modern' + - not (minifirewall_force_upgrade_script | bool) + - _minifirewall_version_check.rc == 1 # grep didn't find but the file exists + +- name: Set install mode to modern if not legacy + set_fact: + minifirewall_install_mode: modern + when: minifirewall_install_mode != 'legacy' + +- name: Debug install mode + debug: + var: minifirewall_install_mode + verbosity: 1 + +####################################################################### + +- name: Fail if minifirewall_main_file is defined (legacy mode) fail: msg: "Variable minifirewall_main_file is deprecated and not configurable anymore." - when: minifirewall_main_file is defined + when: + - minifirewall_install_mode != 'legacy' + - minifirewall_main_file is defined -- include: install.yml +- name: Install tasks (modern mode) + include: install.yml + when: minifirewall_install_mode != 'legacy' -- include: config.yml - when: minifirewall_update_config | bool +- name: Install tasks (legacy mode) + include: install.legacy.yml + when: minifirewall_install_mode == 'legacy' -- include: nrpe.yml +- name: Config tasks (modern mode) + include: config.yml + when: + - minifirewall_install_mode != 'legacy' + - minifirewall_update_config | bool -- include: activate.yml +- name: Config tasks (legacy mode) + include: config.legacy.yml + when: + - minifirewall_install_mode == 'legacy' + - minifirewall_update_config | bool -- include: tail.yml - when: minifirewall_tail_included | bool +- name: Utils tasks + include: utils.yml -- name: Force restart minifirewall +- name: NRPE tasks + include: nrpe.yml + +- name: Activation tasks + include: activate.yml + +- name: Tail tasks (modern mode) + include: tail.yml + when: + - minifirewall_install_mode != 'legacy' + - minifirewall_tail_included | bool + +- name: Tail tasks (legacy mode) + include: tail.legacy.yml + when: + - minifirewall_install_mode == 'legacy' + - minifirewall_tail_included | bool + +# Restart? + +- name: Force restart minifirewall (modern mode) command: /etc/init.d/minifirewall restart register: minifirewall_init_restart failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - when: minifirewall_restart_force | bool \ No newline at end of file + changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + when: + - minifirewall_install_mode != 'legacy' + - minifirewall_restart_force | bool + +- name: Force restart minifirewall (legacy mode) + command: /etc/init.d/minifirewall restart + register: minifirewall_init_restart + failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + when: + - minifirewall_install_mode == 'legacy' + - minifirewall_restart_force | bool \ No newline at end of file diff --git a/minifirewall/tasks/tail.legacy.yml b/minifirewall/tasks/tail.legacy.yml new file mode 100644 index 00000000..7a13eefa --- /dev/null +++ b/minifirewall/tasks/tail.legacy.yml @@ -0,0 +1,50 @@ +--- +- name: Add some rules at the end of minifirewall file + template: + src: "{{ item }}" + dest: "{{ minifirewall_tail_file }}" + force: "{{ minifirewall_tail_force | bool }}" + follow: yes + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2" + - "templates/minifirewall-tail/minifirewall.{{ host_group | default('all') }}.tail.j2" + - "templates/minifirewall-tail/minifirewall.default.tail.j2" + - "templates/minifirewall.default.tail.j2" + register: minifirewall_tail_template + +- debug: + var: minifirewall_tail_template + verbosity: 1 + +- name: source minifirewall.tail at the end of the main file + blockinfile: + dest: "{{ minifirewall_main_file }}" + marker: "# {mark} ANSIBLE MANAGED EXTERNAL RULES" + block: ". {{ minifirewall_tail_file }}" + insertbefore: EOF + register: minifirewall_tail_source + +- debug: + var: minifirewall_tail_source + verbosity: 1 + +- name: restart minifirewall + command: /etc/init.d/minifirewall restart + register: minifirewall_init_restart + failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + when: + - minifirewall_tail_template is changed + - minifirewall_restart_if_needed | bool + +- name: restart minifirewall (noop) + meta: noop + register: minifirewall_init_restart + failed_when: False + changed_when: False + when: not (minifirewall_restart_if_needed | bool) + +- debug: + var: minifirewall_init_restart + verbosity: 1 diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index a1bfba64..ae771017 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -2,7 +2,7 @@ - name: Add some rules at the end of minifirewall file template: src: "{{ item }}" - dest: "/etc/minifirewall.d/{{ minifirewall_tail_file }}" + dest: "{{ minifirewall_tail_file }}" force: "{{ minifirewall_tail_force | bool }}" follow: yes loop: "{{ query('first_found', templates) }}" @@ -19,9 +19,6 @@ verbosity: 1 - name: restart minifirewall - # service: - # name: minifirewall - # state: restarted command: /etc/init.d/minifirewall restart register: minifirewall_init_restart failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" diff --git a/minifirewall/tasks/utils.yml b/minifirewall/tasks/utils.yml new file mode 100644 index 00000000..775bdd95 --- /dev/null +++ b/minifirewall/tasks/utils.yml @@ -0,0 +1,21 @@ +--- + +- include_role: + name: evolix/remount-usr + +- name: /usr/share/scripts exists + file: + dest: /usr/share/scripts + mode: "0700" + owner: root + group: root + state: directory + +- name: blacklist-countries.sh is copied + copy: + src: blacklist-countries.sh + dest: /usr/share/scripts/blacklist-countries.sh + force: "no" + mode: "0700" + owner: root + group: root \ No newline at end of file diff --git a/minifirewall/templates/minifirewall.legacy.j2 b/minifirewall/templates/minifirewall.legacy.j2 new file mode 100644 index 00000000..13b5130d --- /dev/null +++ b/minifirewall/templates/minifirewall.legacy.j2 @@ -0,0 +1,492 @@ +#!/bin/sh + +# minifirewall is shellscripts for easy firewalling on a standalone server +# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel +# See https://gitea.evolix.org/evolix/minifirewall + +# Copyright (c) 2007-2020 Evolix +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License. + +# Description +# script for standalone server + +# Start or stop minifirewall +# + +### BEGIN INIT INFO +# Provides: minfirewall +# Required-Start: +# Required-Stop: +# Should-Start: $network $syslog $named +# Should-Stop: $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the firewall +# Description: Firewall designed for standalone server +### END INIT INFO + +DESC="minifirewall" +NAME="minifirewall" + + +# Variables configuration +######################### + +# iptables paths +IPT=/sbin/iptables +IPT6=/sbin/ip6tables + +# TCP/IP variables +LOOPBACK='127.0.0.0/8' +CLASSA='10.0.0.0/8' +CLASSB='172.16.0.0/12' +CLASSC='192.168.0.0/16' +CLASSD='224.0.0.0/4' +CLASSE='240.0.0.0/5' +ALL='0.0.0.0' +BROAD='255.255.255.255' +PORTSROOT='0:1023' +PORTSUSER='1024:65535' + +chain_exists() +{ + local chain_name="$1" ; shift + [ $# -eq 1 ] && local intable="--table $1" + iptables $intable -nL "$chain_name" >/dev/null 2>&1 +} + +# Configuration +oldconfigfile="/etc/firewall.rc" +configfile="{{ minifirewall_main_file }}" + +IPV6=$(grep "IPV6=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') +DOCKER=$(grep "DOCKER=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') +INT=$(grep "INT=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}') + +case "$1" in + start) + + echo "Start IPTables rules..." + +# Stop and warn if error! +set -e +trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + + +# sysctl network security settings +################################## + +# Don't answer to broadcast pings +echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + +# Ignore bogus ICMP responses +echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + +# Disable Source Routing +for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do +echo 0 > $i +done + +# Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks +# cf http://cr.yp.to/syncookies.html +echo 1 > /proc/sys/net/ipv4/tcp_syncookies + +# Disable ICMP redirects +for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do +echo 0 > $i +done + +for i in /proc/sys/net/ipv4/conf/*/send_redirects; do +echo 0 > $i +done + +# Enable Reverse Path filtering : verify if responses use same network interface +for i in /proc/sys/net/ipv4/conf/*/rp_filter; do +echo 1 > $i +done + +# log des paquets avec adresse incoherente +for i in /proc/sys/net/ipv4/conf/*/log_martians; do +echo 1 > $i +done + +# IPTables configuration +######################## + +$IPT -N LOG_DROP +$IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' +$IPT -A LOG_DROP -j DROP +$IPT -N LOG_ACCEPT +$IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' +$IPT -A LOG_ACCEPT -j ACCEPT + +if test -f $oldconfigfile; then + echo "$oldconfigfile is deprecated, rename to $configfile" >&2 + exit 1 +fi + +if ! test -f $configfile; then + echo "$configfile does not exist" >&2 + exit 1 +fi + +tmpfile=`mktemp` +. $configfile 2>$tmpfile >&2 +if [ -s $tmpfile ]; then + echo "$configfile returns standard or error output (see below). Stopping." >&2 + cat $tmpfile + exit 1 +fi +rm $tmpfile + +# Trusted ip addresses +$IPT -N ONLYTRUSTED +$IPT -A ONLYTRUSTED -j LOG_DROP +for x in $TRUSTEDIPS + do + $IPT -I ONLYTRUSTED -s $x -j ACCEPT + done + +# Privilegied ip addresses +# (trusted ip addresses *are* privilegied) +$IPT -N ONLYPRIVILEGIED +$IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED +for x in $PRIVILEGIEDIPS + do + $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT + done + +# Chain for restrictions (blacklist IPs/ranges) +$IPT -N NEEDRESTRICT + +# We allow all on loopback interface +$IPT -A INPUT -i lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT +# if OUTPUTDROP +$IPT -A OUTPUT -o lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT + +# We avoid "martians" packets, typical when W32/Blaster virus +# attacked windowsupdate.com and DNS was changed to 127.0.0.1 +# $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP +$IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP + + +if [ "$DOCKER" = "on" ]; then + + $IPT -N MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-TRUSTED -j DROP + + $IPT -N MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN + + $IPT -N MINIFW-DOCKER-PUB + $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PUB -j RETURN + + # Flush DOCKER-USER if exist, create it if absent + if chain_exists 'DOCKER-USER'; then + $IPT -F DOCKER-USER + else + $IPT -N DOCKER-USER + fi; + + # Pipe new connection through MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -j RETURN + +fi + + +# Local services restrictions +############################# + +# Allow services for $INTLAN (local server or local network) +$IPT -A INPUT -s $INTLAN -j ACCEPT + +# Enable protection chain for sensible services +for x in $SERVICESTCP1p + do + $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + done + +for x in $SERVICESUDP1p + do + $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + done + +# Public service +for x in $SERVICESTCP1 + do + $IPT -A INPUT -p tcp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT + done + +for x in $SERVICESUDP1 + do + $IPT -A INPUT -p udp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT + done + +# Privilegied services +for x in $SERVICESTCP2 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED + done + +for x in $SERVICESUDP2 + do + $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + done + +# Private services +for x in $SERVICESTCP3 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + done + +for x in $SERVICESUDP3 + do + $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + done + + +if [ "$DOCKER" = "on" ]; then + + # Public services defined in SERVICESTCP1 & SERVICESUDP1 + for dstport in $SERVICESTCP1 + do + $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN + done + + for dstport in $SERVICESUDP1 + do + $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN + done + + # Privileged services (accessible from privileged & trusted IPs) + for dstport in $SERVICESTCP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + # Trusted services (accessible from trusted IPs) + for dstport in $SERVICESTCP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done +fi + +# External services +################### + +# DNS authorizations +for x in $DNSSERVEURS + do + $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT + done + +# HTTP (TCP/80) authorizations +for x in $HTTPSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + done + +# HTTPS (TCP/443) authorizations +for x in $HTTPSSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + done + +# FTP (so complex protocol...) authorizations +for x in $FTPSITES + do + # requests on Control connection + $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT + # FTP port-mode on Data Connection + $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT + done + +# SSH authorizations +for x in $SSHOK + do + $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + done + +# SMTP authorizations +for x in $SMTPOK + do + $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT + done + +# secure SMTP (TCP/465 et TCP/587) authorizations +for x in $SMTPSECUREOK + do + $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT + done + +# NTP authorizations +for x in $NTPOK + do + $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + done + +# Always allow ICMP +$IPT -A INPUT -p icmp -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + + +# IPTables policy +################# + +# by default DROP INPUT packets +$IPT -P INPUT DROP +[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + +# by default, no FORWARING (deprecated for Virtual Machines) +#echo 0 > /proc/sys/net/ipv4/ip_forward +#$IPT -P FORWARD DROP +#$IPT6 -P FORWARD DROP + +# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) +$IPT -P OUTPUT ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT +$IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +$IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +$IPT -A OUTPUT -p udp -j DROP +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + +trap - INT TERM EXIT + + echo "...starting IPTables rules is now finish : OK" + ;; + + stop) + + echo "Flush all rules and accept everything..." + + # Delete all rules + $IPT -F INPUT + $IPT -F OUTPUT + $IPT -F LOG_DROP + $IPT -F LOG_ACCEPT + $IPT -F ONLYTRUSTED + $IPT -F ONLYPRIVILEGIED + $IPT -F NEEDRESTRICT + [ "$DOCKER" = "off" ] && $IPT -t nat -F + $IPT -t mangle -F + [ "$IPV6" != "off" ] && $IPT6 -F INPUT + [ "$IPV6" != "off" ] && $IPT6 -F OUTPUT + + if [ "$DOCKER" = "on" ]; then + $IPT -F DOCKER-USER + $IPT -A DOCKER-USER -j RETURN + + $IPT -F MINIFW-DOCKER-PUB + $IPT -X MINIFW-DOCKER-PUB + $IPT -F MINIFW-DOCKER-PRIVILEGED + $IPT -X MINIFW-DOCKER-PRIVILEGED + $IPT -F MINIFW-DOCKER-TRUSTED + $IPT -X MINIFW-DOCKER-TRUSTED + + fi + + # Accept all + $IPT -P INPUT ACCEPT + $IPT -P OUTPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P INPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT + #$IPT -P FORWARD ACCEPT + #$IPT -t nat -P PREROUTING ACCEPT + #$IPT -t nat -P POSTROUTING ACCEPT + + # Delete non-standard chains + $IPT -X LOG_DROP + $IPT -X LOG_ACCEPT + $IPT -X ONLYPRIVILEGIED + $IPT -X ONLYTRUSTED + $IPT -X NEEDRESTRICT + + echo "...flushing IPTables rules is now finish : OK" + ;; + + status) + + $IPT -L -n -v --line-numbers + $IPT -t nat -L -n -v --line-numbers + $IPT -t mangle -L -n -v --line-numbers + $IPT6 -L -n -v --line-numbers + $IPT6 -t mangle -L -n -v --line-numbers + ;; + + reset) + + echo "Reset all IPTables counters..." + + $IPT -Z + $IPT -t nat -Z + $IPT -t mangle -Z + [ "$IPV6" != "off" ] && $IPT6 -Z + [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z + + echo "...reseting IPTables counters is now finish : OK" + ;; + + restart) + + $0 stop + $0 start + ;; + + *) + + echo "Usage: $0 {start|stop|restart|status|reset|squid}" + exit 1 +esac + +exit 0 diff --git a/squid/defaults/main.yml b/squid/defaults/main.yml index 2188d606..8cbf43d4 100644 --- a/squid/defaults/main.yml +++ b/squid/defaults/main.yml @@ -7,4 +7,3 @@ squid_whitelist_items: [] squid_localproxy_enable: False -minifirewall_main_file: /etc/default/minifirewall diff --git a/squid/tasks/minifirewall.legacy.yml b/squid/tasks/minifirewall.legacy.yml new file mode 100644 index 00000000..f7e78ee5 --- /dev/null +++ b/squid/tasks/minifirewall.legacy.yml @@ -0,0 +1,43 @@ +--- +- name: Check if Minifirewall is present + stat: + path: "/etc/default/minifirewall" + check_mode: no + register: minifirewall_test + +- block: + - name: HTTPSITES list is commented in minifirewall + replace: + dest: "/etc/default/minifirewall" + regexp: "^(HTTPSITES='[^0-9])" + replace: '#\1' + notify: restart minifirewall + + - name: all HTTPSITES are authorized in minifirewall + lineinfile: + dest: "/etc/default/minifirewall" + line: "HTTPSITES='0.0.0.0/0'" + regexp: "HTTPSITES='.*'" + insertafter: "^#HTTPSITES=" + notify: restart minifirewall + + - name: add iptables rules for the proxy + lineinfile: + dest: "/etc/default/minifirewall" + regexp: "^#? *{{ item }}" + line: "{{ item }}" + insertafter: "^# Proxy" + loop: + - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT" + - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d {{ squid_address }} -j ACCEPT" + - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.0/8 -j ACCEPT" + - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8888" + notify: restart minifirewall + + - name: remove minifirewall example rule for the proxy + lineinfile: + dest: "/etc/default/minifirewall" + regexp: '^#.*(-t nat).*(-d X\.X\.X\.X)' + state: absent + notify: restart minifirewall + when: minifirewall_test.stat.exists diff --git a/squid/tasks/minifirewall.yml b/squid/tasks/minifirewall.yml index e878b0a8..5abdf9df 100644 --- a/squid/tasks/minifirewall.yml +++ b/squid/tasks/minifirewall.yml @@ -1,29 +1,37 @@ --- - name: Check if Minifirewall is present stat: - path: "{{ minifirewall_main_file }}" + path: "/etc/default/minifirewall" check_mode: no register: minifirewall_test - block: - name: HTTPSITES list is commented in minifirewall replace: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" regexp: "^(HTTPSITES='[^0-9])" replace: '#\1' notify: restart minifirewall - name: all HTTPSITES are authorized in minifirewall lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" line: "HTTPSITES='0.0.0.0/0'" regexp: "HTTPSITES='.*'" insertafter: "^#HTTPSITES=" notify: restart minifirewall - - name: add iptables rules for the proxy + # The PROXY variable means that minifirewall is "modern" + - name: Look for PROXY variable + shell: "grep -E '^\\s*PROXY=' /etc/default/minifirewall" + failed_when: False + changed_when: False + check_mode: False + register: _minifirewall_proxy_var_check + + - name: Set proxy configuration for minifirewall (legacy mode) lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" regexp: "^#? *{{ item }}" line: "{{ item }}" insertafter: "^# Proxy" @@ -33,11 +41,21 @@ - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.0/8 -j ACCEPT" - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8888" notify: restart minifirewall + when: _minifirewall_proxy_var_check.rc == 1 - - name: remove minifirewall example rule for the proxy + - name: remove minifirewall example rule for the proxy (legacy mode) lineinfile: - dest: "{{ minifirewall_main_file }}" + dest: "/etc/default/minifirewall" regexp: '^#.*(-t nat).*(-d X\.X\.X\.X)' state: absent notify: restart minifirewall + when: _minifirewall_proxy_var_check.rc == 1 + + - name: Set proxy configuration for minifirewall (modern mode) + replace: + dest: "/etc/default/minifirewall" + replace: "PROXY='on'" + regexp: "PROXY='.*'" + notify: restart minifirewall + when: _minifirewall_proxy_var_check.rc == 0 when: minifirewall_test.stat.exists From 61cd2b742886461f16d88e1b601d85b417bab62f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 28 Apr 2022 19:14:31 +0200 Subject: [PATCH 70/79] minifirewall: upstream release 22.04 --- CHANGELOG.md | 2 +- minifirewall/files/minifirewall | 273 +++++++++++++++++++++++++++----- minifirewall/tasks/main.yml | 4 +- 3 files changed, 238 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e058ca..8e77c681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks -* minifirewall: upstream release 22.03.5 +* minifirewall: upstream release 22.04 * openvpn: use a subnet topology instead of the net30 default topology * tomcat: Tomcat 9 by default with Debian 11 * openvpn: use a local copy of files instead of cloning an external git repository diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index f8729f79..f383d87c 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -1,7 +1,8 @@ #!/bin/sh +# shellcheck disable=SC2059 -# minifirewall is shellscripts for easy firewalling on a standalone server -# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel +# minifirewall is a shell script for easy firewalling on a standalone server +# It uses netfilter/iptables http://netfilter.org/ designed for recent Linux kernel # See https://gitea.evolix.org/evolix/minifirewall # Copyright (c) 2007-2022 Evolix @@ -28,7 +29,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.03.5" +VERSION="22.04" NAME="minifirewall" # shellcheck disable=SC2034 @@ -97,6 +98,42 @@ BACKUPSERVERS='' LEGACY_CONFIG='off' +STATE_FILE_LATEST='/var/run/minifirewall_state_latest' +STATE_FILE_CURRENT='/var/run/minifirewall_state_current' +STATE_FILE_PREVIOUS='/var/run/minifirewall_state_previous' +STATE_FILE_DIFF='/var/run/minifirewall_state_diff' + +LOGGER_BIN=$(command -v logger) + +# No colors by default +RED='' +GREEN='' +YELLOW='' +BLUE='' +MAGENTA='' +CYAN='' +WHITE='' +BOLD='' +RESET='' +# check if stdout is a terminal... +if [ -t 1 ]; then + + # see if it supports colors... + ncolors=$(tput colors) + + if [ -n "${ncolors}" ] && [ ${ncolors} -ge 8 ]; then + RED=$(tput setaf 1) + GREEN=$(tput setaf 2) + YELLOW=$(tput setaf 3) + BLUE=$(tput setaf 4) + MAGENTA=$(tput setaf 5) + CYAN=$(tput setaf 6) + WHITE=$(tput setaf 7) + BOLD=$(tput bold) + RESET='\e[m' + fi +fi + ## pseudo dry-run : ## Uncomment and call these functions instead of the real iptables and ip6tables commands # IPT="fake_iptables" @@ -109,6 +146,16 @@ LEGACY_CONFIG='off' # } ## Beware that commands executed from included files are not modified by this trick. +syslog_info() { + if [ -x "${LOGGER_BIN}" ]; then + ${LOGGER_BIN} -t "${NAME}" -p daemon.info "$1" + fi +} +syslog_error() { + if [ -x "${LOGGER_BIN}" ]; then + ${LOGGER_BIN} -t "${NAME}" -p daemon.error "$1" + fi +} sort_values() { echo "$*" | tr ' ' '\n' | sort -h } @@ -139,37 +186,40 @@ chain_exists() { } source_file_or_error() { file=$1 - echo "...sourcing '${file}\`" + syslog_info "sourcing \`${file}'" + printf "${BLUE}sourcing \`%s'${RESET}\n" "${file}" tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) . "${file}" 2>"${tmpfile}" >&2 if [ -s "${tmpfile}" ]; then - echo "${file} returns standard or error output (see below). Stopping." >&2 + syslog_error "Error while sourcing ${file}" + printf "${RED}%s returns standard or error output (see below). Stopping.${RESET}\n" ${file} >&2 cat "${tmpfile}" exit 1 fi - rm "${tmpfile}" + rm -f "${tmpfile}" } source_configuration() { if ! test -f ${config_file}; then - echo "${config_file} does not exist" >&2 + printf "${RED}%s does not exist${RESET}\n" "${config_file}" >&2 ## We still want to deal with this really old configuration file ## even if it has been deprecated since Debian 8 old_config_file="/etc/firewall.rc" if test -f ${old_config_file}; then - echo "${old_config_file} is deprecated. Rename it to ${config_file}" >&2 + printf "${YELLOW}%s is deprecated and ignored. Rename it to %s${RESET}\n" "${old_config_file}" "${config_file}" >&2 fi exit 1 fi - if grep -e "iptables" -e "ip6tables" "${config_file}" | grep -qvE "^#"; then + # If we find something other than a blank line, a comment or a variable assignment + if grep --quiet --extended-regexp --invert-match "^\s*(#|$|\w+=)" "${config_file}"; then # Backward compatible mode ########################### - echo "Legacy config detected" + printf "${YELLOW}legacy config detected${RESET}\n" LEGACY_CONFIG='on' # Non-backward compatible mode @@ -191,10 +241,11 @@ source_configuration() { # and not interfere with the configuration step. tmp_config_file=$(mktemp --tmpdir=/tmp minifirewall.XXX) - grep -E "^\s*[_a-zA-Z0-9]+=" "${config_file}" > "${tmp_config_file}" + # get only variable assignments + grep -E "^\s*\w+=" "${config_file}" > "${tmp_config_file}" source_file_or_error "${tmp_config_file}" - rm "${tmp_config_file}" + rm -f "${tmp_config_file}" else source_file_or_error "${config_file}" fi @@ -207,13 +258,88 @@ source_includes() { done fi } +check_unpersisted_state() { + cmp_bin=$(command -v cmp) + diff_bin=$(command -v diff) + + if [ -z "${cmp_bin}" ]; then + printf "${YELLOW}skip state comparison (Can't find cmp command)${RESET}\n" >&2 + elif [ -z "${diff_bin}" ]; then + printf "${YELLOW}skip state comparison (Can't find diff command)${RESET}\n" >&2 + else + # store current state + mkdir -p "$(dirname "${STATE_FILE_CURRENT}")" + status_without_numbers > "${STATE_FILE_CURRENT}" + + # clean previous diff file + rm -f "${STATE_FILE_DIFF}" + + if [ -f "${STATE_FILE_LATEST}" ]; then + cmp_result=$(cmp "${STATE_FILE_LATEST}" "${STATE_FILE_CURRENT}") + cmp_rc=$? + + if [ ${cmp_rc} -eq 0 ]; then + # echo " rules have not changed since latest start" + : + elif [ ${cmp_rc} -eq 1 ]; then + diff -u "${STATE_FILE_LATEST}" "${STATE_FILE_CURRENT}" > "${STATE_FILE_DIFF}" + printf "${YELLOW}WARNING: current state is different than persisted state, check %s${RESET}\n" "${STATE_FILE_DIFF}" >&2 + else + printf "${RED}ERROR comparing rules:${RESET}\n" >&2 + echo "${cmp_result}" >&2 + fi + fi + # cleanup + rm -f "${STATE_FILE_CURRENT}" + fi +} +report_state_changes() { + cmp_bin=$(command -v cmp) + diff_bin=$(command -v diff) + + if [ -z "${cmp_bin}" ]; then + printf "${YELLOW}skip state comparison (Can't find cmp command)${RESET}\n" >&2 + return + elif [ -z "${diff_bin}" ]; then + printf "${YELLOW}skip state comparison (Can't find diff command)${RESET}\n" >&2 + else + # If there is a known state + # let's compare it with the current state + if [ -f "${STATE_FILE_LATEST}" ]; then + check_unpersisted_state + fi + + # Then reset the known state + mkdir -p "$(dirname "${STATE_FILE_LATEST}")" + status_without_numbers > "${STATE_FILE_LATEST}" + + # But if there is a previous known state + # let's compare with the new known state + if [ -f "${STATE_FILE_PREVIOUS}" ]; then + cmp_result=$(cmp "${STATE_FILE_PREVIOUS}" "${STATE_FILE_LATEST}") + cmp_rc=$? + + if [ ${cmp_rc} -eq 0 ]; then + # echo "Rules have not changed since previous start" + : + elif [ ${cmp_rc} -eq 1 ]; then + diff -u "${STATE_FILE_PREVIOUS}" "${STATE_FILE_LATEST}" > "${STATE_FILE_DIFF}" + printf "${YELLOW}INFO: rules have changed since latest start, check %s${RESET}\n" "${STATE_FILE_DIFF}" >&2 + else + printf "${RED}ERROR comparing rules:${RESET}\n" >&2 + echo "${cmp_result}" >&2 + fi + fi + fi +} start() { - echo "Start IPTables rules..." + syslog_info "starting" + printf "${BOLD}${NAME} starting${RESET}\n" # Stop and warn if error! set -e - trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + trap 'printf "${RED}${NAME} failed : an error occured during startup.${RESET}\n"; syslog_error "failed" ' INT TERM EXIT # sysctl network security settings ################################## @@ -238,14 +364,14 @@ start() { if [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "1" ] || [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "0" ]; then echo "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts else - echo "Invalid SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS value '${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS" "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" >&2 exit 1 fi if [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "1" ] || [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "0" ]; then echo "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses else - echo "Invalid SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES value '${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES" "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" >&2 exit 1 fi @@ -254,14 +380,14 @@ start() { echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" > "${proc_sys_file}" done else - echo "Invalid SYSCTL_ACCEPT_SOURCE_ROUTE value '${SYSCTL_ACCEPT_SOURCE_ROUTE}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ACCEPT_SOURCE_ROUTE" "${SYSCTL_ACCEPT_SOURCE_ROUTE}" >&2 exit 1 fi if [ "${SYSCTL_TCP_SYNCOOKIES}" = "1" ] || [ "${SYSCTL_TCP_SYNCOOKIES}" = "0" ]; then echo "${SYSCTL_TCP_SYNCOOKIES}" > /proc/sys/net/ipv4/tcp_syncookies else - echo "Invalid SYSCTL_TCP_SYNCOOKIES value '${SYSCTL_TCP_SYNCOOKIES}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_TCP_SYNCOOKIES" "${SYSCTL_TCP_SYNCOOKIES}" >&2 exit 1 fi @@ -273,7 +399,7 @@ start() { echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}" done else - echo "Invalid SYSCTL_ICMP_REDIRECTS value '${SYSCTL_ICMP_REDIRECTS}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_ICMP_REDIRECTS" "${SYSCTL_ICMP_REDIRECTS}" >&2 exit 1 fi @@ -282,7 +408,7 @@ start() { echo "${SYSCTL_RP_FILTER}" > "${proc_sys_file}" done else - echo "Invalid SYSCTL_RP_FILTER value '${SYSCTL_RP_FILTER}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_RP_FILTER" "${SYSCTL_RP_FILTER}" >&2 exit 1 fi @@ -291,7 +417,7 @@ start() { echo "${SYSCTL_LOG_MARTIANS}" > "${proc_sys_file}" done else - echo "Invalid SYSCTL_LOG_MARTIANS value '${SYSCTL_LOG_MARTIANS}', must be '0' or '1'." >&2 + printf "${RED}ERROR: invalid %s value '%s', must be '0' or '1'.\n" "SYSCTL_LOG_MARTIANS" "${SYSCTL_LOG_MARTIANS}" >&2 exit 1 fi @@ -707,7 +833,7 @@ start() { ${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT fi else - echo "Unrecognized syntax for BACKUPSERVERS '${server}\`. Use space-separated IP:PORT tuples." >&2 + printf "${RED}ERROR: unrecognized syntax for BACKUPSERVERS '%s\`. Use space-separated IP:PORT tuples.${RESET}\n" "${server}" >&2 exit 1 fi done @@ -718,6 +844,10 @@ start() { ${IPT6} -A INPUT -p icmpv6 -j ACCEPT fi + # source config file for remaining commands + if is_legacy_config; then + source_file_or_error "${config_file}" + fi # IPTables policy ################# @@ -754,17 +884,28 @@ start() { ${IPT6} -A OUTPUT -p udp -j DROP fi - if is_legacy_config; then - source_file_or_error "${config_file}" - fi + # Finish + ######################## trap - INT TERM EXIT - echo "...starting IPTables rules is now finish : OK" + syslog_info "started" + printf "${GREEN}${BOLD}${NAME} started${RESET}\n" + + # No need to exit on error anymore + set +e + + report_state_changes } stop() { - echo "Flush all rules and accept everything..." + syslog_info "stopping" + printf "${BOLD}${NAME} stopping${RESET}\n" + + printf "${BLUE}flushing all rules and accepting everything${RESET}\n" + + mkdir -p "$(dirname "${STATE_FILE_PREVIOUS}")" + status_without_numbers > "${STATE_FILE_PREVIOUS}" # Delete all rules ${IPT} -F INPUT @@ -839,19 +980,45 @@ stop() { ${IPT6} -X NEEDRESTRICT fi - echo "...flushing IPTables rules is now finish : OK" + rm -f "${STATE_FILE_LATEST}" "${STATE_FILE_CURRENT}" + + syslog_info "stopped" + printf "${GREEN}${BOLD}${NAME} stopped${RESET}\n" } status() { - ${IPT} -L -n -v --line-numbers - ${IPT} -t nat -L -n -v --line-numbers - ${IPT} -t mangle -L -n -v --line-numbers - ${IPT6} -L -n -v --line-numbers - ${IPT6} -t mangle -L -n -v --line-numbers + printf "${BLUE}#### iptables --list ###############################${RESET}\n" + ${IPT} --list --numeric --verbose --line-numbers + printf "\n${BLUE}### iptables --table nat --list ####################${RESET}\n" + ${IPT} --table nat --list --numeric --verbose --line-numbers + printf "\n${BLUE}#### iptables --table mangle --list ################${RESET}\n" + ${IPT} --table mangle --list --numeric --verbose --line-numbers + if is_ipv6_enabled; then + printf "\n${BLUE}#### ip6tables --list ##############################${RESET}\n" + ${IPT6} --list --numeric --verbose --line-numbers + printf "\n${BLUE}#### ip6tables --table mangle --list ###############${RESET}\n" + ${IPT6} --table mangle --list --numeric --verbose --line-numbers + fi +} + +status_without_numbers() { + printf "${BLUE}#### iptables --list ###############################${RESET}\n" + ${IPT} --list --numeric + printf "\n${BLUE}### iptables --table nat --list ####################${RESET}\n" + ${IPT} --table nat --list --numeric + printf "\n${BLUE}#### iptables --table mangle --list ################${RESET}\n" + ${IPT} --table mangle --list --numeric + if is_ipv6_enabled; then + printf "\n${BLUE}#### ip6tables --list ##############################${RESET}\n" + ${IPT6} --list --numeric + printf "\n${BLUE}#### ip6tables --table mangle --list ###############${RESET}\n" + ${IPT6} --table mangle --list --numeric + fi } reset() { - echo "Reset all IPTables counters..." + syslog_info "resetting" + printf "${BOLD}${NAME} resetting${RESET}\n" ${IPT} -Z if is_ipv6_enabled; then @@ -865,36 +1032,66 @@ reset() { ${IPT6} -t mangle -Z fi - echo "...reseting IPTables counters is now finish : OK" + syslog_info "reset" + printf "${GREEN}${BOLD}${NAME} reset${RESET}\n" } +show_version() { + cat <. + +${NAME} comes with ABSOLUTELY NO WARRANTY. +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License. +END +} case "${1:-''}" in start) + source_configuration + check_unpersisted_state + start ;; stop) + source_configuration + check_unpersisted_state + stop ;; status) + source_configuration + check_unpersisted_state + status ;; reset) + source_configuration + check_unpersisted_state + reset ;; restart) + source_configuration + check_unpersisted_state + stop start ;; + version) + show_version + ;; + *) - echo "Usage: $0 {start|stop|restart|status|reset}" + echo "Usage: $0 {start|stop|restart|status|reset|version}" exit 1 ;; esac diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index e8355ceb..f5eb9ea4 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -94,8 +94,8 @@ - name: Force restart minifirewall (modern mode) command: /etc/init.d/minifirewall restart register: minifirewall_init_restart - failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + failed_when: "'minifirewall failed' in minifirewall_init_restart.stdout" + changed_when: "'minifirewall started' in minifirewall_init_restart.stdout" when: - minifirewall_install_mode != 'legacy' - minifirewall_restart_force | bool From 749d6a78cdb4259af2d510cf6a5ba99194be9abd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 5 May 2022 09:40:30 +0200 Subject: [PATCH 71/79] redis: Add log2mail user to redis group --- CHANGELOG.md | 3 ++- redis/tasks/default-log2mail.yml | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e77c681..eef50ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,8 @@ The **patch** part changes is incremented if multiple releases happen the same m * minifirewall: configure proxy/backup/sysctl values * minifirewall: compatibility with "legacy" version of minifirewall * nagios-nrpe: Add a check dhcp_pool -* redis : Activate overcommit sysctl +* redis: Activate overcommit sysctl +* redis: Add log2mail user to redis group * munin: Add possibility to install local plugins, and install dhcp_pool plugin ### Changed diff --git a/redis/tasks/default-log2mail.yml b/redis/tasks/default-log2mail.yml index 21628b0c..3c50cab7 100644 --- a/redis/tasks/default-log2mail.yml +++ b/redis/tasks/default-log2mail.yml @@ -17,3 +17,14 @@ tags: - redis - log2mail + +- name: log2mail user is in redis group + user: + name: log2mail + groups: redis + append: yes + state: present + notify: restart log2mail + tags: + - redis + - log2mail \ No newline at end of file From a93c1a9141d26eabba8c06dced56d28041705be9 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 5 May 2022 09:41:27 +0200 Subject: [PATCH 72/79] redis: Don't enable plugins in check mode (prevents errors) --- redis/tasks/default-munin.yml | 1 + redis/tasks/instance-munin.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/redis/tasks/default-munin.yml b/redis/tasks/default-munin.yml index 3f0fe6f4..7856741e 100644 --- a/redis/tasks/default-munin.yml +++ b/redis/tasks/default-munin.yml @@ -49,6 +49,7 @@ - used_keys - used_memory notify: restart munin-node + when: not ansible_check_mode tags: - redis diff --git a/redis/tasks/instance-munin.yml b/redis/tasks/instance-munin.yml index 80c67c6f..bc8d8e9a 100644 --- a/redis/tasks/instance-munin.yml +++ b/redis/tasks/instance-munin.yml @@ -49,6 +49,7 @@ - used_keys - used_memory notify: restart munin-node + when: not ansible_check_mode tags: - redis From 1c6561e6f57d0658bb4937ff621298aec6e00cab Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 6 May 2022 18:09:33 +0200 Subject: [PATCH 73/79] ansible-commit: add --no-lxc flag --- etc-git/files/ansible-commit | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/etc-git/files/ansible-commit b/etc-git/files/ansible-commit index 20ab3a92..892aa418 100644 --- a/etc-git/files/ansible-commit +++ b/etc-git/files/ansible-commit @@ -31,6 +31,7 @@ Usage: ansible-commit --message "add new host" Options --message MESSAGE set the commit message + --no-lxc disable commit inside LXC containers -V, --version print version number -v, --verbose increase verbosity -n, --dry-run actions are not executed @@ -81,7 +82,7 @@ main() { fi fi - if [ -n "${lxc_ls_bin}" ]; then + if [ "${LXC}" = "1" ] && [ -n "${lxc_ls_bin}" ]; then for container in $(${lxc_ls_bin} -1); do if [ -n "${lxc_config_bin}" ]; then # discovered path @@ -136,6 +137,9 @@ while :; do printf 'FAILED: "--message" requires a non-empty option argument.\n' >&2 exit 1 ;; + --no-lxc) + LXC=0 + ;; -n|--dry-run) # disable actual commands DRY_RUN=1 @@ -169,6 +173,7 @@ if [ -z "${MESSAGE}" ]; then fi DRY_RUN=${DRY_RUN:-0} VERBOSE=${VERBOSE:-0} +LXC=${LXC:-1} evocommit_bin=$(command -v evocommit) if [ -z "${evocommit_bin}" ]; then From 4f4c2229e853e1baa444704beada8ca60e302d78 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 6 May 2022 18:10:01 +0200 Subject: [PATCH 74/79] etc-git: release 22.05 of ansible-commit --- etc-git/files/ansible-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc-git/files/ansible-commit b/etc-git/files/ansible-commit index 892aa418..d22f4a6a 100644 --- a/etc-git/files/ansible-commit +++ b/etc-git/files/ansible-commit @@ -2,7 +2,7 @@ set -u -VERSION="22.04.1" +VERSION="22.05" show_version() { cat < Date: Mon, 9 May 2022 10:14:33 +0200 Subject: [PATCH 75/79] =?UTF-8?q?Ajout=20opendkim-genkey=20en=20sha256=20e?= =?UTF-8?q?t=20taille=20cl=C3=A9=204096?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- opendkim/files/opendkim-add.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendkim/files/opendkim-add.sh b/opendkim/files/opendkim-add.sh index 4e11f8cc..d70fdd4b 100644 --- a/opendkim/files/opendkim-add.sh +++ b/opendkim/files/opendkim-add.sh @@ -10,7 +10,7 @@ domain="$(echo "$1"|xargs)" if [ ! -f "/etc/ssl/private/dkim-${servername}.private" ]; then echo "Generate DKIM keys ..." - opendkim-genkey -D /etc/ssl/private/ -r -d "${domain}" -s "dkim-${servername}" + opendkim-genkey -h sha256 -b 4096 -D /etc/ssl/private/ -r -d "${domain}" -s "dkim-${servername}" chown opendkim:opendkim "/etc/ssl/private/dkim-${servername}.private" chmod 640 "/etc/ssl/private/dkim-${servername}.private" mv "/etc/ssl/private/dkim-${servername}.txt" "/etc/ssl/certs/" From 3663783509bbd988835cf6aef006588452aa1a18 Mon Sep 17 00:00:00 2001 From: Eric Morino Date: Mon, 9 May 2022 10:19:18 +0200 Subject: [PATCH 76/79] add change in opendkim role --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eef50ca2..9b2b2046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * tomcat: Tomcat 9 by default with Debian 11 * openvpn: use a local copy of files instead of cloning an external git repository * vrrpd: Store sysctl values in specific file +* opendkim : add generate opendkim-genkey in sha256 and key 4096 ### Fixed From 378ee04c82c950570cdaf957a43298e67f4892fd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 10 May 2022 15:55:08 +0200 Subject: [PATCH 77/79] minifirewall: upstream release 22.05 --- CHANGELOG.md | 2 +- minifirewall/files/minifirewall | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b2b2046..c19d0455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * generate-ldif: Add services check for bkctld * minifirewall: restore "force-restart" and fix "restart-if-needed" * minifirewall: tail template follows symlinks -* minifirewall: upstream release 22.04 +* minifirewall: upstream release 22.05 * openvpn: use a subnet topology instead of the net30 default topology * tomcat: Tomcat 9 by default with Debian 11 * openvpn: use a local copy of files instead of cloning an external git repository diff --git a/minifirewall/files/minifirewall b/minifirewall/files/minifirewall index f383d87c..7dae5787 100755 --- a/minifirewall/files/minifirewall +++ b/minifirewall/files/minifirewall @@ -29,7 +29,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="22.04" +VERSION="22.05" NAME="minifirewall" # shellcheck disable=SC2034 @@ -989,7 +989,7 @@ stop() { status() { printf "${BLUE}#### iptables --list ###############################${RESET}\n" ${IPT} --list --numeric --verbose --line-numbers - printf "\n${BLUE}### iptables --table nat --list ####################${RESET}\n" + printf "\n${BLUE}#### iptables --table nat --list ###################${RESET}\n" ${IPT} --table nat --list --numeric --verbose --line-numbers printf "\n${BLUE}#### iptables --table mangle --list ################${RESET}\n" ${IPT} --table mangle --list --numeric --verbose --line-numbers @@ -1004,7 +1004,7 @@ status() { status_without_numbers() { printf "${BLUE}#### iptables --list ###############################${RESET}\n" ${IPT} --list --numeric - printf "\n${BLUE}### iptables --table nat --list ####################${RESET}\n" + printf "\n${BLUE}#### iptables --table nat --list ###################${RESET}\n" ${IPT} --table nat --list --numeric printf "\n${BLUE}#### iptables --table mangle --list ################${RESET}\n" ${IPT} --table mangle --list --numeric From dd2072b86b34c92026ae081874d055f00f1e2941 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 10 May 2022 16:39:44 +0200 Subject: [PATCH 78/79] minifirewall: fix failed_when conditions on restart --- CHANGELOG.md | 1 + evobackup-client/handlers/main.yml | 5 +++-- evomaintenance/handlers/main.yml | 5 +++-- minifirewall/tasks/config.yml | 2 +- minifirewall/tasks/main.yml | 2 -- minifirewall/tasks/tail.yml | 3 +-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c19d0455..6defc87c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * postfix: Do not send mails through milters a second time after amavis (in packmail) * etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ * etc-git: Make evocommit fully compatible with OpenBSD +* minifirewall: fix `failed_when` condition on restart ### Removed diff --git a/evobackup-client/handlers/main.yml b/evobackup-client/handlers/main.yml index fc1b7739..de71f634 100644 --- a/evobackup-client/handlers/main.yml +++ b/evobackup-client/handlers/main.yml @@ -2,8 +2,9 @@ - name: restart minifirewall command: /etc/init.d/minifirewall restart register: minifirewall_init_restart - failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + failed_when: + - "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + - "'minifirewall started' not in minifirewall_init_restart.stdout" - name: 'created new jail' command: "bkctld restart {{ evolinux_hostname }}" diff --git a/evomaintenance/handlers/main.yml b/evomaintenance/handlers/main.yml index 85884f73..37c9af95 100644 --- a/evomaintenance/handlers/main.yml +++ b/evomaintenance/handlers/main.yml @@ -3,8 +3,9 @@ - name: restart minifirewall command: /etc/init.d/minifirewall restart register: minifirewall_init_restart - failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + failed_when: + - "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + - "'minifirewall started' not in minifirewall_init_restart.stdout" - name: restart minifirewall (noop) meta: noop diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 82b5263a..1ddb9695 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -285,7 +285,7 @@ - name: restart minifirewall command: /etc/init.d/minifirewall restart register: minifirewall_init_restart - failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" + failed_when: "'minifirewall failed' in minifirewall_init_restart.stdout" when: - minifirewall_restart_if_needed | bool - minifirewall_is_running.rc == 0 diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index f5eb9ea4..4a838ee9 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -95,7 +95,6 @@ command: /etc/init.d/minifirewall restart register: minifirewall_init_restart failed_when: "'minifirewall failed' in minifirewall_init_restart.stdout" - changed_when: "'minifirewall started' in minifirewall_init_restart.stdout" when: - minifirewall_install_mode != 'legacy' - minifirewall_restart_force | bool @@ -104,7 +103,6 @@ command: /etc/init.d/minifirewall restart register: minifirewall_init_restart failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" when: - minifirewall_install_mode == 'legacy' - minifirewall_restart_force | bool \ No newline at end of file diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index ae771017..1d708fa4 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -21,8 +21,7 @@ - name: restart minifirewall command: /etc/init.d/minifirewall restart register: minifirewall_init_restart - failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" - changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" + failed_when: "'minifirewall failed' in minifirewall_init_restart.stdout" when: - minifirewall_tail_template is changed - minifirewall_restart_if_needed | bool From 09872fa4ad1a2262ce2296a5caf80e19a5cd0cb9 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 10 May 2022 16:58:32 +0200 Subject: [PATCH 79/79] Release 22.05 --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6defc87c..0b1e59f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,44 +12,52 @@ The **patch** part changes is incremented if multiple releases happen the same m ### Added -* etc-git: use "ansible-commit" to efficiently commit all available repositories (including /etc inside LXC) from Ansible -* minifirewall: configure proxy/backup/sysctl values -* minifirewall: compatibility with "legacy" version of minifirewall -* nagios-nrpe: Add a check dhcp_pool -* redis: Activate overcommit sysctl -* redis: Add log2mail user to redis group -* munin: Add possibility to install local plugins, and install dhcp_pool plugin - ### Changed -* evocheck: upstream release 22.04.1 -* evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware -* evolinux-base: rename backup-server-state to dump-server-state -* dump-server-state: upstream release 22.04.3 -* generate-ldif: Add services check for bkctld -* minifirewall: restore "force-restart" and fix "restart-if-needed" -* minifirewall: tail template follows symlinks -* minifirewall: upstream release 22.05 -* openvpn: use a subnet topology instead of the net30 default topology -* tomcat: Tomcat 9 by default with Debian 11 -* openvpn: use a local copy of files instead of cloning an external git repository -* vrrpd: Store sysctl values in specific file -* opendkim : add generate opendkim-genkey in sha256 and key 4096 - ### Fixed -* Repair keepalived role -* generate-ldif: Correct generated entries for php-fpm in containers -* redis: Remount /usr with RW before adding nagios plugin -* postfix: Do not send mails through milters a second time after amavis (in packmail) -* etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ -* etc-git: Make evocommit fully compatible with OpenBSD -* minifirewall: fix `failed_when` condition on restart - ### Removed ### Security +## [22.05] 2022-05-10 + +### Added + +* etc-git: use "ansible-commit" to efficiently commit all available repositories (including /etc inside LXC) from Ansible +* minifirewall: compatibility with "legacy" version of minifirewall +* minifirewall: configure proxy/backup/sysctl values +* munin: Add possibility to install local plugins, and install dhcp_pool plugin +* nagios-nrpe: Add a check dhcp_pool +* redis: Activate overcommit sysctl +* redis: Add log2mail user to redis group + +### Changed + +* dump-server-state: upstream release 22.04.3 +* evocheck: upstream release 22.04.1 +* evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware +* evolinux-base: rename backup-server-state to dump-server-state +* generate-ldif: Add services check for bkctld +* minifirewall: restore "force-restart" and fix "restart-if-needed" +* minifirewall: tail template follows symlinks +* minifirewall: upstream release 22.05 +* opendkim : add generate opendkim-genkey in sha256 and key 4096 +* openvpn: use a local copy of files instead of cloning an external git repository +* openvpn: use a subnet topology instead of the net30 default topology +* tomcat: Tomcat 9 by default with Debian 11 +* vrrpd: Store sysctl values in specific file + +### Fixed + +* etc-git : Remount /usr in rw for git gc in in /usr/share/scripts/ +* etc-git: Make evocommit fully compatible with OpenBSD +* generate-ldif: Correct generated entries for php-fpm in containers +* keepalived: repair broken role +* minifirewall: fix `failed_when` condition on restart +* postfix: Do not send mails through milters a second time after amavis (in packmail) +* redis: Remount /usr with RW before adding nagios plugin + ## [22.03] 2022-03-02 ### Added @@ -72,8 +80,6 @@ The **patch** part changes is incremented if multiple releases happen the same m * lxc: Fail if /var is nosuid * openvpn: make it compatible with OpenBSD and add some improvements - - ## [22.01.3] 2022-01-31 ### Changed