为Windows Phone架设IKEv2 VPN服务器

0 IKEv2 VPN的用途

企业级VPN的用途在以前搭建OpenVPN服务器的时候介绍过一些。

最近更新的Windows Phone 8.1支持了企业级VPN,系统自带支持的VPN类型是IKEv2。为了能在Windows Phone上使用VPN,就要架设一台IKEv2 VPN服务器。

1 设备概况

1.1 服务器

运行的系统是openSUSE 13.1 x86_64。拥有公网IP,通过LAN直通因特网,同时可以被校园局域网里的IP访问。

test:~ # uname -nrvm
test.miffyliye.org 3.11.6-4-default x86_64
test:~ # ipsec version
Linux strongSwan U5.1.1/K3.11.6-4-default
Institute for Internet Technologies and Applications
University of Applied Sciences Rapperswil, Switzerland
See 'ipsec --copyright' for copyright information.
test:~ #

同时也测试了运行着openSUSE 12.3 x86_64的虚拟机,网卡桥接。

intron:~ # uname -nrvm
intron.miffyliye.org 3.7.10-1.28-default x86_64
intron:~ # ipsec version
Linux strongSwan U5.0.1/K3.7.10-1.28-default
Institute for Internet Technologies and Applications
University of Applied Sciences Rapperswil, Switzerland
See 'ipsec --copyright' for copyright information.
intron:~ #

1.2 客户端

运行着Windows Phone 8.1系统的手机,通过WLAN接入校园局域网。

2 安装配置

IKEv2 VPN支持服务端/客户端双向认证,本实验中采用证书验证服务端,用密码验证客户端。

2.1 证书

继承部署OpenVPN的时候创建的那一套公钥体系,签发服务器证书,证书的Common Name需要和服务器的域名或IP一致,例如test.miffyliye.org。

客户端使用密码认证,只需导入CA证书,用于验证服务器身份。

2.1服务器

安装strongSwan。
su -;
zypper install strongswan-ipsec;

部署证书。
su -;
cp ca.crt /etc/ipsec.d/cacerts/ca.crt.pem;
cp test.miffyliye.org.crt /etc/ipsec.d/certs/test.miffyliye.org.crt.pem;
cp test.miffyliye.org.key /etc/ipsec.d/private/test.miffyliye.org.key.pem;

修改配置文件。
编辑/etc/ipsec.conf,注意替换test.miffyliye.org

# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
    # strictcrlpolicy=yes
    # uniqueids = no

# Add connections here.

conn windows-eap-mschapv2
    keyexchange=ikev2
    ike=aes256-sha1-modp1024!
    esp=aes256-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no
    leftfirewall=yes
    left=%any
    leftsubnet=0.0.0.0/0
    leftauth=pubkey
    leftcert=test.miffyliye.org.crt.pem
    leftid=@test.miffyliye.org
    right=%any
    rightsourceip=10.8.1.0/24
    rightauth=eap-mschapv2
    rightsendcert=never
    eap_identity=%any
    auto=add

编辑/etc/strongswan.conf,注意替换[IP of ns1.miffyliye.org]

# strongswan.conf - strongSwan configuration file

charon {

    # number of worker threads in charon
    threads = 16

    dns1 = [IP of ns1.miffyliye.org]
    dns2 = [IP of ns2.miffyliye.org]

    nbns1 = [IP of ns1.miffyliye.org]
    nbns2 = [IP of ns2.miffyliye.org]

    # send strongswan vendor ID?
    # send_vendor_id = yes

    plugins {

        sql {
            # loglevel to log into sql database
            loglevel = -1

            # URI to the database
            # database = sqlite:///path/to/file.db
            # database = mysql://user:password@localhost/database
        }
    }

    # ...
}

pluto {

}

libstrongswan {

    #  set to no, the DH exponent size is optimized
    #  dh_exponent_ansi_x9_42 = no
}

编辑/etc/ipsec.secrets,注意替换test.miffyliye.orgMiffyLiye

#
# ipsec.secrets
#
# This file holds the RSA private keys or the PSK preshared secrets for
# the IKE/IPsec authentication. See the ipsec.secrets(5) manual page.
#
 : RSA test.miffyliye.org.key.pem
MiffyLiye-Yoga : EAP "PWD1"
*\MiffyLiye-Lumia : EAP "PWD2"

让IKEv2 VPN开机自动运行。
su -;
systemctl enable strongswan.service;

立即启动IKEv2 VPN。
su -;
systemctl start strongswan.service;

2.1.1 防火墙

需要打开IKEv2 VPN需要的通讯端口,并开启NAT。

如果使用SUSE Firewall,可以通过编辑/etc/sysconfig/SuSEfirewall2来修改防火墙规则。
su -;
sed -i '/^FW_ROUTE=\"/s/no/yes/g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_MASQUERADE=\"/s/no/yes/g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_UDP=\"/s/=\"/=\"500\ /g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_UDP=\"/s/\ \"/\"/g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_UDP=\"/s/=\"/=\"4500\ /g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_UDP=\"/s/\ \"/\"/g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_MASQ_NETS=\"/s/=\"/=\"10.8.1.0\/24\ /g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_MASQ_NETS=\"/s/\ \"/\"/g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_IP=\"/s/=\"/=\"esp ah\ /g' /etc/sysconfig/SuSEfirewall2;
sed -i '/^FW_SERVICES_EXT_IP=\"/s/\ \"/\"/g' /etc/sysconfig/SuSEfirewall2;

规则重启防火墙后生效。
su -;
SuSEfirewall2 stop;
SuSEfirewall2 start;

如果关闭了SUSE Firewall,使用iptables,可以添加iptables规则。
su -;
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT;
iptables -A FORWARD -s 10.8.1.0/24 -j ACCEPT;
iptables -t nat -A POSTROUTING -s 10.8.1.0/24 -o eth0 -j MASQUERADE;

2.2 客户端

把之前的CA证书ca.crt重命名为ca.crt.pem,通过OneDrive导入Windows Phone。通过Settings/VPN添加VPN Profile,选Connect using username+password,用户名填MiffyLiye-Lumia,密码是PWD2。

3 结果

在Windows Phone 8.1上连接成功。访问http://special.miffyliye.org/ip/发现显示的是IKEv2 VPN服务器的IP。

4 参考资料

在Windows 7上架设OpenVPN服务器

使用 Strongswan 架设 Ipsec VPN

strongSwan EAP Configuration for Multiple Windows 7 Clients

12 thoughts on “为Windows Phone架设IKEv2 VPN服务器

  1. waleed

    am using it and configured the strongswan

    but still unable to connect

    this is my logs:

    Jun 7 12:02:11 04[NET] received packet: from 92.98.3.184[500] to 10.185.99.156[500] (616 bytes)
    Jun 7 12:02:11 04[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) V V V V ]
    Jun 7 12:02:11 04[ENC] received unknown vendor ID: 1e:2b:51:69:05:99:1c:7d:7c:96:fc:bf:b5:87:e4:61:00:00:00:09
    Jun 7 12:02:11 04[ENC] received unknown vendor ID: fb:1d:e3:cd:f3:41:b7:ea:16:b7:e5:be:08:55:f1:20
    Jun 7 12:02:11 04[ENC] received unknown vendor ID: 26:24:4d:38:ed:db:61:b3:17:2a:36:e3:d0:cf:b8:19
    Jun 7 12:02:11 04[ENC] received unknown vendor ID: 01:52:8b:bb:c0:06:96:12:18:49:ab:9a:1c:5b:2a:51:00:00:00:02
    Jun 7 12:02:11 04[IKE] 92.98.3.184 is initiating an IKE_SA
    Jun 7 12:02:11 04[IKE] local host is behind NAT, sending keep alives
    Jun 7 12:02:11 04[IKE] remote host is behind NAT
    Jun 7 12:02:11 04[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(MULT_AUTH) ]
    Jun 7 12:02:11 04[NET] sending packet: from 10.185.99.156[500] to 92.98.3.184[500] (308 bytes)
    Jun 7 12:02:12 16[NET] received packet: from 92.98.3.184[4500] to 10.185.99.156[4500] (748 bytes)
    Jun 7 12:02:12 16[ENC] parsed IKE_AUTH request 1 [ IDi CERTREQ N(MOBIKE_SUP) CP(ADDR DNS NBNS SRV ADDR6 DNS6 SRV6) SA TSi TSr ]
    Jun 7 12:02:12 16[IKE] received 21 cert requests for an unknown ca
    Jun 7 12:02:12 16[CFG] looking for peer configs matching 10.185.99.156[%any]…92.98.3.184[192.168.1.115]
    Jun 7 12:02:12 16[CFG] selected peer config ‘wp’
    Jun 7 12:02:12 16[IKE] initiating EAP_IDENTITY method (id 0x00)
    Jun 7 12:02:12 16[IKE] peer supports MOBIKE
    Jun 7 12:02:12 16[IKE] no private key found for ‘54.87.230.120’
    Jun 7 12:02:12 16[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
    Jun 7 12:02:12 16[NET] sending packet: from 10.185.99.156[4500] to 92.98.3.184[4500] (68 bytes)

    Reply
    1. MiffyLiye Post author

      Jun 7 12:02:12 16[IKE] no private key found for ’54.87.230.120′
      Jun 7 12:02:12 16[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]

      It seems that the authentication is the problem.

      Reply
  2. ManatsuHotaru

    你好,我自己拿vps捣鼓了一下,发现我的wp8.1连不上,以下是log,请问能否劳驾看一下?错误貌似出在虚拟ip分配上
    …….
    08[IKE] authentication of ‘192.168.1.108’ with EAP successful
    08[IKE] authentication of ‘C=CN, O=strongSwan, CN=192.243.117.151’ (myself) with EAP
    08[IKE] IKE_SA windowsphone[4] established between 192.243.117.151[C=CN, O=strongSwan, CN=192.243.117.151]…101.80.245.165[192.168.1.108]
    08[IKE] peer requested virtual IP %any
    08[CFG] reassigning offline lease to ‘Windows Phone\lwb1993’
    08[IKE] assigning virtual IP 10.24.78.1 to peer ‘Windows Phone\lwb1993’
    08[IKE] peer requested virtual IP %any6
    08[IKE] no virtual IP found for %any6 requested by ‘Windows Phone\lwb1993’ <====没搞懂为什么会没有分配,iptable设置过转发了
    08[KNL] allocating SPI failed: Invalid argument (22)
    08[KNL] unable to get SPI for reqid {4}
    08[IKE] allocating SPI failed
    08[IKE] failed to establish CHILD_SA, keeping IKE_SA
    ……..

    Reply
    1. MiffyLiye Post author

      IPv6的分配在IPv4环境下没什么影响,把ipsec.conf里相应的地方改成类似
      leftsubnet=0.0.0.0/0,::/0

      rightsourceip=10.8.1.0/24,fec3::/120
      就能分配IPv6地址了。
      关键的错误应该是08[KNL] allocating SPI failed: Invalid argument (22)
      可能是64位系统上安装了32位的软件。https://wiki.strongswan.org/issues/352

      Reply
      1. ManatsuHotaru

        你好!感谢你的提示,我已经解决了登陆的问题,但是登陆之后我发现通过vps无法访问外部网络,情况就是除了vps的ip以外其他的ip全都不能访问,请问这可能是什么原因造成的?

        Reply
  3. ManatsuHotaru

    我iptables -L了一下,不确定那里出了问题,能麻烦再看下么?

    root@myonlydesire:~# iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT udp — anywhere anywhere udp dpt:isakmp
    ACCEPT udp — anywhere anywhere udp dpt:ipsec-nat-t

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    ACCEPT all — 10.11.1.0/24 anywhere
    ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination

    Reply
    1. MiffyLiye Post author

      我防火墙用的是SuSEfirewall (openSUSE)和firewalld (CentOS),没有直接用iptables。
      我把openSUSE上的规则贴出来,你参考着看吧。

      Chain INPUT (policy DROP)
      target prot opt source destination
      ACCEPT all -- anywhere anywhere
      ACCEPT all -- anywhere anywhere ctstate ESTABLISHED
      ACCEPT icmp -- anywhere anywhere ctstate RELATED
      input_int all -- anywhere anywhere
      input_ext all -- anywhere anywhere
      LOG all -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning tcp-options ip-options prefix "SFW2-IN-ILL-TARGET "
      DROP all -- anywhere anywhere

      Chain FORWARD (policy DROP)
      target prot opt source destination
      TCPMSS tcp -- anywhere anywhere tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
      forward_int all -- anywhere anywhere
      forward_ext all -- anywhere anywhere
      LOG all -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning tcp-options ip-options prefix "SFW2-FWD-ILL-ROUTING "
      DROP all -- anywhere anywhere

      Chain OUTPUT (policy ACCEPT)
      target prot opt source destination
      ACCEPT all -- anywhere anywhere

      Chain forward_ext (1 references)
      target prot opt source destination
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp echo-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp destination-unreachable
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp time-exceeded
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp parameter-problem
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp timestamp-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp address-mask-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp protocol-unreachable
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp redirect
      ACCEPT all -- anywhere 10.8.0.0/16 ctstate RELATED,ESTABLISHED
      DROP all -- anywhere anywhere PKTTYPE = multicast
      DROP all -- anywhere anywhere PKTTYPE = broadcast
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-FWDext-DROP-DEFLT "
      LOG icmp -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning tcp-options ip-options prefix "SFW2-FWDext-DROP-DEFLT "
      LOG udp -- anywhere anywhere limit: avg 3/min burst 5 ctstate NEW LOG level warning tcp-options ip-options prefix "SFW2-FWDext-DROP-DEFLT "
      DROP all -- anywhere anywhere

      Chain forward_int (1 references)
      target prot opt source destination
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp echo-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp destination-unreachable
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp time-exceeded
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp parameter-problem
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp timestamp-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp address-mask-reply
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp protocol-unreachable
      ACCEPT icmp -- anywhere anywhere ctstate RELATED,ESTABLISHED icmp redirect
      ACCEPT all -- 10.8.0.0/16 anywhere ctstate NEW,RELATED,ESTABLISHED
      DROP all -- anywhere anywhere PKTTYPE = multicast
      DROP all -- anywhere anywhere PKTTYPE = broadcast
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-FWDint-DROP-DEFLT "
      LOG icmp -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning tcp-options ip-options prefix "SFW2-FWDint-DROP-DEFLT "
      LOG udp -- anywhere anywhere limit: avg 3/min burst 5 ctstate NEW LOG level warning tcp-options ip-options prefix "SFW2-FWDint-DROP-DEFLT "
      reject_func all -- anywhere anywhere

      Chain input_ext (1 references)
      target prot opt source destination
      ACCEPT udp -- anywhere anywhere PKTTYPE = broadcast udp dpt:bootps
      ACCEPT udp -- anywhere anywhere PKTTYPE = broadcast udp dpt:netbios-ns
      ACCEPT udp -- anywhere anywhere PKTTYPE = broadcast udp dpt:netbios-dgm
      DROP all -- anywhere anywhere PKTTYPE = broadcast
      ACCEPT icmp -- anywhere anywhere icmp source-quench
      ACCEPT icmp -- anywhere anywhere icmp echo-request
      ACCEPT udp -- anywhere anywhere udp spt:netbios-ns ctstate RELATED
      ACCEPT esp -- anywhere anywhere
      ACCEPT ah -- anywhere anywhere
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:privoxy flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:privoxy
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:http flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:http
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:https flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:https
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:netbios-ssn flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:netbios-ssn
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:microsoft-ds flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:microsoft-ds
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp dpt:webyast flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-ACC-TCP "
      ACCEPT tcp -- anywhere anywhere tcp dpt:webyast
      ACCEPT udp -- anywhere anywhere udp dpt:isakmp
      ACCEPT udp -- anywhere anywhere udp dpt:ipsec-nat-t
      ACCEPT udp -- anywhere anywhere udp dpt:openvpn
      ACCEPT udp -- anywhere anywhere udp dpt:https
      ACCEPT udp -- anywhere anywhere udp dpt:bootps
      ACCEPT udp -- anywhere anywhere udp dpt:domain
      ACCEPT udp -- anywhere anywhere udp dpt:netbios-ns
      ACCEPT udp -- anywhere anywhere udp dpt:netbios-dgm
      DROP all -- anywhere anywhere PKTTYPE = multicast
      DROP all -- anywhere anywhere PKTTYPE = broadcast
      LOG tcp -- anywhere anywhere limit: avg 3/min burst 5 tcp flags:FIN,SYN,RST,ACK/SYN LOG level warning tcp-options ip-options prefix "SFW2-INext-DROP-DEFLT "
      LOG icmp -- anywhere anywhere limit: avg 3/min burst 5 LOG level warning tcp-options ip-options prefix "SFW2-INext-DROP-DEFLT "
      LOG udp -- anywhere anywhere limit: avg 3/min burst 5 ctstate NEW LOG level warning tcp-options ip-options prefix "SFW2-INext-DROP-DEFLT "
      DROP all -- anywhere anywhere

      Chain input_int (1 references)
      target prot opt source destination
      ACCEPT all -- anywhere anywhere

      Chain reject_func (1 references)
      target prot opt source destination
      REJECT tcp -- anywhere anywhere reject-with tcp-reset
      REJECT udp -- anywhere anywhere reject-with icmp-port-unreachable
      REJECT all -- anywhere anywhere reject-with icmp-proto-unreachable

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.