strongSwanの新しい設定方法(vici)
前回設定したstrongSwanのipsec.conf、ipsec.sercretsを使った設定方法は、現在では非推奨となっていて、swanctl.confファイルを利用する方法に置き換えられています。
せっかく設定しましたが、推奨されるswanctlで再度設定をします。
swanctlのインストール
swanctl.confはviciインターフェースで利用され、起動や停止などはswanctlというコマンドで操作します。まずはそのstrongswan-swanctlをインストールします。
strongSwanの起動時に設定(swanctl.conf)を読み込ませる必要がありますので、/etc/strongswan.conf次のような記述を追加します。記述したコマンドはswanctlの全設定を読み込むものです。コマンドの詳細はstrongSwan:「swanctl」を確認してください。
/etc/strongswan.conf
charon {
...
start-scripts {
swanctl =/usr/sbin/swanctl -q
}
...
}
swanctlをインストールすると、/etc/swanctl/ディレクトリが作成されています。この中にあるswanctl.confファイルに設定を記述するか、 同じディレクトリにある conf.d 内に環境に合わせたswanctl.confファイルを作成します。
まずstrongswan:Test swanctl/nat-rw-pskを参考にNAT環境におけるトンネルモードでのIPsec通信を構築します。
先の資料中の端末「alice」をローカル側の端末、ゲートウェイの「sun」をVPSとします。VPSのプライベート側にネットワークインターフェースを作ります。
まずはローカル側の端末「alice」側の設定です。
alice.swanctl.conf
connections {
#「connection-name」は名前です
connection-name {
local_addrs=192.168.1.252 # alice側のプライベートIPアドレス
remote_addrs=123.456.789.1 # sun(ゲートウェイ)のIPアドレス
local {
auth = psk
id = 192.168.1.252 # alice用のID
}
remote {
auth = psk
id = 123.456.789.1 # sun用のID(パスワード指定に利用)
}
children {
# ここの「child-name」も名前です。
# swanctl -i -c でこの名前を指定して接続します。
child-name {
# sunのプライベートネットワーク
remote_ts = 192.168.100.0/24
# もしこの端末をルーター化するなら、aliceのプライベートネットワークを入力します
# コメントアウトのままだと、aliceが同じネットワーク上にいる端末のデータを転送する際はIPsec通信をしません
#local_ts = 192.168.1.0/24
# espのchipher suite
esp_proposals = aes128-sha256,default
# 接続・切断時に実行されるスクリプト
updown = /script.sh
# start_actionに noneを設定すると、設定読み込みだけ
# startを設定すると自動接続になります。
start_action= start
# 切断時再接続します
close_action= start
# Dead Peer Detection時再接続します
dpd_action = start
#モード
mode = tunnel
}
}
# ネゴシエーションリトライ数
keyingtries = 3
# ikeのバージョン
version = 0
# ikeのchipher suite
proposals = aes128-sha256-prfsha256-modp3072,default
}
}
secrets {
# パスワードの設定
# 名前の「ike」の部分は固定です。IKE用のPSKキーのエントリーとなります。
ike-123456789001 {
# 接続しにいく端末のID
id = 123.456.789.1
secret = "pre-shared-key-password"
}
}
次にVPS「sun」の設定です。
sun.swanctl.conf
connections {
server-name {
local_addrs=123.456.789.1 # sunのグローバルアドレス
local {
auth = psk
id = 123.456.789.1 # sun用のid
}
remote {
auth = psk
}
children {
network1 {
# sunのプライベートnetwork
local_ts=192.168.100.0/24
# aliceのプライベートネットワーク
remote_ts = 192.168.1.0/24
esp_proposals = aes128-sha256,default
updown = /script.sh
#設定を読み込んで待機します。
start_action= none
close_action= none
dpd_action= none
#モード
mode = tunnel
}
}
# ネゴシエーションリトライ数
keyingtries = 3
# ikeのバージョン
version = 0
# ikeのchipher set
proposals = aes128-sha256-prfsha256-modp3072,default
}
}
secrets {
#接続クライアント毎にPSKを設定
ike-192168001252 {
id = 192.168.1.252
secret = "pre-shared-key-password"
}
ike-192168001251 {
id = 192.168.1.251
secret = "pre-shared-key-password-other"
}
}
ここではaliceから自動で接続する設定にしましたが、手動で行うには次のようにします。swanctlコマンドはstrongSwanサービスが起動していないと実行できないことに注意してください。
swanctl -i -c child-name
swainctl -t -c child-name
qオプションで設定を読み込み、iオプションで接続cオプションでchildの名前を指定して接続対象選択します。切断する際はtオプションを使います。ipsec.confの設定ではauto=addとすると設定を読み込んでくれましたが、swanctl.confではそれに相当するものが存在しませんので先のようにstart-scriptsの設定をします。また、start_action=startとしたときも、start-scriptsで読み込んでおかないと意図したようになりません。
他新旧の設定の変換テーブルはstrongSwan:「Migration from ipsec.conf to swanctl.conf」に載っています。
暗号化・認証アルゴリズムについて
strongSwanで利用可能な暗号化アルゴリズムや認証アルゴリズムはIKEのバージョンによっても変わりますが、IKE2ならstrongSwan:IKEv2 Cipher Suitesに掲載されています。
スイート(組み合わせ)に記述する主なものは次のようになり、それぞれを-(半角ハイフン)でつなげて指定します。
- 1.Encryption Algorithms(暗号化アルゴリズム)
- 2.Integrity Algorithm(認証アルゴリズム/ハッシュ)
- 3.Puseudo-Random Function(認証アルゴリズム/ハッシュ)
- 4.Diffie Hellman Groups(DH)
esp-proposalの場合は「1-2 」、proposal(ike)の場合は「1-2-3-4」とそれぞれを-でつなげて記述します。
指定時、論理的に存在する名前を設定すればエラーにはなりませんが、実際の環境で利用できないとNO_PROPOSAL_CHOSENエラーが出ます。
また(suite)組み合わせは,(半角コンマ)で複数指定でき、defaultとすると利用可能なものから最適なものを選択してくれます。(筆者の環境では、論理的に存在していて利用できないスイートを指定した場合は,で並べた次の項目に移らずにエラーになってしまうようでした。)
利用可能なアルゴリズムを確認するには「swanctl -g」とします。swanctlコマンドはstrongSwanサービスが起動していないと実行できないことに注意してください。
updownスクリプト
updownは接続時にも切断時にも呼び出されます。多くの場合はその接続時と切断時で違う処理したいと思います。その際はPLUTO変数を使います。strongSwan公式のページにスクリプトのサンプル内にその詳細は記載されています。
接続時と切断時で処理を分ける場合は、「$PLUTO_VERB」という変数を使います。接続時には「up-host」切断時には「down-host」という値が入っています。
注意しなければならないのはこの機能が働くのはIKEv2とIKEv1のQuick Modeの時だけという事です。
L2TP/IPsec
今度はWindows10のVPNツールより、L2TP/IPsec通信をしてみます。
VPSのswanctl.confファイルにchildとsecretのエントリーをを追加します。L2TPトンネルであるxl2tpdの設定は 前回の記事と同じです。
sun.swanctl.conf
children {
...
l2tp-ipsec{
local_ts=123.456.789.1[udp/1701]
start_action = none
close_action = none
dpd_action = none
mode = transport
}
...
secrets {
...
ike-l2tp-ipsec{
id=123.456.789.1
secret = "pre-shared-key-for-l2tp-ipsec"
}
...
}
さらにiptable-persistentファイアウォールを使っている場合は、/etc/iptables/rules.v4に次の記述をしてL2TPのパケットを許可します。
idの謎
L2TP/IPsec用のPSKの指定の仕方は試行錯誤していたら偶然できたのですが、なぜパスワードのid指定がこれで成立するか、筆者はよくわかっていません。
テストをもとにした筆者の推測ですが、次のようになっていると思われます。
IPsecの仕様の中でどのようにidを送受信しているか不明ですがstrongSwanでは設定中のidを送信して利用しているようです。リモート時はremoteの設定項目にあるid値を使います。この値を使って自分のsecretエントリー内からPSKも取得します。
ホスト側は、リモート側のidの値により照合すべきPSKをホスト側のsecretsのエントリーから選択するようです。
リモート側でidを指定しない場合、リモート側のidにはlocal_addrsで設定したアドレスが入り、選択されるPSKはsecrets内の一番最後のエントリーになるようでした。
リモート側がstrongSwanでなくidの値が入っていない時は、ホスト側のlocalに記述されているidの値を使うのではないかと、予想します。
ルーティング
strongSwanで接続したポイントへのルーティングは、IDが220のルーティングテーブルに追加されます。リンクアップしていれば問題ないのですが、そうでなければデフォルトルートに送られてしまします。そしてデフォルトルートはstrongSwanサーバーにデータを転送しようとします。このループを防ぐために、Debianでは「ip route add unreachable xxx.xxx.xxx.xxx/サブネット値 」という形で、パケットを止めるルーティングを設定できます。IDが220番のルーティングテーブルはデフォルトテーブルより優先度が高いので、unreachableのルールを削除しなくても、リンクアップしている時だけ接続できるようになります。
ちなみにルーティングテーブルの一覧は「 ip rule list 」で、テーブルに設定してあるルールの確認は「 ip route show table テーブル名 or all 」とすることで表示できます。
strongSwanでL2TP/IPsecクライアント(追記)
qiita:「Linux上でのL2TP/IPSecのクライアント設定」を参考にさせていただき、strongSwanのviciインターフェースで、IPsec/L2TPクライアントも設定してみました。
サンプル中ではサーバー側を123.456.789.1、ローカル側を192.168.1.1にしています。
/etc/strongswan.conf
charon {
load_modular = yes
plugins {
include strongswan.d/charon/*.conf
}
start-scripts {
swanctl =/usr/sbin/swanctl -q
}
}
/etc/swanctl/swanctl.conf
connections {
sakura-network {
local_addrs=192.168.1.1
remote_addrs=123.456.789.1
local {
auth = psk
id = 192.168.1.1
}
remote {
auth = psk
id = 123.456.789.1
}
children {
l2tp-ipsec {
local_ts=192.168.1.1
remote_ts=123.456.789.1[udp/1701]
start_action = start
close_action = start
dpd_action = start
esp_proposals=default
mode = transport
}
}
keyingtries = 3
version = 0
proposals = aes128-sha256-prfsha256-modp3072,default
#proposals = default
}
}
secrets {
ike-l2tp-ipsec {
secret = "psk-key"
id-a = 123.456.789.1
}
}
xl2tpd.confの末尾に次の項目を加えます。[lac xxxx](xxxxは何でもいいです)の後に次の項目を入力します。
/etc/xl2tpd/xl2tpd.conf
...
[lac l2tpc]
lns = 123.456.789.1
length bit =yes
autodial = yes
redial = yes
redial timeout = 10
max redials = 5
pppoptfile = /etc/ppp/options.l2tpc
options.l2tpcファイルを作成して次の項目を入力します。参考ページにあったもので動かないものは除外しました。MTU、MRU値は環境に合わせて調整してください。
/etc/ppp/options.l2tpc
name testuserpassword password
noauth
mtu 1400
mru 1400
defaultroute
persist
稼働チェック
strongSwanとxl2tpでL2TP/IPsecクライアントを構築した場合は、IPsecとL2TPがそれぞれ独立して稼働します。なのでIPsecがなくても、L2TPだけで通信できてしまいます。この状態だと暗号化されないの危険です。念のためIPsec通信できているか確認しましょう。
てっとり早い方法としてtcpdumpがあります。tcpdumpについては別記事にもまとめていますが、この場合はローカルから次のようにフィルタを作って調べます。
別のターミナルから、L2TPで取得した対抗のアドレスに対して、pingを実行してみて、そのパケットがカプセル化されているか調べます。
pingを送信したタイミングで次のようなパケットが送信されていたらIPsec通信ができていると判断します。