如何在 Linux 機器上用不同的 VLAN 標籤標記 IPv4 和 IPv6 數據包?
我想用不同的 VLAN 標籤標記來自啟用雙棧的連接的傳入 IPv4 和 IPv6 數據包,例如 IPv4 數據包應該轉到 VLAN4,而 IPv6 數據包應該轉到 VLAN6。更一般地說,我想將混合 IPv4 和 IPv6 數據包的雙棧 ip 流拆分為兩個乾淨的單棧網路,這樣您就不會在 IPv6 網路上找到任何 IPv4 數據包,反之亦然。我需要它來測試和支持僅 IPv6 的網路。當然,我仍然需要 IPv4 數據。它不能簡單地被丟棄。
Linux Box Debian Bullseye untagged ┏━━━━━━━━━━━┓ tagged (trunk) ════════════════════════┫eth0 vlan4┣═╦══════════════════════ IPv4 and IPv6 ┃ vlan6┣═╝eth1 IPv4 with VLAN4 tag dual stack ┗━━━━━━━━━━━┛ IPv6 with VLAN6 tag
我查看了 Linux 網橋,
nftables
但無法找到解決方案。我怎樣才能實現這種選擇性標記?
我找到了解決方案。因為我想操作 VLAN,所以我必須使用網橋。VLAN 在 OSI 第 2 層上工作,網橋是可以處理第 2 層協議的設備。所以首先我將兩個 VLAN 介面添加到物理介面eth1。然後將所有介面eth0、vlan4和vlan6 添加到網橋。其餘的由nftables完成。
IPv4 和 IPv6 在 layer3 上定義,在 layer 2 上沒有不同的含義。因此nftables可以將它們作為具有不同“標記”的數據包處理,這是 IP 標頭中的協議類型。幸運的是, nftables可以使用
meta protocol {}
. 它將傳入的未標記 IPv4 和 IPv6 數據包定向到相應的 VLAN 介面。像往常一樣由界面自動完成標記。我使用systemd-networkd,這裡是詳細配置。首先創建網路設備vlan4、vlan6和網橋br0:
~$ sudo -Es ~# cat > /etc/systemd/network/01-vlan4.netdev <<EOF [NetDev] Name=vlan4 Kind=vlan [VLAN] Id=4 EOF ~# cat > /etc/systemd/network/02-vlan6.netdev <<EOF [NetDev] Name=vlan6 Kind=vlan [VLAN] Id=6 EOF ~# cat > /etc/systemd/network/03-br0.netdev <<EOF [NetDev] Name=br0 Kind=bridge [Bridge] DefaultPVID=6 VLANProtocol=802.1q STP=no EOF
然後將介面連接到 eth1 和網橋:
~# cat > /etc/systemd/network/12-eth1_attach-vlans.network <<EOF [Match] Name=eth1 [Network] LLMNR=no LinkLocalAddressing=no VLAN=vlan4 VLAN=vlan6 EOF ~# cat > /etc/systemd/network/16-ifs_add_to_br0.network <<EOF [Match] Name=eth0 vlan4 vlan6 [Network] Bridge=br0 LLMNR=no LinkLocalAddressing=no EOF
現在只需打開橋:
~# cat > /etc/systemd/network/20-br0-up.network <<EOF [Match] Name=br0 [Network] LLMNR=no MulticastDNS=yes EOF
重新啟動後,這將為您提供:
~$ ip -brief address lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP br0 UP 2003:d5:2721:900:9012:fdff:fef0:ea7f/64 fe80::9012:fdff:fef0:ea7f/64 vlan6@eth1 UP vlan4@eth1 UP eth1 UP # these are the slave interfaces of the bridge ~$ sudo bridge link show 4: vlan6@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4 5: vlan4@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4 6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4
也值得檢查
resolvectl
。現在我們必須做最後一步,並使用以下規則使用nftables重定向數據包:~$ cat /etc/nftables.conf #!/usr/sbin/nft -f flush ruleset table bridge filter { chain forward { type filter hook forward priority 0; policy accept; meta protocol { ip6 } iifname "vlan4" drop meta protocol { ip6 } oifname "vlan4" drop meta protocol { ip6 } iifname "vlan6" accept meta protocol { ip6 } oifname "vlan6" accept iifname "vlan6" drop oifname "vlan6" drop } chain output { type filter hook output priority 0; policy drop; meta protocol { ip6 } iifname "vlan6" accept meta protocol { ip6 } oifname "vlan6" accept } }
在轉發鏈上,這將丟棄所有 IPv6 到/從介面vlan4並且只允許它在介面vlan6上。所有其他的東西都被丟棄在介面vlan6上,但是通過介面**vlan4上接受的鏈預設策略。這確保了所有舊的東西,如 ARP 和其他廣播也進入介面vlan4。
輸對外連結只是為了避免網橋本身將數據包發送到錯誤的 VLAN。在我的配置中,它僅使用 IPv6(單堆棧),因此鏈預設策略將刪除所有內容,除了 IPv6 到vlan6。
雖然您的答案顯然對您有用,但它似乎過於復雜。我懷疑它是否可以滿足您的要求,因為它在給定的輸出中缺少任何 IPv4 地址(除了 lo)。
創建 2 個標記介面(例如命名為 vlan4 和 vlan6),為它們分配 IPv4 和 IPv6 地址 + 網關,並使用 sysctl 為 IPv4 禁用 SLAAC 就足夠了。
除了啟用 eth0 和 eth1 之間的流動所需的東西之外,不需要橋接或弄亂 nftables。