L2TP/IPsec VPNサーバの構築(AlmaLinux編)

L2TP/IPsec VPNサーバの構築 - koba::blog で構築したVPNサーバを日常的に利用していましたが、これもAlmaLinuxのサーバに載せ替えます。手順としてはほぼ同じですが、libreswan のバージョンが上がったため設定に変更がありました。

結論から言うと、中国の4GネットワークでのiPhoneの接続は確認できていません。中国の自宅の有線LANからは接続できるので、一旦手順を公開します。後日修正するかもしれません。

RPMパッケージのインストール

以下のパッケージをインストールします。

$ sudo dnf install -y xl2tpd libreswan

インストールされたバージョンを確認します。

$ rpm -q xl2tpd libreswan
xl2tpd-1.3.17-1.el9.x86_64
libreswan-4.12-1.el9.x86_64

xl2tpd 1.3.8 → 1.3.17、libreswan 3.15 → 4.12 とバージョンが上がっています。

前回の設定 ではネット上にある設定例を参考にしました*2が、今回設定がうまく行かず調査したところ、libreswanのページにそのものズバリの 設定例 があったので、これをベースに設定していきます。

設定内容の妥当性は以下のコマンドで確認できるので、随時確認しながら進めます。

$ sudo ipsec verify

IPsecの設定

設定するファイルは

  • /etc/ipsec.conf
  • /etc/ipsec.secrets

です。man 5 ipsec.conf および man 5 ipsec.secrets にドキュメントがインストールされています。

/etc/ipsec.conf

--- /etc/ipsec.conf	2024/01/26 23:27:20	1.1
+++ /etc/ipsec.conf	2024/01/26 23:29:15
@@ -8,7 +8,7 @@
 	# If logfile= is unset, syslog is used to send log messages too.
 	# Note that on busy VPN servers, the amount of logging can trigger
 	# syslogd (or journald) to rate limit messages.
-	#logfile=/var/log/pluto.log
+	logfile=/var/log/pluto.log
 	#
 	# Debugging should only be used to find bugs, not configuration issues!
 	# "base" regular debug, "tmi" is excessive (!) and "private" will log
@@ -33,8 +33,11 @@
 	# To enable IKE and IPsec over TCP for VPN client, also specify
 	# tcp-remote-port=4500 in the client's conn section.
 
+	ikev1-policy=accept
+	uniqueids=no
+
 # if it exists, include system wide crypto-policy defaults
-include /etc/crypto-policies/back-ends/libreswan.config
+#include /etc/crypto-policies/back-ends/libreswan.config
 
 # It is best to add your IPsec connections as separate files
 # in /etc/ipsec.d/

このファイルには全体に関わる config セクションのみを記述し、個々の接続方法設定する conn セクションは

include /etc/ipsec.d/*.conf

のようにインクルードします。

logfile
デバッグログの出力先
ikev1-policy
現在の版ではL2TP(すなわちIKEv1)を使う場合 accept を指定する必要がある(以前との変更点)
/etc/ipsec.d/l2tp-ipsec.conf

ipsec.conf から読み込まれるファイルです。新規に作成し、以下の内容でL2TP VPN用の conn セクションを設定します。

conn L2TP-PSK
	authby=secret
	pfs=no
	auto=add
	rekey=no
	left=%defaultroute
	right=%any
	ikev2=never
	type=transport
	leftprotoport=17/1701
	rightprotoport=17/%any
	dpddelay=15
	dpdtimeout=30
	dpdaction=clear

conn L2TP-PSK-NAT
	also=L2TP-PSK
	rightsubnet=0.0.0.0/0

現在の版ではL2TP(すなわちIKEv1)を使う場合 ikev2never を指定する必要があります。(以前との変更点)

/etc/ipsec.secrets

ここでは設定は行わず、

include /etc/ipsec.d/*.secrets

と個々の接続方法ごとにインクルードします。

/etc/ipsec.d/default.secrets

isecd.conf から読み込まれるファイルです。L2TP VPN用の「共有シークレット」*3を設定します。

: PSK "psksecrets"

psksecrets が共有シークレットです。本来は16バイト以上で設定すべきらしいですが、「共有」として周知される内容なので短く設定される場合が多いようです。

L2TPの設定

設定するファイルは

  • /etc/xl2tpd/xl2tpd.conf
  • /etc/ppp/options.xl2tpd
  • /etc/ppp/chap-secrets

です。

/etc/xl2tpd/xl2tpd.conf

xl2tpd の設定ファイルです。man 5 xl2tpd.conf にドキュメントがあります。

--- /etc/xl2tpd/xl2tpd.conf	2024/01/26 23:35:15	1.1
+++ /etc/xl2tpd/xl2tpd.conf	2024/01/26 23:36:45
@@ -15,7 +15,7 @@
 ; will be used by xl2tpd as its address on pppX interfaces.
 
 [global]
-; listen-addr = 192.168.1.98
+listen-addr = 160.16.70.50
 ;
 ; requires openswan-2.5.18 or higher - Also does not yet work in combination
 ; with kernel mode l2tp as present in linux 2.6.23+
@@ -29,8 +29,8 @@
 ; debug tunnel = yes
 
 [lns default]
-ip range = 192.168.1.128-192.168.1.254
-local ip = 192.168.1.99
+ip range = 192.168.0.101-192.168.0.105
+local ip = 192.168.0.1
 require chap = yes
 refuse pap = yes
 require authentication = yes
listen-addr
サーバの外部アドレス
local ip
サーバの内部アドレス
ip range
クライアントに払い出す内部IPアドレスの範囲

/etc/ppp/options.xl2tpd

xl2tpd が pppd 起動時に指定するオプション(man 8 pppd にドキュメントがあります)を設定するファイルです。ファイル名は xl2tpd.conf の pppoptfile の指定と一致させる必要があります。

--- /etc/ppp/options.xl2tpd	2024/01/26 23:37:32	1.1
+++ /etc/ppp/options.xl2tpd	2024/01/26 23:38:20
@@ -6,7 +6,7 @@
 # ms-dns  192.168.1.3
 # ms-wins 192.168.1.2
 # ms-wins 192.168.1.4
-noccp
+# noccp
 auth
 #obsolete: crtscts
 idle 1800
@@ -25,3 +25,10 @@
 # You need to join the domain on the server, for example using samba:
 # http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients-lucid.html
 
+name xl2tpd
+refuse-pap
+refuse-chap
+refuse-mschap
+require-mschap-v2
+persist
+logfile /var/log/xl2tpd.log

ログファイルはあらかじめ作成しておきます。

$ sudo touch /var/log/xl2tpd.log

/etc/ppp/chap-secrets

pppd のCHAP認証設定ファイルです。xl2tpd 用の認証設定を追加します。

--- /etc/ppp/chap-secrets	2024/01/26 23:40:01	1.1
+++ /etc/ppp/chap-secrets	2024/01/26 23:40:59
@@ -1,2 +1,3 @@
 # Secrets for authentication using CHAP
 # client	server	secret			IP addresses
+"user"		"xl2tpd"	"password"	*
client
接続者の使うユーザ名
server
/etc/ppp/options.xl2tpdname の設定値と合わせる
secret
接続者の使うパスワード
IP addresses
接続を許可するIPアドレス。* は任意を表す

ファイアウォールの設定

ファイアウォールを設定します。IPsec(500/UDP, 4500/UDP, 4500/TCP)と L2TP(1701/UDP, 4500/UDP)が使用するポートを開放し、IPマスカレードを有効にします。

$ sudo firewall-cmd --permanent --add-service=ipsec
$ sudo firewall-cmd --permanent --add-port=1701/udp
$ sudo firewall-cmd --permanent --add-port=4500/udp
$ sudo firewall-cmd --permanent --add-masquerade
$ sudo firewall-cmd --reload

設定状態を確認します。

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: cockpit dhcpv6-client ipsec ssh
  ports: 1701/udp 4500/udp
  protocols: 
  forward: yes
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

カーネルパラメータの設定

/etc/sysctl.d/50-libreswan.conf を修正します。

--- /etc/sysctl.d/50-libreswan.conf	2024/01/24 21:36:17	1.1
+++ /etc/sysctl.d/50-libreswan.conf	2024/01/24 23:20:59
@@ -10,3 +10,12 @@
 net.ipv4.conf.default.accept_redirects = 0
 net.ipv4.conf.all.send_redirects = 0
 net.ipv4.conf.all.accept_redirects = 0
+
+net.ipv4.ip_forward = 1
+net.ipv4.conf.default.rp_filter = 0
+net.ipv4.conf.all.rp_filter = 0
+net.ipv4.conf.ens3.rp_filter = 0
+net.ipv4.conf.ens4.rp_filter = 0
+net.ipv4.conf.ens5.rp_filter = 0
+net.ipv4.conf.lo.rp_filter = 0
+net.ipv4.conf.ip_vti0.rp_filter = 0

ip_forward を有効に、各インタフェースの rp_filter を無効に設定します。

設定をカーネルに反映します。

$ sudo sysctl --system

サービス起動

IPsec および L2TP のサービスを起動します。

$ sudo systemctl enable ipsec
$ sudo systemctl enable xl2tpd
$ sudo systemctl restart ipsec
$ sudo systemctl restart xl2tpd

設定の確認

最後に設定状況を確認します。

$ sudo ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                   	[OK]
Libreswan 4.12
Checking for IPsec support in kernel              	[OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects              	[OK]
         ICMP default/accept_redirects            	[OK]
         XFRM larval drop                         	[OK]
Pluto ipsec.conf syntax                           	[OK]
Checking rp_filter                                	[OK]
Checking that pluto is running                    	[OK]
 Pluto listening for IKE on udp 500               	[OK]
 Pluto listening for IKE/NAT-T on udp 4500        	[OK]
 Pluto ipsec.secret syntax                        	[OBSOLETE]
  003 WARNING: using a weak secret (PSK)
Checking 'ip' command                             	[OK]
Checking 'iptables' command                       	[OK]
Checking 'prelink' command does not interfere with FIPS	[OK]
Checking for obsolete ipsec.conf options          	[OK]

共有シークレットの長さに問題ありますが、それ以外はOKという結果です。

接続確認

実際に接続してみます。自宅の中国聯通の有線LANからは接続できますが、同じ中国聯通の4GネットワークからiPhone SEで接続を試みると、/var/log/pluto.log に以下のログが残されて接続できません。

Jan 27 09:03:09.011443: "L2TP-PSK"[4] 42.84.233.5 #6: responding to Main Mode from unknown peer 42.84.233.5:39311
Jan 27 09:03:09.011688: "L2TP-PSK"[4] 42.84.233.5 #6: WARNING: connection L2TP-PSK PSK length of 3 bytes is too short for HMAC_SHA2_256 PRF in FIPS mode (16 bytes required)
Jan 27 09:03:09.011792: "L2TP-PSK"[4] 42.84.233.5 #6: sent Main Mode R1
Jan 27 09:03:09.175897: "L2TP-PSK"[4] 42.84.233.5 #6: sent Main Mode R2
Jan 27 09:03:09.326878: "L2TP-PSK"[4] 42.84.233.5 #6: ignoring informational payload IPSEC_INITIAL_CONTACT, msgid=00000000, length=28
Jan 27 09:03:09.326947: "L2TP-PSK"[4] 42.84.233.5 #6: Peer ID is ID_IPV4_ADDR: '10.19.90.102'
Jan 27 09:03:09.327518: "L2TP-PSK"[4] 42.84.233.5 #6: IKE SA established {auth=PRESHARED_KEY cipher=AES_CBC_256 integ=HMAC_SHA2_256 group=MODP2048}
Jan 27 09:03:12.386691: "L2TP-PSK"[4] 42.84.233.5 #6: retransmitting in response to duplicate packet; already STATE_MAIN_R3
Jan 27 09:03:15.577079: "L2TP-PSK"[4] 42.84.233.5 #6: retransmitting in response to duplicate packet; already STATE_MAIN_R3
Jan 27 09:03:18.756693: "L2TP-PSK"[4] 42.84.233.5 #6: discarding duplicate packet -- exhausted retransmission; already STATE_MAIN_R3
Jan 27 09:03:31.446583: "L2TP-PSK"[4] 42.84.233.5 #6: discarding duplicate packet -- exhausted retransmission; already STATE_MAIN_R3

同じiPhoneで自宅の有線LANに設置したWi-Fiルータを経由して接続すると接続できるので、4Gネットワークの問題ではないかと疑っています。しかしながら CentOS + libreswan 3.15 で構築したVPNサーバのときは4Gから接続できていたので、設定でカバーできるのではと思い、パラメータ変更を試みます。

*1:EPEL からインストールするので リポジトリの追加 が必要です

*2:なんというコピペプログラマしぐさ!

*3:Windowsでは「事前共有キー」と呼ばれる