🔒 VPN — 虚拟专用网络与WireGuard

加密隧道的原理与实战:从OpenVPN到WireGuard

📖 VPN技术概览

VPN(Virtual Private Network)通过加密隧道在公共网络上建立安全连接。它是远程办公、站点互联和隐私保护的核心技术。

VPN工作原理 ┌──────────┐ 加密隧道 ┌──────────┐ │ 客户端 │════════════════│ VPN服务器 │ │ 10.0.0.2 │ (互联网) │ 10.0.0.1 │ └──────────┘ └─────┬────┘ ↑ │ │ 加密封装 │ 解密转发 │ ↓ 原始数据包 ┌──────────┐ [HTTP请求] │ 内网资源 │ → 加密 → 封装 │ 192.168.x │ → 公网传输 └──────────┘ → 解封 → 解密 VPN数据包封装: [公网IP头][UDP头][WireGuard头][加密的原始数据包]

📊 VPN协议对比

协议加密速度配置推荐
WireGuardChaCha20-Poly1305🟢 极快🟢 简单✅ 首选
OpenVPNAES-256-GCM🟡 中等🔴 复杂⚠️ 兼容
IPSec/IKEv2AES-CBC/CTR🟢 快🔴 复杂⚠️ 企业
PPTPMPPE-128🟢 快🟢 简单❌ 已破
L2TP/IPSecAES-256🟡 中等🟡 中等⚠️ 备选
SSTPTLS 1.2+🟡 中等🟡 中等⚠️ Windows

⚡ WireGuard实战

WireGuard是现代VPN协议的代表——代码仅4000行(OpenVPN约10万行),速度快、安全、配置简单。

# 安装WireGuard
apt install wireguard       # Debian/Ubuntu
yum install wireguard-tools # CentOS/RHEL

# 生成密钥对
wg genkey | tee /tmp/privatekey | wg pubkey > /tmp/publickey
cat /tmp/privatekey
# yNzD0+mQsh18BX21ktJWRGVGVXUTpKT+nQ9F+gUER0k=
cat /tmp/publickey
# 派生自私钥的公钥

# === 服务器端配置 ===

# 生成服务器密钥
wg genkey | tee /etc/wireguard/server_private | wg pubkey > /etc/wireguard/server_public

# /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <服务器私钥>
Address = 10.0.0.1/24           # VPN网关地址
ListenPort = 51820               # 监听端口
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# 客户端1
[Peer]
PublicKey = <客户端1公钥>
AllowedIPs = 10.0.0.2/32        # 分配给客户端1的IP

# 客户端2
[Peer]
PublicKey = <客户端2公钥>
AllowedIPs = 10.0.0.3/32

# === 客户端配置 ===

# /etc/wireguard/wg0.conf (客户端)
[Interface]
PrivateKey = <客户端私钥>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <服务器公钥>
Endpoint = server.example.com:51820
AllowedIPs = 0.0.0.0/0           # 所有流量通过VPN
# AllowedIPs = 10.0.0.0/24       # 仅内网流量通过VPN(分流)
PersistentKeepalive = 25          # 保持NAT映射

启动与管理

# 启动WireGuard
wg-quick up wg0

# 停止WireGuard
wg-quick down wg0

# 查看连接状态
wg show
# interface: wg0
#   public key: xxx
#   private key: (hidden)
#   listening port: 51820
#
# peer: yyy
#   endpoint: 203.0.113.50:51900
#   allowed ips: 10.0.0.2/32
#   latest handshake: 30 seconds ago
#   transfer: 1.50 MiB received, 2.10 MiB sent

# 开机自启
systemctl enable wg-quick@wg0

# 动态添加Peer(无需重启)
wg set wg0 peer <新客户端公钥> allowed-ips 10.0.0.4/32

# 查看特定接口统计
wg show wg0 transfer

🏗️ WireGuard站点互联

# 场景: 两个内网通过WireGuard互联
# 站点A: 192.168.1.0/24  ←→  站点B: 192.168.2.0/24

# === 站点A配置 (10.0.0.1) ===
[Interface]
PrivateKey = <A私钥>
Address = 10.0.0.1/24
ListenPort = 51820

[Peer]
PublicKey = <B公钥>
Endpoint = site-b.example.com:51820
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24   # 允许访问B的内网
PersistentKeepalive = 25

# === 站点B配置 (10.0.0.2) ===
[Interface]
PrivateKey = <B私钥>
Address = 10.0.0.2/24
ListenPort = 51820

[Peer]
PublicKey = <A公钥>
Endpoint = site-a.example.com:51820
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24   # 允许访问A的内网
PersistentKeepalive = 25

# 添加路由(如果PostUp没有自动添加)
# 站点A:
ip route add 192.168.2.0/24 via 10.0.0.2
# 站点B:
ip route add 192.168.1.0/24 via 10.0.0.1

🔐 OpenVPN配置

# OpenVPN虽然复杂,但在企业环境中仍然广泛使用

# 安装OpenVPN
apt install openvpn easy-rsa

# 初始化PKI
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
./easyrsa init-pki
./easyrsa build-ca

# 生成服务器证书
./easyrsa gen-req server nopass
./easyrsa sign-req server server

# 生成Diffie-Hellman参数
./easyrsa gen-dh

# 生成客户端证书
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

# 服务器配置 /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
tls-version-min 1.3
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log

# 启动OpenVPN
systemctl start openvpn-server@server
systemctl enable openvpn-server@server

🔍 VPN安全审计

# WireGuard安全检查
# 1. 检查密钥长度
wg show wg0 | grep "public key"

# 2. 检查监听端口
ss -ulnp | grep 51820

# 3. 检查路由
ip route show | grep wg0

# 4. 检查内核模块
lsmod | grep wireguard

# 5. 检查配置文件权限
ls -la /etc/wireguard/
# 必须是600: -rw------- 1 root root

# VPN泄漏测试
# 连接VPN后检查:
# 1. IP地址是否改变
curl -s https://ifconfig.me

# 2. DNS是否泄漏
# 访问 https://dnsleaktest.com/
dig +short myip.opendns.com @resolver1.opendns.com

# 3. WebRTC泄漏(浏览器)
# 访问 https://browserleaks.com/webrtc

# 流量分析检测
# 检查MTU设置(避免分片)
ip link show wg0
# mtu 1420 是WireGuard默认值

VPN安全最佳实践

# 1. 使用现代协议(WireGuard > OpenVPN > IPSec)
# 2. 密钥管理: 定期轮换预共享密钥
# 3. 最小权限: AllowedIPs只允许必要的网段
# 4. 监控: 记录连接日志和流量统计
# 5. 防火墙: VPN接口也要配置防火墙规则
# 6. DNS: 使用可信DNS服务器,防止DNS泄漏
# 7. 杀开关(Kill Switch): VPN断开时阻止所有流量

# WireGuard Kill Switch配置
[Interface]
PrivateKey = <私钥>
Address = 10.0.0.2/24
DNS = 1.1.1.1

# Kill Switch: 只允许通过VPN发流量
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PostDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

[Peer]
PublicKey = <服务器公钥>
Endpoint = server:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
VPN — 你已掌握WireGuard隧道建立、密钥交换、站点互联、OpenVPN配置和VPN安全审计!
命令已验证:wg genkey/wg pubkey/wg-quick/wg show — 所有命令在Docker沙箱(--cap-add=NET_ADMIN)验证通过
课后思考题:
  1. WireGuard为什么比OpenVPN更快?从加密算法和协议设计角度分析。
  2. VPN的Kill Switch功能为什么重要?没有它会有什么风险?
  3. AllowedIPs = 0.0.0.0/0 和 AllowedIPs = 10.0.0.0/24 的区别是什么?各自适用什么场景?
  4. 如何检测VPN是否存在DNS泄漏?DNS泄漏会导致什么后果?

📚 进阶资源

参考资料:WireGuard Whitepaper | RFC 7748 (Curve25519) | RFC 7539 (ChaCha20-Poly1305) | OpenVPN Documentation