19.9.26

Linux VXLAN in lab 使用 Scapy 模擬VTEP 注入攻擊的攻防腳本

 在Linux 或 WSL 環境中,透過建立兩個模擬主機node1與node2來建立底層的路由網路,在上面建立 VXLAN 介面 掛載至Bridge,實現跨主機的 Layer 2 Overlay ,就是兩個L2的Bridge打隧道串起來,VXLAN 是一種MAC-in-UDP的隧道機制,開一條UDP隧道,跟L2一樣IP對MAC,


參考這個說明會比較好理解

2026 iThome 鐵人賽的文章-NVUE - VXLAN

https://ithelp.ithome.com.tw/articles/10405506



網路架構

[ VM / Namespace 1 ]                                          [ VM / Namespace 2 ]

  ns-app1 (10.0.0.1/24)                                         ns-app2 (10.0.0.2/24)

         | (veth)                                                                      | (veth)

  [ Bridge: br-overlay ]                                        [ Bridge: br-overlay ]

         |                                                                                |

  [ vxlan100 (VNI: 100) ]                                       [ vxlan100 (VNI: 100) ]

===============================================================

                     --- Underlay IP Network (UDP: 4789) ---

   underlay-node1 (192.168.50.1) <=================> underlay-node2 (192.168.50.2)



一層一層建立

先建立兩個 Namespace,並透過 veth 互連:

sudo ip netns add underlay-node1

sudo ip netns add underlay-node2

建立點對點網路

sudo ip link add veth-u1 type veth peer name veth-u2

sudo ip link set veth-u1 netns underlay-node1

sudo ip link set veth-u2 netns underlay-node2

設定 underlay-node1 節點的IP (192.168.50.1/24)

sudo ip netns exec underlay-node1 ip addr add 192.168.50.1/24 dev veth-u1

sudo ip netns exec underlay-node1 ip link set veth-u1 up

sudo ip netns exec underlay-node1 ip link set lo up

設定 underlay-node2 節點的IP (192.168.50.2/24)

sudo ip netns exec underlay-node2 ip addr add 192.168.50.2/24 dev veth-u2

sudo ip netns exec underlay-node2 ip link set veth-u2 up

sudo ip netns exec underlay-node2 ip link set lo up

在 underlay-node1 上建立 Overlay Bridge 與 VXLAN 介面

sudo ip netns exec underlay-node1 ip link add name br-overlay type bridge

sudo ip netns exec underlay-node1 ip link set dev br-overlay up

建立 VXLAN 介面 (VNI: 100  IP: 192.168.50.2 UDP Port: 4789)

sudo ip netns exec underlay-node1 ip link add name vxlan100 type vxlan \

 id 100 

 remote 192.168.50.2 

 local 192.168.50.1 

 dstport 4789 

 dev veth-u1

將 VXLAN 介面加入 Bridge 並啟動

sudo ip netns exec underlay-node1 ip link set dev vxlan100 master br-overlay

sudo ip netns exec underlay-node1 ip link set dev vxlan100 up

在 underlay-node2 上建立 Overlay Bridge 與 VXLAN 介面

sudo ip netns exec underlay-node2 ip link add name br-overlay type bridge

sudo ip netns exec underlay-node2 ip link set dev br-overlay up

建立 VXLAN 介面 (VNI: 100  IP: 192.168.50.1 UDP Port: 4789)

sudo ip netns exec underlay-node2 ip link add name vxlan100 type vxlan 

id 100 

 remote 192.168.50.1 

 local 192.168.50.2 

 dstport 4789 

 dev veth-u2

將 VXLAN 介面加入 Bridge 並啟動

sudo ip netns exec underlay-node2 ip link set dev vxlan100 master br-overlay

sudo ip netns exec underlay-node2 ip link set dev vxlan100 up

建立虛擬機 (ns-app1 與 ns-app2)

建立 App Namespace

sudo ip netns add ns-app1

sudo ip netns add ns-app2

將 ns-app1 連接至 Node 1 的 br-overlay

sudo ip link add veth-app1 type veth peer name veth-app1-br

sudo ip link set veth-app1 netns ns-app1

sudo ip link set veth-app1-br netns underlay-node1

sudo ip netns exec underlay-node1 ip link set dev veth-app1-br master br-overlay

sudo ip netns exec underlay-node1 ip link set dev veth-app1-br up

sudo ip netns exec ns-app1 ip addr add 10.0.0.1/24 dev veth-app1

sudo ip netns exec ns-app1 ip link set dev veth-app1 up

將 ns-app2 連接至 Node 2 的 br-overlay

sudo ip link add veth-app2 type veth peer name veth-app2-br

sudo ip link set veth-app2 netns ns-app2

sudo ip link set veth-app2-br netns underlay-node2

sudo ip netns exec underlay-node2 ip link set dev veth-app2-br master br-overlay

sudo ip netns exec underlay-node2 ip link set dev veth-app2-br up

sudo ip netns exec ns-app2 ip addr add 10.0.0.2/24 dev veth-app2

sudo ip netns exec ns-app2 ip link set dev veth-app2 up

跨 L2 Ping 測試

sudo ip netns exec ns-app1 ping -c 3 10.0.0.2




觀察 Node 1 上的 Bridge 轉發表

sudo ip netns exec underlay-node1 bridge fdb show dev vxlan100






在 Node 1 的 Underlay 介面抓封包

sudo ip netns exec underlay-node1 tcpdump -nni veth-u1 udp port 4789


使用 Scapy 模擬VTEP 注入攻擊的攻防腳本

sudo vim vxlan_security_test.sh

sudo chmod +x vxlan_security_test.sh

sudo ./vxlan_security_test.sh

*****************************************************************************

cat << 'EOF' > vxlan_security_test.sh

#!/usr/bin/env bash

set -e


GREEN='\033[0;32m'

RED='\033[0;31m'

YELLOW='\033[1;33m'

NC='\033[0m'


cleanup() {

    echo -e "\n${YELLOW}[*] 正在清理實驗環境...${NC}"

    iptables -D INPUT -i veth-host -p udp --dport 4789 -j VXLAN_FILTER 2>/dev/null || true

    iptables -F VXLAN_FILTER 2>/dev/null || true

    iptables -X VXLAN_FILTER 2>/dev/null || true

    

    ip link delete veth-host 2>/dev/null || true

    ip netns del tenant-test 2>/dev/null || true

    rm -f /tmp/scapy_inject.py /tmp/test_dump.pcap

    echo -e "${GREEN}[+] 環境清理完成!${NC}"

}

trap cleanup EXIT INT TERM


if [[ $EUID -ne 0 ]]; then

   echo -e "${RED}[!] 請以 root 權限執行 (sudo ./vxlan_security_test.sh)${NC}"

   exit 1

fi


echo -e "${GREEN}==============================================${NC}"

echo -e "${GREEN}    VXLAN Rogue VTEP 攻防全自動驗證測試        ${NC}"

echo -e "${GREEN}==============================================${NC}"


echo -e "\n=== 步驟 1: 檢查依賴環境 ==="

apt-get update -qq && apt-get install -y -qq python3-scapy tcpdump iptables > /dev/null

echo -e "${GREEN}[+] 依賴套件已就緒${NC}"


echo -e "\n=== 步驟 2: 建立 Underlay 與 Overlay 拓撲 ==="

# 1. 建立 veth pair 模擬底層實體網路 (Underlay)

ip link add veth-host type veth peer name veth-rogue

ip addr add 192.168.10.1/24 dev veth-host

ip addr add 192.168.10.2/24 dev veth-rogue

ip link set veth-host up

ip link set veth-rogue up


# 2. 建立租戶命名空間與綁定在 veth-host 的 VXLAN 介面

ip netns add tenant-test

ip link add vxlan100 type vxlan id 100 dstport 4789 local 192.168.10.1 dev veth-host

ip link set vxlan100 netns tenant-test

ip netns exec tenant-test ip link set lo up

ip netns exec tenant-test ip link set vxlan100 up

ip netns exec tenant-test ip addr add 10.0.0.1/24 dev vxlan100

echo -e "${GREEN}[+] 拓撲建立完畢:Host VTEP (192.168.10.1) <---> 租戶內部 (10.0.0.1, VNI 100)${NC}"


# 產生 Scapy 注入腳本 (從 veth-rogue 介面注入)

cat << 'PYEOF' > /tmp/scapy_inject.py

#!/usr/bin/env python3

import sys

from scapy.all import Ether, IP, UDP, VXLAN, ICMP, sendp, get_if_hwaddr


# 參數

src_mac = get_if_hwaddr("veth-rogue")

pkt = (

    Ether(src=src_mac, dst="ff:ff:ff:ff:ff:ff") /

    IP(src="192.168.99.99", dst="192.168.10.1") /      # 偽造外層來源

    UDP(sport=50000, dport=4789) /

    VXLAN(vni=100, flags="Instance") /

    Ether(src="00:11:22:33:44:55", dst="ff:ff:ff:ff:ff:ff") /

    IP(src="10.0.0.66", dst="10.0.0.1") /              # 偽造內層攻擊

    ICMP(type=8, code=0)

)

sendp(pkt, iface="veth-rogue", count=2, inter=0.1, verbose=False)

PYEOF


echo -e "\n=== 步驟 3: 測試階段一 (無防禦,模擬攻擊注入) ==="

rm -f /tmp/test_dump.pcap

ip netns exec tenant-test timeout 4 tcpdump -i vxlan100 -nn -c 1 "icmp" -w /tmp/test_dump.pcap 2>/dev/null &

TCPDUMP_PID=$!

sleep 1.5


echo -e "[*] 從惡意介面發送偽造 VXLAN 注入封包..."

python3 /tmp/scapy_inject.py

wait $TCPDUMP_PID 2>/dev/null || true


CAPTURED=$(tcpdump -r /tmp/test_dump.pcap 2>/dev/null | wc -l)

if [[ "${CAPTURED}" -gt 0 ]]; then

    echo -e "${RED}[!] 攻擊成功:租戶成功接收到外部解封裝的偽造封包!${NC}"

    tcpdump -r /tmp/test_dump.pcap -nn -e 2>/dev/null | head -n 1

else

    echo -e "${RED}[X] 異常:未捕獲到注入封包。${NC}"

fi


echo -e "\n=== 步驟 4: 測試階段二 (啟用 iptables 白名單防禦) ==="

iptables -N VXLAN_FILTER

iptables -A INPUT -i veth-host -p udp --dport 4789 -j VXLAN_FILTER

# 僅允許合法的 VTEP (例如 192.168.10.2),其餘惡意來源全數丟棄

iptables -A VXLAN_FILTER -s 192.168.10.2 -j ACCEPT

iptables -A VXLAN_FILTER -j DROP

echo -e "${GREEN}[+] 已啟用 iptables 規則:阻斷未授權的 UDP 4789 封包${NC}"


rm -f /tmp/test_dump.pcap

ip netns exec tenant-test timeout 4 tcpdump -i vxlan100 -nn -c 1 "icmp" -w /tmp/test_dump.pcap 2>/dev/null &

TCPDUMP_PID=$!

sleep 1.5


echo -e "[*] 再次發送偽造 VXLAN 注入封包..."

python3 /tmp/scapy_inject.py

wait $TCPDUMP_PID 2>/dev/null || true


CAPTURED_DEFENDED=$(tcpdump -r /tmp/test_dump.pcap 2>/dev/null | wc -l)

if [[ "${CAPTURED_DEFENDED}" -eq 0 ]]; then

    echo -e "${GREEN}[+] 防禦驗證成功:租戶未收到任何非法封包 (已在 Underlay 層被攔截) !${NC}"

else

    echo -e "${RED}[!] 防禦失敗:封包仍被穿透!${NC}"

fi


echo -e "\n=== 統計與阻斷計數 ==="

iptables -L VXLAN_FILTER -v -n

EOF

****************************************************************************

沒有留言:

張貼留言