Ubuntu 18.04.1.
Один и тот же файл набора правил ведет себя по-разному, независимо от того, загружается ли система при загрузке (не работает) или загружается вручную после загрузки (работает правильно).
В частности, при загрузке при загрузке nft, по-видимому, идентифицирует рассматриваемый трафик как входящий в его входную цепочку. Но (повторно) загруженный после загрузки, он правильно передает его через прямую цепочку.
Интересующий трафик - это SSH DNAT, идущий от порта 4022 общедоступного интерфейса к внутреннему IP на порту 22.
Мой /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
iif eth0 tcp dport 4022 dnat to 10.0.0.2:22
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "eth0" masquerade
}
}
table ip filter {
chain input {
type filter hook input priority 0; policy drop;
tcp dport 4022 meta nftrace set 1
counter
ip protocol icmp icmp type echo-request accept
ct state { established, related} accept
iif lo accept
iif eth0 accept
iifname "eth0" jump input_eth0
iifname "br0" jump input_br0
}
chain forward {
type filter hook forward priority 0; policy drop;
meta nftrace set 1
counter
ct state { established, related} accept
iifname "eth0" jump forward_eth0
iifname "br0" jump forward_br0
}
chain output {
type filter hook output priority 0; policy accept;
}
# ETH0 :
chain input_eth0 {
counter
tcp dport ssh accept
tcp dport http accept
tcp dport https accept
}
chain forward_eth0 {
counter
ip daddr 10.0.0.2 tcp dport 22 nftrace set 1 accept
}
# LXD BRIDGE :
chain input_br0 {
counter
reject with icmp type host-prohibited
}
chain forward_br0 {
counter
ip saddr 10.0.0.2 accept
ip saddr 10.0.0.10 accept
ip saddr 10.0.0.11 accept
reject with icmp type host-prohibited
}
# POSTROUTING :
chain pr {
type filter hook postrouting priority -10; policy accept;
oifname "eth0" jump pr_eth0
}
chain pr_eth0 {
}
}
Вот как выглядит трассировка монитора nft после загрузки, перед перезагрузкой файла, когда nft, похоже, думает, что трафик должен проходить через его входную цепочку:
trace id 68d42e8a ip filter input packet: iif "eth0" ether saddr 00:de:ad:be:ef:01 ether daddr 00:de:ad:be:ef:02 ip saddr S.S.S.S ip daddr D.D.D.D ip dscp cs0 ip ecn not-ect ip ttl 58 ip id 50033 ip length 60 tcp sport 7240 tcp dport 4022 tcp flags == syn tcp window 29200
trace id 68d42e8a ip filter input rule tcp dport 4022 nftrace set 1 (verdict continue)
trace id 68d42e8a ip filter input rule counter packets 230 bytes 382785 (verdict continue)
trace id 68d42e8a ip filter input rule iif "eth0" accept (verdict accept)
И вот начало трассировки после выдачи «sudo nft -f /etc/nftables.conf», где nft использует свою прямую цепочку, как я и ожидал:
trace id 1177c4c4 ip filter forward packet: iif "eth0" oif "br0" ether saddr 00:de:ad:be:ef:01 ether daddr 00:de:ad:be:ef:02 ip saddr S.S.S.S ip daddr 10.0.0.2 ip dscp cs0 ip ecn not-ect ip ttl 57 ip id 22369 ip length 60 tcp sport 1665 tcp dport ssh tcp flags == syn tcp window 29200
trace id 1177c4c4 ip filter forward rule nftrace set 1 (verdict continue)
trace id 1177c4c4 ip filter forward rule counter packets 41 bytes 6437 (verdict continue)
trace id 1177c4c4 ip filter forward rule iifname "eth0" jump forward_eth0 (verdict jump forward_eth0)
trace id 1177c4c4 ip filter forward_eth0 rule counter packets 1 bytes 60 (verdict continue)
trace id 1177c4c4 ip filter forward_eth0 rule ip daddr 10.0.0.2 tcp dport ssh nftrace set 1 accept (verdict accept)
trace id 1177c4c4 ip filter pr verdict continue
trace id 1177c4c4 ip filter pr
trace id 1177c4c4 ip nat postrouting verdict continue
trace id 1177c4c4 ip nat postrouting
trace id b9475640 ip filter forward packet: iif "br0" oif "eth0" ether saddr 00:de:ad:be:ef:03 ether daddr 00:de:ad:be:ef:04 ip saddr 10.0.0.2 ip daddr S.S.S.S ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 0 ip length 60 tcp sport ssh tcp dport 1665 tcp flags == 0x12 tcp window 28960
trace id b9475640 ip filter forward rule nftrace set 1 (verdict continue)
trace id b9475640 ip filter forward rule counter packets 41 bytes 6437 (verdict continue)
trace id b9475640 ip filter forward rule ct state { } accept (verdict accept)
trace id b9475640 ip filter pr packet: oif "eth0" ip saddr 10.0.0.2 ip daddr S.S.S.S ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 0 ip length 60 tcp sport ssh tcp dport 1665 tcp flags == 0x12 tcp window 28960
trace id b9475640 ip filter pr rule oifname "eth0" jump pr_eth0 (verdict jump pr_eth0)
trace id b9475640 ip filter pr_eth0 verdict continue
trace id b9475640 ip filter pr verdict continue
trace id b9475640 ip filter pr
[...]
Я не вижу предупреждений или ошибок от nft в / var / log / syslog, /var/log/kern.log, dmesg и т. Д.
eth0, br0 и lo настраиваются в / etc / network / interfaces; не использую netplan.
Мое первое предположение заключается в том, что проблема каким-то образом связана с тем фактом, что nft инициализируется до того, как интерфейсы (eth0, br0) включены или, возможно, даже существуют. Я еще не пробовал его на другой ОС, кроме Ubuntu. У меня эта проблема на двух разных серверах. Я не пробовал копировать набор правил nftables в iptables.
Кто-нибудь знает, как исправить или даже устранить эту проблему?