
私はNixOS 22.11(最新のXanModカーネルパッチとacpidとirqbalanceが有効)を実行しているルータでnftablesを使用しています。このマシンには、インターネットに接続するenp4s0と異なるIP LANを提供する2つのローカルWiFiアクセスポイントwlp1s0とwlp5s0の3つのインターフェイスがあります。
私のnftables設定は次のとおりです。ローカルネットワークからのインバウンドDNS、DHCP、およびSSHトラフィックのみを許可し、インターネットへのアウトバウンドおよび転送トラフィックとSNATを許可します。
table ip filter {
chain conntrack {
ct state vmap { invalid : drop, established : accept, related : accept }
}
chain dhcp {
udp sport 68 udp dport 67 accept comment "dhcp"
}
chain dns {
ip protocol { tcp, udp } th sport 53 th sport 53 accept comment "dns"
}
chain ssh {
ip protocol tcp tcp dport 22 accept comment "ssh"
}
chain in_wan {
jump dns
jump dhcp
jump ssh
}
chain in_iot {
jump dns
jump dhcp
}
chain inbound {
type filter hook input priority filter; policy drop;
icmp type echo-request limit rate 5/second accept
jump conntrack
iifname vmap { "lo" : accept, "wlp1s0" : goto in_wan, "enp4s0" : drop, "wlp5s0" : goto in_iot }
}
chain forward {
type filter hook forward priority filter; policy drop;
jump conntrack
oifname "enp4s0" accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "enp4s0" snat to 192.168.1.2
}
}
table ip6 global6 {
chain input {
type filter hook input priority filter; policy drop;
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}
この単純な構成では、KDE Connectが機能しないと予想しました。1714-1764 ポートを開く必要があるため。実際にコンピュータをwlp1s0に接続し、携帯電話をwlp5s0(別のインターフェイス)に接続すると、デバイスはお互いを見ることができず、ロギングルールまたはnftraceを使用してtcpdumpとnftablesを介してパケットを表示できます。
ただし、両方のシステムを同じインターフェイス(wlp1s0など)に配置すると、KDE Connectが正常に動作し、デバイスがお互いを見ることができます。私の推測では、接続追跡のためにこれが起こるようですが、追加しても
chain trace_wan {
type filter hook prerouting priority filter - 1; policy accept;
iifname "wlp1s0" oifname "wlp1s0" meta nftrace set 1
}
テーブルにfilter
移動すると、実行時にパケットは表示されませんnft monitor trace
。同様に、チェーンのインデックス0にロギングルールを挿入すると、syslogにはどのパケットも表示されませんforward
。しかし、実行時にはtcpdump -i wlp1s0 port 1716
nftablesでも見られたかったパケットを見ることができます。
14:33:59.943462 IP 192.168.2.11.55670 > 192.168.2.42.xmsg: Flags [.], ack 20422, win 501, options [nop,nop,TS val 3319725685 ecr 2864656484], length 0
14:33:59.957101 IP 192.168.2.42.xmsg > 192.168.2.11.55670: Flags [P.], seq 20422:20533, ack 1, win 285, options [nop,nop,TS val 2864656500 ecr 3319725685], length 111
2つのデバイスが同じインターフェイスに接続されているとnftablesがこれらのパケットを見ることができないのはなぜですか? nftablesがデフォルトで転送されたすべてのパケットをドロップするようにするにはどうすればよいですか?
コメントで要求された追加情報:
❯ ip -br link
lo UNKNOWN <LOOPBACK,UP,LOWER_UP>
enp2s0 DOWN <BROADCAST,MULTICAST>
enp3s0 DOWN <BROADCAST,MULTICAST>
enp4s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
wlp5s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
wlp1s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
❯ ip -4 -br address
lo UNKNOWN 127.0.0.1/8
enp4s0 UP 192.168.1.2/24
wlp5s0 UP 192.168.3.1/24
wlp1s0 UP 192.168.2.1/24
❯ bridge link
❯ ip route
default via 192.168.1.1 dev enp4s0 proto static
192.168.1.0/24 dev enp4s0 proto kernel scope link src 192.168.1.2
192.168.1.1 dev enp4s0 proto static scope link
192.168.2.0/24 dev wlp1s0 proto kernel scope link src 192.168.2.1
192.168.3.0/24 dev wlp5s0 proto kernel scope link src 192.168.3.1
❯ sysctl net.bridge.bridge-nf-call-iptables
sysctl: error: 'net.bridge/bridge-nf-call-iptables' is an unknown key
答え1
警告:これは一般的なLinuxの答えです。この回答では、NixOS との特定の統合や独自のネットワーク構成方法や構成からランダムなコマンドを呼び出す方法については説明しません。
広報会議
OPの最初のケース(2つの異なるインターフェース)ルーター実際、2つのインターフェイス間のパスwlp1s0そしてwlp5s0:転送されたIPv4トラフィックは次に表示されます。nftables'ホームIP、フィルタ転送フック。
2番目のケースの流量は次のとおりです。ブリッジルータのアクセスポイントインターフェイス経由wlp1s0:nftables'ホームIPテーブルにはブリッジトラフィックは表示されず、IPv4トラフィックのみが表示されます。
さらに、このブリッジングは、標準のLinuxブリッジングレベルでも発生せず、アクセスポイント(AP)のドライバ(および/またはハードウェアアクセラレータ)によって直接実行されます。 2つのWi-Fiデバイスは2つの間で通信します(まだAP)、そのフレームは実際のネットワークスタックに到達しません。
システムが実際にこのトラフィックをフィルタリングするには、次の3つのことが必要です。
- トラフィックがネットワークスタックを通過するようにAP設定を変更します。
- ネットワークスタックがフレームを削除しないように、APに関連付けられているLinuxブリッジがあります。nftables足のレベルで見ることができます。
- 十分nftablesブリッジファミリールール。 ~のためBridgeシリーズのIPステートフルファイアウォール、Linuxカーネル5.3以降が必要です(NixOS 22.11で十分です)。
選択していない他のオプション:
2+3 の代わりに、ステートフルファイアウォールがない場合は、次のことを想像できます。nftables'Web開発者入口と出口のある家(必須)Linuxカーネル>= 5.17輸出用
fwd
)、しかし処理する必要がある特別なケースがたくさんあるでしょう。しないことをお勧めします。3 の代わりに、次を使用します。古いブリッジネットワークフィルタコードブリッジパスで使用するためのステートフルファイアウォールiptables(そしてDockerで使用されます)すべてのルールを同じテーブルに入れます。
nftablesやはり影響を受けるのはこのコードに依存しないように意図されているため、正しい使用のための機能が不足します(ほとんど以下と同等の機能が不足します)。iptables'
physdev
モジュール方式同じルールセットでブリッジトラフィックとルーティングトラフィックを区別する)。これにより、状況は依然として依存します。iptablesしたがって、まだ複数のテーブルが必要です。 (Dockerでのこの複雑な使用法の例:nftablesホワイトリストドッカー)。警告として、Dockerをルーターに追加すると、以下の設定が中断される可能性があります。
設定
変化所有者設定
2つの関連設定を変更する必要があります。所有者設定:
フレームがネットワークスタックによって処理され、ドライバによって短絡されてはならないことを知らせます。
構成は次のとおりです所有者~のためwlp1s0変更する必要があります。両方の Wi-Fi インターフェイスに 1 つの設定がある場合は、2 つの別々の設定が必要です。この回答ではこの統合については説明しませんが、単一のインターフェイスに焦点を当てています。wlp1s0。
AP分離以下で有効にする必要があります
hostapd.conf
。ap_isolate=1
これで、2つのステーションクライアント(STA)間のフレームがAPドライバによって直接処理されず、ネットワークスタックに到着します。
構成所有者ブリッジを使用し、ワイヤレスインターフェイスをブリッジポートに設定
以前の設定でのみルーターと送受信するフレームのみがルーターで処理されます。ルーティングスタックの一部ネットワーク山。ルータに属していないか、ルータから来るフレームは単に削除されます。これは、イーサネットインターフェイスがそのMACアドレスに属さないユニキャストフレームを受信した場合に発生します。これが設定名が指定された理由です
ap_isolate
。 STAはデフォルトで互いに分離されています。この問題を解決するにはブリッジが必要です。言う所有者設定wlp1s0APモードで設定すると、ブリッジポートとして機能できます。指定された名前を使用してブリッジを作成するか(好ましくは)既存のブリッジを再利用し、実行時にインターフェイスをブリッジポートに設定します。誰の名前も選んだbrwlan1。
ブリッジの構成存在する
hostapd.conf
:bridge=brwlan1
ブリッジの使用に関するネットワーク設定の変更
接続ポートがなく、待ち時間のないブリッジの設定
手動で次のようになります。
ip link add name brwlan1 up type bridge forward_delay 0
注:
hostapd
Wi-Fiインターフェースをブリッジに接続するためのツールです。これは、ブリッジポートに設定する前にAPに設定する必要があるためです。何でも動くルーティング(階層3)設定情報wlp1s0到着brwlan1:
ip addr delete 192.168.2.1/24 dev wlp1s0 ip addr add 192.168.2.1/24 dev brwlan1
これには、DHCP設定など、さまざまなアプリケーションのインターフェイス参照の変更も含まれます。
...そしてnftablesただし、これについては次のセクションで説明します。
持つ所有者走る
一度確認してくださいwlp1s0インスタンスが実行中です。wlp1s0に設定brwlan1ブリッジポート:
人々は次のような内容を見るでしょう。
# bridge link show dev wlp1s0 6: wlp1s0 <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master brwlan1 state forwarding priority 32 cost 100
次に、個々のブリッジポートでヘアピンモードをイネーブルにします。
現在、STA-to-STA通信は依然として不可能であり、STA-to-APまたはAP-to-STAのみが可能です。 STA-to-STAは、単一のブリッジポートにフレームが到着する必要があります。wlp1s0同じブリッジポートから再送信します。これらのフレームを転送するためのブリッジがありますが、まだそうではありません。デフォルトでは、イーサネットブリッジ(またはスイッチ)は通常の有線設定では意味がないため、元のポートに戻すことを無効にします。
だからヘッドピン以下で有効にする必要があります。wlp1s0したがって、このポートで受信したフレームは同じポートで再送信できます。現在は開発版(ブランチ)のみ基本)の所有者新しい設定パラメータの承認
bridge_hairpin=1
これを自動的に実行します(バージョン2.10はまだ十分に新しいものではありません)。これは、以下を使用して手動で実行できます。bridge
コマンド(使用されていないbrctl
コマンドはこの機能をサポートしていません):bridge link set dev wlp1s0 hairpin on
この部分には正しいオペレーティングシステムの統合が必要です。所有者付属wlp1s0ブリッジポートでのみ使用できるため、ブリッジポートとして使用されます。
hostapd
設定したいwlp1s0デーモンの前でブリッジポートとして機能し、ネットワーク構成ツールにコマンドを実行させます。それ以外の場合、競合状態が発生した場合は、sleep 3;
コマンドの実行時にインターフェイスがブリッジポートであることを確認するために、このコマンドの前に遅延(たとえば)を挿入することを検討できます。wlp1s0ブリッジを切断/再接続するには(再起動などhostapd
)、このコマンドを再実行する必要があります。ネットワーク構成で呼び出す必要があります。
適応するnftablesルールセット
...使用ブリッジファミリーIPシリーズの代わりに。これはルーティングに非常に似ています。ルーター用のフレームは入力フックに表示され、ルーターのフレームは出力フックに表示され、STA-STAフレームは順方向フックに表示できます。
オブジェクトの名前空間はテーブルごとに適用されるため、両方の間でルールを再利用できないため、いくつかの重複が必要です。関連するルーティングルールの関連部分をコピーして調整しました。今後。たとえば、いくつかのカウンタを使用してpingとKDE接続ポートを有効にしました。一部の定型句は実際には必要ありません(たとえば、最初にIPv6のユニバーサル削除ルールがある場合は単に置き換える
ether type ip ip protocol tcp tcp dport 1714
ことができます。このコマンドは、カーネルにルールを提供するときに必要な定型句を内部的に挿入します)。tcp dport 1714
nft
table bridge filter # for idempotence delete table bridge filter # for idempotence table bridge filter { chain conntrack { ct state vmap { invalid : drop, established : accept, related : accept } } chain kdeconnect { udp dport 1714-1764 counter accept tcp dport 1714-1764 counter accept } chain forward { type filter hook forward priority filter; policy drop; jump conntrack ether type ip6 drop # just like OP did: drop any IPv6 icmp type echo-request counter accept jump kdeconnect ether type arp accept # mandatory for IPv4 connectivity counter } }
しなければならないwlp5s0後で同じものが独自の別々のブリッジで構成される予定であり、ブリッジポートごとまたはブリッジあたり(
iifname wlp1s0
またはibrname brwlan1
必要に応じて)フィルタリングが必要です。他の場合は、依然としてOP初期ルールセットの標準ルーティングによって処理される。入力フィルタと出力フィルタのフックが設定されていないため、ルータに入ってくるトラフィックが許可されるか、他のインターフェイスにルーティングされるトラフィックになります。
OPnftablesルーティングも調整する必要があります。
table ip filter
この単語が表示されるたびに、現在ルーティングに参加しているインターフェイスwlp1s0
に置き換える必要があります。brwlan1