Роутер на Debian: nftables, NAT, DHCP и пошаговая проверка
Пример ниже: WAN-интерфейс enp1s0 получает адрес от провайдера, LAN-интерфейс enp2s0 имеет адрес 192.168.50.1/24. Перед применением замените имена интерфейсов на свои.
1. Проверяем интерфейсы и маршруты
ip -br link
ip -br addr
ip route
resolvectl status 2>/dev/null || cat /etc/resolv.conf
ping -c 3 1.1.1.12. Устанавливаем пакеты
apt update
apt install nftables dnsmasq tcpdump conntrack iproute2
systemctl enable nftables3. Делаем резервную копию
mkdir -p /root/router-backup
cp -a /etc/nftables.conf /root/router-backup/nftables.conf.$(date +%F-%H%M) 2>/dev/null || true
cp -a /etc/dnsmasq.conf /root/router-backup/dnsmasq.conf.$(date +%F-%H%M)
ip addr > /root/router-backup/ip-addr.txt
ip route > /root/router-backup/ip-route.txt4. Назначаем адрес LAN
Для systemd-networkd создайте файл:
cat > /etc/systemd/network/20-lan.network <<'EOF'
[Match]
Name=enp2s0
[Network]
Address=192.168.50.1/24
ConfigureWithoutCarrier=yes
EOF
systemctl enable --now systemd-networkd
networkctl reload
networkctl reconfigure enp2s0
ip -br addr show enp2s05. Включаем маршрутизацию
cat > /etc/sysctl.d/99-router.conf <<'EOF'
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=1
EOF
sysctl --system
sysctl net.ipv4.ip_forward6. Настраиваем nftables и NAT
cat > /etc/nftables.conf <<'EOF'
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
iifname "enp2s0" ip saddr 192.168.50.0/24 udp dport { 53, 67 } accept
iifname "enp2s0" ip saddr 192.168.50.0/24 tcp dport { 22, 53 } accept
ip protocol icmp accept
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
iifname "enp2s0" oifname "enp1s0" ip saddr 192.168.50.0/24 accept
}
chain output { type filter hook output priority 0; policy accept; }
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100;
oifname "enp1s0" ip saddr 192.168.50.0/24 masquerade
}
}
EOF
nft -c -f /etc/nftables.conf
systemctl restart nftables
nft list ruleset7. Настраиваем DHCP и DNS
cat > /etc/dnsmasq.d/router.conf <<'EOF'
interface=enp2s0
bind-interfaces
dhcp-range=192.168.50.100,192.168.50.200,255.255.255.0,12h
dhcp-option=3,192.168.50.1
dhcp-option=6,192.168.50.1
server=1.1.1.1
server=8.8.8.8
log-dhcp
EOF
dnsmasq --test
systemctl enable --now dnsmasq
systemctl status dnsmasq --no-pager8. Проверяем с клиента
ip addr
ip route
ping -c 3 192.168.50.1
ping -c 3 1.1.1.1
getent hosts example.com
curl -I https://example.com9. Проверяем на роутере
journalctl -u dnsmasq --since '15 min ago' --no-pager
conntrack -L | head
tcpdump -ni enp2s0 host 192.168.50.100
tcpdump -ni enp1s0 icmp or port 53
nft list chain inet filter forward10. Пример port forwarding
Чтобы направить внешний TCP 8443 на внутренний сервер 192.168.50.10:443, добавьте в таблицу NAT цепочку prerouting:
nft add chain ip nat prerouting '{ type nat hook prerouting priority -100; }'
nft add rule ip nat prerouting iifname "enp1s0" tcp dport 8443 dnat to 192.168.50.10:443
nft add rule inet filter forward iifname "enp1s0" oifname "enp2s0" ip daddr 192.168.50.10 tcp dport 443 accept
nft list rulesetПосле проверки перенесите рабочие правила в /etc/nftables.conf, иначе они исчезнут после перезагрузки.
11. Диагностика
sysctl net.ipv4.ip_forward
ip route
nft monitor trace
journalctl -u nftables -u dnsmasq -b --no-pager
ss -lunp | grep -E ':(53|67)\b'
df -h12. Rollback
systemctl stop dnsmasq
rm -f /etc/dnsmasq.d/router.conf /etc/sysctl.d/99-router.conf
sysctl --system
cp /root/router-backup/nftables.conf.TIMESTAMP /etc/nftables.conf
nft -f /etc/nftables.conf
rm -f /etc/systemd/network/20-lan.network
networkctl reloadКритерий успеха: клиент получает адрес 192.168.50.x, шлюз и DNS 192.168.50.1, открывает сайты, а новые входящие подключения с WAN блокируются, кроме явно настроенных DNAT-правил.