今回はAWS EC2(AmazonLinux2023)にStrongswanというソフトをインストールして、VPNサーバを構築する記事です。AWS上に検証環境があり、クライアントPC含めて挙動を確認したいときにVPNセッションを張れる回線、NW機器がなくて困っている方への一助になればと思います。
StrongSwanは、オープンソースで開発されているクロスプラットフォーム対応の IPsecベースのVPN(仮想プライベートネットワーク)ソフトウェアです。主にLinux環境で広く利用されていますが、Android、FreeBSD、macOS、Windowsなどのオペレーティングシステムでも動作します。
IKEv1およびIKEv2(Internet Key Exchange)プロトコルを完全にサポートしており、X.509公開鍵証明書による強力な認証メカニズムを利用できるのが大きな特徴です。
VPNソフトの比較
色々とVPNソフトはありますので、メジャーなSoftEther VPNとWireguardとの機能比較表を作りました。
| 名称 | StrongSwan | Wireguard | SoftEther VPN |
|---|---|---|---|
| 用途 | 企業VPN・拠点間 | 小規模・個人・拠点間 | 多目的・汎用VPN |
| 利用プロトコル | IPsec (IKEv1/IKEv2) | 独自プロトコル | 複数のVPN方式(L2TP/IPSec,OpenVPN互換,SSTP,独自プロトコル) |
| クライアントソフト要否 | 不要 | 必須 | プロトコルに依存 |
| 暗号化方式 | IPsec | 独自 | TLS(SSL) ※IPsec互換機能あり |
| AD・RADIUS連携 | ユーザー認証・認可をVPN外部(AD/RADIUS)に完全委譲できる | なし | AD/RADIUS対応はあるが「VPN側でユーザー管理する思想」 |
| 認証方式 | PSK、ユーザー/パスワード(EAP必須)、証明書、EAP + RADIUS | 公開鍵のみ | ユーザー/パスワード、証明書、RADIUS |
| ACL・ルーティング制御 | OS側機能に依存 | IP単位でのアクセス制御のみでその他はOS側機能依存 | 仮想HUB(L2)やルーティング機能(L3),NAT機能あり |
ざっくりまとめるとこんな感じです。
WireGuard
「拠点間や個人用途に向いた、シンプル高速なVPN」=お手軽簡単したい人構築向け
→拠点間接続や個人用途に最適だが、企業標準機能は持たない。
strongSwan
「企業標準のIPsec VPNを構築するための実装」=各種連携を行うSIer向け構築
→AD・RADIUSと連携した標準的な社内VPN構築に適する。
SoftEther VPN =豊富な管理・設定機能があり、運用ノウハウある人向け構築向け
「多様な接続方式を1台で提供できる柔軟なVPNサーバ」
→検証・多様な利用環境・簡易構築に強い
今回のゴール
AWS側には必要IP、ポートの透過許可したVPCとPublicSubnetをデプロイし、Internet gatewayを経由してClientとEC2でVPN接続を構築します。
一般的なNW機器によるVPN接続(ハードウェアVPN)ではなく、サーバ上でソフトウェアを動作させてVPNを構築するソフトウェアVPNの構成です。VPN接続後、VPC内のプライベートIPのみのEC2へのVPN経由でPing応答を確認します。
前提条件
- 今回はVPNサーバはAmazonEC2(AmazonLinux2023)で構築します。
- StrongswanはソースをDLして、ビルド・インストールします。
- Strongswanの設定方式はモダンな swanctl.conf利用方式です。レガシーな ipsec.confは利用しません
- Windows 11の標準VPN設定機能(ビルトインVPNクライアント)でVPN接続します。
※クライアントソフトはPCにインストールしません - EC2のデプロイについては本記事の主題ではないので割愛します。
- Strongswanは最新の安定版(執筆時)を使用します。
- 本記事の内容はあくまで検証目的なので本番運用時はしっかりとセキュリティ設定しましょう。設定は自己責任でお願いします。
設定の流れ
EC2のデプロイはクライアントPCとEC2が通信できるようにセキュリティグループが設定されていれば問題ありません。デプロイは他に詳しい記事がありますので割愛します。デプロイ完了し、EC2のPublic IPアドレスにSSHで接続できる状態になっている前提で手順を記載します。
⓪事前準備
#OSの最新版へのバージョンアップ
dnf -y update
#日本語に設定変更
localectl set-locale LANG=ja_JP.UTF-8
#タイムゾーンを日本時間に変更
timedatectl set-timezone Asia/Tokyo
#ホスト名の変更
hostnamectl set-hostname "任意のホスト名"
#設定反映のため再起動
reboot
①Strongswanパッケージのインストール
#ビルドに必要なコンパイラと、ネットワーク管理ツールをインストール
sudo dnf groupinstall "Development Tools" -y
sudo dnf install -y openssl-devel libcap-devel nftables systemd-devel
②StrongSwan のソースビルドとインストール
# ソースのダウンロードと解凍
cd /usr/local/src
sudo curl -O https://download.strongswan.org/strongswan.tar.bz2
sudo tar xjvf strongswan.tar.bz2
cd strongswan-*
# ビルド設定(Windows接続に必要なオプションを有効化)
sudo ./configure --prefix=/usr --sysconfdir=/etc --enable-systemd --enable-swanctl --enable-vici --enable-openssl --enable-eap-mschapv2 --enable-eap-identity
# コンパイルとインストール
sudo make && sudo make install
③PKI(証明書)の作成と配置
サーバーのパブリックIP をベースに生成します。
#ルートの下に証明書用のディレクトリを作成
mkdir -p ~/pki/{cacerts,certs,private}
# CA(認証局)作成
pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem
#有効期間10年で、証明書の識別名(コモンネーム)=VPN CAという名前の.pem形式の証明書を作成
pki --self --ca --lifetime 3650 --in ~/pki/private/ca-key.pem --dn "CN=VPN CA" --outform pem > ~/pki/cacerts/ca-cert.pem
# サーバー証明書作成(Windows用フラグ serverAuth を付与)
export SERVER_IP="EC2のPublic IP" ←自身の環境に変更してください。
pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem
pki --pub --in ~/pki/private/server-key.pem | pki --issue --lifetime 3650 --cacert ~/pki/cacerts/ca-cert.pem --cakey ~/pki/private/ca-key.pem --dn "CN=$SERVER_IP" --san $SERVER_IP --flag serverAuth --flag ikev1 --outform pem > ~/pki/certs/server-cert.pem
# 生成した各証明書をstrongswanが利用するディレクトリへ配置
sudo cp ~/pki/cacerts/ca-cert.pem /etc/swanctl/x509ca/
sudo cp ~/pki/certs/server-cert.pem /etc/swanctl/x509/
sudo cp ~/pki/private/server-key.pem /etc/swanctl/private/
sudo chmod 600 /etc/swanctl/private/server-key.pem
④設定ファイル (swanctl.conf) の編集
strongswanのコンフィグファイルを編集して、環境設定を行います。
# swanctl.confを編集
vim /etc/swanctl/swanctl.conf
#以下のように編集
connections {
ikev2-vpn {
version = 2
proposals = aes256-sha256-modp2048,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024,default
rekey_time = 0s
pools = rw_pool
fragmentation = yes
local {
auth = pubkey
certs = server-cert.pem
id = {実際のEC2のグローバルIP}
}
remote {
auth = eap-mschapv2
id = %any
}
children {
net {
local_ts = 0.0.0.0/0
}
}
}
}
pools {
rw_pool {
#VPN接続したクライアントには10.10.1.0/24の中からIPを振る
addrs = 10.10.1.0/24
#VPN接続したクライアントのDNSは8.8.8.8を設定
dns = 8.8.8.8
}
}
secrets {
eap-user1 {
#VPN接続時のユーザID
id = vpnuser
#VPN接続時のパスワード
secret = vpnpassword123
}
private-server {
file = server-key.pem
}
}
⑤ユニットファイルの編集
strongswan.service実行のタイミングでどのようなファイルを読み込みするのかユニットファイルの指定を変更
#strongswan.serviceの編集
vim /usr/lib/systemd/system/strongswan.service
#以下のように内容を修正
-------------------
[Unit]
Description=strongSwan IPsec IKEv1/IKEv2 daemon
After=network.target
[Service]
Type=simple
ExecStart=/usr/libexec/ipsec/charon
# 起動時の自動読み込みは削除
Restart=on-failure
[Install]
WantedBy=multi-user.target
-------------------
#システム設定の再読み込み
systemctl daemon-reload
#サービスの再起動
systemctl restart strongswan
#設定ファイルの再読み込み
swanctl --load-all
#設定状態の確認
/usr/sbin/swanctl --version
#設定が正常にできていると以下のようにstrongswanのシステムバージョンが表示されます。
strongSwan swanctl 6.0.6
⑥OS・ネットワーク設定(転送とNAT)
VPN経由でインターネットを閲覧するための設定
#IPフォワーディングの有効化
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
#nftables による NAT設定(IPマスカレード設定)
sudo systemctl enable --now nftables
sudo nft add table ip nat
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule ip nat postrouting oifname "ens5" ip saddr 10.10.1.0/24 counter masquerade
※"ens5"はEC2のNICのデバイス名なので環境に合わせて変更
※デバイス名不明であれば"ip a"コマンドでプライベートIPが表示されている値です。
#MSSクランプの設定(経路上のMTUに合わせて、MSS(データ部分のサイズ)を自動的に最適化)
sudo nft add rule ip nat postrouting oifname "ens5" tcp flags syn tcp option maxseg size set rt mtu
#設定の永続化
sudo nft list ruleset | sudo tee /etc/nftables/main.nft
echo 'include "/etc/nftables/main.nft"' | sudo tee -a /etc/nftables.conf
#設定の反映
sudo swanctl --load-all
#設定ファイルの再読み込み
sudo swanctl --load-all
#正常に読み込みできると以下のように結果が出力されて、successfullyと表示がでます
loaded certificate from '/etc/swanctl/x509/server-cert.pem'
loaded certificate from '/etc/swanctl/x509ca/ca-cert.pem'
loaded RSA key from '/etc/swanctl/private/server-key.pem'
loaded eap secret 'eap-user1'
no authorities found, 0 unloaded
loaded pool 'rw_pool'
successfully loaded 1 pools, 0 unloaded
loaded connection 'ikev2-vpn'
successfully loaded 1 connections, 0 unloaded
⑦EC2セキュリティ設定
EC2はインスタンスが自身宛てではない、または自身のIPアドレス以外を送信元とする通信を破棄する「ソース/宛先チェック」というセキュリティ機能がデフォルト有効になっています。VPNサーバとして、VPC内の通信を経由させる場合は、このチェックを無効(停止)にする必要があります。
<参照>
EC2管理コンソールで該当インスタンスを選択した上で「アクション」-「ネットワーキング」から「ソース/宛先チェックを変更」をクリックします。

⑧接続準備と確認
それでは実際にクライアントPCのVPN設定を行い、接続まで進めましょう
Windows11では[設定]のネットワークとインターネットで、VPN設定ができます。
VPN設定のプロファイルはこんな感じで設定します。
クライアントPCに③で作成したCA証明書をインストールします。CA証明書を入れておかないと信頼されていない接続先となり、VPN接続が失敗します。
証明書のインストール方法ですが検索欄で「証明書」と検索すると「コンピュータ証明書の管理」という項目が出てくるので、そちらになります。
[ユーザ証明書の管理]ではありません
追加する箇所は「信頼されたルート証明機関」-「証明書」です。証明書フォルダを右クリックして、すべてのタスクを選択し、インストールを行います。

CA証明書をインストールするとこんな感じで追加されています。
これでVPN接続できる環境は整ったでの実際にVPN接続できるか確認しましょう。こんな感じでVPN接続先セグメントのIP(10.10.1.x/24)が取れていればOKです。

上手くいかないときはEC2側で「swanctl --list-sas」コマンドを実行することで、現状の接続状態が見えます。
表示内容をコピーして、AIに聞けばどこで詰まっているか教えてくれると思います。
正常に接続できるとVPN接続したことで、PPPアダプターに10.10.1.1が割当られており、10.0.0.77にPingを打つと応答がかえってきています。

VPN接続した状態でnslookupコマンドでyahoo.co.jpを名前解決するとGoogleのDNS(8.8.8.8)で解決できています。このGoogle DNSはswanctl.confで指定した値です。
EC2側で以下コマンドで接続中のユーザーを表示させることができます。
sudo swanctl --list-sas
接続中のユーザの情報は以下のような形で表示されます。
ikev2-vpn: #8, ESTABLISHED, IKEv2, 5e70d593bXXXXXXX_i da1cea7a42a4XXXX_r*
local '{EC2のグローバルIP}' @ {EC2のプライベートIP}[4500]
#接続元(クライアント)の識別情報と、実際に通信が来ているグローバルIP、およびポート番号です。
remote '172.20.10.2' @ {グローバルIP}[42594] EAP: 'vpnuser' [10.10.1.1]
AES_CBC-256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
established 769s ago
net: #1, reqid 1, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-256/HMAC_SHA1_96
installed 769s ago, rekeying in 2545s, expires in 3191s
in c8918566, 2298083 bytes, 40874 packets, 0s ago
out 51ff27f2, 73853476 bytes, 54471 packets, 1s ago
local 0.0.0.0/0
remote 10.10.1.1/
おわりに
AD連携やRADIUS連携できるので、組合せればちゃんとしたVPN環境が組めそうな予感がします。PC側にアプリインストールが要らないのは便利だと感じます。
参考にしたサイト






