Raspberry Pi L2TP/IPsec VPNクライアントの構築

Raspberry Pi

はじめに

本記事では、Raspberry Piを使用して、VPNサーバにL2TP/IPsecを使用して接続する方法について記載いたします。L2TP/IPsecは、主にPC等を使用して、会社や自宅のネットワークに接続する際に使用されます。通信の内容は、IPsecにより暗号化が行われるため、安全に通信を行うことができます。本記事では、IPsecプロトコルを実装したstrongSwanとL2TPプロトコルを実装したxl2tpdを使用します。

環境

  1. ボート
    Raspberry Pi 4 Model B
  2. OS
    Raspberry Pi OS with desktop
    Release date: January 11th 2021
    Kernel version: 5.4

L2TP/IPsecについて

L2TP/IPsecの概要が分かれば、「strongSwan」および「xl2tpd」の設定を行う際に、何についての設定を行っているかが理解しやすいと思いますので、はじめに、「L2TP/IPsec」の概要について説明いたします。

L2TPは、PPTPとL2FのL2トンネリングプロトコルの仕様を統合して、IETFにより標準化されたプロトコルです。L2TPでは、PPPプロトコルの機能を使用して、ユーザー認証やIPアドレス、ゲートウェイ等の配布に関する機能が提供されます。しかし、通信を暗号化する機能がないため、暗号化機能を追加するため、L3トンネリングプロトコルである「IPsec」と組み合わせて使用されます。このため、「L2TP/IPsec」などと呼ばれています。
L2TP/IPsecでは、接続する際、暗号化されていない中でL2TP通信を開始するのではなく、IPsecで暗号化された中でL2TP通信を開始します。
次に、L2TP/IPsecにおける通信の開始手順の概要を記載します。

  1. L2TP/IPsecでは、はじめに通信を暗号化するために、IPsecプロトコルを使用して、接続先との間にIPsecトンネルを作成します。
    接続先と接続元の双方でIPsecトンネルを確立するために、事前共有鍵(PSK:Pre-Shared Key)やデジタル証明書が使用されます。
  2. この暗号化されたIPsecトンネルを使用して、L2TPプロトコルを使用して通信を開始します。
    PPPプロトコルと同様に接続元のユーザー認証のために、ユーザーIDとパスワードが使用されます。ユーザー認証後、IPアドレスやゲートウェイ、DNSサーバ情報の配布や設定が行われます。

L2TP/IPsecによるVPN接続を行うためには、「事前共有鍵(PSK:Pre-Shared Key)」、「ユーザーID」、「パスワード」が必要になります。

事前準備

Raspberry Pi OSのパッケージ一覧及びインストール済みパッケージを更新します。

pi@raspberrypi:~ $ sudo apt update
pi@raspberrypi:~ $ sudo apt upgrade
pi@raspberrypi:~ $

パッケージ更新が完了したら、Raspberry Pi OSを最新状態にするために再起動を行います。

pi@raspberrypi:~ $ sudo reboot

strongSwan、xl2tpdおよびike-scanのインストール

strongSwan、xl2tpdおよびike-scanパッケージのインストールを行います。
ike-scanは、L2TP/IPsec VPN サーバが使用しているIPsecのアルゴリズムを確認することができるユーティリティです。

pi@raspberrypi:~ $ sudo apt install strongswan xl2tpd ike-scan
pi@raspberrypi:~ $

本記事で、インストールを行ったバージョンは、以下のとおりです。

pi@raspberrypi:~ $ ipsec --version
Linux strongSwan U5.7.2/K5.10.11-v7l+
University of Applied Sciences Rapperswil, Switzerland
See 'ipsec --copyright' for copyright information.
pi@raspberrypi:~ $
pi@raspberrypi:~ $ xl2tpd -v

xl2tpd version:  xl2tpd-1.3.12
pi@raspberrypi:~ $
pi@raspberrypi:~ $ ike-scan --version
ike-scan 1.9.4

Copyright (C) 2003-2009 Roy Hills, NTA Monitor Ltd.
ike-scan comes with NO WARRANTY to the extent permitted by law.
You may redistribute copies of ike-scan under the terms of the GNU
General Public License.
For more information about these matters, see the file named COPYING.

$Id$
$Id$
$Id$
$Id$
$Id$
pi@raspberrypi:~ $

IPsecアルゴリズムの確認

ike-scanを使用して、L2TP/IPsec VPNサーバで利用可能なIPsecのアルゴリズムの確認を行います。

シェルスクリプトの作成

ike-scanを使用して、暗号化アルゴリズム、ハッシュアルゴリズム、Diff-Hellmanグループ、認証方式の全ての組み合わせで、アルゴリズムを確認するため、以下の「ike-scan.sh」シェルスクリプトを作成します。

pi@raspberrypi:~ $ vi ike-scan.sh

【記載内容】
#!/usr/bin/sh

# Encryption algorithms: 3des=5, aes128=7/128, aes192=7/192, aes256=7/256
ENCLIST="5 7/128 7/192 7/256"
# Hash algorithms: md5=1, sha1=2, sha256=5, sha384=6, sha512=7
HASHLIST="1 2 5 6 7"
# Diffie-Hellman groups: 1, 2, 5, 14, 15, 19, 20, 21
GROUPLIST="1 2 5 14 15 19 20 21"
# Authentication method: Preshared Key=1, RSA signatures=3
AUTHLIST="1 3"

for ENC in $ENCLIST; do
    for HASH in $HASHLIST; do
        for GROUP in $GROUPLIST; do
            for AUTH in $AUTHLIST; do
                echo ike-scan --trans=$ENC,$HASH,$AUTH,$GROUP -M "$@"
                ike-scan --trans=$ENC,$HASH,$AUTH,$GROUP -M "$@"
            done
        done
    done
done

pi@raspberrypi:~ $

作成した「ipsec-scan.sh」シェルスクリプトに実行権限を設定します。

pi@raspberrypi:~ $ chmod a+x ike-scan.sh
pi@raspberrypi:~ $ ls -l
total 8
~(略)~
-rwxr-xr-x 1 pi pi  672 Feb  5 14:38 ike-scan.sh
~(略)~
pi@raspberrypi:~ $

アルゴリズムの確認

「ike-scan.sh」スクリプトを実行すると、以下のように結果が表示されます。
(※「a.b.c.d」は、接続先のL2TP/IPsec VPNサーバのアドレスに適宜置き換えてください。)

pi@raspberrypi:~ $ sudo ./ike-scan.sh a.b.c.d | grep SA=
        SA=(Enc=3DES Hash=SHA1 Auth=PSK Group=2:modp1024 LifeType=Seconds LifeDuration(4)=0x00007080)
        SA=(Enc=AES Hash=SHA1 Auth=PSK Group=2:modp1024 KeyLength=128 LifeType=Seconds LifeDuration(4)=0x00007080)
        SA=(Enc=AES Hash=SHA1 Auth=PSK Group=2:modp1024 KeyLength=256 LifeType=Seconds LifeDuration(4)=0x00007080)
pi@raspberrypi:~ $

この結果からIPsecのフェーズ1で利用可能なアルゴリズムが分かります。
例えば、3行目の結果から、「aes256-sha1-modp1024」アルゴリズムが利用でき、認証は事前共有鍵(PSK)が使用できることがわかります。
IPsecで利用可能なアルゴリズムが分かりましたので、以降では、strongSwan及びxl2tpdの設定を行います。

strongSwanの設定

strongSwanの設定を行い、IPsecトンネルを構成します。

ipsec.confファイルの設定

以下のように、「/etc/ipsec.config」ファイルを編集します。

pi@raspberrypi:~ $ sudo vi /etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
        # strictcrlpolicy=yes
        # uniqueids = no

# Add connections here.

conn vpn01
        # IPsecのモード指定(トランスポートモード)
        type=transport
        # 認証方式(事前共有鍵による認証)
        authby=secret
        # 鍵交換アルゴリズム(ikev1)
        keyexchange=ikev1
        # 
        rekey=yes
        # 
        keyingtries=1

        # IPsecフェーズ1で使用するアルゴリズム
        ike=aes256-sha1-modp1024
        # IPsecフェーズ2で使用するアルゴリズム
        esp=aes256-sha1

        # 接続元のIPアドレス
        # (L2TP/IPsec VPNサーバから配布されるアドレスを使用)
        left=%any
        # 接続元のポート設定
        # (L2TPで使用するUDPの1701番ポート)
        leftprotoport=udp/1701

        # 接続先のIPアドレス
        # (L2TP/IPsec VPNサーバのアドレス)
        right=a.b.c.d
        # 接続先のポート
        # (L2TPで使用するUDPの1701番ポート)
        rightprotoport=udp/1701

        # 接続が閉じられた場合の動作
        # (再接続)
        closeaction=restart
        # Dead Pear Detection時の動作
        # (再接続)
        dpdaction=restart

        # 起動時の動作(自動接続)
        auto=start

include /var/lib/strongswan/ipsec.conf.inc
pi@raspberrypi:~ $

ipsec.secretsファイルの設定

次に、「/etc/ipsec.secrets」ファイルを編集し、使用する事前共有鍵(PSK:Pre-Shared Key)を設定します。
「a.b.c.d」には、接続先のL2TP/IPsec VPNサーバのIPアドレスを記載します。
「pre-shared key」には、事前共有鍵を記載します。
(注:各フィールドの間のスペースに気を付けてください。)

pi@raspberrypi:~ $ sudo vi /etc/ipsec.secrets

【記載内容】
# This file holds shared secrets or RSA private keys for authentication.
a.b.c.d : PSK "pre-shared key"  <= 事前共有鍵を記載

# RSA private key for this host, authenticating it to any other host
# which knows the public part.

# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/ipsec.secrets.inc

接続確認

設定内容を反映させるため、strongSwanの再起動を行います。

pi@raspberrypi:~ $ sudo systemctl restart ipsec
pi@raspberrypi:~ $

以下のように、接続確認を行います。

pi@raspberrypi:~ $ sudo ipsec status
Security Associations (1 up, 0 connecting):
       vpn01[1]: ESTABLISHED 13 seconds ago, xxx.xxx.xxx.xxx[xxx.xxx.xxx.xxx]...yyy.yyy.yyy.yyy[yyy.yyy.yyy.yyy]
       vpn01{1}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c3b32246_i 21a729e4_o
       vpn01{1}:   xxx.xxx.xxx.xxx/32[udp/l2f] === yyy.yyy.yyy.yyy/32[udp/l2f]
pi@raspberrypi:~ $

「ESTABLISHED」と記載されていれば、問題なくIPsecトンネルが確立されています。

xl2tpdの設定

strongSwanの設定でIPsecトンネルが作成できましたので、次に、xl2tpdの設定を行い、L2TPトンネルを構成します。

xl2tpd.confファイルの設定

以下のように、「/etc/xl2tpd/xl2tpd.conf」ファイルを編集します。

pi@raspberrypi:~ $ sudo vi /etc/xl2tpd/xl2tpd.conf

【記載内容】
;
; Sample l2tpd configuration file
;
; This example file should give you some idea of how the options for l2tpd
; should work.  The best place to look for a list of all options is in
; the source code itself, until I have the time to write better documentation :)
; Specifically, the file "file.c" contains a list of commands at the end.
;
; You most definitely don't have to spell out everything as it is done here
;
; コメントアウトを解除
[global]                               ; Global parameters:
; コメントアウトを解除
port = 1701                            ; * Bind to port 1701
; auth file = /etc/l2tpd/l2tp-secrets  ; * Where our challenge secrets are
; access control = yes    ; * Refuse connections without IP match
; rand source = dev       ; Source for entropy for random
;                         ; numbers, options are:
;                           ; dev - reads of /dev/urandom
;                           ; sys - uses rand()
;                           ; egd - reads from egd socket
;                           ; egd is not yet implemented

; <以下を追記>
[lac vpn01]
lns = aaa.bbb.ccc.ddd                    ; L2TP/IPsec VPNサーバのアドレスを記載
require chap = yes                       ; CHAP認証を使用
refuse pap = no                          ; PAP認証は使用しない
require authentication = yes             ; 認証を要求
pppoptfile = /etc/ppp/options.l2tpd.lac  ; 使用するpppdオプションファイルを指定
length bit = yes
redial = yes
redial timeout = 10
max redials = 5

pi@raspberrypi:~ $

options.l2tpd.lacファイルの設定

「/etc/ppp/options.l2tpd.lac」ファイルの設定を行い、PPPに関するパラメータ設定を行います。
「mtu」、「mru」は、小さめに設定していますので、ご使用の環境に合わせて設定してください。

pi@raspberrypi:~ $ sudo vi /etc/ppp/options.l2tpd.lac
name "user"
noauth
mtu 1210
mru 1210
defaultroute
persist
logfile /var/log/xl2tpd.log

pi@raspberrypi:~ $

chap-secretsファイルの設定

「/etc/ppp/chap-secrets」ファイルを編集し、CHAP認証で使用する名前、パスワード、IP アドレスを設定します。
第1フィールドに「ユーザーID」を記載します。
第2フィールドに「*」を記載します。
第3フィールドに「パスワード」を記載します。
第4フィールドに「*」を記載します。

pi@raspberrypi:~ $ sudo vi /etc/ppp/chap-secrets

【記載内容】
# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
user      *       password       *

pi@raspberrypi:~ $

接続

設定内容を反映させるため、strongSwanおよびxl2tpdを再起動します。
注:必ずstrongSwanサービスおよびxl2tpdサービスを停止した後、strongSwanサービスを起動してからxl2tpdサービスを起動してください。

pi@raspberrypi:~ $ sudo systemctl stop xl2tpd.service
pi@raspberrypi:~ $ sudo systemctl stop ipsec.service
pi@raspberrypi:~ $ sudo systemctl start ipsec.service
pi@raspberrypi:~ $ sudo systemctl start xl2tpd.service
pi@raspberrypi:~ $

次に、IPsecトンネルが構築されていることを確認します。

pi@raspberrypi:~ $ sudo ipsec status
Security Associations (1 up, 0 connecting):
       vpn01[1]: ESTABLISHED 13 seconds ago, xxx.xxx.xxx.xxx[xxx.xxx.xxx.xxx]...yyy.yyy.yyy.yyy[yyy.yyy.yyy.yyy]
       vpn01{1}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c3b32246_i 21a729e4_o
       vpn01{1}:   xxx.xxx.xxx.xxx/32[udp/l2f] === yyy.yyy.yyy.yyy/32[udp/l2f]
pi@raspberrypi:~ $

次に、L2TPトンネルを構築します。
ここで、「vpn01」は、「xl2tpd.conf」ファイルで記載したトンネル名です。

pi@raspberrypi:~ $ sudo xl2tpd-control connect vpn01
pi@raspberrypi:~ $

接続確認

以下のように、「pppX」インターフェイスが作成されているか確認します。

pi@raspberrypi:~ $ ip a
~(略)~
9: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1210 qdisc pfifo_fast state UNKNOWN group default qlen 3
    link/ppp
    inet xxx.xxx.xxx.xxx peer xxx.xxx.xxx.254/32 scope global ppp0
       valid_lft forever preferred_lft forever
pi@raspberrypi:~ $

「pppX」というインターフェイスが作成されていれば、問題なくL2TPトンネルが構築され、L2TP/IPsecで接続されています。

経路情報等の自動設定

L2TP/IPsecの接続が確立されると、pppdは、「/etc/ppp/ip-up.d/」ディレクトリを確認します。このディレクトリにシェルスクリプトが存在し、かつ実行可能になっている場合、pppdは、そのシェルスクリプトを実行します。
したがって、このシェルスクリプトに接続が確立された時に実行したい経路情報の設定やその他の設定を行うコマンドを記載しておけば、接続が確立されるたびに自動的に実行されるようになります。
しかし、シェルスクリプトを記載する際に、注意しなければならいことがあります。
/etc/ppp/ip-up.d/ディレクトリのシェルスクリプトは、すべてのppp接続の際に実行されるシェルスクリプトであるため、その接続に応じたコマンドが正しく実行されるように記載する必要があります。
このため、pppdからシェルスクリプトにいくつかのパラメータが渡されるようになっていますので、このパラメータを使用して、接続(インターフェイス)ごとに正しくコマンドが実行されるように記載します。

パラメータ内容
$1pppdが使うインターフェイス名(例:ppp0)
$2ttyデバイス名
$3ttyデバイス速度
$4インターフェイスのローカルIPアドレス
$5リモートのIPアドレス
$6pppdのipparamオプションで指定するパラメータ

例えば、ppp0インターフェイスで接続された場合に、スタティックルートを追加するには、以下のように記載します。(ここでは、シェルスクリプトファイルを「addroute」とします。)

pi@raspberrypi:~ $ sudo vi /etc/ppp/ip-up.d/addroute

【記載内容】
#!/bin/sh
# ppp.ip-up hook script for route

if [ -n "`echo $1 | grep ppp`" ]; then
    route add -net 192.168.10.0 netmask 255.255.255.0 dev $1  <-- スタティックルートの追加
fi

exit 0

pi@raspberrypi:~ $

次に、以下のとおり、シェルスクリプトに実行可能権限を付与します。

pi@raspberrypi:~ $ sudo chmod +x /etc/ppp/ip-up.d/addroute
pi@raspberrypi:~ $

その他

以下に、IPsecトンネルおよびL2TPトンネルの構築および閉じるコマンドを記載します。

L2TPトンネルを構築する場合

pi@raspberrypi:~ $ sudo xl2tpd-control connect <トンネル名>
pi@raspberrypi:~ $

L2TPトンネルを閉じる場合

pi@raspberrypi:~ $ sudo xl2tpd-control disconnect <トンネル名>
pi@raspberrypi:~ $

IPsecトンネルを構築する場合

pi@raspberrypi:~ $ sudo ipsec up <コネクション名>
pi@raspberrypi:~ $

IPsecトンネルを閉じる場合

pi@raspberrypi:~ $ sudo ipsec down <コネクション名>
pi@raspberrypi:~ $

以上です。

タイトルとURLをコピーしました