strongSwanでLet’s Encrypt証明書を使ったIKEv2 VPNサーバーを作る

これは自分のためのメモです。

この世界が誕生する前から、実はowner203はこの世界をVPNアクセスポイントとして使っていました。owner203は家の外でインターネットを使うことが多く、VPNを使うのはもちろんセキュリティのためです。特にフリーWi-Fiを使うときはなおさらです。ConoHaの回線速度はとても早いので、常時VPNをオンにしても速度は落ちません。

VPNにはいろんなタイプがありますけど、安全性とクライアントの設定しやすさを考慮したうえで、やはりIKEv2に他なりません。iOS、macOSとWindowsではアプリ不要で設定できるし、Wi-Fiとモバイルデータの切り替えでも切断しないなど、他のタイプより優秀だと思いました。

IKEv2接続は原理的にサーバー証明書が必要です。自己署名の証明書を使うマニュアルが多くあるけど、自己署名だと、クライアントが手動でルート認証局を信頼設定にする必要があるなど面倒くさいから、接続を簡単化するため、Let’s Encryptの証明書を使います。英語の参考資料を読みながら設定したが、自分が理解できるようにここで整理しておきます。サーバーOSはUbuntu 18.04です。

Apacheの導入

すべての作業の前に、まずhttpサーバーを設定しました。後でLet’s Encryptの証明書を取得するために先にインストールしておきます。

sudo apt update
sudo apt install apache2

インストールしたら、ufwで使うポートを開けます。

sudo ufw allow 'Apache Full'
sudo ufw status #確認する

Let’s Encryptの導入

まずApache用のCertbotを入れます。

sudo apt install python-certbot-apache

もしこれでダメだったらCertbotのPPAを入れてからもう一度試します。Ubuntu最新版では不要のはずです。

sudo add-apt-repository ppa:certbot/certbot  #最新版では不要

証明書を取得する前に、まずApacheでドメインのconfファイルを設定します。複数ドメインをバーチャルホストでホストしていない場合は省略可能です。

sudo vi /etc/apache2/sites-available/owner203.com.conf
/etc/apache2/sites-available/owner203.com.conf

#次の行を追記する
ServerName owner203.com;
sudo apache2ctl configtest  #設定ファイルをテストする
sudo systemctl reload apache2 #設定ファイルをリロードする

これから証明書を取得します。基本的に表示内容を従えれば大丈夫です。

sudo certbot --apache -d owner203.com -d www.owner203.com  #もっとドメインがあれば-dで追加する

Let’s Encryptの証明書は有効期限が短いので、定期的に更新しないといけません。このCertbotで証明書を取得した場合は自動的に/etc/cron.d/で自動更新の設定が済んだはずです。ここで自動更新のテストをやってみます。

sudo certbot renew --dry-run

strongSwanの導入

いよいよ本題に入ります。IKEv2の作成にはstrongSwanを使います。Androidでも公式クライアントAppを入れることでIKEv2接続ができます。strongSwanのインストールはとても簡単です。

sudo apt install strongswan

次にstrongSwanの設定ファイルを編集します。設定内容が多いので、オリジナルの設定ファイルをバックアップして書き直します。

sudo mv /etc/ipsec.conf{,.original}
sudo vi /etc/ipsec.conf
/etc/ipsec.conf

config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no

conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
ike=aes256-sha1-modp1024,3des-sha1-modp1024! #iOSを対応するために暗号化メソッドをaes256-sha1-modp1024に指定する
esp=aes256-sha1,3des-sha1! #上の行と順番を一致する
dpdaction=clear
dpddelay=300s
rekey=no
left=%any
leftid=@owner203.com
leftcert=fullchain.pem #この行ではIKEv2で使うサーバー証明書をstrongSwanに指定したが、後でCertbotで取得した証明書ファイルをstrongSwanのフォルダにコピーしないといけない
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
eap_identity=%identity

次にIKEv2接続で使う認証情報を設定します。

sudo vi /etc/ipsec.secrets
/etc/ipsec.secrets

#以下の行を追記する
: RSA "privkey.pem" #IKEv2で使うクライアント証明書をstrongSwanに指定する
vpn_username : EAP "vpn_password" #複数ユーザーを設定する場合は行を追加して設定する
#追記はここまで

strongSwanを再起動して、設定を有効にする。

sudo systemctl restart strongswan

ファイアーウォールに関する設定

これからは、クライアントがVPNで接続してサーバーのインターネットを使うために、ufwでポートを開けて、IPv4のデータ転送を設定します。

まず、IKEv2とIPSecが使う500番ポートと4500番ポートを開きます。

sudo ufw allow 500,4500/udp

次の操作へ進む前に、サーバーが使うネットワークインターフェースを確認しないといけません。これはサーバーをログインした直後に表示されるSystem informationで確認できます。ConoHaの場合はeth0でした。

Output

System information as of Xxx Xxx 00 00:00:00 JST 2019
System load: 0.0 Processes: 000
Usage of /: 00.0% of 00.00GB Users logged in: 0
Memory usage: 00% IP address for eth0: 000.000.000.000
Swap usage: 0%

またip routeコマンドでも確認できます。

ip route | grep default
Output

default via 000.000.000.1 dev eth0 proto dhcp src 000.000.000.000 metric 100

もしeth0ではない場合、次の操作でeth0の箇所を自分のサーバーが使うインターフェース名に変更します。

ufwが使うフィルターファイルを編集します。

sudo vi /etc/ufw/before.rules
/etc/ufw/before.rules

#以下の行を追記する
*nat
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT

*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT
#追記はここまで

*filter
#中略...
#以下の行を追記する
-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT
#追記はここまで

#後略...
sudo vi /etc/ufw/sysctl.conf
/etc/ufw/sysctl.conf

#前略...
#次の行のコメントマークを解除する
net/ipv4/ip_forward=1

#中略...
#次の行の設定を確認する
net/ipv4/conf/all/accept_redirects=0

#中略...
#以下の行を追記する
net/ipv4/conf/all/send_redirects=0
net/ipv4/ip_no_pmtu_disc=1
#追記はここまで

#後略...

ufwを再起動して、設定を有効にします。

sudo ufw disable
sudo ufw enable

証明書ファイルの配置

strongSwanの設定で証明書ファイルを指定したが、これから実際に証明書ファイルをstrongSwanのフォルダにコピーします。

sudo cp -f /etc/letsencrypt/live/owner203.com/fullchain.pem /etc/ipsec.d/certs/fullchain.pem
sudo cp -f /etc/letsencrypt/live/owner203.com/privkey.pem /etc/ipsec.d/private/privkey.pem

Let’s Encryptの証明書は自動更新されますが、更新されるたびに手動でコピーするのは面倒くさいので、これを自動化しておきます。/etc/cron.d/で空ファイルを作成して、コマンドを記入します。

sudo vi /etc/cron.d/copycerts
/etc/cron.d/copycerts

0 4 10 * * root cp -f /etc/letsencrypt/live/owner203.com/fullchain.pem /etc/ipsec.d/certs/fullchain.pem && cp -f /etc/letsencrypt/live/owner203.com/privkey.pem /etc/ipsec.d/private/privkey.pem && systemctl restart strongswan.service

owner203は、毎月の10日午前4時に最新の証明書を自動コピーして上書きする、という設定にしました。必要に応じて数値を変更できます。

中間証明書の取得

これまで設定をしたら、iOS、macOSとAndroidではもう接続できます。ただWindowsからの接続には、サーバーで中間証明書を入れないといけません。

sudo wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem -O \
/etc/ipsec.d/cacerts/lets-encrypt-x3-cross-signed.pem

これで、iOS、Android、WindowsのクライアントはIKEv2でサーバーに接続して、サーバーのネット回線を使うことができるようになりました。

クライアントの設定

iOSとmacOS

iOSとmacOSクライアントの設定はとても簡単です。新規でVPN接続を作成して必要項目を設定します。

タイプIKEv2
説明
任意
サーバ自分のドメイン
リモートID自分のドメイン
ローカルID空欄
ユーザ認証ユーザ名
ユーザ名設定したVPNユーザー名
パスワード設定したVPNパスワード

Android

Androidクライアントから接続するには、strongSwanのAppをインストールする必要があります。Google Playからダウンロードできます。ADD VPN PROFILEからVPNプロファイルを作成して、以下の項目を設定します。

Server自分のドメイン
VPN TypeIKEv2 EAP (Username/Password)
Username設定したVPNユーザー名
Password設定したVPNパスワード
Show advanced settingsチェックを入れる
IKEv2 Algorithmsaes256-sha1-modp1024

コメントを残す

メールアドレスが公開されることはありません。