标签 ikev2 下的文章

ikev2 客户端mtu引起的网络故障

网络拓扑:

                  InWall Internet
                          |
                          | 
     ikev2 客户端-------路由器-----openvpn mtu1400-----VPS-------OutWall Internet
                          |
                          |
                     ikev2服务器

故障现象:
ios的ikev2客户端打开境内外网站正常
windows的ikev2客户端境内网站正常,不能打开境外https网站,境外http网站大部分资源加载不全

排查:
windows连接vpn后,使用ipip.net查看出口公网ip,发现已经是ikev2 vpn服务器出口ip,ping 境外ip是通的,telnet检查443端口是通,curl测试发现卡在证书协商
据此基本可以确定是mtu引起的问题,使用命令ping -l 1370 -f 境外网址,不断调整包大小,发现最大mtu是1370

解决办法:
连接vpn后,使用命令
netsh interface ipv4 set subinterface "vpn名称" mtu=1350 store=persistent
修改windows ikev2 虚拟网卡mtu为1350
问题解决

总结:
一开始使用的是ios的ikev2客户端,都没有出现问题,查找资料发现苹果系的ikev2客户端默认mtu是1280,苹果选择这个mtu大小还有一个原因是ipv6的最小包大小是1280
ikev2服务器strongswan应该是可以设置mtu的,后续更新。

附:
strongSwan Android client: MTU 1400
MacOS / iOS built-in IPsec client: MTU 1280
Windows built-in IPsec client: MTU 1400
Cisco VPN client: MTU 1300

相关文章链接:
windows使用ikev2遇到的坑,及批处理batch脚本和powershell脚本
使用ping测试路径里设备的mtu
MTU woes in IPsec tunnels and how you can fix it

ikev2自动更新let's encrypt证书

由于ikev2不能使用通配符证书,使用免费一年期证书存在一定风险(比如阿里云,通过证书可以找到跟域名关联的账号,进而实名查水表),所以推荐使用let's encrypt证书。但是let's encrypt证书有一个问题就是有效期只有三个月,所以写了个脚本自动更新证书。

以下以dns更新证书方式,域名dns服务商为cloudflare为例,服务器需要已经使用ikev2自动安装脚本安装ikev2(可以选择自签名证书),python包管理工具pip,

首先拿到cloudflare的Global API Key,目前certbot还不支持cloudflare的 zone api key

创建脚本使用的cloudflare的账号密码文件,记住路径填写到脚本的CLOUDFLARE_CREDENTIALS后

# Cloudflare API credentials used by Certbot
dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567

并修改密码文件权限为400,防止certbot报错

chmod 0400 #文件路径

自动更新脚本,CERT_DOMAIN是ikev2证书的域名,CLOUDFLARE_CREDENTIALS是cloudflare账号密码文件路径,LE_EMAIL是let's encrypt证书联系邮箱(证书过期提醒)

脚本会检测是否安装certbot,域名证书是否第一次签发,证书是否需要更新,并将新证书复制到ipsec的证书目录

#! /bin/bash
CERT_DOMAIN=vpn.example.com
CLOUDFLARE_CREDENTIALS='/root/letsencrypt/cloudflarednsapi.conf'
LE_EMAIL='example@gmail.com'


function checkcertbot(){
if [ -z "`pip list certbot-dns-cloudflare |grep certbot-dns-cloudflare`" ];
then
pip install certbot-dns-cloudflare
fi
}

function checkcert(){
if [ ! -f "/etc/letsencrypt/live/${CERT_DOMAIN}/cert.pem" ];
then renewipseccert
else
CERT_EXPIRE=$(openssl x509 -checkend 1728000 -noout -in /etc/letsencrypt/live/$CERT_DOMAIN/cert.pem|grep not)
if [ -z "$CERT_EXPIRE" ];
then
renewipseccert
else
echo "The cert will not expire in 20 days,nothing to do."
fi
fi
}


function renewipseccert(){
/usr/local/bin/certbot  certonly -d ${CERT_DOMAIN} \
--agree-tos \
--non-interactive \
--email $LE_EMAIL  \
--dns-cloudflare \
--dns-cloudflare-credentials ${CLOUDFLARE_CREDENTIALS}
cp /etc/letsencrypt/live/$CERT_DOMAIN/chain.pem /usr/local/etc/ipsec.d/cacerts/ca.cert.pem
cp /etc/letsencrypt/live/$CERT_DOMAIN/cert.pem /usr/local/etc/ipsec.d/certs/server.cert.pem
cp /etc/letsencrypt/live/$CERT_DOMAIN/privkey.pem /usr/local/etc/ipsec.d/private/server.pem
/usr/sbin/service ipsec restart
}

checkcertbot
checkcert

在crontab里添加每5天执行一次即可

crontab -e
0 0 */5 * * #脚本路径


google cloud platform(gcp)的一个关于网络的坑

gcp这个网络坑是vm网卡的mtu是1460,一般其他vps或云服务的都是1500。

在gcp上使用更换付费账号的方式重新撸了300刀一年,其实在15/16年就用过一年,当时台湾服务器还没被草烂,联通直连能跑满带宽,后来用的人越来越多,很多ip被墙了,到期之后就没再用。

最近发现gcp新放出来一批ip,识别地址是美国,还没有被各大视频网站(Netflix,hbo,hulu等)加入黑名单,所以又撸了一年,先用着。

之前用gcp只是用ss,没有碰到mtu的问题。这次用gcp做落地机出现了问题。
境内路由器隧道到阿里云香港然后隧道到gcp香港,再出去,由于隧道的原因链路最小mtu是1390,小于gcp网卡1460,所以没有问题。

我的苹果设备需要一个ikev2服务器访问美国服务,按之前的一键脚本一路下来很顺利,却打不开谷歌的各种服务,但是ping正常,telnet正常,刚开始以为是dns问题,一键脚本默认是8.8.8.8,服务器是169.254.169.254的内网ip,修改dns服务器地址之后依然不行。然后想到是不是gcp对nat有什么限制,遍历gcp设置,各种查文档,改配置也是一无所获。

ikev2建立连接后,客户端通过telnet发现是可以建立tcp连接的,然后通过curl -v去请求测试,发现curl -v google.com可以收到301状态码,但是curl -v www.google.com卡在tcp建立连接后接收http报文,curl -v https://www.google.com 卡在tls协商,其实从这基本可以确定是mtu问题了,因为卡住之前都是小包碰不到分片或丢包,到接收http报文或者tls协商都是大包,超过mtu都是要分片或丢包,由于关于mtu的问题很久没有遇到了,一时没想起来。

惆怅迷惑之际拿起了wireshark抓包,curl -v www.google.com后,wireshark出现“tcp previous segment not captured”,终于意识到大包被丢包了,可能是mtu问题。ifconfig发现imac的ipsec0接口mtu是1400,sudo ifconfig ipsec0 mtu 1200 up,问题解决。但是不能每个客户端都修改mtu,ios怎么修改mtu?

查询文档,谷歌建议vm网卡使用1460,说是全球链路中最大1460,先不管了修改vm网卡为1500,vm只作中转不从vm直接上传什么应该问题不大。

gcp关于strongswan的文档根本没有提到mtu问题。

windows使用ikev2遇到的坑,及批处理batch脚本和powershell脚本

2020.7.6更新:添加坑0,mtu问题

给公司测试ikev2 vpn,mac和ios一切正常,但是发现windows手动添加vpn有不少坑,总结一下,并附上批处理脚本(实际调用powershell)
以下在windows10下测试,ikev2服务器使用ubuntu下strongswan,代理所有路由,ikev2服务器安装脚本见之前文章https://www.willnet.net/index.php/archives/100/

坑0,windows的vpn虚拟网卡默认mtu是1400,
现象:如果服务端的mtu小于1400的话,会出现能ping通地址,但是网页不能打开的问题
解决办法:修改vpn虚拟网卡mtu值
连接vpn后,以管理员身份执行以下命令

netsh interface ipv4 set subinterface "vpn名称" mtu=1350  store=persistent

具体详见ikev2 客户端mtu引起的网络故障

坑1:
windows默认不支持DH2048_AES256协商协议
现象:提示策略匹配错误
解决办法:添加注册表项,不需要重启生效

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters里新建类型为DWORD的NegotiateDH2048_AES256 键,值设置为1

0 禁用AES-256-CBC和MODP-2048
1 启用AES-256-CBC和MODP-2048
2 强制使用AES-256-CBC和MODP-2048

坑2:
windows默认不支持Symmetric NAT类型路由器后的ikev2服务器
现象:提示809错误,或者提示路由器不支持nat
解决办法:添加注册表项,并需要重启生效

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent里新建类型为DWORD的AssumeUDPEncapsulationContextOnSendRule 键,值设置为2

0
A value of 0 (zero) configures Windows so that it cannot establish security associations with servers that are located behind NAT devices. This is the default value.
1
A value of 1 configures Windows so that it can establish security associations with servers that are located behind NAT devices.
2
A value of 2 configures Windows so that it can establish security associations when both the server and the Windows Vista-based or Windows Server 2008-based VPN client computer are behind NAT devices.

坑3:
windows手动添加的vpn默认没有开启默认路由
现象:连接成功,但是对外ip没有改变
解决办法:手动添加修改或者使用powershell新建vpn连接,手动路径:控制面板\网络和 Internet\网络连接,vpn网卡,属性,网络,ipv4,属性,高级,勾选在远程网络上使用默认网关

坑4:
windows10默认开启了smart multi-homed name resolution功能
现象:有线网络下连接vpn后不使用vpn的dns
解决办法:修改vpn网卡的跃点数,小于有线网卡即可。脚本自动解决待更新

批处理脚本如下,实际是使用批处理调用powershell命令,由于需要修改注册表,需要管理员权限运行

install.cmd

@echo off&PUSHD %~DP0 &TITLE ikev2 VPN安装/卸载程序
mode con cols=160 lines=50
set TempFile_Name=%SystemRoot%\System32\BatTestUACin_SysRt%Random%.batemp
( echo "BAT Test UAC in Temp" >%TempFile_Name% ) 1>nul 2>nul
if exist %TempFile_Name% (
del %TempFile_Name% 1>nul 2>nul&&goto :address
) else (
echo;请以管理员身份运行,按任意键退出 &&goto :end
)

:address
cls
echo;请输入办公地点:
echo;1:北京
echo;2:成都
echo;3:重庆
set/p choose1=请输入选项并按回车:
echo %choose1%|findstr /i "[123]">nul&&goto :install
goto :address

:install
cls
echo;请选择安装或者卸载VPN(ikev2):
echo;i:安装
echo;u:卸载
echo;q:退出
set/p choose2=请输入选项并按回车:
echo %choose2%|findstr /i "[iuq]">nul&&goto :%choose1%%choose2%
goto :install

:1i
cls
echo;安装北京VPN
echo;===========================
echo;***步骤1:删除同名VPN***
(powershell -Command "& {Remove-VpnConnection -Name "北京办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤2:安装新的VPN***
powershell -Command "& {Add-VpnConnection -Name "北京办公室" -ServerAddress "beijing.example.com" -AuthenticationMethod "Eap" -EncryptionLevel "Maximum" -RememberCredential -TunnelType "Ikev2" -PassThru;}"
echo;成功
echo;
echo;***步骤3:清理注册表***
(powershell -Command "& {Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256"; Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule ";}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤4:添加注册表***
(powershell -Command "& {New-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1 -propertyType dword; New-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2 -propertyType dword;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤5:设置注册表***
powershell -Command "& {Set-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1; Set-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2;}"
echo;成功
echo;
echo;***步骤6:重启电脑***
echo;按任意键重启电脑,或按右上角 X 退出后手动重启电脑
pause>nul
shutdown -r -t 0
goto :end

:1u
cls
echo;卸载北京VPN
echo;===========================
(powershell -Command "& {Remove-VpnConnection -Name "北京办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功,按任意键退出...
goto :end

:2i
cls
echo;安装成都VPN
echo;===========================
echo;***步骤1:删除同名VPN***
(powershell -Command "& {Remove-VpnConnection -Name "成都办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤2:安装新的VPN***
powershell -Command "& {Add-VpnConnection -Name "成都办公室" -ServerAddress "chengdu.example.com" -AuthenticationMethod "Eap" -EncryptionLevel "Maximum" -RememberCredential -TunnelType "Ikev2" -PassThru;}"
echo;成功
echo;
echo;***步骤3:清理注册表***
(powershell -Command "& {Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256"; Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule ";}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤4:添加注册表***
(powershell -Command "& {New-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1 -propertyType dword; New-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2 -propertyType dword;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤5:设置注册表***
powershell -Command "& {Set-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1; Set-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2;}"
echo;成功
echo;
echo;***步骤6:重启电脑***
echo;按任意键重启电脑,或按右上角 X 退出后手动重启电脑
pause>nul
shutdown -r -t 0
goto :end

:2u
cls
echo;卸载成都VPN
echo;===========================
(powershell -Command "& {Remove-VpnConnection -Name "成都办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功,按任意键退出...
goto :end

:3i
cls
echo;安装重庆VPN
echo;===========================
echo;***步骤1:删除同名VPN***
(powershell -Command "& {Remove-VpnConnection -Name "重庆办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤2:安装新的VPN***
powershell -Command "& {Add-VpnConnection -Name "重庆办公室" -ServerAddress "chongqing.example.com" -AuthenticationMethod "Eap" -EncryptionLevel "Maximum" -RememberCredential -TunnelType "Ikev2" -PassThru;}"
echo;成功
echo;
echo;***步骤3:清理注册表***
(powershell -Command "& {Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256"; Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule ";}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤4:添加注册表***
(powershell -Command "& {New-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1 -propertyType dword; New-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2 -propertyType dword;}") 1>nul 2>nul
echo;成功
echo;
echo;***步骤5:设置注册表***
powershell -Command "& {Set-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1; Set-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2;}"
echo;成功
echo;
echo;***步骤6:重启电脑***
echo;按任意键重启电脑,或按右上角 X 退出后手动重启电脑
pause>nul
shutdown -r -t 0
goto :end

:3u
cls
echo;卸载重庆VPN
echo;===========================
(powershell -Command "& {Remove-VpnConnection -Name "重庆办公室" -Force -PassThru;}") 1>nul 2>nul
echo;成功,按任意键退出...
goto :end

:end
pause>nul

powershell脚本,需要以管理员身份运行powershell然后执行install.ps1
install.ps1

Remove-VpnConnection -Name "成都办公室" -Force

Add-VpnConnection -Name "成都办公室" -ServerAddress "chengdu.example.com" -AuthenticationMethod "Eap" -EncryptionLevel "Maximum" -RememberCredential -TunnelType "Ikev2"

Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256"

Remove-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule"

New-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1 -propertyType dword

New-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule" -value 2 -propertyType dword

Set-ItemProperty HKLM:\System\CurrentControlSet\Services\Rasman\Parameters -name "NegotiateDH2048_AES256" -value 1

Set-ItemProperty HKLM:\System\CurrentControlSet\Services\PolicyAgent -name "AssumeUDPEncapsulationContextOnSendRule " -value 2

ikev2配合radius和ldap认证vpn服务器搭建,适合iphone,macos

ikev2的vpn是苹果系统默认推荐的方式,不需要下载客户端,企业用户配合ldap账号管理很方便。
以下方法基于ubuntu16.04系统,使用脚本https://quericy.me/blog/699/

20180823提醒一下,strongswan不支持野卡(通配符域名证书),需要使用具体的域名证书。
参考https://tools.ietf.org/html/rfc6125#section-7.2

20180524添加我改写的一键安装脚本https://github.com/trepwq/ikev2-radius-ldap/raw/master/install-ikev2-radius-ldap.sh
以下为原作者脚本安装步骤

首先申请域名证书,可以用阿里云免费的单域名证书,申请下来后证书里第一部分是域名证书,写入server.cert.pem;第二部分是ca证书,写入ca.cert.pem ,另一个key文件修改为server.pem,把这三个文件放到quericy脚本的相同目录里。
然后按照提示一步一步来,需要注意的是我开启了snat,其他为默认。如果网卡ip地址是内网ip,就输入内网ip,然后在路由器端把500和4500端口的udp转发给这个内网ip就可以了。
脚本安装完之后修改配置文件/usr/local/etc/ipsec.conf, 把里面的rightauth=eap-mschapv2修改为rightauth=eap-radius,然后在/usr/local/etc/strongswan.d/charon/eap-radius.conf 的servers段添加服务器地址和密码

servers {
        server_synology {
                        address = 192.168.1.1
                        secret = secret
                        }
}

我这里使用了群晖的radius-server。
最后重启ipsec restart。ps,ipsec reload对很多修改不起作用。
最最后添加ipsec开机启动

root@ubuntu:~# cat /etc/rc.local 
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

/usr/local/sbin/ipsec start


exit 0

由于使用了域名证书,根证书在苹果系统里是已经存在的,所以不需要导入证书,直接输入用户名密码即可。