双端独立 IP 的 IX 路由配置
双端独立 IP 的 IX 路由配置教程,以 halo 家的 IX 产品为例。
流程图 #
前置端 #
IX产品一般只对各大云厂有路由,你需要准备阿里云、腾讯云等云厂的VPS为前置机。
使用 nft 规则直接转发特定端口到IX端。编辑/etc/nftables.conf,注意替换尖括号中的内容。
#!/usr/sbin/nft -f
flush ruleset
table inet main {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
meta l4proto { tcp, udp } th dport <PORT> dnat ip to <IX-PUBLIC-IP:PORT>
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state { established, related } accept
ct status dnat accept
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ct status dnat masquerade
}
}
## 测试配置
nft -c -f /etc/nftables.conf
## 使nft生效
systemctl restart nftables
systemctl enable nftables
## 开启 ipv4 转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/90-fwd.conf
sysctl -p /etc/sysctl.d/90-fwd.conf
IX端 #
halo家的IX和HK端都是独立的IP和机器,需要同时购买IX和HK两个VPS,然后在面板上组SDWAN,让IX和HK走内网通信。
要实现各接口流量原进原出、IX机通外网,同时不影响nft转发,策略路由是最好的方案。
我们可以创建个systemd服务,开机后自动设置。由于配置过程中会破坏默认路由,以下操作建议在VNC中进行,或者从HK端SSH连接到IX端进行配置。
创建一个配置脚本并编辑/root/apps/netinit/netinit.sh:
#!/bin/bash
if [ $# != 1 ]
then
echo "Use $(basename "$0") <set|clear>"
exit 1;
fi
TOIP="192.168.X.X" ## HK端SDWAN-IP,注意修改为你自己的
PORT_FWD="25000-25020" ## 端口转发规则,注意修改为你自己的
TO_PREFIX=$(echo "$TOIP" | cut -d. -f1-3)
SDWAN_DEV=$(ip -o -4 addr show | grep "$TO_PREFIX" | awk '{print $2}')
PUBLIC_DEV=$(ip -4 route show default | awk '{print $5}')
nftrule=$(cat <<EOF
table inet main {
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ct state != new meta mark set ct mark
iifname "$PUBLIC_DEV" ct mark 0 meta mark set 0x5 ct mark set meta mark
}
chain prerouting_fwd {
type nat hook prerouting priority dstnat; policy accept;
iifname "$PUBLIC_DEV" meta l4proto { tcp, udp } th dport $PORT_FWD dnat ip to $TOIP
}
chain output {
type route hook output priority mangle; policy accept;
meta mark 0 meta mark set ct mark
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state { established, related } accept
ct status dnat accept
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ct status dnat oifname "$SDWAN_DEV" masquerade
}
}
EOF
)
function ClearRules()
{
IPRULE=$(ip rule show | grep 100)
if [ -n "$IPRULE" ]
then
ip route del default via "$TOIP" dev "$SDWAN_DEV" table 100
ip rule del not fwmark 0x5 lookup 100
fi
nft flush ruleset
echo "clear rules"
}
function SetRules()
{
ip route add default via "$TOIP" dev "$SDWAN_DEV" table 100
ip rule add not fwmark 0x5 lookup 100
echo "$nftrule" | nft -f -
sysctl -w net.ipv4.ip_forward=1 > /dev/null
echo "nameserver 8.8.4.4" > /etc/resolv.conf
echo "set rules"
}
if [ $1 = 'set' ]
then
ClearRules
SetRules
elif [ $1 = 'clear' ]
then
ClearRules
fi
创建服务文件并编辑/root/apps/netinit/netinit.service:
[Unit]
Description=netinit.sh
After=network.target nss-lookup.target network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/bash /root/apps/netinit/netinit.sh set
ExecStop=/usr/bin/bash /root/apps/netinit/netinit.sh clear
[Install]
WantedBy=multi-user.target
## 测试
bash /root/apps/netinit/netinit.sh set
## 检查配置
root@debian:~# ip r
default via 165.X.X.1 dev ens18 proto static
10.0.X.0/20 dev ens19 proto kernel scope link src 10.0.X.X
165.X.X.0/23 dev ens18 proto kernel scope link src 165.X.X.X
192.168.X.0/23 dev ens20 proto kernel scope link src 192.168.X.X
root@debian:~# ip rule
0: from all lookup local
32765: not from all fwmark 0x5 lookup 100
32766: from all lookup main
32767: from all lookup default
root@debian:~# ip r show table 100
default via <HK-SDWAN-IP> dev ens20
root@debian:~# nft list ruleset
table inet main {
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ct state != new meta mark set ct mark
iifname "ens18" ct mark 0x00000000 meta mark set 0x00000005 ct mark set meta mark
}
chain prerouting_fwd {
type nat hook prerouting priority dstnat; policy accept;
iifname "ens18" meta l4proto { tcp, udp } th dport 1234-5678 dnat ip to 192.168.X.X
}
chain output {
type route hook output priority mangle; policy accept;
meta mark 0x00000000 meta mark set ct mark
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state { established, related } accept
ct status dnat accept
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ct status dnat oifname "ens20" masquerade
}
}
## 使其生效
ln -s /root/apps/netinit/netinit.service /etc/systemd/system/netinit.service
systemctl daemon-reload
systemctl restart netinit
systemctl enable netinit
HK端 #
使用 nft 规则设置IX端为白名单,避免被邻居偷路由。
编辑/etc/nftables.conf,注意替换尖括号中的内容。
#!/usr/sbin/nft -f
flush ruleset
table inet main {
chain forward {
type filter hook forward priority filter; policy drop;
ct state { established, related } accept
ip saddr <IX-SDWAN-IP> accept
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr <IX-SDWAN-IP> masquerade
}
}
## 测试配置
nft -c -f /etc/nftables.conf
## 使nft生效
systemctl restart nftables
systemctl enable nftables
## 开启 ipv4 转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/90-fwd.conf
sysctl -p /etc/sysctl.d/90-fwd.conf