2026年6月5日

2026年6月5日

L2TP/IPsec の VPN サーバーを構築する方法|strongSwan と xl2tpd の設定・ファイアウォールのポート・Windows / macOS / iOS からの接続

L2TP/IPsec の VPN サーバーは、strongSwan で IPsec(事前共有鍵、トランスポートモード)を張り、その中で xl2tpd が L2TP トンネルを受け、PPP でクライアントに IP アドレスを配る、という 3 層の組み合わせで動きます。設定ファイルは ipsec.conf / ipsec.secrets、xl2tpd.conf、options.xl2tpd、chap-secrets の 5 つで、迷いやすいのはファイアウォールと NAT です。

結論を先にまとめます。

  • L2TP/IPsec の利点は、Windows・macOS・iOS・Android の標準機能で追加ソフトなしに接続できることです。会社の WordPress 管理画面や SSH を「VPN 経由だけ許可」にする入口として今も使われています。
  • 必要なポートは UDP 500(IKE)、UDP 4500(NAT-T)、ESP(プロトコル 50)です。L2TP の UDP 1701 は IPsec の中を通るので、外部に直接開ける必要はありません。
  • 新しく作るなら、IKEv2(strongSwan 単体)や WireGuard の方が構成が簡単で速いです。L2TP/IPsec を選ぶ理由が「古い機器や標準クライアントで事前共有鍵だけで入りたい」である場合に限ります。
  • つながらないときの切り分け(エラー 789 / 809、NAT 越えのレジストリ)は別記事 L2TP/IPsec の VPN がつながらないときの切り分け にまとめています。
L2TP/IPsec VPN の構築の流れ。IPsec(strongSwan)の設定、L2TP と PPP の設定、ファイアウォールと NAT、クライアント接続

L2TP/IPsec の仕組み

層 担当 役割 設定ファイル
IPsec strongSwan 事前共有鍵(PSK)で IKEv1 の交渉をし、ESP で暗号化する。L2TP の UDP 1701 だけをトランスポートモードで守る /etc/ipsec.conf、/etc/ipsec.secrets
L2TP xl2tpd IPsec の中で L2TP トンネルを受け、PPP セッションを起こす /etc/xl2tpd/xl2tpd.conf
PPP pppd ユーザー名・パスワード(MS-CHAPv2)の認証、クライアントへの IP アドレスと DNS の配布 /etc/ppp/options.xl2tpd、/etc/ppp/chap-secrets

クライアントは「IPsec の事前共有鍵」と「PPP のユーザー名・パスワード」の 2 段で認証されます。事前共有鍵は全員で共通、ユーザー名・パスワードは人ごとに分ける、という運用になります。

手順 1: パッケージを入れる

Ubuntu 22.04 / 24.04、Debian 12 を前提にします。

sudo apt update
sudo apt install strongswan xl2tpd ppp

Ubuntu の strongswan パッケージは ipsec コマンドと /etc/ipsec.conf を使う構成(starter)で動きます。サービス名は strongswan-starter です(環境によっては strongswan)。

手順 2: IPsec(strongSwan)を設定する

/etc/ipsec.conf を次のように書きます。既定の内容は退避しておきます。

config setup
    uniqueids=no

conn L2TP-PSK
    keyexchange=ikev1
    authby=secret
    type=transport
    left=%defaultroute
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    ike=aes256-sha1-modp2048,aes256-sha256-modp2048,aes128-sha1-modp1024!
    esp=aes256-sha1,aes256-sha256,aes128-sha1!
    rekey=no
    forceencaps=yes
    dpdaction=clear
    dpddelay=30s
    auto=add
  • type=transport: L2TP/IPsec はトンネルモードではなくトランスポートモードで、UDP 1701 のパケットだけを守ります。
  • uniqueids=no: 同じ事前共有鍵で複数台が同時に接続するために必要です。
  • forceencaps=yes: NAT の内側のクライアント(家庭やモバイル回線はほぼ該当)のため、常に UDP 4500 でカプセル化します。
  • ike= / esp= の候補は、Windows・macOS・iOS の標準クライアントが提案する組み合わせを含めています。modp1024 は古い方式ですが、古い端末との互換性のために残しています。不要なら外してください。

事前共有鍵は /etc/ipsec.secrets に書きます。長いランダムな文字列を使います。

%any %any : PSK "ここに長いランダムな事前共有鍵"
sudo chmod 600 /etc/ipsec.secrets
sudo systemctl enable --now strongswan-starter
sudo ipsec statusall

手順 3: L2TP(xl2tpd)と PPP を設定する

/etc/xl2tpd/xl2tpd.conf を次のようにします。ip range はクライアントに配る私的なアドレス、local ip はサーバー側のアドレスで、サーバーの LAN と重ならない範囲にします。

[global]
port = 1701
ipsec saref = no

[lns default]
ip range = 10.99.0.10-10.99.0.200
local ip = 10.99.0.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
ppp debug = no
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

/etc/ppp/options.xl2tpd に PPP の設定を書きます。DNS は社内の DNS か、公開の DNS を指定します。

ipcp-accept-local
ipcp-accept-remote
ms-dns 10.99.0.1
noccp
auth
mtu 1280
mru 1280
proxyarp
lcp-echo-failure 4
lcp-echo-interval 30
connect-delay 5000
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2

ms-dns にサーバー自身を書く場合は、サーバーで DNS(unbound など)を動かしている必要があります。動かしていなければ、社内の DNS や公開 DNS の IP にします。

ユーザーは /etc/ppp/chap-secrets に 1 行ずつ書きます。形式は「ユーザー名 サーバー名 パスワード 割り当て IP」で、IP は * で自動割り当てです。

# client   server   secret                 IP addresses
taro       l2tpd    "ユーザーごとの長いパスワード"   *
sudo chmod 600 /etc/ppp/chap-secrets
sudo systemctl enable --now xl2tpd

手順 4: IP 転送・NAT・ファイアウォール

VPN 経由で社内やインターネットに出るには、カーネルの IP 転送と NAT(マスカレード)が必要です。

# IP 転送を有効にする
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-vpn.conf
sudo sysctl --system

ufw を使っている場合の例です。外向きのインターフェース名(eth0 等)は環境に合わせます。

# 受け入れるポート
sudo ufw allow 500/udp
sudo ufw allow 4500/udp
# ESP(プロトコル 50)
sudo ufw allow proto esp from any to any

/etc/ufw/before.rules の先頭(*filter より前)に NAT の節を足します。

*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.99.0.0/24 -o eth0 -j MASQUERADE
COMMIT

/etc/default/ufw の DEFAULT_FORWARD_POLICY を ACCEPT にしてから sudo ufw reload します。firewalld の環境では --add-service=ipsec(UDP 500 / 4500 と ESP)と --add-masquerade で同等の設定になります。

クラウド(AWS のセキュリティグループ、Azure の NSG など)では、OS のファイアウォールとは別に、クラウド側でも UDP 500 / 4500 を許可します。ESP は NAT 越え(UDP 4500 でのカプセル化)が使われる限り不要なことが多いですが、サーバーがパブリック IP を直接持つ構成では ESP も通します。

手順 5: クライアントから接続する

OS 標準のクライアントで入力する項目は次のとおりです。

項目 Windows 11 macOS iOS / iPadOS
設定の場所 設定 → ネットワークとインターネット → VPN → VPN 接続を追加 システム設定 → VPN → VPN 構成を追加 → L2TP over IPSec 設定 → 一般 → VPN とデバイス管理 → VPN 構成を追加 → L2TP
サーバー サーバーのホスト名または IP 同左 同左
VPN の種類 「事前共有キーを使った L2TP/IPsec」 (L2TP over IPSec を選択) (L2TP を選択)
事前共有鍵 「事前共有キー」欄 認証設定 → 共有シークレット シークレット
ユーザー名・パスワード サインイン情報 アカウント名・パスワード アカウント・パスワード

Windows で、サーバーが NAT の内側(クラウドの多くはこの構成)にあるときは、クライアント側のレジストリ AssumeUDPEncapsulationContextOnSendRule を 2 にして再起動しないと接続できません。この点と、エラー番号ごとの切り分けは L2TP/IPsec の VPN がつながらないときの切り分け に書いています。

接続できたら、サーバー側で確認します。

sudo ipsec statusall          # ESTABLISHED と INSTALLED が出る
sudo journalctl -u xl2tpd -n 30
ip addr show ppp0             # PPP のインターフェースができている

WordPress の観点: 管理画面と SSH を VPN 経由だけにする

VPN を作る目的の多くは、「WordPress の管理画面と SSH を VPN からだけ開けたい」です。VPN が動いたら、Nginx で wp-login.php と /wp-admin/ を VPN のアドレス範囲だけに許可します。

location ~ ^/(wp-login\.php|wp-admin/) {
    allow 10.99.0.0/24;     # VPN クライアント
    allow 203.0.113.10;     # 事務所の固定 IP
    deny all;
    # 以下は通常の PHP の処理
}
location = /wp-admin/admin-ajax.php {
    allow all;              # 訪問者向けの機能が使う
}

SSH も sshd_config の AllowUsers や ufw で VPN の範囲に絞ります。国別の制限と組み合わせる方法は Nginx の GeoIP2 で国別にアクセスを制限する方法 に、パスワード認証を追加で掛ける方法は Nginx でベーシック認証を設定する方法 にまとめています。

なお、Cloudflare などの CDN を前に置いているサイトでは、オリジンへの直接アクセスを CDN の IP だけに絞っているはずです。その場合は、VPN からも CDN 経由でアクセスすることになるので、Cloudflare 側の WAF ルールで VPN の出口 IP を許可します。

よくある質問

今から L2TP/IPsec を選ぶ理由はありますか

標準クライアントだけで、事前共有鍵とユーザー名・パスワードで入れることが理由になります。ただし IKEv2(strongSwan で証明書または EAP-MSCHAPv2)も Windows 7 以降・macOS・iOS の標準クライアントで使え、NAT 越えやモバイルでの再接続(MOBIKE)が L2TP/IPsec より素直です。WireGuard は専用アプリが要りますが、設定が短く速度も出ます。新規に作るなら、まず IKEv2 か WireGuard を検討し、古い機器の都合があるときだけ L2TP/IPsec にする、という順番を勧めます。

事前共有鍵は全員同じでよいのですか

L2TP/IPsec の仕組み上、事前共有鍵はサーバーに 1 つ(%any %any)で全員共通になります。人ごとに分けるのは PPP のユーザー名・パスワードです。退職者が出たら chap-secrets の行を消し、事前共有鍵も定期的に変えます。

Android からは接続できますか

Android は 12 以降で標準の VPN クライアントから L2TP/IPsec の選択肢が外されました。Android の端末が多い場合は、IKEv2 か WireGuard の方を用意する方が現実的です。

クライアントは IP を配られたのにインターネットに出られません

IP 転送(net.ipv4.ip_forward)、NAT のマスカレード、ufw の DEFAULT_FORWARD_POLICY のいずれかが抜けている典型例です。sudo sysctl net.ipv4.ip_forward、sudo iptables -t nat -L POSTROUTING -n、/etc/default/ufw の順に確かめます。

まとめ

  • L2TP/IPsec の VPN サーバーは strongSwan(IPsec、PSK、トランスポートモード)+ xl2tpd(L2TP)+ PPP(MS-CHAPv2 認証と IP 配布)の 3 層で、設定ファイルは 5 つです。
  • 外部に開けるのは UDP 500 / 4500 と ESP で、IP 転送と NAT を忘れると「つながるが出られない」状態になります。
  • 新規なら IKEv2 か WireGuard を先に検討し、L2TP/IPsec は標準クライアントと事前共有鍵が条件のときに選びます。

関連記事

参考: strongSwan Documentation、strongSwan – Windows Clients、xl2tpd(GitHub)、Microsoft Learn – Configure L2TP/IPsec server behind NAT-T device

更新履歴: 2026-11-09 全面改訂(定型文の記事を、strongSwan と xl2tpd の設定ファイル・ファイアウォール・クライアント設定・WordPress 管理画面の VPN 限定の手順に置き換え。切り分けは別記事に分離)。この記事はワードプレス博士(ライトセンド株式会社)が運営しています。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲