Tech Beans

Web企業で働くエンジニアのBlog


strongSwan でVPN(IKEv2) を 構築する Part.1

基本的な手順は参考元サイトをもとに構築していく。

  • 想定クライアント

※今回、最終的にユーザー名・パスワード認証は成功しているが、公開鍵認証はiOS, OS Xのネイティブクライアントで動作できていない。 OSX側の問題の可能性もあるので、解決したら記事更新予定。

VPN方式の違いについては、前回記事でまとめている。 soymsk.hatenablog.com

乱数精度の確認

参考:

証明書発行で利用する乱数の精度を確認する。

ホスト上のエントロピーは下記のコマンドで確認できる。 以下の値が1000以上なら問題ないらしい。

# cat /proc/sys/kernel/random/entropy_avail
66

足りてない。。

# yum install rng-tools
#  cat /dev/random | rngtest  -c 1000

乱数生成が遅いのか、上記コマンドも全く返ってこない。

乱数用のエントロピーが低すぎる状態であることはわかったので、havegedをインストールし、エントロピーの生成を増やしてみる。 (下記はVPNの構築については必須ではない)

haveged

havagedのセットアップ

$ sudo yum install haveged
$ sudo systemctl enable haveged
$ sudo systemctl start haveged

$ sudo cat /proc/sys/kernel/random/entropy_avail
2273

これで、エントロピーが1000を超えて生成されるようになった。

Install Strongswan

StrongswanをインストールはyumでOK

$ sudo yum install strongswan

認証鍵の作成

つづいて、IKEv2で使うサーバー側のCA認証鍵の生成を行う。 認証鍵は、strongswanのpkiサブコマンドで作成できる。

ルート証明書の作成

自己署名のルート証明書(いわゆるオレオレ証明書)を作成していく。

自己署名のルート証明書について

今回は自己署名のルート証明書を作成したが、 VPN接続の前に、クライアントにルート証明書をインストールする必要がある。

公的なCAから証明書発行が得られるのであれば、クライアントにルート証明書をインストールする手間が不要になるのでそちらがオススメ。

まずはルートサーバーの秘密鍵を作成する。

# cd /etc/strongswan
# strongswan pki --gen --type rsa --size 4096 --outform der > ipsec.d/private/strongswanKey.der
# chmod 600 ipsec.d/private/strongswanKey.der

続いて、ルート証明書を作成。(dnの中身は適宜書き換えること)

# strongswan pki --self --ca --lifetime 3650 --in ipsec.d/private/strongswanKey.der --type rsa --dn "C=JP, O=soymsk, CN=strongSwan Root CA" --outform der > ipsec.d/cacerts/strongswanCert.der

# 作成したルート証明書の内容確認
# strongswan  pki --print --in ipsec.d/cacerts/strongswanCert.der
  subject:  "C=JP, O=soymsk, CN=strongSwan Root CA"
  issuer:   "C=JP, O=soymsk, CN=strongSwan Root CA"
  validity:  not before Oct 07 22:41:11 2016, ok
  .....

VPNサーバーの認証鍵の作成

VPNサーバー自身の秘密鍵を作成

# strongswan pki --gen --type rsa --size 2048 --outform der > ipsec.d/private/vpnHostKey.der
# chmod 600 ipsec.d/private/vpnHostKey.der

続いて、作成したルート証明書秘密鍵から、公開鍵を生成する。

  • CNと--sanにはドメイン名あるいはIPアドレスを指定できるが、これはVPNサーバーのものである必要があるので注意
  • --flag に以下の設定を入れている。
    • Windowsのクライアントからアクセスする場合には、--flag serverAuthが必要。
    • OS X 10.7.3以前のOSXでは、--flag ikeIntermediateが必要。
# strongswan pki --pub --in ipsec.d/private/vpnHostKey.der --type rsa | strongswan pki --issue --lifetime 730 --cacert ipsec.d/cacerts/strongswanCert.der --cakey ipsec.d/private/strongswanKey.der --dn "C=JP, O=soymsk, CN=soymsk.example.jp" --san soymsk.example.jp --flag serverAuth --flag ikeIntermediate --outform der > ipsec.d/certs/vpnHostCert.der

# strongswan --issue --help
# --cacert: CA certificate file.  作成したルート証明書のパス
# --cakey: CA private key file. 作成したルート秘密鍵のパス

作成したサーバー公開鍵は、以下のコマンドで詳細を確認できる。

# strongswan pki --print --in ipsec.d/certs/vpnHostCert.der
  subject:  "C=JP, O=soymsk, CN=soymsk.example.jp"
  issuer:   "C=JP, O=soymsk, CN=strongSwan Root CA"
  validity:  not before Oct 08 08:06:09 2016, ok
             not after  Oct 08 08:06:09 2018, ok (expires in 729 days)
  ......

# OpenSSLを使っても確認できる
# openssl x509 -inform DER -in ipsec.d/certs/vpnHostCert.der -noout -text

クライアントの認証鍵を作成

ルート証明書を使って、今度はクライアントの認証鍵を発行する。 やり方はサーバー認証鍵のものと同じような流れになるが、CNの部分がユーザー名@ドメインの形になる。

秘密鍵の作成

# cd /etc/strongswan/
# strongswan pki --gen --type rsa --size 2048 --outform der > ipsec.d/private/vpnClientKey.der
# chmod 600 ipsec.d/private/vpnClientKey.der

公開鍵の作成

# strongswan pki --pub --in ipsec.d/private/vpnClientKey.der --type rsa | \
 strongswan pki --issue --lifetime 730 --cacert ipsec.d/cacerts/strongswanCert.der --cakey ipsec.d/private/strongswanKey.der \
 --dn "C=JP, O=soymsk, CN=vpnuser@soymsk.example.jp" --san vpnuser@soymsk.example.jp" \
 --outform der > ipsec.d/certs/vpnClientCert.der 

クライント秘密鍵、公開鍵、ルート証明をPEM形式に変換したのち、パスワードつきでPKCS#12 ファイルにまとめる。

# openssl rsa -inform DER -in ipsec.d/private/vpnClientKey.der -out ipsec.d/private/vpnClientKey.pem -outform PEM
writing RSA key

# openssl x509 -inform DER -in ipsec.d/certs/vpnClientCert.der -out ipsec.d/certs/vpnClientCert.pem -outform PEM

# openssl x509 -inform DER -in ipsec.d/cacerts/strongswanCert.der -out ipsec.d/cacerts/strongswanCert.pem -outform PEM


# openssl pkcs12 -export  -inkey ipsec.d/private/vpnClientKey.pem -in ipsec.d/certs/vpnClientCert.pem \
 -name "my private VPN Certificate"  -certfile ipsec.d/cacerts/strongswanCert.pem \
 -caname "strongSwan Root CA" -out myVpnClient.p12 
Enter Export Password: passwordを入力
Verifying - Enter Export Password: もう一度パスワードを入力

作りたいクライアント数分、上記のファイルを作成する。 クライアントには、

を登録して、パスフレーズを入力すればOK。

認証鍵の生成はこれで完了。

IPsecの設定

続いて、IPsecの設定を行う。あと少し!

/etc/strongswan/ipsec.conf を次のように書く。

# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
      charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2,  mgr 2"


# Add connections here.
conn %default
      keyexchange=ikev2
      ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!
      esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!
      dpdaction=clear
      dpddelay=300s
      rekey=no
      left=%any
      leftsubnet=0.0.0.0/0
      # VPN Server証明書
      leftcert=vpnHostCert.der
      leftsendcert=always
      right=%any
      rightdns=8.8.8.8,8.8.4.4
      # rightsourceip: VPNクライアントが接続してきた際に、接続先ネットワークで割り振られるIPを指定する
      # この設定では、VPNクライアントには192.168.1.1などが割り振られることになる。
      # VPNサーバーが所属するネットワークとは別に設定すること。
      rightsourceip=192.168.1.0/24
 


conn IPSec-IKEv2
    keyexchange=ikev2
    auto=add

# OSX, iOSクライアントは主にこちら
conn IPSec-IKEv2-EAP
    also="IPSec-IKEv2"
    rightauth=eap-mschapv2
    eap_identity=%any
    # OSX, iOSではleftid(VPN Server CN)
    leftid=@soymsk.example.jp

iOS8対応などは不要のため、元記事からいくつか設定を省いている。

VPNクライアント設定

クライアントの情報を設定するには、以下のファイルを編集する。

/etc/strongswan/ipsec.secrets:

# 公開鍵認証
: RSA vpnHostKey.der

# ユーザー名・パスワード認証
# `[<domain>\]<ユーザー名> : EAP "<パスワード>" `
vpnuser : EAP "EAPパスワード"

(パスワードがハッシュ化後のものでなく、平文なのがちょっと怖い)

ファイヤウォール、ルーター設定

インターネット側からNAT(ルーター)越しにアクセスを受け付けるために、FWとルーターの設定をする。

Firewalld 設定

# firewall-cmd --add-masquerade --permanent
# firewall-cmd  --query-masquerade --permanent
# firewall-cmd --add-port=4500/udp --permanent
# firewall-cmd --add-port=500/udp --permanent
# firewall-cmd --add-service="ipsec" --permanent
# systemctl restart firewalld
# firewall-cmd --list-all # 設定を確認

ルーター設定

インターネット側からのUDPの500, 4500ポートアクセスをVPNサーバーにポートフォワードするように設定する。

sysctlの設定

VPNサーバーからローカルネットワーク内のホストへIPフォワードを有効にするために、sysctlの設定を変更する. (XX-の部分は優先度を決めるので、適切な数字で!) /etc/sysctl.d/XX-vpn.conf :

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

設定を反映

# sysctl -p

VPN サーバー起動

ようやくVPNサーバーの構築が終ったので起動してみる。

# systemctl enable strongswan
# systemctl start strongswan

# systemctl status strongswan
   strongswan.service - strongSwan IPsec IKEv1/IKEv2 daemon using ipsec.conf
   Loaded: loaded (/usr/lib/systemd/system/strongswan.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2016-10-08 10:11:43 JST; 15s ago

どうやら起動に成功しているようだ。

クライアントからの接続設定

ちょっと長くなったので別記事にまとめる予定。

追記(2016/11/28)

これだけの設定では特定サイトにアクセスできない。 具体的にはMTU値を調整する必要があるが、詳しくはPart2にて。

soymsk.hatenablog.com