Skip to content

Instantly share code, notes, and snippets.

@SebastiaanKloos
Created March 19, 2026 12:55
Show Gist options
  • Select an option

  • Save SebastiaanKloos/56a3c9a06bf99ce4950c006c0feec16c to your computer and use it in GitHub Desktop.

Select an option

Save SebastiaanKloos/56a3c9a06bf99ce4950c006c0feec16c to your computer and use it in GitHub Desktop.
Security check voor algemeen gebruik
#!/bin/bash
# ============================================================
# Server Security Check Script
# Controleert op verdachte processen, open poorten en
# misconfiguraties na een incident of als preventieve check.
# Gebruik: sudo bash security_check.sh
# ============================================================
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
warn() { echo -e "${YELLOW}[WAARSCHUWING]${NC} $1"; }
alert() { echo -e "${RED}[GEVAAR]${NC} $1"; }
ok() { echo -e "${GREEN}[OK]${NC} $1"; }
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
header() { echo -e "\n========== $1 =========="; }
echo "============================================================"
echo " Server Security Check — $(date)"
echo " Hostname: $(hostname)"
echo "============================================================"
# ------------------------------------------------------------
header "1. VERDACHTE PROCESSEN"
# ------------------------------------------------------------
# Bekende legitieme procesnamen voor whitelist
KNOWN_SHORT="systemd|python|python3|nginx|mysqld|redis|redis-server|alloy|postfix|snapd|sshd|bash|sh|dash|node|perl5|flowguard|memcached|rsyslogd|journald|networkd|resolved|timesyncd|logind|polkitd|udisksd|upowerd|dockerd|containerd|irqbalance|multipathd|packagekitd|crond|atd|acpid|ModemManager|agetty|dbus-daemon|fail2ban|supervisord"
# Processen zonder volledig pad — gebruik eenvoudigere grep zonder speciale haakjes
echo "Processen zonder volledig pad (legitieme namen uitgefilterd):"
SUSPICIOUS=$(ps aux | awk 'NR>1 {print $1, $2, $11}' \
| awk '$3 !~ /^\// && $3 !~ /^\[/' \
| grep -v "^root " \
| grep -vE "systemd|sshd|nginx|php|dbus|sd-pam|agetty|bash|sh|ps|grep|awk|sed|sort|uniq|cat|ls|find|cut|tr|head|tail|wc|date|tee|xargs|cp|mv|rm|chmod|python|node|docker|containerd")
if [ -n "$SUSPICIOUS" ]; then
echo "$SUSPICIOUS" | while IFS= read -r line; do
alert "Verdacht proces zonder pad: $line"
done
else
ok "Geen verdachte processen zonder pad"
fi
# Processen met exact 6-8 kleine letters als volledige naam
echo ""
echo "Processen met willekeurige korte naam (mogelijke malware):"
RANDOM_NAMES=$(ps aux | awk 'NR>1 {print $11}' \
| grep -oE '^[a-z]{6,8}$' \
| grep -vE "^($KNOWN_SHORT)$" \
| sort -u)
if [ -n "$RANDOM_NAMES" ]; then
while IFS= read -r proc; do
alert "Mogelijk verdacht proces: $proc"
done <<< "$RANDOM_NAMES"
else
ok "Geen processen met verdacht willekeurige korte naam"
fi
# Perl processen
echo ""
echo "Perl processen (altijd handmatig controleren):"
PERL_PROCS=$(ps aux | grep -E ' perl | perl$' | grep -v grep)
if [ -n "$PERL_PROCS" ]; then
warn "Perl processen gevonden — controleer of dit legitiem is:"
echo "$PERL_PROCS"
echo "$PERL_PROCS" | awk '{print $2}' | while read -r pid; do
exe=$(ls -la /proc/$pid/exe 2>/dev/null)
fd3=$(ls -la /proc/$pid/fd/3 2>/dev/null)
info " PID $pid exe: $exe"
[ -n "$fd3" ] && warn " PID $pid fd/3 (script): $fd3"
done
else
ok "Geen Perl processen actief"
fi
# Hoog CPU gebruik
echo ""
echo "Processen met >10% CPU (mogelijke cryptominers):"
LEGIT_CPU="nginx|php|mysql|mysqld|redis|node|python|docker|containerd|alloy|java|ruby|kworker|ksoftirq|migration|jbd2|kcompact"
HIGH_CPU=$(ps aux | awk 'NR>1 && $3 > 10.0 {print}' | grep -vE "$LEGIT_CPU")
if [ -n "$HIGH_CPU" ]; then
warn "Hoog CPU gebruik door mogelijk onbekend proces:"
echo "$HIGH_CPU"
else
ok "Geen onverwacht hoog CPU gebruik"
fi
# Processen die draaien vanuit /tmp of /var/tmp
echo ""
echo "Processen die draaien vanuit /tmp of /var/tmp:"
TMP_PROCS=""
for pid in /proc/[0-9]*; do
exe=$(readlink "$pid/exe" 2>/dev/null)
if echo "$exe" | grep -qE "^/tmp|^/var/tmp|^/dev/shm"; then
cmdline=$(cat "$pid/cmdline" 2>/dev/null | tr '\0' ' ' | cut -c1-80)
TMP_PROCS="$TMP_PROCS\nPID $(basename $pid): $exe | $cmdline"
fi
done
if [ -n "$TMP_PROCS" ]; then
alert "Processen gevonden die draaien vanuit tmp:"
echo -e "$TMP_PROCS"
else
ok "Geen processen draaien vanuit /tmp of /var/tmp"
fi
# Deleted binaries — fileless malware
echo ""
echo "Processen met verwijderde binaries (fileless malware):"
DELETED=$(ls -la /proc/[0-9]*/exe 2>/dev/null | grep " (deleted)" | grep -v "^total")
if [ -n "$DELETED" ]; then
alert "Processen met verwijderd binary — mogelijke fileless malware:"
echo "$DELETED"
else
ok "Geen processen met verwijderde binaries"
fi
# ------------------------------------------------------------
header "2. OPEN NETWERK POORTEN"
# ------------------------------------------------------------
echo "Alle luisterende services:"
ss -tulpn 2>/dev/null
echo ""
echo "Controle op gevaarlijke publiek bereikbare services:"
check_public() {
local port=$1
local name=$2
local fix=$3
# Alleen gevaarlijk als het luistert op 0.0.0.0 of :: (alle interfaces)
# 127.0.0.1 en [::1] zijn veilig (lokaal only)
if ss -tulpn 2>/dev/null | grep ":$port " | grep -vE "127\.0\.0\.1|^\[::1\]|\[::1\]:" | grep -qE "0\.0\.0\.0|^\*|::$| ::|::\]"; then
alert "$name luistert publiek op poort $port — aanvalsvector!"
[ -n "$fix" ] && info "Fix: $fix"
else
ok "$name niet publiek bereikbaar"
fi
}
check_public 11211 "Memcached" "sudo sed -i 's/-l 0.0.0.0/-l 127.0.0.1/' /etc/memcached.conf && sudo systemctl restart memcached"
check_public 6379 "Redis" "sudo sed -i 's/^bind.*/bind 127.0.0.1/' /etc/redis/redis.conf && sudo systemctl restart redis"
check_public 3306 "MySQL" ""
check_public 5432 "PostgreSQL" ""
check_public 27017 "MongoDB" "Voeg 'bindIp: 127.0.0.1' toe aan /etc/mongod.conf"
# Onverwachte poorten
echo ""
echo "Onverwachte open poorten (mogelijke backdoors):"
KNOWN_PORTS="21|22|25|53|80|443|587|3000|3306|5432|6379|8000|8080|8443|8461|9000|9090|9100|11080|11211|11443|12345|33060"
UNEXPECTED=$(ss -tulpn 2>/dev/null \
| awk '{print $5}' \
| grep -oE '[0-9]+$' \
| sort -un \
| awk -v ports="$KNOWN_PORTS" \
'BEGIN{n=split(ports,a,"|"); for(i=1;i<=n;i++) known[a[i]]=1}
!known[$1] && $1 > 1024 {print $1}')
if [ -n "$UNEXPECTED" ]; then
while IFS= read -r port; do
proc=$(ss -tulpn 2>/dev/null | grep ":$port " | grep -oP 'users:\(\("\K[^"]+' | head -1)
warn "Onverwachte poort $port open (proces: ${proc:-onbekend})"
done <<< "$UNEXPECTED"
else
ok "Geen onverwachte open poorten"
fi
# ------------------------------------------------------------
header "3. VERDACHTE BESTANDEN"
# ------------------------------------------------------------
echo "Uitvoerbare bestanden in /tmp en /var/tmp:"
EXEC_TMP=$(find /tmp /var/tmp -type f -executable 2>/dev/null \
| grep -vE "yarn|node_modules|\.cache")
if [ -n "$EXEC_TMP" ]; then
while IFS= read -r f; do
alert "Uitvoerbaar bestand in tmp: $f"
done <<< "$EXEC_TMP"
else
ok "Geen verdachte uitvoerbare bestanden in /tmp of /var/tmp"
fi
echo ""
echo "Bestanden in /dev/shm:"
DEV_SHM=$(find /dev/shm -type f 2>/dev/null)
if [ -n "$DEV_SHM" ]; then
warn "Bestanden gevonden in /dev/shm:"
echo "$DEV_SHM"
else
ok "/dev/shm is leeg"
fi
echo ""
echo "Recent aangemaakte bestanden in /var/tmp (laatste 7 dagen):"
RECENT_VARTMP=$(find /var/tmp -type f -mtime -7 2>/dev/null | grep -vE "systemd-private")
if [ -n "$RECENT_VARTMP" ]; then
while IFS= read -r f; do warn "Recent bestand: $f"; done <<< "$RECENT_VARTMP"
else
ok "Geen recente bestanden in /var/tmp"
fi
# ------------------------------------------------------------
header "4. CRONTABS"
# ------------------------------------------------------------
echo "Root crontab:"
ROOT_CRON=$(crontab -l 2>/dev/null | grep -v "^#\|^$")
if [ -n "$ROOT_CRON" ]; then
warn "Root crontab heeft entries:"
echo "$ROOT_CRON"
else
ok "Root crontab is leeg"
fi
echo ""
echo "Gebruiker crontabs:"
FOUND_CRON=0
for f in /var/spool/cron/crontabs/*; do
[ -f "$f" ] || continue
content=$(grep -v "^#\|^$" "$f" 2>/dev/null)
if [ -n "$content" ]; then
warn "Crontab voor $(basename $f):"
echo "$content"
FOUND_CRON=1
fi
done
[ $FOUND_CRON -eq 0 ] && ok "Alle gebruiker crontabs zijn leeg"
echo ""
echo "Recent aangepaste cron bestanden (laatste 7 dagen):"
RECENT_CRON=$(find /etc/cron* /var/spool/cron -type f -newer /etc/passwd -mtime -7 2>/dev/null)
if [ -n "$RECENT_CRON" ]; then
while IFS= read -r f; do warn "Recent aangepast: $f"; done <<< "$RECENT_CRON"
else
ok "Geen recent aangepaste cron bestanden"
fi
# ------------------------------------------------------------
header "5. SSH AUTHORIZED KEYS"
# ------------------------------------------------------------
for homedir in /root /home/*; do
keyfile="$homedir/.ssh/authorized_keys"
[ -f "$keyfile" ] || continue
user=$(basename "$homedir")
count=$(grep -c "^ssh" "$keyfile" 2>/dev/null || echo 0)
info "$user: $count SSH key(s)"
grep "^ssh" "$keyfile" | while IFS= read -r key; do
comment=$(echo "$key" | awk '{print $NF}')
echo " → $comment"
done
done
# ------------------------------------------------------------
header "6. RECENTE LOGINS"
# ------------------------------------------------------------
echo "Laatste 20 logins:"
last | head -20
echo ""
echo "Gefaalde loginpogingen (laatste 10):"
if lastb 2>/dev/null | grep -q "[a-z]"; then
lastb 2>/dev/null | head -10
else
grep "Failed password" /var/log/auth.log 2>/dev/null | tail -10 \
|| ok "Geen gefaalde logins gevonden"
fi
# ------------------------------------------------------------
header "7. SYSTEMD SERVICES"
# ------------------------------------------------------------
KNOWN_SERVICES="systemd|docker|containerd|mysql|nginx|php|redis|memcach|network|cron|ssh|irq|rsyslog|snapd|multipathd|udisk|logind|polkit|dbus|udev|timesyncd|journald|packagekit|atd|fail2ban|supervisor|sendmail|getty|serial|alloy|postfix|sysstat|acpid|ModemManager|upower|flowguard|unattended|apparmor|apport|irqbalance|user@"
echo "Actieve services buiten de standaard set:"
UNKNOWN=$(systemctl list-units --type=service --state=running --no-pager 2>/dev/null \
| grep "\.service" \
| grep -vE "$KNOWN_SERVICES")
if [ -n "$UNKNOWN" ]; then
warn "Controleer deze services handmatig:"
echo "$UNKNOWN"
else
ok "Geen onbekende actieve services"
fi
# ------------------------------------------------------------
header "8. UITGAANDE NETWERKVERBINDINGEN"
# ------------------------------------------------------------
echo "Verbindingen naar externe IPs:"
MYIPS=$(hostname -I)
MYIP_PATTERN=$(echo "$MYIPS" | tr ' ' '\n' | grep -v '^$' | sed 's/\./\\./g' | paste -sd'|')
EXTERNAL=$(ss -tp 2>/dev/null | grep ESTAB \
| grep -v "127\.0\.0\.1\|::1" \
| grep -vE "$MYIP_PATTERN" \
| grep -vE "nginx|php|mysql|sshd" \
| head -20)
if [ -n "$EXTERNAL" ]; then
echo "$EXTERNAL"
else
ok "Geen verdachte externe verbindingen"
fi
# ------------------------------------------------------------
header "SAMENVATTING"
# ------------------------------------------------------------
echo ""
echo "Check voltooid op $(date)."
echo ""
echo -e "Legenda:"
echo -e " ${RED}[GEVAAR]${NC} = Direct actie vereist"
echo -e " ${YELLOW}[WAARSCHUWING]${NC} = Controleer en beoordeel"
echo -e " ${GREEN}[OK]${NC} = Geen probleem gevonden"
echo -e " ${BLUE}[INFO]${NC} = Ter informatie"
echo ""
echo "Bij twijfel: isoleer de server en doe een clean rebuild."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment