配置IKEv2服务器

搭建 IKEv2 VPN 服务器

在家中的 NAS 上搭建 IKEv2 VPN 服务器,实现多端远程组网。


1. 安装所需软件

安装 strongswancertbot

1
pacman -S strongswan certbot

2. 域名和证书配置

  1. 设置域名 DDNS
    以域名 vpn.kore.host 为例。

  2. certbot获取证书
    由于StrongSwan默认配置不支持letsencrypt的EC私钥,所以申请证书的命令会稍稍不一样

    1
    sudo certbot certonly --standalone -d vpn.kore.host --key-type rsa --rsa-key-size 4096
  3. 然后将证书做软连接

    1
    2
    3
    4
    cd /etc/ipsec.d/
    ln -s /etc/letsencrypt/live/vpn.kore.host/chain.pem ./certs/ca.cert.pem
    ln -s /etc/letsencrypt/live/vpn.kore.host/cert.pem ./cacerts/server.cert.pem
    ln -s /etc/letsencrypt/live/vpn.kore.host/privkey.pem ./private/server.pem

    live文件夹里的软连接是由certbot管理的,所以配置好了就不需要更改,3个月后certbot renew也不需要重新管理软链接。

—–证书配置的以下内容过期,请按上面的内容配置—–

  1. 设置域名 DDNS
    以域名 vpn.kore.host 为例。

  2. 生成服务器私钥
    进入 /etc/ipsec.d/ 目录,生成 RSA 私钥:

    1
    2
    3
    cd /etc/ipsec.d/
    ipsec pki --gen --type rsa --size 4096 --outform pem > private/private.pem
    chmod 600 private/private.pem
  3. 生成证书请求文件
    使用 OpenSSL 生成证书请求文件:

    1
    openssl req -new -key private/private.pem -out private/self.csr

    需要填写相关信息,如地址、邮箱、子域名等。

  4. 获取 Let’s Encrypt 证书
    使用 Certbot 获取证书:

    1
    certbot certonly --manual --csr private/self.csr

    按照提示完成域名验证。

  5. 整理证书文件
    获取到的证书文件包括 0001_chain.pem,将其重命名为 cert.pem,并按以下结构放置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /etc/ipsec.d
    ├── aacerts
    ├── acerts
    ├── cacerts
    │ └── 0000_chain.pem
    ├── certs
    │ ├── 0000_cert.pem
    │ └── cert.pem
    ├── crls
    ├── ocspcerts
    ├── private
    │ ├── private.pem
    │ └── self.csr
    └── reqs

    至此,服务器私钥和证书配置完成。


3. 配置文件

编辑 /etc/ipsec.conf 文件,配置 IKEv2 连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# /etc/ipsec.conf - StrongSwan IPsec configuration file

config setup
# 全局设置,例如日志级别等
uniqueids = no
charondebug = "ike 1, knl 1, cfg 0, net 0, esp 1" # 精简日志输出

# 默认设置,适用于所有连接,除非在连接配置中覆盖
conn %default
keyexchange = ike # 优先 IKEv2 交换密钥
ike = aes256-sha256-modp4096,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha1-modp2048,3des-sha1-modp2048,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024
esp = aes256-sha256,aes256-sha1,3des-sha1 # ESP 加密算法
compress = yes # 压缩
dpdaction = clear # 断开后清理连接
dpddelay = 60s # 延长 DPD 检查时间,减少握手频率
rekey = no # 禁止自动 rekey,减少握手过程
fragmentation = yes # 支持碎片化,帮助处理大的 IKE 消息
left = %any # 左侧(服务器)的公共 IP 地址
leftid = @vpn.kore.host # 使用服务器域名作为身份 ID
leftcert = server.cert.pem
leftsubnet = 192.168.2.0/24 # 允许客户端访问的局域网子网
leftdns = 119.29.29.29 # 服务器向客户端发送的 DNS 服务器
leftfirewall = yes # 启用服务器端防火墙
leftsendcert = always # 总是发送服务器证书
mobike = yes # 支持客户端的移动性和多主机功能
forceencaps = no # 强制封装所有流量,帮助混淆(默认关闭)

# IKEv2 EAP 连接配置
conn IKEv2-EAP
also = %default # 继承 %default 的默认设置
auto = add # 自动加载
right = %any # 右侧(客户端)的 IP 地址
rightauth = eap-mschapv2 # 右侧使用 EAP MSCHAPv2 进行认证
rightsendcert = never # 客户端不发送证书
rightsourceip = 10.10.0.0/24 # 分配给客户端的 IP 范围
rightikeport = 8484 # 使用非标准端口以减少被识别可能性
eap_identity = %any # 允许客户端使用任意 EAP 身份

# 下面的内容不用管,我也没有配置好
# XAUTH 连接配置
conn IKEv2-XAUTH
also = %default # 继承 %default 的默认设置
#auto = start # 自动加载
right = %any # 右侧(客户端)的 IP 地址
rightauth = xauth # 使用 XAUTH 认证
rightsendcert = never # 客户端不发送证书
rightsourceip = 10.10.0.0/24 # 分配给客户端的 IP 范围
rightikeport = 8484 # 使用非标准端口以减少被识别可能性
forceencaps = no # 在此连接中关闭强制封装

# PSK 连接配置
conn IKEv2-PSK
also = %default # 继承 %default 的默认设置
#auto = start # 自动加载
right = %any # 右侧(客户端)的 IP 地址
rightauth = psk # 使用 PSK 认证
rightsendcert = never # 客户端不发送证书
rightsourceip = 10.10.0.0/24 # 分配给客户端的 IP 范围
rightikeport = 8484 # 使用非标准端口以减少被识别可能性
forceencaps = no # 在此连接中关闭强制封装
fragmentation = no

编辑 /etc/strongswan.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files
charon {
ikedebug = yes
log_level = 2 # 调试级别
load_modular = yes
compress = yes
plugins {
include strongswan.d/charon/*.conf
}
dns1 = 8.8.8.8
dns2 = 8.8.4.4
nbns1 = 8.8.8.8
nbns2 = 8.8.4.4
}
include strongswan.d/*.conf

编辑 /usr/local/etc/ipsec.secrets,填写用户和密码。注意格式严格:

1
2
3
4
5
6
7
8
9
10
11
# ipsec.secrets - strongSwan IPsec secrets file
: RSA server.pem

# EAP 用户
test : EAP "123456789"

# PSK 用户
#%any : PSK "123456789"

# XAUTH 用户
tengx : XAUTH "123456789"

4. 防火墙配置

使用 ufw 配置防火墙规则,以内网192.168.2.0/24,vpn网段10.10.0.0/24为例:

1
2
3
4
sudo ufw allow 500
sudo ufw allow 4500/udp
sudo ufw allow proto esp from any to any
sudo ufw route allow in on eno1 from 10.10.0.0/24 to 192.168.2.0/24

编辑 /etc/ufw/sysctl.conf,取消注释以下行:

1
2
3
net/ipv4/ip_forward=1
net/ipv6/conf/default/forwarding=1
net/ipv6/conf/all/forwarding=1

编辑 /etc/ufw/before.rules,添加以下规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.10.0.0/24 -o eno1 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.0.0/24 -o eno1 -j MASQUERADE
COMMIT

*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.0.0/24 -o eno1 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT

-A ufw-before-forward -s 10.10.0.0/24 -d 192.168.2.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.0.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.0.0/24 -j ACCEPT

重新加载防火墙:

1
ufw reload

确保路由器防火墙也放行相关端口。


5. 启动服务

有两种启动方式(更建议使用第一种方式,已经按上面配置好了):

  1. 通过 strongswan-starter 启动
    编辑 /etc/ipsec.conf 后,使用以下命令启动:

    1
    2
    3
    sudo systemctl start strongswan-starter
    systemctl status strongswan-starter
    journalctl -f -u strongswan-starter
  2. 通过 swanctl 管理(一种新的方式,不过参考材料较少)
    编辑 /etc/swanctl/conf.d/conn.conf,配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    connections {
    ikev2-eap-mschapv2 {
    version = 2
    unique = never
    proposals = aes256-sha256-prfsha256-modp2048, aes256gcm16-prfsha384-modp1024, default
    rekey_time = 0s
    pools = primary-pool-ipv4, primary-pool-ipv6
    fragmentation = yes
    dpd_delay = 30s
    send_cert = always
    local_addrs = %any
    remote_addrs = %any
    local_port = 500
    remote_port = 500
    mobike = yes
    fragmentation = no

    local {
    auth = pubkey
    certs = /etc/ipsec.d/certs/cert.pem
    id = vpn.kore.host
    }
    remote {
    auth = eap-mschapv2
    eap_id = %any
    }
    children {
    ikev2-eap-mschapv2 {
    local_ts = 192.168.2.0/24
    rekey_time = 0s
    dpd_action = clear
    esp_proposals = aes256-sha256, aes128-sha1, default
    }
    }
    }
    }

    pools {
    primary-pool-ipv4 {
    addrs = 10.10.0.0/24
    dns = 8.8.8.8,8.8.4.4
    }
    primary-pool-ipv6 {
    addrs = fec1::0/16
    dns = 2001:4860:4860::8888,2606:4700:4700::1111
    }
    }

    secrets {
    private-www {
    file = /etc/ipsec.d/private/privkey.pem
    }
    eap-test {
    id = test
    secret = "123321"
    }
    }

6. 客户端额外配置(Windows)

上面的配置结论是:vpn分配内网10.10.0.0/24网段,只允许访问192.168.2.0/24网段,外网的权限不开放。这会导致Windows连接上vpn后无法访问互联网。

原因是Windows 不支持自动分流,可以通过更改路由规则来简单实现分流,需手动配置路由规则:

  1. 打开网络控制面板,找到 VPN 连接,右键选择“属性”。

  2. 在“网络”标签中,双击“IPv4 协议”,进入“高级”设置,取消勾选“使用默认网关”。

  3. 使用管理员权限打开命令提示符,输入以下命令查找 VPN 连接的接口编号:

    1
    route print | findstr HomeNAS

    记录最前面的数字(例如 28)。

  4. 添加静态路由规则:

    1
    route add 192.168.2.0/24 0.0.0.0 if 28

    如需永久生效,添加 -p 参数:

    1
    route -p add 192.168.2.0/24 0.0.0.0 if 28
  5. 重新连接 VPN 即可。


7. 排错方式

  1. 查看 StrongSwan 日志

    1
    journalctl -u -f strongswan-starter
  2. 查看防火墙拦截日志

    1
    journalctl -f | grep BLOCK

通过以上步骤,您可以成功搭建并配置 IKEv2 VPN 服务器,实现多端远程组网。