#!/usr/bin/env bash # veilor-os — base hardening (services, DNS, fail2ban, auditd) # Idempotent. Run as root during kickstart %post or post-install. set -uo pipefail GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' ok() { echo -e "${GREEN}[OK]${NC} $*"; } info() { echo -e "${YELLOW}[INFO]${NC} $*"; } err() { echo -e "${RED}[ERR]${NC} $*"; } [[ $EUID -eq 0 ]] || { err "Must run as root"; exit 1; } echo "════════════════════════════════════════════════════════" echo " veilor-os :: 10-harden-base" echo "════════════════════════════════════════════════════════" # ── Remove KDE Connect (network exposure, DBus surface) ── info "Removing kdeconnectd" dnf remove -y kdeconnectd 2>/dev/null && ok "kdeconnectd removed" || info "kdeconnectd absent" # ── systemd-resolved: LLMNR off, DNSSEC, DNS-over-TLS ── info "Hardening systemd-resolved" mkdir -p /etc/systemd/resolved.conf.d cat > /etc/systemd/resolved.conf.d/veilor-hardening.conf << 'EOF' [Resolve] LLMNR=no DNSSEC=allow-downgrade DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net DNSOverTLS=opportunistic EOF systemctl restart systemd-resolved 2>/dev/null || true ok "systemd-resolved hardened (LLMNR off, DNSSEC, DoT)" # ── fail2ban ── info "Installing fail2ban" rpm -q fail2ban &>/dev/null || dnf install -y fail2ban fail2ban-firewalld cat > /etc/fail2ban/jail.local << 'EOF' [DEFAULT] backend = systemd bantime = 3600 findtime = 600 maxretry = 5 banaction = firewallcmd-rich-rules banaction_allports = firewallcmd-rich-rules [sshd] enabled = true mode = aggressive port = ssh maxretry = 3 bantime = 86400 [pam-generic] enabled = true filter = pam-generic bantime = 3600 maxretry = 5 EOF systemctl enable fail2ban ok "fail2ban configured + enabled" # ── auditd rules ── info "Deploying auditd rules" mkdir -p /etc/audit/rules.d cat > /etc/audit/rules.d/99-veilor-hardening.rules << 'EOF' ## veilor-os audit ruleset -D -b 8192 -f 1 ## time & clock -a always,exit -F arch=b64 -S adjtimex,settimeofday -k time-change -a always,exit -F arch=b32 -S adjtimex,settimeofday,stime -k time-change -a always,exit -F arch=b64 -S clock_settime -k time-change -a always,exit -F arch=b32 -S clock_settime -k time-change -w /etc/localtime -p wa -k time-change ## identity -w /etc/group -p wa -k identity -w /etc/passwd -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity ## hostname / network -a always,exit -F arch=b64 -S sethostname,setdomainname -k system-locale -a always,exit -F arch=b32 -S sethostname,setdomainname -k system-locale -w /etc/hosts -p wa -k system-locale -w /etc/hostname -p wa -k system-locale ## SELinux -w /etc/selinux/ -p wa -k MAC-policy ## logins -w /var/log/lastlog -p wa -k logins -w /var/run/faillock/ -p wa -k logins -w /var/run/utmp -p wa -k session -w /var/log/wtmp -p wa -k logins -w /var/log/btmp -p wa -k logins ## perm changes -a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -k perm_mod -a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -k perm_mod -a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -k perm_mod ## access denials -a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access -a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access -a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access -a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access ## privileged commands -a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/chsh -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/chfn -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/gpasswd -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/chage -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/pkexec -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/mount -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/umount -F perm=x -F auid>=1000 -F auid!=unset -k privileged ## kernel modules -w /sbin/insmod -p x -k modules -w /sbin/rmmod -p x -k modules -w /sbin/modprobe -p x -k modules -a always,exit -F arch=b64 -S init_module,delete_module,finit_module -k modules -a always,exit -F arch=b32 -S init_module,delete_module,finit_module -k modules ## sudoers -w /etc/sudoers -p wa -k scope -w /etc/sudoers.d/ -p wa -k scope ## sshd -w /etc/ssh/sshd_config -p wa -k sshd -w /etc/ssh/sshd_config.d/ -p wa -k sshd ## cron -w /etc/crontab -p wa -k cron -w /etc/cron.d/ -p wa -k cron -w /etc/cron.daily/ -p wa -k cron -w /etc/cron.hourly/ -p wa -k cron -w /etc/cron.monthly/ -p wa -k cron -w /etc/cron.weekly/ -p wa -k cron -w /var/spool/cron/ -p wa -k cron ## sysctl -w /etc/sysctl.conf -p wa -k sysctl -w /etc/sysctl.d/ -p wa -k sysctl ## firewall -w /etc/firewalld/ -p wa -k firewall ## boot -w /etc/default/grub -p wa -k grub -w /etc/grub.d/ -p wa -k grub ## systemd -w /etc/systemd/system/ -p wa -k systemd -w /usr/lib/systemd/system/ -p wa -k systemd EOF augenrules --load 2>/dev/null || true systemctl enable auditd ok "auditd rules deployed" echo "════════════════════════════════════════════════════════" echo " 10-harden-base complete" echo "════════════════════════════════════════════════════════"