Ubuntu安装和配置strongSwan

2015.04.09/2015.08.17发布于笔记暂无评论/目录

记录在Ubuntu 14.04上安装和配置strongSwan的过程。

装完之后才发现只能在墙内翻腾,一番调查后发现客户端的IKE_AUTH包根本无法到达墙外的服务端,改端口也没用。不过好歹也折腾了一番,姑且记下来。

编译安装strongSwan

Ubuntu 14.04仓库里的strongSwan是5.1.2版本的,稍微有点老,这里从官方网站下载最新的5.3.0版本。

cd /tmp
wget http://download.strongswan.org/strongswan-5.3.0.tar.bz2
tar xvf strongswan-5.3.0.tar.bz2
cd strongswan-5.3.0

在编译strongSwan之前先安装一下依赖库:

sudo apt-get install libpam0g-dev libssl-dev build-essential

参考网上的一篇教程,使用如下参数编译strongSwan。另外,如果你的VPS是OpenVZ服务器[1],据说还应该再加上一个--enable-kernel-libipsec参数。

./configure  --enable-eap-identity --enable-eap-md5 \
--enable-eap-mschapv2 --enable-eap-tls --enable-eap-ttls --enable-eap-peap  \
--enable-eap-tnc --enable-eap-dynamic --enable-eap-radius --enable-xauth-eap  \
--enable-xauth-pam  --enable-dhcp  --enable-openssl  --enable-addrblock --enable-unity  \
--enable-certexpire --enable-radattr --enable-openssl --disable-gmp

最后编译并安装

make
sudo make install

如果在configure的时候没有配置--prefix参数,那么strongSwan默认被安装到/usr/local目录下,配置文件安装在/usr/local/etc目录下。

创建密钥和证书

这里可参考这篇文章和官方wiki上的一篇教程

为方便,下面的命令不再加sudo,可以直接su。

自签署根证书

首先创建一个根证书的RSA密钥:

cd /usr/local/etc/ipsec.d

ipsec pki --gen --type rsa \
--size 4096 --outform pem \
> private/strongSwanCAKey.pem

然后使用这个密钥自签署一个根证书(公钥):

ipsec pki --self --ca --lifetime 3650 \
--in private/strongSwanCAKey.pem --type rsa \
--dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
--outform pem > cacerts/strongSwanCACert.pem

服务端密钥和证书

接下来,创建服务端使用的密钥和证书,记得--dn--san参数的myvpn.domain改成自己VPS的域名或IP[2][3]

ipsec pki --gen --type rsa --size 2048 \
--outform pem > private/strongSwanServerKey.pem

ipsec pki --pub --in private/strongSwanServerKey.pem --type rsa | \
ipsec pki --issue --lifetime 730 \
--cacert cacerts/strongSwanCACert.pem \
--cakey private/strongSwanCAKey.pem \
--dn "C=CH, O=strongSwan, CN=myvpn.domain" \
--san myvpn.domain \
--flag serverAuth --flag ikeIntermediate \
--outform pem > certs/strongSwanServerCert.pem

客户端密钥和证书

然后生成客户端的密钥和证书,生成证书时记得--dn--san参数的邮件地址aabb@myvpn.domain改成自己的。

ipsec pki --gen --type rsa --size 2048 \
--outform pem > private/clientAABBKey.pem

ipsec pki --pub --in private/clientAABBKey.pem --type rsa | \
ipsec pki --issue --lifetime 730 \
--cacert cacerts/strongSwanCACert.pem \
--cakey private/strongSwanCAKey.pem \
--dn "C=CH, O=strongSwan, CN=aabb@myvpn.domain" \
--san aabb@myvpn.domain \
--outform pem > certs/clientAABBCert.pem

为了方便在Win7和IOS客户端上使用,我们把根证书和客户端的密钥+证书打包成一个PKCS #12文件。这一步会提示输入密码,也可以留空。

openssl pkcs12 -export -inkey private/clientAABBKey.pem \
-in certs/clientAABBCert.pem -name "AABB's Client Certificate" \
-certfile cacerts/strongSwanCACert.pem \
-caname "strongSwan Root CA" \
-out private/clientAABB.p12

设置密钥和证书权限

记得设置一下证书目录和文件的权限:

chmod 700 cacerts certs private crls
chmod 600 cacerts/* certs/* private/*

最后,罗列一下刚刚创建的密钥和证书:

cacerts/:
    strongSwanCACert.pem        --  * 根证书,用于签署服务端和客户端的证书

certs/:
    clientAABBCert.pem          --  * 客户端aabb的证书
    strongSwanServerCert.pem    --  服务端的证书

private/:
    strongSwanCAKey.pem         --  根证书的密钥
    clientAABBKey.pem           --  * 客户端aabb的密钥
    clientAABB.p12              --  * 根证书+客户端密钥+客户端证书
    strongSwanServerKey.pem     --  服务端的密钥

上面加(*)号的都是需要下载到客户端安装的文件。

吊销客户端证书

有时候可能想吊销AABB客户端的证书,可以使用如下命令:

ipsec pki --signcrl --reason key-compromise \
--cacert cacerts/strongSwanCACert.pem \
--cakey private/strongSwanCAKey.pem \
--cert certs/clientAABBCert.pem \
--outform pem > crls/crl.pem

如果还想吊销一个客户端证书,参考这篇教程,需要先将老的crl.pem文件保存到一个临时文件里:

cp crls/crl.pem crl.pem.tmp

ipsec pki --signcrl --reason key-compromise \
--cacert cacerts/strongSwanCACert.pem \
--cakey private/strongSwanCAKey.pem \
--cert certs/StolenClientCert.pem \
--lastcrl crl.pem.tmp \
--outform pem > crls/crl.pem

rm crl.pem.tmp

配置strongSwan

ipsec.conf

ipsec.conf的详细参数说明可参考官方的wiki

sudo cat > /usr/local/etc/ipsec.conf << EOF 
config setup
    uniqueids=never 

conn ubuntu-networkmanager-strongswan
    keyexchange=ikev2
    left=%defaultroute
    leftauth=pubkey
    leftsubnet=0.0.0.0/0
    leftcert=strongSwanServerCert.pem
    right=%any
    rightauth=pubkey
    rightsourceip=10.31.2.0/24
    rightcert=clientAABBCert.pem
    auto=add
EOF

注意rightsourceip这里配置的ip段,稍后要添加iptables规则。

ipsec.secrets

这里保存服务器证书的密钥和登录密码等内容,如果密钥有密码,也要在后面加上,详细说明见官方文档

sudo cat > /usr/local/etc/ipsec.secrets << EOF
: RSA strongSwanServerKey.pem
: PSK "A quick bRown FOX jumps"
: XAUTH "0ver a Lazy 0ld Dog"
aabb %any : EAP "BBAA"
EOF

strongswan.conf

配置strongswan,官方文档见这里

sudo cat > /usr/local/etc/strongswan.conf << EOF
charon {
    load_modular = yes
    duplicheck.enable = no
    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
EOF

charon-logging.conf

strongswan的默认配置会把日志写到系统日志里,可以参考官方文档将日志写入一个单独的文件。

sudo cat > /usr/local/etc/strongswan.d/charon-logging.conf << EOF
charon {
    filelog {
        /var/log/strongswan.log {
            append = yes
            default = 1
            flush_line = yes
            ike_name = yes
            time_format = %b %e %T
        }
    }
}
EOF

系统配置

ip转发

修改/etc/sysctl.conf,启用ip转发,取消注释。

net.ipv4.ip_forward = 1

然后导入配置

sudo sysctl -p

iptables配置

先备份下当前的配置:

sudo iptables-store > ~/iptables.rules

用下面的命令确认下网络接口,如果不是eth0,注意替换成实际的接口。

ip route show | grep '^default' | sed -e 's/.* dev \([^ ]*\).*/\1/'

添加如下规则:

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.31.2.0/24  -j ACCEPT
iptables -A INPUT -i eth0 -p esp -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 500 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 500 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 10.31.2.0/24 -o eth0 -j MASQUERADE

# 解决有的网站无法访问的问题
iptables -t mangle -A FORWARD -o eth0 -p tcp -m tcp \
--tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 \
-j TCPMSS --set-mss 1360

启动strongSwan服务

启动和停止服务

sudo ipsec start
sudo ipsec stop

也可以下载一个init脚本:

sudo wget -O /etc/init.d/strongswan \
https://raw.githubusercontent.com/strongswan/strongswan/master/packages/strongswan/debian/strongswan-starter.ipsec.init

# 改一下ipsec的路径并添加执行权限
sudo sed -i 's|DAEMON=/usr/sbin|DAEMON=/usr/local/sbin|' /etc/init.d/strongswan
sudo chmod +x /etc/init.d/strongswan

以后就可以用service命令启动了

sudo service strongswan start
sudo service strongswan stop
sudo service strongswan restart

客户端配置

以Ubuntu 14.04为例,安装以下软件包:

sudo apt-get install network-manager-strongswan

然后会自动安装相应的依赖包。注意strongswan和openswan不兼容,如果之前安装过openswan则会自动被卸载,相应的,l2tp vpn也会无法再使用。

可参考官方的NetworkManager配置说明

常见问题

Necessary secrets not provided

使用ubuntu的NetworkManager创建的strongSwan vpn连接(pubkey)报错:

Necessary secrets for the VPN connection were not provided.

问题应该是NetworkManager没法从gnome-keyring获取密钥的密码引起的,安装完network-manager-strongswan包后重启下客户端操作系统(或者直接重启gnome-keyring-daemon服务)。

有的网站无法访问

问题表现为有的网站能正常访问,而有的网站死活刷不出来,在服务器端使用tcpdump可以捕获到如下错误:

 ICMP xxx.xxx.xxx.xxx unreachable - need to frag (mtu 1422), length 556

应该就是所谓的mtu问题

解决方法参考上面的文章,添加一条iptables规则:

iptables -t mangle -A FORWARD -o eth0 -p tcp -m tcp \
--tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 \
-j TCPMSS --set-mss 1360

注意,接口-o eth0一定要设置对,俺就在这里被坑了很久。

无法访问外部网站或IP

首先考虑配置(证书)是否正确,从命令行启动,看是否有什么异常输出。

sudo ipsec start
# conn1 是/usr/local/etc/ipsec.conf里conn的名字
sudo ipsec up conn1

其次,检查服务端的iptables是否正确配置,特别是接口是否配置正确,比如eth1写成了eth0。

参考资料


  1. 可以安装virt-what包来查看VPS使用的虚拟化技术。

  2. strongSwan Wiki#Requirements for certificates used with Windows 7. 2015.04.08

  3. strongSwan Wiki#Certificate requirements for iOS interoperability. 2015.04.08

#strongSwan#vpn

评论