|||||||||||||||||||||

なんぶ電子

- 更新: 

strongSwanの新しい設定方法(vici)

strongswan

前回設定したstrongSwanのipsec.conf、ipsec.sercretsを使った設定方法は、現在では非推奨となっていて、swanctl.confファイルを利用する方法に置き換えられています。

せっかく設定しましたが、推奨されるswanctlで再度設定をします。

swanctlのインストール

swanctl.confはviciインターフェースで利用され、起動や停止などはswanctlというコマンドで操作します。まずはそのstrongswan-swanctlをインストールします。

# apt install 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 -q
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のパケットを許可します。

-A INPUT -p udp --dport 1701 -j ACCEPT

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 testuser
password password
noauth
mtu 1400
mru 1400
defaultroute
persist

稼働チェック

strongSwanとxl2tpでL2TP/IPsecクライアントを構築した場合は、IPsecとL2TPがそれぞれ独立して稼働します。なのでIPsecがなくても、L2TPだけで通信できてしまいます。この状態だと暗号化されないの危険です。念のためIPsec通信できているか確認しましょう。

てっとり早い方法としてtcpdumpがあります。tcpdumpについては別記事にもまとめていますが、この場合はローカルから次のようにフィルタを作って調べます。

# tcpdump -i インターフェース名 dst host 123.456.789.1

別のターミナルから、L2TPで取得した対抗のアドレスに対して、pingを実行してみて、そのパケットがカプセル化されているか調べます。

pingを送信したタイミングで次のようなパケットが送信されていたらIPsec通信ができていると判断します。

...192.168.1.1.ipsec-nat-t > l2tpserver.jp.ipsec-nat-t: UDP-encap: ESP(...

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告