同一Ubuntu 22.04.4 LTS服务器配置多同端口(51820)不同IP段WireGuard接口的问题咨询
嘿,我在Ubuntu 22.04上折腾过不少WireGuard多接口的场景,你的问题我刚好碰到过,给你一步步捋清楚怎么解决:
首先,你碰到的核心问题——没法添加第二个同端口的WireGuard接口,是因为默认情况下第一个接口已经把0.0.0.0:51820(所有IP的51820端口)占了,系统不允许两个套接字绑定同一个IP:端口组合。你之前想把监听端口绑定到IP段的思路方向对,但WireGuard不支持直接绑定IP段,不过可以绑定到每个接口的虚拟IP,这样就绕开了端口冲突的问题。
第一步:修改WireGuard接口配置,解决端口冲突
给每个WireGuard接口的配置文件加上BindAddress参数,指定该接口的虚拟IP,同时保留ListenPort=51820。这样每个接口会绑定到不同的IP:51820组合,就不会冲突了。
比如你的wg0.conf改成这样:
[Interface] PrivateKey = <你的私钥内容> Address = 10.0.0.1/24 ListenPort = 51820 BindAddress = 10.0.0.1 # 绑定到wg0的虚拟IP,避免和wg1冲突 # 下面是你的Peer配置,按原有内容保留即可 [Peer] PublicKey = <Peer的公钥> AllowedIPs = 10.0.0.2/32 # ...其他Peer配置
wg1.conf对应修改:
[Interface] PrivateKey = <你的私钥内容> Address = 10.0.1.1/24 ListenPort = 51820 BindAddress = 10.0.1.1 # 绑定到wg1的虚拟IP [Peer] PublicKey = <Peer的公钥> AllowedIPs = 10.0.1.2/32 # ...其他Peer配置
修改完后重启两个接口:
wg-quick down wg0 && wg-quick up wg0 wg-quick down wg1 && wg-quick up wg1
现在再跑ss -uln | grep 51820,应该能看到两条监听记录:10.0.0.1:51820和10.0.1.1:51820,而不是之前的0.0.0.0:51820了,端口冲突的问题就解决了。
第二步:过滤对应IP段外的流量
你想丢弃对应接口IP段外的流量,这里分两种情况处理:
- WireGuard内部过滤:每个Peer配置里的
AllowedIPs参数已经能过滤虚拟IP——比如wg0的Peer设置AllowedIPs=10.0.0.0/24,WireGuard会自动拒绝虚拟IP不在这个段的Peer流量,不需要额外规则。 - 公网侧非法流量过滤:如果要拦截非你的Peer发的垃圾UDP包,可以用iptables给每个接口的绑定IP加规则,只允许合法Peer的公网IP访问51820端口。
可以把规则加到接口的PostUp/PostDown里,这样接口启动/关闭时自动加载/删除规则:
比如wg0.conf的[Interface]段加上:
# 先创建ipset存储wg0的Peer公网IP,比逐条写规则灵活 PostUp = ipset create wg0_peers hash:ip 2>/dev/null PostUp = ipset add wg0_peers <Peer1公网IP> 2>/dev/null PostUp = ipset add wg0_peers <Peer2公网IP> 2>/dev/null # 只允许wg0_peers集合里的IP访问10.0.0.1:51820 PostUp = iptables -A INPUT -p udp --dport 51820 -d 10.0.0.1 -m set --match-set wg0_peers src -j ACCEPT # 丢弃其他所有访问10.0.0.1:51820的UDP包 PostUp = iptables -A INPUT -p udp --dport 51820 -d 10.0.0.1 -j DROP # 关闭接口时清理规则和ipset PostDown = iptables -D INPUT -p udp --dport 51820 -d 10.0.0.1 -m set --match-set wg0_peers src -j ACCEPT PostDown = iptables -D INPUT -p udp --dport 51820 -d 10.0.0.1 -j DROP PostDown = ipset destroy wg0_peers 2>/dev/null
wg1.conf的规则对应改成-d 10.0.1.1和对应的wg1 Peer公网IP即可。如果嫌ipset麻烦,也可以直接把Peer公网IP写到iptables规则里,比如:
PostUp = iptables -A INPUT -p udp --dport 51820 -d 10.0.0.1 -s <Peer1公网IP> -j ACCEPT PostUp = iptables -A INPUT -p udp --dport 51820 -d 10.0.0.1 -s <Peer2公网IP> -j ACCEPT PostUp = iptables -A INPUT -p udp --dport 51820 -d 10.0.0.1 -j DROP PostDown = iptables -D INPUT -p udp --dport 51820 -d 10.0.0.1 -s <Peer1公网IP> -j ACCEPT PostDown = iptables -D INPUT -p udp --dport 51820 -d 10.0.0.1 -s <Peer2公网IP> -j ACCEPT PostDown = iptables -D INPUT -p udp --dport 51820 -d 10.0.0.1 -j DROP
验证配置
重启接口后,用这些命令检查配置是否生效:
ss -uln | grep 51820:确认两个接口分别绑定到各自的虚拟IP:51820wg show wg0/wg show wg1:确认Peer连接状态正常iptables -L INPUT -v -n:确认过滤规则已经加载- 测试非法流量:用其他机器发UDP包到服务器的51820端口,看是否被丢弃
注意事项
- Ubuntu 22.04.4的WireGuard版本已经支持
BindAddress参数,不需要升级 - 每个接口必须使用独立的私钥,不能共用
- 如果你的服务器开了UFW防火墙,要先允许51820端口的UDP流量:
ufw allow 51820/udp
要是你操作中碰到具体报错,把wg-quick up wg1的输出贴出来,我再帮你排查。
备注:内容来源于stack exchange,提问作者southmountain

