IPSec/L2TPでVPN通信を行うための設定例をご紹介します。
※注意事項※
Armadillo Base OSではOpen VPNのクライアントとしての機能を有しています。
これを利用するとGUIで設定ファイルを読み込ませるだけで簡単にVPN接続が可能となりますので、
VPNを利用する必要がある場合に、方式の指定が無ければOpenVPNを利用されることをお勧めいたします。
どうしてもIPSecを使用する必要がある場合はこの記事をご参考ください。
今回は、StrongSwanとXL2TPDというソフトウェアを使ってIPSec通信を行います。 ABOSに直接インストールして使用することも可能ですが、 コンテナにインストールして使用する方法もありますので、今回はこちらをご案内します。
設定手順
システム構成
今回はクライアント・サーバ両方をArmadilloとコンテナにて構築しました。
本来はインターネットを経由して通信確認を行うものですが、グローバルIPを用意できなかったため、
ローカルネットワーク内での検証となりました。
Armadillo-IoT A6EとArmadillo-IoT G4を同一LAN内に設置しています。
L2TPでトンネリングを行って、その上でIPSecによる暗号化を行います。
Armadillo-IoT A6Eをサーバ、Armadillo-IoT G4をクライアントとして動作させ、
サーバからクライアントにIPアドレスを割り当てています。
以下の手順はこの構成を想定したものでありますので、 ご自身の環境に合わせて設定や実行手順を適宜変更してください。
ソフト構成
Alpine LinuxベースのコンテナにStrongSwanとxl2tpdをインストールします。 このコンテナのネットワークはhostモードで動作させ、ホストOSのネットワークインタフェースを直接操作します。 StrongSwanやxl2tpdの設定ファイルはコンテナイメージ内に直接配置せず、 マウントされているABOSの書き込み可能領域に配置して、これをコピーして使用させています。 これにより、設定の変更が必要な場合はコンテナイメージはそのままでファイルのみを書き換えるだけで変更が可能です。
手順
準備
サーバ/クライアントとなるArmadilloのIPアドレスを確認しておいてください。
サーバを構築する場合はクライアントから接続するIPアドレスを、クライアントを構築する場合はサーバに接続するインタフェースのIPアドレスを確認しておいてください。
またサーバからクライアントに割り当てられるIPアドレスの範囲についても確認しておいてください。
プロジェクト作成: VSCodeでABOSDEのメニューからshell new projectでプロジェクトを新規作成します。
Dockerfile編集
Alpine Linuxのコンテナイメージを使用するためにDockerfileを編集します。 冒頭のコンテナイメージ指定箇所を「debian:bullseye-slim」から「alpine:latest」に変更します。 これに合わせて、「apt-get update && apt-get upgrade -y && apt-get install -y」を「apk update && apk upgrade && apk add -f」に変更します。
packages.txtファイル編集
strongswanとxl2tpdを追加します。
app.confファイル編集
以下を追加します。
「add_hotplugs /dev/tty」L2TPでttyデバイスを使用するため 「set_network host」ネットワークをhostモードで動作させるため 「add_args --privileged」ネットワークデバイスの追加などに権限が必要なため
設定ファイル作成(クライアント側):
以下のファイルを/app/srcの下に作成します。
・xl2tpd.conf L2TPの接続設定を行うためのファイル
[global]
auth file = /etc/ppp/chap-secrets
port = 1701
[lns default]
;pap認証・chap認証・ユーザ認証など必要に応じて変更してください。
refuse pap = yes
refuse chap = yes
require authentication = yes
hostname = xl2tpd
ppp debug = yes
;L2TP Access Concentrator(LAC)は、L2TPトンネルを受け入れる側の装置やソフトウェアを指します。通常、LACはクライアントからのL2TP接続を受け入れ、認証やトンネルの確立を行います。
;「[lac]」セクションでは、LACの構成に関連するパラメータや設定を記述します。
[lac l2tpc]
lns = 192.168.11.59
length bit = yes
autodial = yes
redial = yes
redial timeout = 10
max redials = 5
;「pppoptfile」とは、ポイントツーポイントプロトコル(PPP)接続の構成パラメータを含むPPPオプションファイルを指します。このファイルは、認証方法、暗号化オプション、DNSサーバーなど、PPP接続に関連する設定を指定するために使用されます。ファイル名は任意です。
pppoptfile= /etc/ppp/options.l2tpd
・options.l2tpd
name [任意のユーザ名]
password [任意のパスワード]
noauth
mtu 1400
mru 1400
defaultroute
persist
・chap-secrets PPP接続に使用するユーザ名・パスワードなどを設定するファイル
# Secrets for authentication using CHAP
# client server secret IP addresses
[任意のユーザ名] * [任意のパスワード] *
・swanctl.conf IPSecの設定を行うためのファイル
connections {
#任意のコネクション名
ipsec-test {
#自身のIPアドレス(L2TP接続後に払い出されるIPアドレス)
local_addrs=192.168.1.0/24
#サーバのIPアドレス(L2TP接続後のIPアドレス)
remote_addrs=192.168.1.99
local {
#認証方法の指定:PreSharedKeyを使う
auth = psk
#クライアントの任意のID(サーバ側でも使用する)
id = g4
}
remote {
auth = psk
#サーバのID(サーバ側で設定したものと同じIDを記載する)
id = a6e
}
children {
#詳細設定(proposalsやmodeは環境に応じて設定してください。
l2tp-ipsec {
#サーバのアドレス(L2TP接続後のIPアドレス)
remote_ts = 192.168.1.99
#接続確立時に何かさせたい場合、ここでスクリプトを指定する
updown = /vol_app/src/updown.sh
start_action = start
close_action = start
dpd_action = start
#暗号化アルゴリズム認証アルゴリズム鍵交換方式などの設定
esp_proposals = default
#IPSecの通信モードの設定 ここではトランスポートモードに設定
mode = transport
}
}
keyingtries = 3
version = 0
#暗号化アルゴリズム認証アルゴリズム鍵交換方式などの設定
proposals = aes128-sha256-prfsha256-modp3072,default
}
}
#PSKの設定
secrets {
ike-l2tp-ipsec {
#クライアントのID
id-a = g4
#サーバに接続するためのPSK
secret = "[任意のPSK]"
}
}
設定ファイル作成(サーバ側)
クライアント側と同様に以下のファイルを/app/srcの下に作成します。
・xl2tpd.conf L2TPの接続設定を行うためのファイル
[global]
auth file=/etc/ppp/chap-secrets
[lns default]
;PPP接続時にクライアントに対して割り当てるIPアドレスの範囲
ip range = 192.168.1.128-192.168.1.254
;PPP接続時のサーバのIPアドレス
local ip = 192.168.1.99
refuse pap = yes
refuse chap = yes
require authentication = yes
hostname = localserver
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
・options.l2tpd PPPオプションファイル
name xl2tpd
ipcp-accept-local
ipcp-accept-remote
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
nodefaultroute
nobsdcomp
mtu 1372
mru 1372
・chap-secrets PPP接続に使用するユーザ名・パスワードなどを設定するファイル
# Secrets for authentication using CHAP
# client server secret IP addresses
[任意のユーザ名] * [任意のパスワード] *
・swanctl.conf IPSecの設定を行うためのファイル
connections {
#任意のコネクション名
ctlserver {
#サーバのIPアドレス(L2TP接続後のIPアドレス)
local_addrs=192.168.1.99
local {
auth = psk
id = a6e
}
remote {
auth = psk
}
children {
l2tp-ipsec {
#サーバのIPアドレス(L2TP接続後のIPアドレス)
local_ts = 192.168.1.99[udp/1701]
#クライアントのIPアドレス(L2TP接続後に割り振られるIPアドレス範囲)
remote_ts = 192.168.1.0/24[udp/1701]
start_action = none
close_action = none
dpd_action = none
mode = transport
}
}
keyingtries = 3
version = 0
proposals = aes128-sha256-prfsha256-modp3072,default
}
}
secrets {
ike-l2tp-ipsec {
#クライアントのID
id = g4
#サーバに接続するためのPSK
secret = "[任意のPSK]"
}
}
main.shファイル編集
設定ファイルを所定のディレクトリにコピーして、
IPSecを起動、設定ファイルを指定してxl2tpdを実行、
swanctlコマンドでIPSecサーバ/クライアントを実行します。
(サーバ側)
#!/bin/bash -e
cp /vol_app/src/swanctl.conf /etc/swanctl/conf.d/
cp /vol_app/src/chap-secrets /etc/ppp/
cp /vol_app/src/options.xl2tpd /etc/ppp/
ipsec start
sleep 30
xl2tpd -D -c /vol_app/src/xl2tpd.conf &
swanctl -q
sleep infinity
(クライアント側)
#!/bin/bash -e
cp /vol_app/src/swanctl.conf /etc/swanctl/conf.d/
cp /vol_app/src/chap-secrets /etc/ppp/
cp /vol_app/src/options.l2tpc /etc/ppp/
ipsec start
sleep 30
xl2tpd -D -c /vol_app/src/xl2tpd.conf &
swanctl -q
swanctl -i -c l2tp-ipsec
sleep infinity
以上を踏まえてコンテナをビルド→転送して実行すると、IPSec/L2TPで通信が行われます。
動作確認
サーバ・クライアントそれぞれでifconfigコマンドを実行し、
「ppp〇」というネットワークデバイスが作成され、サーバ側が192.168.1.99・クライアント側が192.168.1.128となっていることを確認します。
サーバ側にtsharkをインストールしてパケットが暗号化されていることを確認します。
クライアント側からpingを実行
/ # ping 192.168.1.99
PING 192.168.1.99 (192.168.1.99): 56 data bytes
64 bytes from 192.168.1.99: seq=0 ttl=64 time=11.024 ms
64 bytes from 192.168.1.99: seq=1 ttl=64 time=5.583 ms
サーバ側でパケットをモニタリング
armadillo:~# tshark -i ppp0
Capturing on 'ppp0'
1 0.000000000 192.168.1.128 → 192.168.1.99 ESP 136 ESP (SPI=0xcf9ef92d)
2 0.000506296 192.168.1.99 → 192.168.1.128 ESP 136 ESP (SPI=0xc6d65f20)
3 1.000080123 192.168.1.128 → 192.168.1.99 ESP 136 ESP (SPI=0xcf9ef92d)
ICMPではなくESPとして表示される