Posted at

iOS/AndroidでIKEv2接続できるVPN環境のつくりかた


この記事は

常時接続(Always-on)VPNの環境を試してみたかった事と、

自宅アクセスをSoftetherによるL2TP/IPSecから置き換えるためのメモ


環境


  • さくらのVPS(プラン1G)

  • Ubuntu Server 18.04.2 LTS(ISOイメージインストール)


ネットワーク


  • ens3 : WAN

  • ens4 : LAN(192.168.100.1、スイッチには接続していない)

  • ens5 : 未使用

(IPv6設定は省略)


パッケージ


  • strongSwan

  • (サーバ証明書を作るのが面倒くさい場合)certbot

  • (DNSキャッシュをVPNサーバで行う場合)Dnsmasq

apt -y install strongswan strongswan-pki certbot dnsmasq

strongswan-pkiipsec pki コマンドが利用できるのでとりあえず入れておく。


設定(サーバ認証:証明書、ユーザ認証:ID/PASS)


証明書の作成

VPNサーバ用の証明書を準備する。オレオレかLet's Encryptのどちらかで。

本来はVPN利用時に公的なサーバ証明書を利用することは推奨されていない臭い。けど手っ取り早い。


オレオレ証明書の場合

オレオレCA証明書とそれで署名したサーバ証明書を作る。



Let's Encryptの場合

strongSwanが /etc/ipsec.d/配下の証明書以外読まないっぽいので、取得後にコピーしておく。自動化は省略。

# Let's Encrypt の中間証明書

cp /etc/letsencrypt/live/example.com/chain.pem /etc/ipsec.d/cacerts/chain.pem

# 発行したサーバ証明書と秘密鍵
cp /etc/letsencrypt/live/example.com/privkey.pem /etc/ipsec.d/private/privkey.pem
cp /etc/letsencrypt/live/example.com/cert.pem /etc/ipsec.d/certs/cert.pem


ufwの設定

IPSecで利用するUDPの500と4500を開ける。

NAT-T前提なのでAHとかESPは放置。

ufw allow 500,4500/udp


/etc/ufw/sysctl.conf

IP転送の有効化


sysctl.conf

net.ipv4.ip_forward=1    #コメントアウトを解除



/etc/ufw/before.rules

ufwコマンドでできないiptablesの設定


before.rules

-A POSTROUTING -o ens3 -j MASQUERADE

-A INPUT -s 192.168.101.0/24 -m policy --dir in --pol ipsec -j ACCEPT
-A FORWARD -d 192.168.101.0/24 -j ACCEPT
-A FORWARD -s 192.168.101.0/24 -j ACCEPT
-A FORWARD -s 192.168.101.0/24 -o ens3 -p tcp -m policy --dir in --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1281:1536 -j TCPMSS --set-mss 1280


/etc/dnsmasq.conf

DNSキャッシュを行う場合のみ。

外部公開してしまわないように。


dnsmasq.conf

listen-address=127.0.0.1,192.168.100.1



strongSwanの設定


/etc/ipsec.secrets

証明書秘密鍵の指定とユーザアカウントの登録


ipsec.secrets

#RSAの場合

: RSA privkey.pem
#ECDSAの場合
: ECDSA privkey.pem

user : EAP "password"



/etc/ipsec.conf

自身がIPSecの仕様やstrongswanの設定値を理解していない部分が多く、もっと調整の余地がある


ipsec.conf

config setup

# strictcrlpolicy=yes
# uniqueids = no

conn iOS-IKEV2
auto=add
dpdaction=restart
dpddelay = 60s
keyexchange=ikev2
keyingtries=%forever

ike=aes256-sha256-ecp521,aes256-sha256-modp2048,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128-sha1-modp1024
# Android stronSwan Client用と、AC2.9.1版AlwaysOnの初期値を追加
esp=aes256-sha256,aes256-sha1

leftcert=cert.pem #サーバ証明書のファイル名
leftid=example.com #サーバ証明書のCNまたはSAN
leftsendcert=always
leftsubnet=0.0.0.0/0

right=%any
rightsourceip=192.168.101.0/24 #クライアントに割り当てるアドレス帯
rightdns=8.8.8.8,8.8.4.4 #クライアントが利用するDNSサーバ
#rightdns=192.168.100.1 #DnsmasqとかでDNSキャッシュを行う場合はサーバのローカルIPとか

rightauth=eap-mschapv2
eap_identity=%any

mobike = yes



クライアント側設定


iOS(手動)


iOS(AC2)


Android公式Client

Google Play Store からクライアントをダウンロード

Play Store非搭載端末の場合やPlay Storeを使いたくない場合は公式サイトから突っ込む。


設定(サーバ認証:証明書、ユーザ認証:証明書)


今後の課題


  • ID/PASS(eap-mschapv2と証明書(EAP-TLS)の2つの認証方式の併用

  • Always-ON VPNの安定化


    • 常時接続はCellular接続とWi-Fi接続でそれぞれVPNを張る

    • 現状の設定では、1 ID 1接続のため、Wi-Fiにつなぐと交互に接続/切断を繰り返すことがある

    • uniqueids=noで回避

    • ipsec.confにWi-Fi用のConn設定を設け、プロファイルでCellular/Wi-Fiを別設定にすること回避

    • プロファイルいじりでも何とかなりそう



  • 常時接続+グローバルHTTPプロキシ

  • on-demand vpn


    • どっかにわかりやすい記事があった。やり方だけならProfile Reference。



  • per-app vpn


    • iOSはMDMがないと無理

    • Androidはクライアントに設定あり




個人的なまとめ


  • L2TP/IPSec(主にSoftEther)と較べての体感


    • 接続が早い

    • 切れにくい(Cellular⇔Wi-Fiとか、電車とか)

    • ユーザ管理が面倒



すでにstrongswan+xl2tpで環境作っているなら、切り替えは容易かもしれない。

PPTP は、iOS10/Sierra からは使えなくなった。

PSK設定のサーバに接続する場合、macOS/iOS/Windowsでは手動設定不可

(macOSでは設定でPSKとユーザ認証が同時に設定できない。iOSとWindowsはPSKを入れる箇所が見当たらない)

PSKを使わなければ、iOS、macOS、Windowsそれぞれで手動設定可能

プロファイルを使えばmacOS、iOSでPSK+ID/PASSの利用は可能

旧記述はコメントアウト


参考にさせていただいたページ/サイト