StrongSwan 是 Linux 上 IPsec 的开源实现项目。是已停止的 FreeS/WAN 开源项目的一个分支,同属 FreeS/WAN 后代的还包括 OpenSwan 和 LibreSwan 。
首先,对 IPsec 有个简单的了解。IPsec 是一种安全 VPN 协议,用于端到端通信安全,连接多台计算机建立虚拟局域网。IPsec 位于 OSI 模型的第三层网络层,同属这层的是 IP、ICMP 这些协议,TCP 、UDP 是第四层传输层,想要在互联网中传输离不开互联网协议,所以 IPsec 常用 UDP 作为其传输协议,源端口和目标端口为 500。
IPsec 协议套件还包括 AH 身份验证标头协议、ESP 封装安全协议、SA 安全关联协议。IKEv2 是 IPsec 最新的密钥交换协议,用于建立 SA 安全关联。IPsec 包含两种模式,传输模式和隧道模式,传输模式最初旨在保护 IPv6主机到主机直接连接,隧道模式区别在于原始 IP 由 ESP 封装加密,再套上外部 IP 头。
StrongSwan 包含 swanctl.conf 和旧版 ipsec.conf 两种配置方式,文章中使用新版 swanctl 进行配置。
配置选择
根据 StrongSwan 的官方文档,目前 StrongSwan 支持与 Windows内置客户端认证的方式有三种:
- 使用 RSA 签名 X.509 机器证书。
- 使用 EAP-TLS X.509 用户证书。
- 使用 EAP-MSCHAPv2 密码认证。
考虑到可能共享给朋友进行连接,配置密码认证更为方便,所以选择配置 EAP-MSCHAPv2 密码认证。
安装 StrongSwan
环境:Debian 12 。
sudo apt install charon-systemd strongswan-swanctl libcharon-extra-plugins strongswan-pki libstrongswan-extra-plugins libtss2-tcti-tabrmd0
生成自签名证书
RSA 签名的证书兼容性更强,接下来使用 StrongSwan 的 pki 工具生成证书。 生成网关证书的 san 字段需要更改,moon.strongswan.org 是限定的主机名, carol@strongswan.org 的邮箱,10.0.20.100 是 IP,最好把公网和内网 IP 都设置上。
# 生成 ca 密钥
pki --gen --type rsa --size 2048 --outform pem > strongswanKey.pem
# 生成 ca 证书
pki --self --ca --lifetime 3652 --in strongswanKey.pem \
--dn "C=CH, O=strongSwan, CN= My strongSwan Root CA" \
--outform pem > strongswanCert.pem
# 生成网关密钥
pki --gen --type rsa --size 2048 --outform pem > moonKey.pem
# 生成网关证书
pki --req --type priv --in moonKey.pem \
--dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
--san moon.strongswan.org \
--san carol@strongswan.org \
--san 10.0.20.100 \
--outform pem > moonReq.pem
pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
--type pkcs10 \
--in moonReq.pem \
--serial 01 \
--lifetime 1826 \
--flag serverAuth \
--outform pem > moonCert.pem
pki --print --in moonCert.pem
拷贝证书到配置目录。
sudo cp moonKey.pem /etc/swanctl/private/moonKey.pem
sudo cp moonCert.pem /etc/swanctl/x509/moonCert.pem
sudo cp strongswanCert.pem /etc/swanctl/x509ca/strongswanCert.pem
使用 Let’s Encrypt 生成的证书
优点是不用导入 ca 证书。可以参考 Fedora + Alpine 部署 Frp 内网穿透 Cerbot 申请 SSL 证书,证书类型选 rsa 。 复制证书。
sudo cp fullchain.pem /etc/swanctl/x509/moonCert.pem
sudo cp privkey.pem /etc/swanctl/private/moonKey.pem
sudo cp chain.pem /etc/swanctl/x509ca/strongswanCert.pem
配置 swanctl
编辑 /etc/swanctl/swanctl.conf 。
secrets 为连接的用户账号密码,pools 是虚拟 IP 池,local.id 是限定的主机名。
connections {
eap {
proposals = 3des-aes128-aes192-aes256-sha1-sha256-sha384-modp1024,aes256-sha1-sha256-sha384-modp2048
pools = ipv4
send_cert = always
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = eap-mschapv2
eap_id = %any
}
children {
eap {
local_ts = 0.0.0.0/0
}
}
}
}
pools {
ipv4 {
addrs = 10.0.100.0/24
}
}
secrets {
eap {
id = strongswan
secret = strongswan123
}
}
开启 IP 转发。
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.conf
sudo sysctl -p
开启 NAT
如果设置虚拟 IP 还需要开启网卡 NAT,10.0.100.0/24 为虚拟 IP 段,eth0 为网卡接口。
iptables -t nat -A POSTROUTING -s 10.0.100.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.100.0/24 -o eth0 -j MASQUERADE
DHCP
可以使用局域网内的 DHCP 分配 IP,而不是 NAT 的虚拟 IP。
修改 /etc/swanctl/swanctl.conf , pools 改成 dhcp 。
connections {
eap {
pools = dhcp
...
dhcp 配置文件 /etc/strongswan.d/charon/dhcp.conf。
# server = 255.255.255.255
dhcp server 默认是广播地址,可以指定自己局域网内的 dhcp 服务器地址。
开启 systemd 日志
编辑 /etc/strongswan.conf 。
charon-systemd {
journal {
default = 1
ike = 2
knl = 3
}
}
实时观察日志。
sudo journalctl -f -u strongswan
启动 strongswan 服务
sudo systemctl start strongswan
配置 Windows 客户端
传输根 CA 证书 strongswanCert.pem 到 Windows 上,修改后缀为 crt。
双击证书 -> 安装证书 -> 存储位置 本地计算机 -> 将所有证书都放入下列存储 -> 受信任的根证书颁发机构 -> 完成。
设置 -> 网络和 Intelnet -> VPN -> 添加 VPN 连接 -> 填写域名或者 IP -> VPN类型 IKEv2 -> 用户名密码。 最后点击连接即可。
Frp 内网穿透
当 StrongSwan 部署在内网,没有公网 IP 时,可以通过 Frp 内网穿透来访问。
127.0.0.1 为 StrongSwan 所在 IP 。
[[proxies]]
name = "isakmp"
type = "udp"
localIP = "127.0.0.1"
localPort = 500
remotePort = 500
[[proxies]]
name = "ipsec-nat-t"
type = "udp"
localIP = "127.0.0.1"
localPort = 4500
remotePort = 4500