Blokování skenu portů

Pokročilá ochrana proti skenování portů na úrovni síťového rozhraní pomocí nftables.

Tento modul firewallu je určený k ochraně proti skenování portů a podobným síťovým útokům. Je navržen pro nasazení na rozhraní eth0 (Ingress) a poskytuje:

  • Detekci TCP SYN scan, TCP NULL scan, TCP XMAS scan
  • Detekci UDP scanů (malé pakety na netypické porty)
  • Dynamický blacklist s automatickým timeoutem (30 min)
  • Manuální blacklist pro trvalé blokování celých rozsahů (CIDR)
  • Whitelist pro důvěryhodné zdroje (např. security tým, VPN) s podporou subnetů
  • Detailní logování s jednotnými prefixy pro SIEM

Tabulka je implementována v nftables na úrovni netdev (Ingress), což zajišťuje minimální dopad na výkon, protože pakety jsou zahazovány ještě před procesem conntracku.

Struktura tabulky

table netdev portscan_protection {
    set portscan_whitelist { type ipv4_addr; flags interval; }
    set portscan_blacklist_manual { type ipv4_addr; flags interval; }
    set portscan_blacklist { type ipv4_addr; flags timeout; }
    chain INGRESS { ... }
}

Komponenty

1. Whitelist

  • Set portscan_whitelist obsahuje IP adresy nebo subnety, kterým je dovoleno provádět port scany.
  • Díky příznaku interval lze přidávat celé sítě (např. 172.24.2.0/24).
  • Whitelist má absolutní prioritu – provoz z těchto IP není blokován ani logován.
# Přidání sítě na whitelist
nft add element netdev portscan_protection portscan_whitelist { 172.24.2.0/24 }
# Výpis whitelistu
nft list set netdev portscan_protection portscan_whitelist
# Smazání z whitelistu
nft delete element netdev portscan_protection portscan_whitelist { 172.24.2.0/24 }

2. Blacklisty

  • Dynamický (`portscan_blacklist`): Obsahuje IP adresy detekované jako útočné. IP jsou přidávány automaticky s timeoutem 30 minut.
  • Manuální (`portscan_blacklist_manual`): Slouží administrátorovi k trvalému zablokování celých subnetů/rozsahů.
# Výpis automaticky zabanovaných IP
nft list set netdev portscan_protection portscan_blacklist
# Ruční smazání IP z automatického blacklistu
nft delete element netdev portscan_protection portscan_blacklist { 1.2.3.4 }
# Ruční zablokování celého rozsahu (trvale)
nft add element netdev portscan_protection portscan_blacklist_manual { 10.99.0.0/16 }

3. Detekce TCP scanů

Detekované typy:

  • TCP SYN scan: Pokusy o navázání spojení bez dokončení handshake.
  • TCP NULL scan: Pakety bez jakýchkoliv nastavených TCP příznaků.
  • TCP XMAS scan: Pakety s neobvyklou kombinací příznaků (FIN, PSH, URG).

Každá detekce používá meter pro rate‑limitování podle IP adresy, loguje incident s jasným prefixem, přidává IP do blacklistu a paket zahodí (drop).

4. Detekce UDP scanů

  • Sleduje UDP provoz na netypické porty (pakety menší než 200B).
  • Výjimky (nepovažováno za scan): 53 (DNS), 123 (NTP), 443 (QUIC), 5353 (mDNS), 67/68 (DHCP).
  • Při překročení limitu dojde k logování, přidání do blacklistu a dropu paketu.

5. Logování

Logování se provádí přímo v kernel logu. Použité prefixy umožňují snadnou filtraci v SIEM:

  • '[PYROMANIK-PORTSCAN-TCP-SYN] '
  • '[PYROMANIK-PORTSCAN-TCP-NULL] '
  • '[PYROMANIK-PORTSCAN-TCP-XMAS] '
  • '[PYROMANIK-PORTSCAN-UDP] '

Konfigurace rate limitů

  • TCP SYN scan: 20 paketů / sekundu, burst 10
  • TCP NULL / XMAS scan: 5 paketů / sekundu, burst 5
  • UDP scan: 10 paketů / sekundu, burst 10

Doporučení pro provoz

  1. Whitelistujte pouze důvěryhodné IP - VPN rozsahy security týmu, interní jump hosty a monitorovací systémy.
  2. Blacklist timeout - Výchozích 30 minut je bezpečný začátek. Pro agresivnější ochranu lze zvýšit na 2 hodiny.
  3. Monitoring logů - Doporučeno napojení na SIEM / centralizovaný logging a nastavení alertů na opakované zápisy z jedné IP.
  4. Testování - Pravidla ověřte pomocí nástroje nmap (např. nmap -sS, -sN, -sX) z externí sítě.
  5. Ingress vrstva - Detekce probíhá na nejnižší možné úrovni. To chrání zdroje serveru, protože útočník nezatěžuje vyšší vrstvy kernelu.

Příklad nasazení

# Načtení pravidel ze souboru
nft -f port-scan-protection-ingress.nft

# Ověření, že tabulka a sety existují
nft list table netdev portscan_protection

# Přidání rozsahu do whitelistu za běhu
nft add element netdev portscan_protection portscan_whitelist { 172.24.2.0/24 }

Pravidla pro NFT (Implementace)

table netdev portscan_protection {

    set portscan_whitelist {
        type ipv4_addr
        flags interval
        elements = { 172.24.2.16, 172.24.2.0/24 }
    }

    set portscan_blacklist_manual {
        type ipv4_addr
        flags interval
    }

    set portscan_blacklist {
        type ipv4_addr
        flags timeout
        timeout 30m
    }

    chain INGRESS {
        type filter hook ingress device "eth0" priority -400; policy accept;

        # 0) Whitelist
        ip saddr @portscan_whitelist accept

        # 1) Blacklisty
        ip saddr @portscan_blacklist_manual drop
        ip saddr @portscan_blacklist drop

        # 2) TCP SYN scan
        tcp flags & (syn|ack) == syn \
            meter tcp_syn_scan { ip saddr limit rate over 20/second burst 10 packets } \
            log prefix "[PYROMANIK-PORTSCAN-TCP-SYN] " flags all \
            add @portscan_blacklist { ip saddr } \
            drop

        # 3) TCP NULL scan
        tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 \
            meter tcp_null_scan { ip saddr limit rate over 5/second burst 5 packets } \
            log prefix "[PYROMANIK-PORTSCAN-TCP-NULL] " flags all \
            add @portscan_blacklist { ip saddr } \
            drop

        # 4) TCP XMAS scan
        tcp flags & (fin|psh|urg) == (fin|psh|urg) \
            meter tcp_xmas_scan { ip saddr limit rate over 5/second burst 5 packets } \
            log prefix "[PYROMANIK-PORTSCAN-TCP-XMAS] " flags all \
            add @portscan_blacklist { ip saddr } \
            drop

        # 5) UDP scan
        udp length < 200 \
        udp sport != { 53, 123, 443, 5353, 67, 68 } \
            meter udp_scan { ip saddr limit rate over 10/second burst 10 packets } \
            log prefix "[PYROMANIK-PORTSCAN-UDP] " flags all \
            add @portscan_blacklist { ip saddr } \
            drop
    }
}