備忘録的なもの

DH2/modp1024 を使っている L2TP/IPSec な VPN に接続するためのメモ

毎回どういうことなのか、どうやって繋いだかを忘れて調べながら設定する羽目になってるのでメモとして残す。

背景

今の職場では L2TP/IPSec な VPN を使っていて、勤怠とかの社内システムにはそれ経由じゃないとアクセスできない様になっている。

自分のマシンから繋ぐ際 1 の環境としては、例によって OS (ディストリビューション) は ArchLinux でネットワークの管理に NetworkManager 、 L2TP/IPSec 接続のために以下のパッケージを使っている。

  • community/networkmanager-l2tp
  • aur/libreswan

ただ、単純にこれらのパッケージを AUR から入れて NetworkManager で VPN の設定をしただけだと接続に失敗する。

journalctl で失敗時の NetworkManager.service ipsec.service 辺りのログを見ても、 「あぁコレが原因か」というログを見つけられず「 IKEv1 の途中で何故かタイムアウトで失敗してるっぽい?」くらいしか分からなかったのだが、 色々調べたり試した結果から言うと VPN サーバとクライアントの両方で利用可能な鍵交換方式が存在せず、 結果として IPSec の最初のネゴシエーションが完了せず失敗、ということらしかった。

IPSec でのネゴシエーション失敗について

まず「 IPSec の最初のネゴシエーションに失敗する」という部分について、 IPSec 自体について調べたことと合わせて今回の状況をざっくりまとめる。

IPSec はその処理の中でいくつかのプロトコルを組み合わせて使っている。

  • 通信データの改ざん防止のための認証ヘッダを付加する AH (Authentication Header)
  • データのカプセル化を行う ESP (Encapsulating Security Payload)
  • 鍵交換を行う IKE (Internet Key Exchange)

また、それぞれのプロトコルの中で使う具体的な暗号方式等のネゴシエーションは、 IPSec での通信の最初の方にある IKE プロトコルの中で行っている。 そしてネゴシエーションの結果を VPN サーバのアドレス等の情報と合わせて SA (Security Association) と呼ばれるパラメータセット 2 にまとめ、 これを使って通信を行うような流れになっている。

この IKE の中に、鍵交換に使う Diffie-Hellman グループのネゴシエーションと実際の鍵交換処理が含まれるのだが、 当然 VPN サーバとクライアントの両方で使用可能なグループが存在しないと通信できないことになる。

しかし今回の場合それが存在せず、ネゴシエーションが成功しないというのが接続失敗の原因らしかった。

実際に VPN サーバ側で利用可能なグループを確認すると以下のような感じになる。

❯ sudo ./ike-scan.sh <VPNサーバのアドレス> | grep SA=
        SA=(Enc=3DES Hash=SHA1 Group=2:modp1024 Auth=PSK LifeType=Seconds LifeDuration=28800)
        SA=(Enc=3DES Hash=SHA1 Group=2:modp1024 Auth=RSA_Sig LifeType=Seconds LifeDuration=28800)
確認方法について

Known Issues · nm-l2tp/NetworkManager-l2tp Wiki · GitHub

こちら参考に、というかそのままスクリプトを作って VPN サーバに対してスキャンを行っている。 問題ないとは思うがネットワーク越しに対向をスキャンする行為ではあるので、実行する際はそのことを認識しておいた方が良いかもしれない。

スクリプトの中で使っている ike-scan コマンドは AUR にもあるので、 yay -S ike-scan とかでインストールできる。

#!/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

上記の通り VPN サーバ側は Diffie-Hellman グループとして DH2/modp1024 しか対応してないのだが、 この DH2/modp1024 はもはやセキュアじゃないって事でデフォルトではやサポートされなくなってきている。

なので、この DH2/modp1024 使えない問題を回避する必要があり、以下で行っているのはその作業になる。

設定作業

ということで、 DH2/modp1024 を自分のマシン側で使えるようにする必要があるのだが、 実のところ networkmanager-l2tp にしても libreswan にしても実装としては残っているので大した作業は必要なく、 ビルド時に必要なパラメータを指定してビルドし直してやれば使えるようになる。

各パッケージの PKGBUILD を取ってきて現状を確認する。

  • aur/libreswan (4.12-1)
    • ビルド時に USE_DH2=true を指定する必要がある
❯ yay -G libreswan
:: (1/1) Downloaded PKGBUILD: libreswan

❯ cat libreswan/PKGBUILD
〜(省略)〜

# https://git.centos.org/rpms/libreswan/blob/c8s/f/SPECS/libreswan.spec
_bargs=(
  FINALLIBEXECDIR='/usr/lib/ipsec'
  #INC_MANDIR='/usr/share/man'
  FINALMANDIR='/usr/share/man'
  FINALSBINDIR='/usr/bin'
  #INC_USRLOCAL='/usr' # required by 3.32 for /usr/share/doc
  PREFIX='/usr'
  USE_DNSSEC=false
  USE_LABELED_IPSEC=false
  USE_LIBCAP_NG=true
  USE_DH2=true # insecure modp1024

  USE_LEAK_DETECTIVE=false
  USE_XAUTH=true
)

〜(省略)〜

build() {
  set -u
  cd "${_srcdir}"

  # Disable new warning introduced with GCC 6 (-Wunused-const-variable=)
  local _cf=(
    #-Wno-error=sign-compare
    #-Wno-error=unused-const-variable
    #-Wno-error=implicit-fallthrough
    #-Wno-error=maybe-uninitialized
    #-Wno-error=pointer-compare
    #-Wno-error=format-truncation
    #-DNSS_PKCS11_2_0_COMPAT=1 # nss 3.52 https://github.com/libreswan/libreswan/issues/342
    -Wno-error=unused-result
  )

  CFLAGS="${CFLAGS} ${_cf[*]}" \
  nice make -s "${_bargs[@]}" programs
  set +u
}

〜(省略)〜
  • aur/networkmanager-l2tp (1.20.10-1)
    • ビルド時に --enable-libreswan-dh2 を指定する必要がある
❯ yay -G networkmanager-l2tp
:: (1/1) ABS から PKGBUILD をダウンロード: networkmanager-l2tp

❯ cat networkmanager-l2tp/PKGBUILD

〜(省略)〜

build() {
  export NOCONFIGURE=1
  cd $pkgname-$pkgver
  ./autogen.sh
  ./configure \
    --libexecdir=/usr/lib/NetworkManager \
    --localstatedir=/var \
    --prefix=/usr \
    --sysconfdir=/etc \
    --with-pppd-plugin-dir=/usr/lib/pppd/$_pppver \
    --with-gtk4
  sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
  make
}

〜(省略)〜

以上の通り、 libreswan の方はこのままで良いが networkmanager-l2tp の方はビルドし直す必要があることが分かるので、 PKGBUILD を修正してビルドし直す。

また、修正してインストールしたパッケージが AUR の方でバージョンアップがあった際に置き換えられないように、 modified グループに追加して AUR ヘルパーでのアップデート時に無視するような設定もついでに足しておく。

  • networkmanager-l2tp/PKGBUILD
@@ -22,6 +22,7 @@
   'strongswan: IPSec support')
 source=("$pkgname-$pkgver.tar.gz"::"$url/archive/$pkgver.tar.gz")
 b2sums=('d2958b9aa803ffb498ed9481ef1726587f881570a247c0f9d06738a2188adf3130e3a91fa3facb67994bd6add196caeb6344a94ef04b4785c5389ed511343258')
+groups=('modified')

 prepare() {
   ln -sf NetworkManager-l2tp-$pkgver $pkgname-$pkgver
@@ -37,7 +38,8 @@
     --prefix=/usr \
     --sysconfdir=/etc \
     --with-pppd-plugin-dir=/usr/lib/pppd/$_pppver \
-    --with-gtk4
+    --with-gtk4 \
+    --enable-libreswan-dh2
   sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
   make
 }
  • /etc/pacman.conf
@@ -24,6 +24,7 @@
 # Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
 #IgnorePkg   =
 #IgnoreGroup =
+IgnoreGroup = modified

 #NoUpgrade   =
 #NoExtract   =

で、ビルドしてインストールする。

❯ cd networkmanager-l2tp/

❯ makepkg -si
==> パッケージを作成: networkmanager-l2tp 1.20.10-1 (2024年02月11日 07時30分23秒)

〜(省略)〜

❯ yay -Qs networkmanager-l2tp
local/networkmanager-l2tp 1.20.10-1 (modified)
    L2TP support for NetworkManager

あとは NetworkManager で VPN の設定をすれば接続が成功する。( IPSec の設定に注意する)

NetworkManager での VPN 設定の画面キャプチャ
NetworkManager での VPN 設定の IPSec 部分の画面キャプチャ
NetworkManager での VPN 設定のPPP 部分の画面キャプチャ

おわりに

調べた感じ今回の DH2/modp1024 は危殆化を理由に使われなくなってきているという理解をしているのだが、 Windows や Mac 使ってる人からは特にこういった話もなく普通に繋がっているらしい( DH2/modp1024 を標準でサポートしている?)ので、 実際のところどのくらい気にするものなんだろうかというのは若干気になる。

おそらくは関連する CVE とかいろんなソフトウェアの対応傾向とかを整理して各々で対応決めているんだろうとは思うが、 その辺りの調べ方というか判断のコツというか勘所というかがあんまりわかってなく、時間ばっかりかかりそうだったので自分は少しググったくらいで諦めてしまった。

参考


  1. 基本的には会社からそれなりのノート PC ( Windows ノート or Macbook Pro )が支給されるのだが、希望すれば私物マシンでの作業も許される感じ (コロナ流行で急遽始まったリモートワークに伴う一時的な例外措置が整備されずに残っているだけ説がある) ↩︎

  2. 正確には SA は確立したコネクション自体を指すが、実質的にパラメータセットと言えるというのが正しいらしい ↩︎