为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.org和MiffyLiye。

#
# 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.