wireguard 分流

wireguard 客户端可以配置成, 根据 IP 段选择 连接对应的wireguard 服务器端? 例如 wireguard 客户端IP 为 192.168.10.0/24 时, 连接 wireguard 服务器A端, 33.33.33.33 wireguard 客户端IP 为 192.168.20.0/24 时, 连接 wireguard 服务器B端, 44.44.44.44 wireguard 客户端IP 为 192.168.30.0/24 时, 连接 wireguard 服务器C端, 55.55.55.55 wireguard 客户端 安装在openwrt 中, wireguard 服务器端 安装到 centos 服务器中, 有 3台服务器 A,B, C

解决方案

方案一:用 luci-app-pbr(VPN Policy-Based Routing)

1) 安装

opkg update
opkg install luci-app-pbr pbr
#(如未装 WG)
opkg install wireguard-tools kmod-wireguard

2) 配 3 条 WireGuard 接口(/etc/config/network)

关键点:三个接口分别指向 33.33.33.33 / 44.44.44.44 / 55.55.55.55;为避免默认路由被抢占,关闭 route_allowed_ips(或 AllowedIPs 不设 0.0.0.0/0)。

config interface 'wgA'
  option proto 'wireguard'
  list addresses '10.8.0.2/32'       # 你在 A 服务器分给 OpenWrt 的隧道 IP
  option private_key 'XXXXX'
  option peerdns '0'
  option mtu '1420'                  # 视需要调整
  option metric '50'                 # 防止干扰主路由

config wireguard_wgA
  option public_key 'PUBKEY_A'
  option endpoint_host '33.33.33.33'
  option endpoint_port '51820'
  option persistent_keepalive '25'
  list allowed_ips '0.0.0.0/0'       # 让隧道可承载全流量
  option route_allowed_ips '0'       # 但不自动加默认路由

config interface 'wgB'
  option proto 'wireguard'
  list addresses '10.9.0.2/32'
  option private_key 'YYYYY'
  option peerdns '0'
  option mtu '1420'
  option metric '50'

config wireguard_wgB
  option public_key 'PUBKEY_B'
  option endpoint_host '44.44.44.44'
  option endpoint_port '51820'
  option persistent_keepalive '25'
  list allowed_ips '0.0.0.0/0'
  option route_allowed_ips '0'

config interface 'wgC'
  option proto 'wireguard'
  list addresses '10.10.0.2/32'
  option private_key 'ZZZZZ'
  option peerdns '0'
  option mtu '1420'
  option metric '50'

config wireguard_wgC
  option public_key 'PUBKEY_C'
  option endpoint_host '55.55.55.55'
  option endpoint_port '51820'
  option persistent_keepalive '25'
  list allowed_ips '0.0.0.0/0'
  option route_allowed_ips '0'

防火墙:把 wgA/wgB/wgC 加到一个 vpn zone(出方向 ACCEPT,或转发到 WAN),LAN 允许 forward 到 vpn

3) 策略路由(/etc/config/pbr)

config pbr 'config'
  option enabled '1'
  option strict_enforcement '1'
  option verbosity '1'

config policy
  option name 'LAN10_to_A'
  option src_addr '192.168.10.0/24'
  option interface 'wgA'

config policy
  option name 'LAN20_to_B'
  option src_addr '192.168.20.0/24'
  option interface 'wgB'

config policy
  option name 'LAN30_to_C'
  option src_addr '192.168.30.0/24'
  option interface 'wgC'

重启网络/服务:

/etc/init.d/network restart
/etc/init.d/pbr restart

4): DNS 防泄漏

/etc/config/dhcp(dnsmasq)

  • 关闭本机 DNS 监听(只当 DHCP 不当 DNS)
  • 各网段通过 DHCP option 6 下发各自专属 DNS
    你可以用自己三台服务器的隧道侧地址(例如在服务器 A/B/C 上监听 10.8.0.1/10.9.0.1/10.10.0.1 的递归或转发 DNS),也可以用公共 DNS。下面给两套写法,你选其一。
config dnsmasq
  option domainneeded '1'
  option boguspriv '1'
  option authoritative '1'
  option noresolv '1'
  option port '0'          # 关闭本机53端口,路由器不提供DNS

# 按你的实际接口名修改(示例假设 br-lan10/20/30 对应的 dhcp 段名为 lan10/lan20/lan30)
config dhcp 'lan10'
  option interface 'lan10'
  option start '100'
  option limit '100'
  option leasetime '12h'
  # 下面两行二选一(只保留你选的那行!)
  # 【A 方案:用服务器A的隧道侧DNS】(建议跑 unbound/dnsmasq 在 10.8.0.1)
  # list dhcp_option '6,10.8.0.1'
  # 【B 方案:用公共DNS(示例Cloudflare)】
  list dhcp_option '6,1.1.1.1,1.0.0.1'

config dhcp 'lan20'
  option interface 'lan20'
  option start '100'
  option limit '100'
  option leasetime '12h'
  # 【A:服务器B】
  # list dhcp_option '6,10.9.0.1'
  # 【B:公共DNS(示例Google)】
  list dhcp_option '6,8.8.8.8,8.8.4.4'

config dhcp 'lan30'
  option interface 'lan30'
  option start '100'
  option limit '100'
  option leasetime '12h'
  # 【A:服务器C】
  # list dhcp_option '6,10.10.0.1'
  # 【B:公共DNS(示例Quad9)】
  list dhcp_option '6,9.9.9.9,149.112.112.112'

若采用【A 方案】,请在三台 CentOS 上各自开一个本地 DNS(unbound/dnsmasq 任一),监听隧道 IP(如 10.8.0.1),并允许递归到公网;这样天然“所有 DNS 一定走隧道”。

5): /etc/config/firewall(严格拦截 53,只放行白名单 DNS)

为每个网段添加两条规则:允许到“白名单 DNS”的 53拒绝其它 53
(下面示例分别给出 A/B 两种上游写法,保留你实际使用的 IP)

######## LAN10 -> 只许到 A 方案的 10.8.0.1(或 B 方案的 1.1.1.1/1.0.0.1) ########
config rule
  option name 'LAN10 allow DNS to A(or CF)'
  option src 'lan10'
  option proto 'tcpudp'
  option dest_port '53'
  # A 方案(服务器A在隧道侧的DNS)
  # option dest_ip '10.8.0.1'
  # B 方案(Cloudflare)
  option dest_ip '1.1.1.1 1.0.0.1'
  option target 'ACCEPT'

config rule
  option name 'LAN10 block other DNS'
  option src 'lan10'
  option proto 'tcpudp'
  option dest_port '53'
  option target 'REJECT'

######## LAN20 -> 只许到 B 方案的 10.9.0.1(或 8.8.8.8/8.8.4.4) ########
config rule
  option name 'LAN20 allow DNS to B(or Google)'
  option src 'lan20'
  option proto 'tcpudp'
  option dest_port '53'
  # A 方案(服务器B)
  # option dest_ip '10.9.0.1'
  # B 方案(Google)
  option dest_ip '8.8.8.8 8.8.4.4'
  option target 'ACCEPT'

config rule
  option name 'LAN20 block other DNS'
  option src 'lan20'
  option proto 'tcpudp'
  option dest_port '53'
  option target 'REJECT'

######## LAN30 -> 只许到 C 方案的 10.10.0.1(或 9.9.9.9/149.112.112.112) ########
config rule
  option name 'LAN30 allow DNS to C(or Quad9)'
  option src 'lan30'
  option proto 'tcpudp'
  option dest_port '53'
  # A 方案(服务器C)
  # option dest_ip '10.10.0.1'
  # B 方案(Quad9)
  option dest_ip '9.9.9.9 149.112.112.112'
  option target 'ACCEPT'

config rule
  option name 'LAN30 block other DNS'
  option src 'lan30'
  option proto 'tcpudp'
  option dest_port '53'
  option target 'REJECT'

6): 服务器端(CentOS)最小可用示例(每台一份)

以 A 为例(B/C 同理改端口与网段):

/etc/wireguard/wg0.conf

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_A_PRIVKEY>

# 打开转发 + NAT(iptables 版本,nft/火墙按需替换)
PostUp   = sysctl -w net.ipv4.ip_forward=1 ; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# OpenWrt(wgA)的公钥
PublicKey = <OPENWRT_PUBKEY_FOR_A>
AllowedIPs = 10.8.0.2/32

B/C 建议用不同的隧道网段(如 10.9.0.0/24、10.10.0.0/24),便于区分与排错。
启动:

systemctl enable --now wg-quick@wg0

7): 在 CentOS 服务器上开“隧道侧 DNS”

举例:在 A 服务器(10.8.0.1)用 dnsmasq 作转发器(轻量、够用),B/C 同理改 IP。

/etc/dnsmasq.d/wg-dns.conf

# 仅监听隧道口
interface=wg0
listen-address=10.8.0.1
bind-interfaces
no-resolv
# 上游你可选 Cloudflare/Google/Quad9 等
server=1.1.1.1
server=1.0.0.1
cache-size=1000

启动并自启:

systemctl enable --now dnsmasq

方案二:纯 UCI 手工(多路由表 + ip rule)

1) 同上先建 3 条 WG 接口(与方案一相同),保持 route_allowed_ips '0'

2) 自定义路由表与规则(/etc/config/network)

# 路由表 101/102/103:默认走各自的 wg 接口
config route
  option interface 'wgA'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '101'

config rule
  option src '192.168.10.0/24'
  option lookup '101'
  option priority '1010'

config route
  option interface 'wgB'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '102'

config rule
  option src '192.168.20.0/24'
  option lookup '102'
  option priority '1020'

config route
  option interface 'wgC'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '103'

config rule
  option src '192.168.30.0/24'
  option lookup '103'
  option priority '1030'

/etc/init.d/network restart

3):给每个表加“默认走 wgX”的路由(/etc/config/network)

##### 表101:默认经 wgA #####
config route
  option interface 'wgA'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '101'          # => ip route add default dev wgA table 101

#(如用IPv6,同样建一条默认路由到 wgA)
# config route6
#   option interface 'wgA'
#   option target '::'
#   option netmask '0'
#   option table '101'

##### 表102:默认经 wgB #####
config route
  option interface 'wgB'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '102'          # => default dev wgB

# config route6
#   option interface 'wgB'
#   option target '::'
#   option netmask '0'
#   option table '102'

##### 表103:默认经 wgC #####
config route
  option interface 'wgC'
  option target '0.0.0.0'
  option netmask '0.0.0.0'
  option table '103'          # => default dev wgC

# config route6
#   option interface 'wgC'
#   option target '::'
#   option netmask '0'
#   option table '103'

用策略规则把各源网段指向对应表(/etc/config/network)

##### LAN10 -> 表101 -> wgA #####
config rule
  option src '192.168.10.0/24'
  option lookup '101'
  option priority '1010'

##### LAN20 -> 表102 -> wgB #####
config rule
  option src '192.168.20.0/24'
  option lookup '102'
  option priority '1020'

##### LAN30 -> 表103 -> wgC #####
config rule
  option src '192.168.30.0/24'
  option lookup '103'
  option priority '1030'

编辑 /etc/iproute2/rt_tables 末尾追加:

101 t_wgA
102 t_wgB
103 t_wgC

应用并自检

/etc/init.d/network restart

# 查看规则与表
ip rule
ip route show table 101
ip route show table 102
ip route show table 103

# 看 WG 是否在传数据
wg show