diff --git a/vpn-overlay/vxlan/README.md b/vpn-overlay/vxlan/README.md new file mode 100644 index 00000000..3a47fc32 --- /dev/null +++ b/vpn-overlay/vxlan/README.md @@ -0,0 +1,50 @@ +# VXLAN Overlay 工具集 + +本目录包含构建与诊断二层 VXLAN Overlay 网络的实用脚本,适用于云主机场景(如 AWS EC2),支持安全模式(保留 eth0 仅用于管理面)。 + +--- + +## 🛠️ 脚本列表 + +| 脚本名称 | 说明 | +|----------|------| +| `setup_sit_vxlan.sh` | 安全模式部署 VXLAN Overlay 网络,仅桥接 `vxlan + veth` | +| `overlay_diag.sh` | 自动诊断 VXLAN 接口、桥接状态、FDB 转发表、Overlay 连通性 | + +--- + +## 🚀 使用方法 + +### 1️⃣ 初始化 Overlay 网络 + +- dev_interface:出口物理网卡(如 ens5) +- local_ip:本机内网 IP(VXLAN 使用) +- remote_ip:对端节点的内网 IP +- br0_ip:本地 Overlay 地址(如 10.255.0.2) +- cidr_suffix(可选):默认为 16(设置为 /16 子网) +- vxlan_id(可选):默认 100 + +示例: bash setup_sit_vxlan.sh ens5 54.65.102.93 18.179.15.13 10.255.0.2 16 100 + +### 2️⃣ 诊断 Overlay 网络连通性 + +示例: + +bash overlay_diag.sh +bash overlay_diag.sh 10.255.0.2 10.255.0.3 + +诊断内容: + +- 接口是否存在、是否为 UP 状态; +- br0 IP 是否为非 /32 掩码; +- bridge fdb 是否学习到对端 MAC; +- ping 测试 Overlay 层连通性; +- NAT(MASQUERADE)规则是否存在; +- VXLAN 报文抓包命令提示(UDP port 4789)。 + +### 📦 典型应用场景 + +- 构建多节点跨主机的 L2 Overlay 隧道; +- 支持 VXLAN over 公网 IP,内部互通 10.255.0.0/16; +- 云主机或虚拟机跨可用区桥接; +- 上层可用于 gretap、bridge、L2 BGP、广播集群等。 diff --git a/vpn-overlay/vxlan/overlay_diag.sh b/vpn-overlay/vxlan/overlay_diag.sh new file mode 100644 index 00000000..bcda3ab2 --- /dev/null +++ b/vpn-overlay/vxlan/overlay_diag.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# overlay_diag.sh - VXLAN Overlay 自动诊断工具(Pro 版) + +set -e + +if [ $# -ne 2 ]; then + echo "用法: $0 " + exit 1 +fi + +LOCAL_IP="$1" +REMOTE_IP="$2" +BR_IF="br0" +VETH_A="veth_overlay" +VETH_B="veth_peer" +VXLAN_IF=$(ip -o link show | grep -o 'vxlan[0-9]\+' | head -n 1) +VXLAN_ID=$(echo "$VXLAN_IF" | grep -o '[0-9]\+') + +echo "============================" +echo "🔍 VXLAN Overlay 网络诊断工具" +echo "============================" +echo "📍 本地 Overlay IP: $LOCAL_IP" +echo "📍 对端 Overlay IP: $REMOTE_IP" +echo "📦 VXLAN 接口: $VXLAN_IF" +echo "🆔 VXLAN ID: $VXLAN_ID" +echo "" + +# 接口存在性检测 +for iface in "$VXLAN_IF" "$VETH_A" "$VETH_B" "$BR_IF"; do + if ip link show "$iface" &>/dev/null; then + echo "✅ 接口 $iface 存在" + else + echo "❌ 接口 $iface 不存在" + fi +done +echo "" + +# 接口 UP 状态 +for iface in "$VXLAN_IF" "$VETH_A" "$VETH_B" "$BR_IF"; do + state=$(cat /sys/class/net/$iface/operstate 2>/dev/null || echo "unknown") + echo "📶 接口 $iface 状态: $state" +done +echo "" + +# br0 IP 信息 +br0_ip=$(ip -4 addr show "$BR_IF" | grep -oP 'inet \K[\d.]+/\d+') +if [[ "$br0_ip" == */32 ]]; then + echo "⚠️ br0 IP 为 /32:$br0_ip → 建议设置为 /16 或其他实际子网" +else + echo "✅ br0 IP 设置为:$br0_ip" +fi +echo "" + +# FDB 表 +echo "📡 FDB 转发表 (bridge fdb show dev $VXLAN_IF):" +bridge fdb show dev "$VXLAN_IF" +echo "" + +# ping 连通性测试 +echo "🔁 ping 对端 Overlay IP: $REMOTE_IP(从 $VETH_A 发起)" +ping -c 3 -I "$VETH_A" "$REMOTE_IP" || echo "⚠️ ping 失败,可能未打通 VXLAN 或对端未启动" +echo "" + +# iptables SNAT 检查 +echo "🧱 iptables NAT 规则检查(是否有 MASQUERADE):" +iptables -t nat -S POSTROUTING | grep MASQUERADE || echo "⚠️ 没有检测到 MASQUERADE 规则" +echo "" + +# 抓包提示 +echo "🔬 VXLAN 报文检测提示(需 root 权限):" +echo "👉 可运行以下命令查看 VXLAN 报文是否流动:" +echo " sudo tcpdump -ni $VXLAN_IF udp port 4789" +echo " sudo tcpdump -ni $VETH_B" +echo " sudo tcpdump -ni $BR_IF" +echo "" + +echo "📌 若 ping 不通但 FDB 存在,可能为对端未配置、未学习或防火墙阻断。" +echo "✅ 诊断完成!" diff --git a/vpn-overlay/vxlan/setup_sit_vxlan.sh b/vpn-overlay/vxlan/setup_sit_vxlan.sh index 245cef70..acc99c47 100644 --- a/vpn-overlay/vxlan/setup_sit_vxlan.sh +++ b/vpn-overlay/vxlan/setup_sit_vxlan.sh @@ -1,17 +1,17 @@ #!/bin/bash -# 安全版 VXLAN Overlay 脚本:保留 eth0 做管理面,仅桥接 vxlan0 + vethX -# 用法: -# ./setup_overlay_safe.sh +# 安全版 VXLAN Overlay 脚本(参数顺序改为 dev_if + ip 信息) set -e -LOCAL_IP="$1" -REMOTE_IP="$2" -BRIDGE_IP="$3" -VNI="${4:-100}" # VXLAN ID,默认 100 +DEV_IF="$1" +LOCAL_IP="$2" +REMOTE_IP="$3" +BRIDGE_IP="$4" +CIDR_SUFFIX="${5:-16}" +VNI="${6:-100}" -if [ -z "$LOCAL_IP" ] || [ -z "$REMOTE_IP" ] || [ -z "$BRIDGE_IP" ]; then - echo "Usage: $0 [vxlan_id]" +if [ -z "$DEV_IF" ] || [ -z "$LOCAL_IP" ] || [ -z "$REMOTE_IP" ] || [ -z "$BRIDGE_IP" ]; then + echo "Usage: $0 [cidr_suffix] [vxlan_id]" exit 1 fi @@ -19,8 +19,10 @@ VXLAN_IF="vxlan${VNI}" BR_IF="br0" VETH_A="veth_overlay" VETH_B="veth_peer" +BRIDGE_CIDR="${BRIDGE_IP}/${CIDR_SUFFIX}" +SUBNET="$(echo "$BRIDGE_IP" | cut -d. -f1-2).0.0/${CIDR_SUFFIX}" -echo "🧠 安全模式:仅桥接 $VXLAN_IF 和 $VETH_B,不动 eth0" +echo "🧠 安全模式:仅桥接 $VXLAN_IF 和 $VETH_B,不动 $DEV_IF" # 清理旧接口 for iface in "$VXLAN_IF" "$BR_IF" "$VETH_A" "$VETH_B"; do @@ -33,10 +35,10 @@ done # 创建 VXLAN 接口 echo "[1] 创建 VXLAN 接口:$VXLAN_IF" -ip link add "$VXLAN_IF" type vxlan id "$VNI" dstport 4789 local "$LOCAL_IP" remote "$REMOTE_IP" +ip link add "$VXLAN_IF" type vxlan id "$VNI" dstport 4789 local "$LOCAL_IP" remote "$REMOTE_IP" dev "$DEV_IF" ip link set "$VXLAN_IF" up -# 创建 veth pair 模拟数据交换接口 +# 创建 veth pair echo "[2] 创建 veth pair:$VETH_A <-> $VETH_B" ip link add "$VETH_A" type veth peer name "$VETH_B" ip link set "$VETH_A" up @@ -49,17 +51,28 @@ ip link set "$VXLAN_IF" master "$BR_IF" ip link set "$VETH_B" master "$BR_IF" ip link set "$BR_IF" up -# 分配 BRIDGE IP -echo "[4] 配置 br0 地址:$BRIDGE_IP" -ip addr add "$BRIDGE_IP" dev "$BR_IF" +# 配置 IP 和子网掩码 +echo "[4] 配置 br0 地址:$BRIDGE_CIDR" +ip addr add "$BRIDGE_CIDR" dev "$BR_IF" -# 可选 SNAT 出口(若该主机需要 NAT 功能) -echo "[5] 启用 IP 转发 + SNAT(可选)" +# 启用 SNAT +echo "[5] 启用 IP 转发 + SNAT(出口:$DEV_IF,子网:$SUBNET)" sysctl -w net.ipv4.ip_forward=1 -iptables -t nat -C POSTROUTING -s 10.255.0.0/16 -o eth0 -j MASQUERADE 2>/dev/null || \ -iptables -t nat -A POSTROUTING -s 10.255.0.0/16 -o eth0 -j MASQUERADE +iptables -t nat -C POSTROUTING -s "$SUBNET" -o "$DEV_IF" -j MASQUERADE 2>/dev/null || \ +iptables -t nat -A POSTROUTING -s "$SUBNET" -o "$DEV_IF" -j MASQUERADE + +# 自动触发 ARP 学习 +REMOTE_LAST_OCTET="$(echo "$REMOTE_IP" | awk -F. '{print $4}')" +if [[ "$REMOTE_LAST_OCTET" -eq 2 ]]; then + REMOTE_BR_IP="10.255.0.3" +else + REMOTE_BR_IP="10.255.0.2" +fi + +echo "[6] 触发 ARP 学习 ping:$REMOTE_BR_IP ← from $VETH_A" +ping -c 1 -I "$VETH_A" "$REMOTE_BR_IP" || true echo "✅ 安全 Overlay 构建完成:" echo " - vxlan: $VXLAN_IF" -echo " - bridge: $BR_IF (IP: $BRIDGE_IP)" -echo " - 管理面未修改 eth0,可正常连通" +echo " - bridge: $BR_IF (IP: $BRIDGE_CIDR)" +echo " - SNAT 子网:$SUBNET → $DEV_IF"