强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

NetworkManager 运维教程 / 第 6 章:VPN 集成

第 6 章:VPN 集成

6.1 VPN 概述

NetworkManager 通过插件系统支持多种 VPN 协议,提供了统一的连接管理体验。

支持的 VPN 类型

VPN 类型插件包名说明
OpenVPNnetwork-manager-openvpn最广泛使用的开源 VPN
WireGuardnetwork-manager-wireguard现代高速 VPN
IPSec/IKEv2network-manager-strongswan / libreswan企业级 VPN
L2TPnetwork-manager-l2tpL2TP over IPSec
PPTPnetwork-manager-pptp旧式 VPN(不推荐)
Cisco AnyConnectnetwork-manager-openconnectCisco VPN 兼容
Fortinetnetwork-manager-fortisslvpnFortiGate VPN

安装 VPN 插件

# Debian / Ubuntu
sudo apt install network-manager-openvpn
sudo apt install network-manager-wireguard
sudo apt install network-manager-strongswan
sudo apt install network-manager-l2tp
sudo apt install network-manager-openconnect

# RHEL / Fedora
sudo dnf install NetworkManager-openvpn
sudo dnf install NetworkManager-wireguard
sudo dnf install NetworkManager-strongswan
sudo dnf install NetworkManager-l2tp
sudo dnf install NetworkManager-openconnect

# Arch Linux
sudo pacman -S networkmanager-openvpn
# WireGuard 内核模块已内置
sudo pacman -S networkmanager-wireguard   # AUR
sudo pacman -S networkmanager-strongswan
sudo pacman -S networkmanager-l2tp
sudo pacman -S networkmanager-openconnect

# 安装后重启 NM
sudo systemctl restart NetworkManager

# 验证插件已加载
nmcli connection add type --help | grep -i vpn

6.2 OpenVPN

从 .ovpn 文件导入

# 最简单的方式:直接导入 .ovpn 配置文件
nmcli connection import type openvpn file /path/to/client.ovpn

# 导入后查看
nmcli connection show "client"

# 重命名导入的连接
nmcli connection modify "client" connection.id "Office-VPN"

# 激活连接
nmcli connection up "Office-VPN"

手动创建 OpenVPN 连接

nmcli connection add \
    type vpn \
    vpn-type openvpn \
    con-name "MyOpenVPN" \
    vpn.data " \
        remote=vpn.example.com, \
        port=1194, \
        proto=tcp, \
        dev-type=tun, \
        ca=/path/to/ca.crt, \
        cert=/path/to/client.crt, \
        key=/path/to/client.key, \
        cipher=AES-256-GCM, \
        auth=SHA256, \
        comp-lzo=adaptive, \
        tunnel-mtu=1500, \
        remote-cert-tls=server" \
    ipv4.method auto \
    ipv4.never-default no \
    ipv6.method ignore

# 如果使用用户名/密码认证
nmcli connection add \
    type vpn \
    vpn-type openvpn \
    con-name "OpenVPN-UserPass" \
    vpn.data " \
        remote=vpn.example.com, \
        port=1194, \
        proto=udp, \
        dev-type=tun, \
        ca=/path/to/ca.crt, \
        auth-user-pass=yes, \
        cipher=AES-256-GCM" \
    vpn.secrets "password=your_vpn_password" \
    ipv4.method auto

OpenVPN 常用参数

参数说明示例
remote服务器地址vpn.example.com
port端口1194
proto协议tcp / udp
dev-type设备类型tun(路由)/ tap(桥接)
caCA 证书路径/etc/openvpn/ca.crt
cert客户端证书/etc/openvpn/client.crt
key客户端私钥/etc/openvpn/client.key
cipher加密算法AES-256-GCM
comp-lzo压缩adaptive / yes / no

split-tunnel vs 全隧道

# 全隧道(所有流量走 VPN)
nmcli connection modify "MyOpenVPN" ipv4.never-default no

# Split tunnel(只有特定网段走 VPN)
nmcli connection modify "MyOpenVPN" \
    ipv4.never-default yes \
    ipv4.routes "10.0.0.0/8" \
    ipv4.route-metric 50

# DNS 通过 VPN 解析
nmcli connection modify "MyOpenVPN" \
    ipv4.dns-priority -50 \
    ipv4.dns "10.0.0.1"

6.3 WireGuard

WireGuard 是新一代 VPN 协议,以简洁、高速、安全著称。

手动创建 WireGuard 连接

# 生成密钥对(如果还没有)
wg genkey | tee privatekey | wg pubkey > publickey

# 查看密钥
cat privatekey
cat publickey

# 创建 WireGuard 连接
nmcli connection add \
    type wireguard \
    con-name "WG-Office" \
    ifname wg0 \
    wireguard.private-key "$(cat privatekey)" \
    ipv4.method manual \
    ipv4.addresses "10.10.0.2/24" \
    ipv4.dns "10.10.0.1" \
    ipv4.routes "192.168.1.0/24" \
    wireguard.peer "publickey_of_server, \
        endpoint=vpn.example.com:51820, \
        allowed-ips=0.0.0.0/0, \
        persistent-keepalive=25"

# 激活
nmcli connection up "WG-Office"

# 查看 WireGuard 状态
wg show wg0
wg show

WireGuard 参数详解

# WireGuard 接口参数
nmcli connection modify "WG-Office" \
    wireguard.private-key-file "/etc/wireguard/private.key" \
    wireguard.listen-port 51820 \
    wireguard.mtu 1420

# WireGuard Peer 参数
# 通过 wireguard.peer 设置
# 格式:
#   <public-key>, endpoint=<host:port>, allowed-ips=<cidr>, persistent-keepalive=<sec>

# 添加多个 Peer
nmcli connection modify "WG-Office" \
    +wireguard.peer "peer2_pubkey, \
        endpoint=vpn2.example.com:51820, \
        allowed-ips=172.16.0.0/16, \
        persistent-keepalive=25"

# 查看 Peer 配置
nmcli connection show "WG-Office" | grep wireguard.peer

WireGuard vs OpenVPN

特性WireGuardOpenVPN
代码行数~4000 行~100,000 行
协议UDP onlyTCP / UDP
加密ChaCha20, Curve25519OpenSSL(灵活)
速度极快中等
连接切换秒级需要重连
NAT 穿透优秀良好
内核支持Linux 5.6+ 内建用户态
配置复杂度简单较复杂
适用场景站点互联、移动 VPN复杂认证需求

完整 WireGuard 站点互联示例

# 站点 A(10.10.0.1)配置
nmcli connection add \
    type wireguard \
    con-name "WG-SiteB" \
    ifname wg0 \
    wireguard.private-key "/etc/wireguard/siteA.key" \
    wireguard.listen-port 51820 \
    ipv4.method manual \
    ipv4.addresses "10.10.0.1/24" \
    wireguard.peer "SITE_B_PUBLIC_KEY, \
        endpoint=siteb.example.com:51820, \
        allowed-ips=192.168.2.0/24, \
        persistent-keepalive=25"

# 站点 B(10.10.0.2)配置
nmcli connection add \
    type wireguard \
    con-name "WG-SiteA" \
    ifname wg0 \
    wireguard.private-key "/etc/wireguard/siteB.key" \
    wireguard.listen-port 51820 \
    ipv4.method manual \
    ipv4.addresses "10.10.0.2/24" \
    wireguard.peer "SITE_A_PUBLIC_KEY, \
        endpoint=sitea.example.com:51820, \
        allowed-ips=192.168.1.0/24, \
        persistent-keepalive=25"

6.4 IPSec / IKEv2

使用 strongSwan

# 安装
sudo apt install network-manager-strongswan charon-systemd

# 创建 IKEv2 连接
nmcli connection add \
    type vpn \
    vpn-type strongswan \
    con-name "IPSec-VPN" \
    vpn.data " \
        address=vpn.example.com, \
        gateway-id=vpn.example.com, \
        certificate=/path/to/client.crt, \
        key=/path/to/client.key, \
        ca-cert=/path/to/ca.crt, \
        usercert=/path/to/client.crt, \
        userkey=/path/to/client.key, \
        ike=aes256-sha2_256-modp2048!, \
        esp=aes256-sha2_256!, \
        ipcomp=no, \
        method=eap-tls, \
        encapsulation=yes" \
    ipv4.method auto \
    ipv4.never-default no

使用 Libreswan(RHEL 默认)

# 安装
sudo dnf install NetworkManager-libreswan

# 创建连接
nmcli connection add \
    type vpn \
    vpn-type libreswan \
    con-name "Libreswan-VPN" \
    vpn.data " \
        left=%defaultroute, \
        leftcert=client.example.com, \
        right=vpn.example.com, \
        rightid=@vpn.example.com, \
        rightsubnet=0.0.0.0/0, \
        ikev2=yes, \
        encapsulation=yes" \
    ipv4.method auto

6.5 L2TP

# 安装
sudo apt install network-manager-l2tp xl2tpd

# 创建 L2TP 连接
nmcli connection add \
    type vpn \
    vpn-type l2tp \
    con-name "Corp-L2TP" \
    vpn.data " \
        gateway=vpn.example.com, \
        user=john.doe, \
        password-flags=0, \
        ipsec-enabled=yes, \
        ipsec-psk=pre-shared-key, \
        ipsec-ike=aes256-sha1-modp1024, \
        ipsec-esp=aes256-sha1" \
    vpn.secrets "password=yourpassword" \
    ipv4.method auto

# 如果需要 MSCHAPv2 认证
nmcli connection modify "Corp-L2TP" \
    vpn.data "+, refuse-pap=yes, refuse-chap=yes, refuse-eap=yes"

6.6 VPN 连接管理

基本操作

# 查看 VPN 连接
nmcli connection show | grep -i vpn

# 激活 VPN
nmcli connection up "MyOpenVPN"

# 激活 VPN 并输入密码
nmcli connection up "MyOpenVPN" --ask

# 断开 VPN
nmcli connection down "MyOpenVPN"

# 查看 VPN 连接详情
nmcli connection show "MyOpenVPN"

# 查看 VPN 状态
nmcli device show tun0    # 或 wg0

VPN 自动连接

# 设置 VPN 开机自动连接
nmcli connection modify "MyOpenVPN" \
    connection.autoconnect yes

# 在特定网络下自动连接 VPN
# 需要使用 dispatcher 脚本(见第 8 章)

# VPN 自动重连
nmcli connection modify "MyOpenVPN" \
    connection.autoconnect-retries 3

# VPN 连接超时
nmcli connection modify "MyOpenVPN" \
    connection.wait-device-timeout 30000

VPN 配置文件管理

# VPN 连接文件存储位置
ls /etc/NetworkManager/system-connections/

# 导出 VPN 配置
nmcli connection export "MyOpenVPN" > /backup/my-vpn.nmconnection

# 导入配置
nmcli connection load /backup/my-vpn.nmconnection
nmcli connection reload

# 查看 VPN 的密钥文件(需要 root)
sudo cat /etc/NetworkManager/system-connections/"MyOpenVPN.nmconnection"

6.7 VPN 路由配置

# 全隧道:所有流量走 VPN
nmcli connection modify "MyVPN" \
    ipv4.never-default no \
    ipv4.dns-priority -50

# Split tunnel:只有内网走 VPN
nmcli connection modify "MyVPN" \
    ipv4.never-default yes \
    +ipv4.routes "10.0.0.0/8" \
    +ipv4.routes "172.16.0.0/12" \
    +ipv4.routes "192.168.0.0/16"

# 排除特定路由
nmcli connection modify "MyVPN" \
    +ipv4.routing-rules "priority 100 from 192.168.1.0/24 table main"

# IPv6 VPN 配置
nmcli connection modify "MyVPN" \
    ipv6.method auto \
    ipv6.ip6-privacy 0

6.8 VPN 故障排查

# 查看 VPN 连接日志
journalctl -u NetworkManager | grep -i vpn

# OpenVPN 详细日志
journalctl -u NetworkManager | grep -i "openvpn\|ovpn"

# WireGuard 状态
wg show

# IPSec 日志
journalctl -u strongswan  # strongSwan
journalctl -u ipsec        # Libreswan

# 测试 VPN 连通性
ping -c 3 10.0.0.1         # VPN 网关
traceroute 10.0.0.1        # 路由跟踪

# 检查 VPN 接口
ip addr show tun0
ip addr show wg0
ip route | grep tun0

# 常见问题排查
# 1. 证书过期
openssl x509 -in client.crt -noout -dates

# 2. DNS 泄露测试
# 连接 VPN 后访问 https://dnsleaktest.com

# 3. MTU 问题
ping -M do -s 1400 vpn.example.com

6.9 本章小结

要点说明
安装插件apt/dnf install network-manager-<vpn-type>
导入配置nmcli connection import type openvpn file <file>
WireGuard现代高速 VPN,推荐新部署使用
OpenVPN成熟稳定,兼容性最好
路由控制ipv4.never-default 控制隧道模式
自动连接connection.autoconnect yes
排障`journalctl -u NetworkManager

扩展阅读