标题描述的需求比较特化, WireGuard 的应用场景非常广泛, 只是给 IPV6-Only 的机器添加 IPV4 网络比较典型.
Cloudflare 的 Warp 和 Tailscale 都是基于 WireGuard 的, 它们也都能做到给机器添加特殊的网络出口访问.
最近 Warp 刚好又故障了, 所以折腾了下手动配置 WireGuard , 实现使用一台双栈服务器为 IPV6-Only 的机器提供 IPV4 网络出口.
本文使用的系统环境
- OS: Debian12 / Bookworm
- WireGuard: v1.0.20210914
- netfilter: iptables v1.8.9 (不用 nft 是因为命令写进配置里太复杂了…)
首先在两台服务器上都安装 WireGuard
bash
apt update && apt install wireguard-tools wireguard
进入配置目录, 为两台服务器创建密钥对
bash
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey
privatekey
是私钥, publickey
是公钥.
编写服务端配置, 新建 wg233.conf
文件, wg233 可以替换为自己想要的接口名称.
ini
[Interface]
Address = 10.39.0.1/24 # 内网IP/CIDR
ListenPort = 39182 # 监听端口
PrivateKey = 服务端的 privatekey 内容
# Hooks, 用于在开启 WireGuard 接口时启用 IP 转发和添加 NAT 规则
PostUp = echo "1" > /proc/sys/net/ipv4/ip_forward
# 如果服务器的公网接口不是 eth0, 请替换为实际的接口名称
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[Peer]
PublicKey = 客户端的 publickey 内容
AllowedIPs = 10.39.0.2/32 # 稍后将要配置的客户端IP
编写客户端配置, 同样的新建一个配置文件, 配置文件名即为接口名 (不需要和服务端一致).
ini
[Interface]
Address = 10.39.0.2/24 # 和服务端的 AllowedIPs 一致
PrivateKey = 客户端的 privatekey 内容
# 客户端的 Hooks, 这里添加了对 Docker 的支持
# 若你更改过 Docker 的默认接口和网段, 请相应修改
PostUp = iptables -A FORWARD -i docker0 -o %i -j ACCEPT
PostUp = iptables -A FORWARD -i %i -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o %i -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 172.17.0.0/16 -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostDown = iptables -D FORWARD -i docker0 -o %i -j ACCEPT
[Peer]
PublicKey = 服务端的 publickey 内容
Endpoint = [服务端公网ipv6]:39182
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25 # keepalive 间隔, 单位秒
启动两个 WireGuard 服务:
bash
systemctl enable --now wg-quick@wg233
输入 wg
命令查看状态, 预期输出:
bash
interface: wg233
public key: QdUOWJE...Nnm8=
private key: (hidden)
listening port: 55670
fwmark: 0xca6c
peer: TcO+...vanU=
endpoint: [ip]:39182
allowed ips: 0.0.0.0/0
latest handshake: 44 seconds ago
transfer: 34.35 MiB received, 3.72 MiB sent
persistent keepalive: every 25 seconds
Some tips:
已经删除了的 WireGuard 配置还在 systemd 里?
使用下面的命令清理:
bashsystemctl reset-failed
WireGuard 附带安装的 openresolv 修改了原来的 DNS 配置?
openresolv 的配置在
/etc/resolvconf.conf
.将 name_servers 部分设为你想要使用的 DNS 服务器, 用空格分隔多个:
ini# Configuration for resolvconf(8) # See resolvconf.conf(5) for details resolv_conf=/etc/resolv.conf # If you run a local name server, you should uncomment the below line and # configure your subscribers configuration files below. #name_servers=127.0.0.1 name_servers="2606:4700:4700::1111 2001:4860:4860::8888 2001:4860:4860::8844" # Mirror the Debian package defaults for the below resolvers # so that resolvconf integrates seemlessly. dnsmasq_resolv=/var/run/dnsmasq/resolv.conf pdnsd_conf=/etc/pdnsd.conf unbound_conf=/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf
关于 IP/CIDR 的计算:
Q.E.D.