最近我在Ubuntu服务器上配置了WireGuard VPN,并实现了一个特定的路由转发需求:将服务器上的流量(例如 `192.168.100.0/24` 子网)通过WireGuard隧道转发回家(客户端)。过程中遇到了一些问题,但最终通过调试和重启解决。以下是我的完整方案和经验总结。
目标
– **服务器端**:运行WireGuard,IP为 `10.100.70.1`,将 `192.168.100.0/24` 的流量路由到客户端。
– **客户端**:ROS系统,运行WireGuard 客户端,IP为 `10.100.70.2`,接收并处理服务器转发的流量。
– **场景**:服务器作为VPN中继,客户端可能连接到目标子网或进一步处理流量。
## 环境
– **操作系统**:Ubuntu(服务器),ROS(客户端)
– **WireGuard版本**:最新版本(通过 `apt install wireguard` 安装)
– **网络接口**:服务器公网接口为 `eth0`,WireGuard接口为 `wg0`
## 配置步骤
1. 安装WireGuard
在服务器和客户端上安装WireGuard:
sudo apt update
sudo apt install wireguard -y
2. 生成密钥对
为服务器和客户端生成公钥/私钥对:
#### 服务器:
cd /etc/wireguard
wg genkey | tee server_privatekey | wg pubkey > server_publickey
chmod 600 server_privatekey server_publickey
#### 客户端:
interface/wireguard/add
将服务器的公钥给客户端,客户端的公钥给服务器。
3. 配置WireGuard
#### 服务器配置 (`/etc/wireguard/wg0.conf`):
[Interface]
ListenPort = 51820
PrivateKey = <服务器私钥>
[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.100.70.2/32, 192.168.100.0/24
[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.100.70.3/32, 192.168.110.0/24
– `AllowedIPs` 包含客户端IP和目标子网,表示服务器允许将这些流量转发给客户端。
#### 客户端配置 (`/etc/wireguard/wg0.conf`):
interface/wireguard/peer add allowed-address=0.0.0.0/0 endpoint-address=<服务器地址> endpoint-port=51820 interface=wireguard2 public-key= <服务器私公钥>
– 客户端的 `AllowedIPs` 表示它接受服务器转发的目标子网流量。
4. 启用IP转发
在服务器和客户端上启用IP转发:
sudo sysctl -w net.ipv4.ip_forward=1
sudo nano /etc/sysctl.conf # 添加或取消注释 net.ipv4.ip_forward=1
sudo sysctl -p
5. 添加路由
在服务器上添加路由,将 `192.168.100.0/24` 的流量转发到客户端:
sudo ip route add 192.168.100.0/24 via 10.100.70.2 dev wg0
6. 配置防火墙和NAT
确保服务器允许转发流量:
sudo iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo apt install iptables-persistent -y
sudo iptables-save > /etc/iptables/rules.v4
如果使用ufw:
sudo ufw allow 51820/udp
7. 启动WireGuard
启动WireGuard并设置开机自启:
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0
8.映射服务器上80端口请求到内网
服务器上配置端口转发
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.100.13:80
iptables -A FORWARD -i eth0 -o wg0 -p tcp -d 192.168.100.13 --dport 80 -j ACCEPT
ufw allow 80/tcp
家里ROS配置好回源路由
/ip/firewall/mangle
add action=mark-connection chain=prerouting comment=wg-goback-conn connection-mark=no-mark connection-state=new in-interface=wireguard2 new-connection-mark=\
from_wg2 passthrough=yes
add action=mark-routing chain=prerouting comment=wg-goback-route connection-mark=from_wg2 in-interface=!wireguard2 new-routing-mark=to-wg-2 passthrough=yes
/ip/route/
add disabled=no dst-address=0.0.0.0/0 gateway=10.100.70.1 routing-table=to-wg-2 suppress-hw-offload=no
9.防火墙规则持久化
使用 iptables-persistent
sudo apt install iptables-persistent -y
安装过程中会提示保存当前的IPv4和IPv6规则,选择“是”以保存现有规则(如果已有规则)。
配置好NAT和转发规则后,保存到持久化文件:
sudo iptables-save > /etc/iptables/rules.v4
# NAT转发80和443端口
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.255.255.13:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.255.255.13:443
iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
# 允许转发
iptables -A FORWARD -i eth0 -o wg0 -p tcp -d 10.255.255.13 --dport 80 -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -p tcp -d 10.255.255.13 --dport 443 -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
# 保存规则
sudo iptables-save > /etc/iptables/rules.v4
重启验证
10.wireguard配置持久化
wg showconf wg0
#显示当前的wg配置
wg syncconf wg0 /etc/wireguard/wg0.conf
#使用/etc/wireguard/wg0.conf配置文件来连接wg0的配置
11.如果你客户端没有公网,服务器有公网地址,建议客户端勾选persistent-keepalive,或者写脚本定期保活。
persistent-keepalive (integer:0..65535; Default: 0)
A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from a peer, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds.
调试过程
配置完成后,我尝试从服务器ping `192.168.100.1`,但遇到了问题:
– **错误1**:`From 10.100.70.1 Destination Host Unreachable` 和 `ping: sendmsg: Required key not available`。
– **错误2**:在 `192.168.100.0/24` 侧抓不到ping包。
### 排查步骤
1. **检查WireGuard状态**:
sudo wg
确认握手正常,客户端IP可ping通(`ping 10.100.70.2` 成功)。
2. **检查路由**:
ip route
确保路由规则存在。
3. **抓包分析**:
sudo tcpdump -i wg0 -n
检查ping包是否通过 `wg0` 发送。
4. **检查防火墙**:
sudo iptables -L -v -n
确认没有丢包规则。
### 解决方法
在反复检查配置无误后,我尝试重启服务器:
sudo reboot
重启后,ping `192.168.100.1` 成功,流量正常转发到客户端。
## 最终验证
– 服务器:`ping 192.168.100.1` 通。
– 客户端:抓包确认收到服务器转发的流量。
– 路由表和WireGuard状态正常。
## 经验教训
1. **重启的力量**:有时配置未即时生效,重启可以解决潜在的系统状态问题。
2. **AllowedIPs的重要性**:服务器和客户端的 `AllowedIPs` 必须匹配目标子网。
3. **抓包调试**:`tcpdump` 是追踪流量流向的利器。
4. **防火墙配置**:确保转发规则和NAT正确设置。
## 总结
通过这套方案,我成功实现了服务器到客户端的流量路由转发。WireGuard配置简单,但细节(如IP转发、路由和防火墙)至关重要。希望这篇记录能帮到有类似需求的读者!