简述问题和目标

node A 公网 IP:[usVDS ip]
node A GRE IP:192.168.200.1/24

node B 公网 IP:[usWest ip]
node A GRE IP:192.168.200.2/24

系统环境:均为 debian 12

目标:node A 的私网 IP 可以与 node B 的私网 IP 加密互联。

我有一台美东 VDS 和美西的 VPS,其中美东的 VDS 性能强但是线路差,美西的 VPS 线路好,但是性能差。为了实现美东 VDS 跑后端服务,美西 VPS 作为出口,故决定使用 gre over ipsec 构建点对点隧道。

为什么不直接使用代理:性能差且我不希望流量未加密在公网跑(即使是 TLS 加密过的)
为什么不使用 wireguard:wireguard 使用 UDP,众所周知,UDP 被大多数国内外 ISP 强制 QOS。如果使用 udp2raw 转为 TCP 模式,那我认为着实没必要。

配置GRE隧道

启用 GRE 内核模块:

echo "ip_gre" >> /etc/modules
modprobe ip_gre

image.png

启用内核 ipv4转发参数:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.conf
sysctl -p

image.png

配置GRE网络接口:

usVDS节点:

auto gre_to_west
iface gre_to_west inet tunnel
address 192.168.200.1
netmask 30
mode gre
endpoint [usWest public IP]
ttl 64

image.png

usWest节点:

auto gre_to_vds
iface gre_to_vds inet tunnel
address 192.168.200.2
netmask 30
mode gre
endpoint [usVDS public IP]
ttl 64

启用 GRE 网口:

image.png

放行 gre 协议:

# 在 usVDS 执行
ufw allow proto gre from [usWest IP] to [usVDS ip]

# 在 usWest 执行
ufw allow proto gre from [usVDS ip] to [usWest IP]

验证结果:

image.png

在 usWest 使用 tcpdump 抓取 gre 隧道的包:

image.png

显而易见,GRE 隧道是明文传输,在公网是极度不安全的,所以我们让 GRE 隧道构建在 ipsec 中。

配置 ipsec

安装 ipsec 相关工具并且初始化:

apt install -y libreswan

生成需要的 key,并且做记录

在 usWest、usVDS 上执行:

ipsec showhostkey --list
ipsec showhostkey --left --rsaid [keyid]

返回结果如下图所示:

image.png

在 usVDS 上创建 /etc/ipsec.d/ipsec.conf配置文件,并且填入下面的配置:

# /etc/ipsec.conf - Node A (IP: usVDS) IPsec 配置

config setup
    protostack=netkey   # 使用 netkey 协议栈

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    authby=secret    # 使用预共享密钥 (PSK)

# 配置 GRE over IPsec 连接
conn gre-ipsec
    left=[usVDS ip]     # 本地端 IP 地址 (Node A)
    leftsubnet=192.168.200.0/30   # 只让 GRE 隧道子网的流量走 IPsec 隧道
    right=[usWest ip]  # 远程端 IP 地址 (Node B)
    rightsubnet=192.168.200.0/30  # 只让 GRE 隧道子网的流量走 IPsec 隧道
    ike=aes256-sha2_256    # IKE 协议配置
    esp=aes256-sha2_256    # ESP 协议配置
    auto=start             # 自动启动连接

在 usWest上创建 /etc/ipsec.d/ipsec.conf配置文件,并且填入下面的配置:

# /etc/ipsec.conf - Node B (IP: usWest) IPsec 配置

config setup
    protostack=netkey   # 使用 netkey 协议栈

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    authby=secret    # 使用预共享密钥 (PSK)

# 配置 GRE over IPsec 连接
conn gre-ipsec
    left=[usWest ip]   # 本地端 IP 地址 (Node B)
    leftsubnet=192.168.200.0/30   # 只让 GRE 隧道子网的流量走 IPsec 隧道
    right=[usVDS ip]    # 远程端 IP 地址 (Node A)
    rightsubnet=192.168.200.0/30  # 只让 GRE 隧道子网的流量走 IPsec 隧道
    ike=aes256-sha2_256    # IKE 协议配置
    esp=aes256-sha2_256    # ESP 协议配置
    auto=start             # 自动启动连接

在 usWest 上的/etc/ipsec.secrets创建 secret 文件,填入下述内容:

# /etc/ipsec.secrets - Node B (IP: usWest) 预共享密钥配置

[usWest ip] [usVDS ip] : PSK "your_secret_key"

在 usWest 上的/etc/ipsec.secrets创建 secret 文件,填入下述内容:

# /etc/ipsec.secrets - Node A (IP: usVDS) 预共享密钥配置

[usVDS ip] [usWest ip] : PSK "your_secret_key"

放行防火墙,在 usVDS 执行:

# 允许从节点 B (usWest) 到节点 A (usVDS) 的 ESP 协议
ufw allow proto esp from [usWest ip] to [usVDS ip]

# 允许从节点 B (usWest) 到节点 A (usVDS) 的 UDP 500 端口 (IKE 协商)
ufw allow proto udp from [usWest ip] to [usVDS ip] port 500

# 允许从节点 B (usWest) 到节点 A (usVDS) 的 UDP 4500 端口 (NAT-T 保护 IPsec 流量)
ufw allow proto udp from [usWest ip] to [usVDS ip] port 4500

放行防火墙,在 usWest 执行:

# 允许从节点 A (usVDS) 到节点 B (usWest) 的 ESP 协议
sudo ufw allow proto esp from [usVDS ip] to [usWest ip]

# 允许从节点 A (usVDS) 到节点 B (usWest) 的 UDP 500 端口 (IKE 协商)
sudo ufw allow proto udp from [usVDS ip] to [usWest ip] port 500

# 允许从节点 A (usVDS) 到节点 B (usWest) 的 UDP 4500 端口 (NAT-T 保护 IPsec 流量)
sudo ufw allow proto udp from [usVDS ip] to [usWest ip] port 4500

在两个节点使用ipsec start启动 ipsec 服务,并且使用 systemctl status ipsec.serviceipsec verify 查看服务状态是否正常。

image.png

image.png

验证,如下图所示,gre 隧道是通的:

image.png

通过在对端抓包,发现此时已经不是明文传输,ICMP 的包被封装到了 ESP 包中

image.png

同理,再次监控 gre 接口,可以发现已经没有明文数据包了。

image.png

最后修改:2025 年 07 月 27 日
如果觉得我的文章对你有用,请随意赞赏