00 nftables nedir?
nftables, Linux kernel 3.13'te tanıtılan ve iptables, ip6tables, arptables ile ebtables'ın yerini alan modern netfilter ön yüzüdür. Tekil bir araç (nft) ile tüm protokol ailelerini yönetebilir, daha güçlü eşleştirme mekanizmaları ve JIT derlemeli kural işleme sunar.
iptables vs nftables
| Özellik | iptables | nftables |
|---|---|---|
| Kernel versiyonu | 2.4+ | 3.13+ |
| Araç | iptables, ip6tables, arptables, ebtables | nft (tek araç) |
| IPv4/IPv6 | Ayrı tablolar | Tek tabloda inet ailesi |
| Kural değerlendirme | Linear tarama | Sets/maps ile O(1) lookup |
| Atomik güncelleme | Kısıtlı | Transaction tabanlı — tüm set tek işlem |
| Durum | Legacy (maintenance mode) | Aktif geliştirme, önerilen |
Mimari
Kullanıcı alanı: nft CLI
│
Kernel alanı: netlink socket
│
nf_tables subsystem
│
┌──────────────┼──────────────────┐
│ │ │
ip table ip6 table inet table
(IPv4 only) (IPv6 only) (IPv4 + IPv6)
│
┌──────┼──────┐
│ │ │
input forward output (+ prerouting, postrouting)
Debian 10+, Ubuntu 20.04+, Fedora 18+ ve RHEL 8+ sistemlerde nftables varsayılan güvenlik duvarı altyapısı haline geldi. iptables-nft wrapper'ı sayesinde eski iptables komutları nftables backend üzerinde çalışır. Yeni projeler için doğrudan nft syntax kullanın.
Bu bölümde
- nftables = iptables + ip6tables + arptables + ebtables yerini alıyor
- Tek nft CLI, tüm protokol aileleri, inet = IPv4+IPv6 ortak tablo
- Sets/maps ile O(1) kural araması; atomik ruleset güncellemeleri
01 Temel kavramlar
nftables'ın veri modeli: table → chain → rule hiyerarşisi ve her katmanın rolü. Hook noktaları paketin kernel içindeki yolculuğunu belirler.
Nesne hiyerarşisi
table inet filterip saddr 192.168.1.1 dropNetfilter hook noktaları
Gelen paket
│
[prerouting] ← DNAT burada yapılır
│
Routing kararı
├──── Yerel süreç için ──────► [input] ──► Uygulama
│
└──── Forward ────────────► [forward] ──► [postrouting] ──► Çıkış
↑
[output] (yerel çıkan)
Chain türleri ve priority
| Hook | Yön | Tipik priority | Kullanım |
|---|---|---|---|
| prerouting | Gelen, routing öncesi | -100 (raw), 0 (filter), 100 (mangle) | DNAT, connection tracking |
| input | Gelen, yerel | 0 (filter) | Gelen bağlantı filtreleme |
| forward | Transit | 0 (filter) | Router/gateway kural |
| output | Çıkan, yerel | 0 (filter) | Çıkan trafik kısıtlama |
| postrouting | Çıkan, routing sonrası | 100 (nat) | SNAT, MASQUERADE |
Bu bölümde
- table → chain → rule hiyerarşisi; her katman bağımsız isimlendirme
- Base chain hook'a bağlı; priority = değerlendirme sırası (küçük = önce)
- Set ve map: O(1) lookup ile büyük IP/port listelerini verimli yönet
02 nft syntax
nft komutunun genel sözdizimi ve temel işlemler: table/chain/rule ekleme, silme, listeleme ve yapılandırma dosyasından yükleme.
Temel nft komutları
# Tüm ruleset'i göster
nft list ruleset
# Belirli bir tabloyu göster
nft list table inet filter
# Table oluştur
nft add table inet filter
# Chain oluştur (base chain — hook'a bağlı)
nft add chain inet filter input \
'{ type filter hook input priority 0; policy drop; }'
# Chain oluştur (regular chain)
nft add chain inet filter check_ssh
# Kural ekle (chain'in sonuna)
nft add rule inet filter input \
ct state established,related accept
# Kural ekle (chain'in başına)
nft insert rule inet filter input \
iif lo accept
# Tüm kuralları sil
nft flush ruleset
# Tabloyu sil (içindeki tüm chain+rule ile)
nft delete table inet filter
Yapılandırma dosyası kullanımı
# /etc/nftables.conf — systemd tarafından yüklenir
# Dosyadan yükle
nft -f /etc/nftables.conf
# Sözdizimi kontrolü (uygulamadan)
nft -c -f /etc/nftables.conf
# Mevcut ruleset'i dosyaya kaydet
nft list ruleset > /etc/nftables.conf
# systemd ile başlangıçta yükle
systemctl enable nftables
systemctl start nftables
nftables.conf yapısı
#!/usr/sbin/nft -f
# /etc/nftables.conf
# Önceki kuralları temizle
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Loopback
iif "lo" accept
# Kurulu bağlantılar
ct state { established, related } accept
# Geçersiz paketleri düşür
ct state invalid drop
# SSH
tcp dport 22 accept
# ICMP (ping)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Bu bölümde
- nft list ruleset: mevcut tüm kuralları görüntüle
- nft -f dosya: atomik olarak tüm ruleset'i uygula
- policy drop: default reddet — yalnızca açıkça izin verilenler geçer
03 Temel kural yazımı
IP adresi, port ve bağlantı durumu eşleştirme ifadeleri — nftables kural sözdiziminin yapı taşları.
IP adresi eşleştirme
# Kaynak IP'ye göre drop
nft add rule inet filter input ip saddr 10.0.0.5 drop
# Hedef IP'ye göre kabul
nft add rule inet filter input ip daddr 192.168.1.1 accept
# Subnet eşleştirme
nft add rule inet filter input ip saddr 192.168.0.0/16 accept
# IPv6 eşleştirme
nft add rule inet filter input ip6 saddr 2001:db8::/32 drop
# inet: hem IPv4 hem IPv6
nft add rule inet filter input ip saddr 10.0.0.0/8 log prefix "RFC1918: " drop
Port ve protokol eşleştirme
# TCP port
nft add rule inet filter input tcp dport 80 accept
nft add rule inet filter input tcp dport 443 accept
# Port aralığı
nft add rule inet filter input tcp dport 8000-8080 accept
# Port listesi (küme)
nft add rule inet filter input tcp dport { 22, 80, 443, 8443 } accept
# UDP
nft add rule inet filter input udp dport 51820 accept # WireGuard
nft add rule inet filter input udp dport 53 accept # DNS
# Kaynak + hedef port kombinasyonu
nft add rule inet filter input \
ip saddr 192.168.1.0/24 tcp dport { 22, 443 } accept
Bağlantı durumu (ct state)
# Stateful firewall — temel şablon
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Kurulu ve ilişkili bağlantılar her zaman geçer
ct state { established, related } accept
# Geçersiz paket (bozuk durum tablosu)
ct state invalid counter drop
# Yeni bağlantı — port bazlı izin
ct state new tcp dport 22 accept
ct state new tcp dport { 80, 443 } accept
ct state new udp dport 51820 accept
# ICMP: rate limit ile flood koruması
ip protocol icmp limit rate 10/second accept
ip6 nexthdr icmpv6 limit rate 10/second accept
# Gerisi: log ve drop
counter log prefix "INPUT DROP: " drop
}
}
Eylemler
| Eylem | Açıklama |
|---|---|
accept | Paketi kabul et, chain değerlendirmesini durdur |
drop | Paketi sessizce düşür — gönderene bildirim yok |
reject | Paketi reddet + ICMP unreachable/TCP reset gönder |
reject with icmp type port-unreachable | ICMP port unreachable ile reddet |
log prefix "TEXT " level info | Kernel log'a yaz (dmesg/journalctl) |
counter | Eşleşen paket/byte sayacı — sonraki eylemle birleşir |
goto chain_name | Başka chain'e git — geri dönüş yok |
jump chain_name | Başka chain'e dal — zincir bitince geri döner |
Bu bölümde
- ct state established,related: stateful firewall temeli — her zaman ilk kurala koy
- Küme sözdizimi { 80, 443 }: birden fazla değeri tek kuralla eşleştir
- counter + log: izleme ve hata ayıklama için birlikte kullan
04 NAT
nftables NAT kuralları, ip nat tablosu (veya inet nat) altında prerouting ve postrouting chain'lerinde tanımlanır. MASQUERADE, SNAT, DNAT ve port forwarding örnekleri.
MASQUERADE — dinamik SNAT
flush ruleset
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# eth0 üzerinden çıkan tüm trafiği masquerade et
# (dinamik IP için SNAT alternatifi)
oifname "eth0" masquerade
}
}
table inet filter {
chain forward {
type filter hook forward priority 0; policy drop;
# LAN'dan WAN'a forward
iifname "eth1" oifname "eth0" ct state new,established,related accept
iifname "eth0" oifname "eth1" ct state established,related accept
}
}
SNAT — sabit kaynak IP
# Sabit IP'li SNAT (MASQUERADE yerine — performans daha iyi)
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "eth0" snat to 203.0.113.5
}
}
DNAT — port forwarding
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Dış port 2222 → iç sunucu SSH (22)
iifname "eth0" tcp dport 2222 dnat to 192.168.1.10:22
# HTTP forward — iç web sunucusuna
iifname "eth0" tcp dport 80 dnat to 192.168.1.20:80
# UDP port forward (örn. TFTP)
iifname "eth0" udp dport 69 dnat to 192.168.1.30:69
}
}
WireGuard ile NAT — tam örnek
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state { established, related } accept
ct state invalid drop
tcp dport 22 accept
udp dport 51820 accept # WireGuard
ip protocol icmp accept
}
chain forward {
type filter hook forward priority 0; policy drop;
iifname "wg0" accept # VPN'den gelen forward
oifname "wg0" ct state established,related accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "eth0" masquerade # VPN istemcileri internete çıkar
}
}
Bu bölümde
- MASQUERADE: dinamik IP (DHCP) için; SNAT: sabit IP için daha verimli
- DNAT prerouting'de yapılır; forward chain'de izin kuralı da gereklidir
- WireGuard + NAT: wg0 forward + eth0 MASQUERADE kombinasyonu
05 Sets ve maps
nftables set'leri, IP adresleri veya portların gruplandırılmasını sağlar. Map'ler ise anahtar-değer eşleştirmesi yaparak DNAT hedeflerini veya counter gruplarını dinamik yönetmeye olanak tanır.
Named set — IP whitelist
table inet filter {
# Tanımlı IP seti
set admin_hosts {
type ipv4_addr
flags constant
elements = {
192.168.1.10,
192.168.1.11,
10.10.0.1
}
}
# Dinamik engel listesi (çalışma zamanında güncellenebilir)
set blocklist {
type ipv4_addr
flags dynamic, timeout
timeout 1h # 1 saat sonra otomatik temizlenir
gc-interval 5m
}
chain input {
type filter hook input priority 0; policy drop;
# Whitelist'ten gelen SSH kabul
ip saddr @admin_hosts tcp dport 22 accept
# Blocklist'ten gelen her şeyi düşür
ip saddr @blocklist drop
}
}
# Çalışma zamanında set güncellemesi
nft add element inet filter blocklist { 1.2.3.4, 5.6.7.8 }
nft delete element inet filter blocklist { 1.2.3.4 }
nft list set inet filter blocklist
Interval set — subnet kümesi
table inet filter {
set rfc1918 {
type ipv4_addr
flags interval
elements = {
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16
}
}
chain input {
type filter hook input priority 0; policy drop;
# RFC1918 adresleri sadece iç arayüzden kabul
ip saddr @rfc1918 iifname "eth1" accept
ip saddr @rfc1918 iifname "eth0" drop
}
}
Map — DNAT hedef mapping
table ip nat {
# Port → iç sunucu IP:port eşleştirmesi
map port_forward {
type inet_service : ipv4_addr . inet_service
elements = {
2222 : 192.168.1.10 . 22, # SSH
8080 : 192.168.1.20 . 80, # Web
8443 : 192.168.1.20 . 443, # HTTPS
}
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Map'ten DNAT hedefini al
iifname "eth0" tcp dport map @port_forward dnat to
}
}
Port knocking — state machine
table inet filter {
# Port knocking için durum takibi
set knock1 {
type ipv4_addr; flags dynamic, timeout; timeout 10s;
}
set knock2 {
type ipv4_addr; flags dynamic, timeout; timeout 10s;
}
set allowed_ssh {
type ipv4_addr; flags dynamic, timeout; timeout 60s;
}
chain input {
type filter hook input priority 0; policy drop;
# Açık olan SSH erişimine izin ver
ip saddr @allowed_ssh tcp dport 22 accept
# Port knock sekansı: 7000 → 8000 → SSH açık
tcp dport 7000 add @knock1 { ip saddr }
ip saddr @knock1 tcp dport 8000 add @allowed_ssh { ip saddr }
ct state { established, related } accept
}
}
Bu bölümde
- Named set: IP listesi tek yerde tanımla, birden fazla kuralta kullan
- flags dynamic + timeout: çalışma zamanında eklenip otomatik silinen set
- Map ile DNAT: port → hedef eşleştirmesi, kural sayısını dramatik azaltır
06 Gömülü güvenlik politikası
Kaynak kısıtlı gömülü sistemler için minimal ama güçlü güvenlik duvarı politikası: default drop, stateful firewall, rate limiting ve flood koruması.
Default drop politikası
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
# Default: DROP — yalnızca açıkça izin verilenler geçer
policy drop;
# 1. Loopback — hiçbir zaman engelleme
iif lo accept
# 2. Kurulu bağlantılar — performans için en başta
ct state established,related accept
# 3. Geçersiz — hemen düşür
ct state invalid drop
# 4. Servis kuralları (platforma göre özelleştir)
tcp dport 22 accept # SSH yönetim
udp dport 51820 accept # WireGuard VPN
# 5. ICMP — rate limit ile
ip protocol icmp icmp type echo-request limit rate 5/second accept
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 5/second accept
# ICMPv6 ND gerekli (Neighbor Discovery)
ip6 nexthdr icmpv6 icmpv6 type {
nd-neighbor-solicit, nd-neighbor-advert,
nd-router-solicit, nd-router-advert
} accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Rate limiting — brute force koruması
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
# SSH brute force koruması
# Dakikada 3'ten fazla yeni SSH bağlantısı: log ve drop
tcp dport 22 ct state new \
limit rate over 3/minute burst 5 packets \
log prefix "SSH BRUTE: " level warn drop
tcp dport 22 ct state new accept
# HTTP flood koruması
tcp dport { 80, 443 } ct state new \
limit rate over 100/second burst 200 packets drop
tcp dport { 80, 443 } accept
# ICMP flood (ping flood)
ip protocol icmp \
limit rate over 10/second burst 20 packets drop
ip protocol icmp accept
}
}
SYN flood koruması
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
# SYN flood — TCP SYN paketleri için rate limit
tcp flags syn tcp dport { 80, 443 } \
limit rate over 200/second burst 500 packets \
log prefix "SYN FLOOD: " drop
# Geçersiz TCP bayrakları
tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 drop # NULL scan
tcp flags & (fin|syn) == (fin|syn) drop # XMAS scan
ct state new tcp dport { 22, 80, 443 } accept
ip protocol icmp accept
}
}
Bu bölümde
- policy drop = whitelist modeli; tüm bilinmeyenler bloke edilir
- limit rate over: eşiği aşan trafiği drop et; burst ile kısa spike'lara tolerans
- TCP bayrak kontrolü: NULL ve XMAS scan gibi port tarama tekniklerini engelle
07 Pratik: IoT gateway güvenlik duvarı
WAN (eth0), LAN (eth1) ve WireGuard VPN (wg0) arayüzleri olan bir IoT gateway için tam nftables yapılandırması: NAT, rate limit, port forward ve WireGuard entegrasyonu.
Ağ topolojisi
İnternet
│
eth0 (WAN — DHCP, dinamik IP)
│
┌──┴──────────────────────────────────┐
│ IoT Gateway │
│ nftables güvenlik duvarı │
└──┬──────────────────┬────────────────┘
│ │
eth1 (LAN) wg0 (VPN)
192.168.2.0/24 10.10.0.0/24
IoT cihazları Uzak yönetim
Tam gateway nftables.conf
#!/usr/sbin/nft -f
# /etc/nftables.conf — IoT Gateway güvenlik duvarı
flush ruleset
# ─── Değişkenler ─────────────────────────────────────
define WAN = "eth0"
define LAN = "eth1"
define VPN = "wg0"
define LAN_NET = 192.168.2.0/24
define VPN_NET = 10.10.0.0/24
# ─── Engel listesi ───────────────────────────────────
table inet raw {
set blocklist {
type ipv4_addr
flags dynamic, timeout
timeout 1h
gc-interval 10m
}
chain prerouting {
type filter hook prerouting priority -300; policy accept;
ip saddr @blocklist counter drop
}
}
# ─── NAT ─────────────────────────────────────────────
table ip nat {
map port_forward {
type inet_service : ipv4_addr . inet_service
elements = {
8022 : 192.168.2.10 . 22, # IoT cihaz 1 SSH
8080 : 192.168.2.20 . 80, # IoT cihaz 2 HTTP
}
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
iifname $WAN tcp dport map @port_forward dnat to
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname $WAN masquerade
}
}
# ─── Filtre ──────────────────────────────────────────
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid counter drop
# WAN: yalnızca VPN ve ICMP
iifname $WAN udp dport 51820 accept # WireGuard
iifname $WAN ip protocol icmp \
limit rate 5/second accept
iifname $WAN drop # diğer WAN girişi yok
# LAN: güvenilir ağ
iifname $LAN ip saddr $LAN_NET accept
# VPN: yönetim arayüzü
iifname $VPN ip saddr $VPN_NET tcp dport 22 \
limit rate 3/minute burst 5 packets accept
iifname $VPN ip saddr $VPN_NET accept
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
ct state invalid drop
# LAN → WAN: internete çıkış
iifname $LAN oifname $WAN \
ip saddr $LAN_NET ct state new accept
# LAN → VPN: VPN ağına ulaşım
iifname $LAN oifname $VPN accept
# VPN → LAN: uzak yönetim
iifname $VPN oifname $LAN ip saddr $VPN_NET accept
# WAN → LAN: yalnızca port forward ile
iifname $WAN oifname $LAN ct state dnat accept
# IoT cihazları arası izolasyon (isteğe bağlı)
# iifname $LAN oifname $LAN drop
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Yapılandırmayı uygula ve test et
# Sözdizimi kontrolü
nft -c -f /etc/nftables.conf && echo "Syntax OK"
# Uygula
nft -f /etc/nftables.conf
# Doğrulama
nft list ruleset
nft list counters # counter değerlerini izle
# Bağlantı testleri
ping -c3 8.8.8.8 # WAN çıkışı
ssh -p 8022 192.168.2.10 # DNAT port forward test
ping -c3 10.10.0.2 # VPN bağlantısı
# Rate limit testleri
hping3 -S --flood -p 22 <gateway_ip> # SYN flood simülasyonu
nft list set inet raw blocklist # dinamik engel listesini izle
# systemd ile kalıcı hale getir
systemctl enable nftables
systemctl start nftables
IoT cihazları genellikle birbirinden izole edilmesi gereken düşük güvenlik profilli cihazlardır. iifname $LAN oifname $LAN drop kuralı etkinleştirilerek LAN izolasyonu sağlanabilir; böylece ele geçirilen bir cihaz diğer LAN cihazlarına saldıramaz. Bu özellikle endüstriyel IoT ve medikal cihazlar için önemlidir.
Bu bölümde
- WAN/LAN/VPN arayüz ayrımı: her yönün ayrı güvenlik politikası
- Map ile DNAT port forward: port_forward map tüm yönlendirmeyi tek tanımda toplar
- inet raw + blocklist set: tüm trafikten önce (-300 priority) engel listesi