From 18e3b4dc08796381d41bbc14ac67d3404e01f772 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 5 Mar 2026 11:38:02 +0100 Subject: [PATCH 1/5] Suppress cleanup() errors for missing files The mv commands in cleanup() print confusing "cannot stat" errors when files don't exist, which is expected on first provisioning runs. Signed-off-by: Lars Erik Wik Co-Authored-By: Claude Opus 4.6 --- ci/setup-cfengine-build-host.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/setup-cfengine-build-host.sh b/ci/setup-cfengine-build-host.sh index 616894802..683afe241 100755 --- a/ci/setup-cfengine-build-host.sh +++ b/ci/setup-cfengine-build-host.sh @@ -37,11 +37,11 @@ function cleanup() fi echo "Cleaning up CFEngine install by moving to /var/bak.cfengine and /opt/bak.cfengine" rm -rf /var/bak.cfengine - mv /var/cfengine /var/bak.cfengine || true + mv /var/cfengine /var/bak.cfengine 2>/dev/null || true rm -rf /opt/bak.cfengine - mv /opt/cfengine /opt/bak.cfengine || true - mv /var/log/CFE* /var/bak.cfengine/ || true - mv /var/log/postgresql.log /var/bak.cfengine || true + mv /opt/cfengine /opt/bak.cfengine 2>/dev/null || true + mv /var/log/CFE* /var/bak.cfengine/ 2>/dev/null || true + mv /var/log/postgresql.log /var/bak.cfengine 2>/dev/null || true if command -v pkill >/dev/null 2>&1; then pkill -9 cf-agent || true From 395180d8f5b87d6944e2b1bcacab6cc2b20489df Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 5 Mar 2026 13:43:37 +0100 Subject: [PATCH 2/5] Export NO_CONFIGURE so it propagates to autogen.sh subprocesses Signed-off-by: Lars Erik Wik Co-Authored-By: Claude Opus 4.6 --- build-scripts/autogen | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build-scripts/autogen b/build-scripts/autogen index 1e270f55d..dee90a064 100755 --- a/build-scripts/autogen +++ b/build-scripts/autogen @@ -61,7 +61,8 @@ for proj in $projects; do log_debug "Running autogen.sh for project $proj..." ( cd "$BASEDIR/$proj" - NO_CONFIGURE=1 run_and_print_on_failure ./autogen.sh + export NO_CONFIGURE=1 + run_and_print_on_failure ./autogen.sh ) done From e02399e1ad080516a0a8261bb0b90a2106e49407 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 5 Mar 2026 15:16:47 +0100 Subject: [PATCH 3/5] Harden SSH on build hosts: disable root login and password auth Disable PermitRootLogin, PasswordAuthentication, and KbdInteractiveAuthentication in sshd_config to enforce key-only SSH access. This prevents brute force attacks on VMs exposed via autossh tunnels through the SSH bridge. Ticket: ENT-13766 Signed-off-by: Lars Erik Wik Co-Authored-By: Claude Opus 4.6 --- ci/cfengine-build-host-setup.cf | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ci/cfengine-build-host-setup.cf b/ci/cfengine-build-host-setup.cf index 4be6ad25b..2bb888332 100644 --- a/ci/cfengine-build-host-setup.cf +++ b/ci/cfengine-build-host-setup.cf @@ -262,6 +262,30 @@ root - core unlimited * - core unlimited "); + "/etc/ssh/sshd_config" + edit_line => comment_lines_matching("^PermitRootLogin\s+(?!no\s*$).*", "#"), + classes => if_repaired("sshd_hardened"), + comment => "Comment out insecure PermitRootLogin values"; + "/etc/ssh/sshd_config" + edit_line => comment_lines_matching("^PasswordAuthentication\s+(?!no\s*$).*", "#"), + classes => if_repaired("sshd_hardened"), + comment => "Comment out insecure PasswordAuthentication value"; + "/etc/ssh/sshd_config" + edit_line => comment_lines_matching("^KbdInteractiveAuthentication\s+(?!no\s*$).*", "#"), + classes => if_repaired("sshd_hardened"), + comment => "Comment out insecure KbdInteractiveAuthentication value (OpenSSH 8.7+)"; + "/etc/ssh/sshd_config" + edit_line => comment_lines_matching("^ChallengeResponseAuthentication\s+(?!no\s*$).*", "#"), + classes => if_repaired("sshd_hardened"), + comment => "Comment out insecure ChallengeResponseAuthentication value (OpenSSH < 8.7)"; + "/etc/ssh/sshd_config" + edit_line => lines_present("PermitRootLogin no +PasswordAuthentication no +KbdInteractiveAuthentication no +ChallengeResponseAuthentication no"), + classes => if_repaired("sshd_hardened"), + comment => "Ensure SSH hardening directives are present"; + ubuntu_16|ubuntu_18|redhat_9|redhat_10:: "/etc/hosts" -> { "ENT-12437" } edit_line => regex_replace("127.0.0.1 localhost localhost.localdomain","127.0.0.1 localhost.localdomain"), @@ -343,6 +367,12 @@ jenkins_builds ALL=NOPASSWD: /usr/bin/podman !have_sys_user.(suse|sles|opensuse):: "useradd -u 3 sys" contain => in_shell; + services: + sshd_hardened:: + "sshd" + service_policy => "restart", + comment => "Restart sshd to apply hardened configuration"; + # skip /etc/hosts change for now, seems kind of wrong and corrupts ip6 entries like `::1 ip6-ip6-loopback` # maybe the following is needed to silence such errors as: ubuntu-16-mingw-j1: sudo: unable to resolve host localhost.localdomain # ubuntu:: From 7d592b8c94cc5cfd3a1d2b1229cfaa6f081bb76f Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 5 Mar 2026 15:31:33 +0100 Subject: [PATCH 4/5] Install epel-release on all RHEL/CentOS versions Broaden epel-release from redhat_7/centos_7 only to all redhat/centos platforms. This is needed to install fail2ban (and potentially other EPEL packages) on RHEL 8/9/10. Signed-off-by: Lars Erik Wik Co-Authored-By: Claude Opus 4.6 --- ci/cfengine-build-host-setup.cf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/cfengine-build-host-setup.cf b/ci/cfengine-build-host-setup.cf index 2bb888332..8992cfac8 100644 --- a/ci/cfengine-build-host-setup.cf +++ b/ci/cfengine-build-host-setup.cf @@ -124,8 +124,9 @@ bundle agent cfengine_build_host_setup "xfsprogs"; # note that shellcheck, fakeroot and ccache require epel-release to be installed - (redhat_7|centos_7).(yum_dnf_conf_ok):: + (redhat|centos).(yum_dnf_conf_ok):: "epel-release"; + (redhat_7|centos_7).(yum_dnf_conf_ok):: "ccache"; "fakeroot"; "perl-JSON-PP"; From 797e416ee3e3eee7296268d9cbca1dabbb8c3a0e Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 5 Mar 2026 15:34:48 +0100 Subject: [PATCH 5/5] Install and configure fail2ban on all build hosts Install fail2ban on Debian/Ubuntu and RHEL/CentOS platforms to ban IPs with repeated failed SSH auth attempts. Configures sshd jail with 5 max retries, 1 hour ban time, and 10 minute find window. Ticket: ENT-13766 Signed-off-by: Lars Erik Wik Co-Authored-By: Claude Opus 4.6 --- ci/cfengine-build-host-setup.cf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ci/cfengine-build-host-setup.cf b/ci/cfengine-build-host-setup.cf index 8992cfac8..c70b48d7f 100644 --- a/ci/cfengine-build-host-setup.cf +++ b/ci/cfengine-build-host-setup.cf @@ -24,6 +24,8 @@ bundle agent cfengine_build_host_setup "ntp"; debian|ubuntu:: + "fail2ban" + comment => "Ban IPs with repeated failed SSH auth attempts"; "libltdl7" package_policy => "delete"; "libltdl-dev" package_policy => "delete"; "binutils"; @@ -126,6 +128,8 @@ bundle agent cfengine_build_host_setup # note that shellcheck, fakeroot and ccache require epel-release to be installed (redhat|centos).(yum_dnf_conf_ok):: "epel-release"; + "fail2ban" + comment => "Ban IPs with repeated failed SSH auth attempts"; (redhat_7|centos_7).(yum_dnf_conf_ok):: "ccache"; "fakeroot"; @@ -263,6 +267,17 @@ root - core unlimited * - core unlimited "); + "/etc/fail2ban/jail.local" + create => "true", + content => "[sshd] +enabled = true +port = ssh +maxretry = 5 +bantime = 3600 +findtime = 600", + classes => if_repaired("fail2ban_config_changed"), + comment => "Configure fail2ban to ban IPs after 5 failed SSH attempts within 10 minutes"; + "/etc/ssh/sshd_config" edit_line => comment_lines_matching("^PermitRootLogin\s+(?!no\s*$).*", "#"), classes => if_repaired("sshd_hardened"), @@ -373,6 +388,14 @@ jenkins_builds ALL=NOPASSWD: /usr/bin/podman "sshd" service_policy => "restart", comment => "Restart sshd to apply hardened configuration"; + any:: + "fail2ban" + service_policy => "start", + comment => "Ensure fail2ban is running"; + fail2ban_config_changed:: + "fail2ban" + service_policy => "restart", + comment => "Restart fail2ban to apply jail configuration"; # skip /etc/hosts change for now, seems kind of wrong and corrupts ip6 entries like `::1 ip6-ip6-loopback` # maybe the following is needed to silence such errors as: ubuntu-16-mingw-j1: sudo: unable to resolve host localhost.localdomain