Check-Ports — Audit des ports ouverts

Scanne et affiche tous les ports en écoute sur le serveur (ss/netstat), les compare aux règles iptables actives, et effectue un scan nmap externe si disponible.

sécuritéauditportsréseausysadmin
$ curl scripts.ysavary.fr/check-ports | bash

Check-Ports — Audit des ports ouverts

Fait un état complet des ports en écoute sur le serveur et les croise avec les règles firewall actives. Utile pour auditer la surface d'exposition.

Ce que fait le script :

bash
#!/bin/bash
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info()  { echo -e "${GREEN}[INFO]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
ok()    { echo -e "${GREEN}  ✓${NC}  $*"; }
bad()   { echo -e "${RED}  ✗${NC}  $*"; }
title() { echo -e "\n${BLUE}══ $* ══${NC}"; }

[[ $EUID -ne 0 ]] && { warn "Lancer en root pour voir tous les processus."; }

LOCAL_IP=$(hostname -I | awk '{print $1}')

# ── Ports en écoute ───────────────────────────────────────────────────────────
title "Ports TCP en écoute"
ss -tlnp 2>/dev/null | awk 'NR>1 {
    split($4, addr, ":");
    port = addr[length(addr)];
    proc = $6;
    gsub(/users:\(\("/, "", proc); gsub(/".*/, "", proc);
    printf "  %-8s %-25s %s\n", port, $4, proc
}' | sort -n | uniq

title "Ports UDP en écoute"
ss -ulnp 2>/dev/null | awk 'NR>1 {
    split($4, addr, ":");
    port = addr[length(addr)];
    proc = $6;
    gsub(/users:\(\("/, "", proc); gsub(/".*/, "", proc);
    printf "  %-8s %-25s %s\n", port, $4, proc
}' | sort -n | uniq

# ── Règles iptables ───────────────────────────────────────────────────────────
title "Règles iptables INPUT actives"
if command -v iptables &>/dev/null; then
    iptables -L INPUT -n -v --line-numbers 2>/dev/null | \
        grep -E '(ACCEPT|DROP|REJECT|Chain)' | \
        awk '{printf "  %s\n", $0}'
else
    warn "iptables non disponible."
fi

# ── Analyse croisée : ports exposés vs firewall ───────────────────────────────
title "Analyse : ports exposés sans règle firewall explicite"

FW_PORTS=$(iptables -L INPUT -n 2>/dev/null | grep -oP 'dpt:\K\d+' | sort -n | uniq)
LISTEN_PORTS=$(ss -tlnp 2>/dev/null | awk 'NR>1 {split($4,a,":"); print a[length(a)]}' | sort -n | uniq)

EXPOSED=()
while IFS= read -r port; do
    [[ -z "$port" || "$port" == "0" ]] && continue
    # Loopback seulement ?
    BINDS=$(ss -tlnp 2>/dev/null | awk -v p="$port" 'NR>1 && $4 ~ ":" p "$"  {print $4}')
    ONLY_LOOPBACK=true
    while IFS= read -r bind; do
        [[ "$bind" == 127.0.0.1:* || "$bind" == "[::1]:"* ]] || ONLY_LOOPBACK=false
    done <<< "$BINDS"
    $ONLY_LOOPBACK && continue

    if echo "$FW_PORTS" | grep -qx "$port"; then
        ok "Port $port — autorisé dans iptables"
    else
        bad "Port $port — EN ÉCOUTE SANS RÈGLE FIREWALL"
        EXPOSED+=("$port")
    fi
done <<< "$LISTEN_PORTS"

# ── Nmap (si dispo) ───────────────────────────────────────────────────────────
title "Scan nmap local (top 1000 ports)"
if command -v nmap &>/dev/null; then
    nmap -sT -sU --top-ports 100 -T4 "$LOCAL_IP" 2>/dev/null \
        | grep -E '^[0-9]+/(tcp|udp)' \
        | awk '{printf "  %-20s %-10s %s\n", $1, $2, $3}'
else
    warn "nmap non installé. Pour installer : apt-get install -y nmap"
    info "Scan via ss uniquement."
fi

# ── Résumé ────────────────────────────────────────────────────────────────────
title "Résumé"
TCP_COUNT=$(ss -tlnp 2>/dev/null | awk 'NR>1' | wc -l)
UDP_COUNT=$(ss -ulnp 2>/dev/null | awk 'NR>1' | wc -l)
echo ""
echo "  IP principale     : $LOCAL_IP"
echo "  Ports TCP écoute  : $TCP_COUNT"
echo "  Ports UDP écoute  : $UDP_COUNT"
echo ""

if [[ ${#EXPOSED[@]} -gt 0 ]]; then
    warn "${#EXPOSED[@]} port(s) en écoute sans règle firewall :"
    for p in "${EXPOSED[@]}"; do
        echo -e "  ${RED}→ Port $p${NC}"
    done
    echo ""
    warn "Ferme ces ports ou ajoute une règle iptables."
else
    ok "Tous les ports en écoute publique ont une règle firewall correspondante."
fi
echo ""