VPN接続時に「bad control packet!」が発生して通信できない件の解消法 〜Ubuntu 22.04 LTS + L2TP/IPsec〜

VPN接続時に「bad control packet!」が発生して通信できない件の解消法 〜Ubuntu 22.04 LTS + L2TP/IPsec〜
Page content

UbuntuでのVPN

職場のデスクトップマシンとしてUbuntu 22.04 LTSを新規導入してからつまずいたことの一つ、L2TP/IPsecでのVPN接続に関して。L2TP/IPsecに必要なパッケージを導入しただけの状態ではVPN接続がうまく行かないようなので、その解消方法をメモしておきます。

項目内容
OSUbuntu 22.04.2 LTS (Jammy Jellyfish) のGNOMEデスクトップ環境
VPNの接続方式L2TP/IPsec

困った現象

  1. Ubuntu標準ではVPN接続方式としてL2TP/IPsecが選択できないため、まずは次のコマンドでパッケージを導入する: sudo apt install network-manager-l2tp network-manager-l2tp-gnome
  2. L2TP/IPsecでのVPN接続を行うと、接続後にIPアドレスは取得できているのに接続先のLANへの通信ができず、syslogには次のメッセージが流れる
    $ tail -F /var/log/syslog | grep -E 'pppd|xl2tpd'
    (snip)
    Jun 13 ZZ:ZZ:ZZ ホスト名 NetworkManager[28364]: xl2tpd[28364]: check_control: Received out of order control packet on tunnel 699 (got 2, expected 3)
    Jun 13 ZZ:ZZ:ZZ ホスト名 NetworkManager[28364]: xl2tpd[28364]: handle_control: bad control packet!
    Jun 13 ZZ:ZZ:ZZ ホスト名 NetworkManager[28364]: xl2tpd[28364]: check_control: Received out of order control packet on tunnel 699 (got 2, expected 3)
    Jun 13 ZZ:ZZ:ZZ ホスト名 NetworkManager[28364]: xl2tpd[28364]: handle_control: bad control packet!
    
  3. どうやら、VPN接続後に余計なroutingが1個追加されてしまいルート設定がおかしくなるらしい
    $ route -n | grep 接続先IPアドレス
    接続先IPアドレス  0.0.0.0             255.255.255.255 UH    0      0        0 ppp0 # ←これが不要らしい
    接続先IPアドレス  ローカルIPアドレス  255.255.255.255 UGH   50     0        0 enp2s0
    

解消方法

https://github.com/nm-l2tp/NetworkManager-l2tp/issues/132#issuecomment-1155098198 の内容を参考に、loggerのオプションを少し変更しています。

  1. sudo vim /etc/ppp/ip-up.d/0001routesなどで次の内容のファイルを作成する
    #!/bin/sh
    
    # 0001routes
    # Ref: https://github.com/nm-l2tp/NetworkManager-l2tp/issues/132#issuecomment-1155098198
    
    # This script is called with the following arguments:
    # Arg Name
    # $1 Interface name
    # $2 The tty
    # $3 The link speed
    # $4 Local IP address for the interface
    # $5 Peer IP address
    # $6 Optional 'ipparam' parameter specified to pppd
    
    logger -t 0001routes "Removing wrong vpn ip address on $1 for local $4 and peer $5."
    ip addr del $4 peer $5 dev $1
    
  2. sudo chmod +x /etc/ppp/ip-up.d/0001routesで実行権限を付与する
  3. L2TP/IPsecでのVPN接続を再度試みると、上記のスクリプト0001routesが実行されてsyslogに次のメッセージが出力され、ip addr del ...が行われたであろうことがわかる
    Jun 13 ZZ:ZZ:ZZ ホスト名 0001routes: Removing wrong vpn ip address on ppp0 for local XXX.XXX.XXX.XXX and peer YYY.YYY.YYY.YYY.
    
  4. ルート設定の不具合が解消してVPN接続先と正常に通信できるはず

追記 [2023-06-14]: openfortivpnと併用できない

/etc/ppp/ip-up.d/0001routesの施策は、過去に次のリンクで紹介したopenfortivpnとどうも併用できません。必要なルート設定を削除してしまうということらしく、対策を考え中。

追記 [2023-08-08]: openfortivpnとの併用方法

上記の「openfortivpnと併用できない」問題は、ナイスな解法が思いつかず、結局のところ運用でカバーしています。具体的には、次のようなaliasを用意しておき、

alias forti-off='sudo chmod +x /etc/ppp/ip-up.d/0001routes'
alias forti-on='sudo chmod -x /etc/ppp/ip-up.d/0001routes'

openfortivpnでVPN接続を行うときにはforti-on (スクリプト0001routesを非実行化)、別のVPN接続へ切り替えるときにはforti-off (スクリプト0001routesを実行化) を実行することにしています。

参考リンク