VPN接続が突然切断されると、Linux OSはパケットを物理ネットワークインターフェースへ自動的にフォールバック(経路変更)してしまいます。その結果、気付かないうちに本来のIPアドレスやDNSクエリがインターネット上へ丸見えになってしまいます。この現象は一瞬で発生するため、リモートワークやプライベートなブラウジング中の身元漏洩につながるリスクがあります。
Kill Switchはこの問題を解決するために設計されました。安全回路(ブレーカー)のように機能し、VPN接続が切断された瞬間に外部への通信を即座に完全遮断します。
LinuxでVPN Kill Switchを実装する手法
現在、この仕組みを導入するには主に4つのアプローチがあります。
- VPNクライアント付属の機能: 商用アプリ内のKill Switchスイッチや、設定ファイル内のup/downスクリプトフックを利用する。
- UFW(Uncomplicated Firewall): 簡潔な構文で扱いやすいが、実態はiptablesのルールを生成している。
- 従来のiptables: 古くからLinuxで使われてきた実績ある方式で、パケットフィルタリングテーブルを直接操作する。
- 最新のnftables: パケットフィルタリングの最新フレームワーク。Linuxカーネル3.13以降でiptablesを完全に置き換え、Debian 10やUbuntu 20.04以降ではデフォルトとなっている。
各ソリューションの実用的な比較
運用環境へ導入するにあたり、それぞれトレードオフが存在します。
1. VPNクライアント内蔵のKill Switch
- メリット: ワンクリックまたは簡単なコマンド1つですぐに有効化できる。
- リスク: VPNプロセスがクラッシュしたり、メモリ不足(OOM killer)で強制終了された場合に脆弱になる。プロセスが異常終了するとクリーンアップスクリプトが実行されないため、OSは通常のWi-Fiや有線LAN経由でデータを送信し続けてしまう。
2. UFWファイアウォール
- メリット: 直感的な構文で、Linux初心者でも理解しやすい。
- リスク: 仮想インターフェース(
wg0、tun0など)が頻繁にオン・オフされる環境では柔軟性に欠ける。DHCPでIPアドレスが再割り当てされた際、UFWの静的ルールによってローカルネットワーク接続が途切れてしまうトラブルが起きやすい。
3. 従来のiptables
- メリット: 普及率が高く、CentOS 7などの古いディストリビューションでもドキュメントが豊富。
- リスク: IPv4用(
iptables)とIPv6用(ip6tables)で2つの別々のファイルを作成・管理する必要がある。1行変更するだけでもカーネルがルールテーブル全体をリロードするため、CPUリソースの無駄が生じ、既存の接続が切断される可能性がある。
4. 最新のnftables
- メリット: IPv4とIPv6を単一のテーブル(
family inet)に統合可能。アトミックトランザクション方式を採用しており、実行中の接続を切断することなく数マイクロ秒で即時反映される。カーネル内で直接動作するバイトコードエンジンにより、パケットフィルタリングのパフォーマンスが非常に優れている。 - デメリット: ブロック構造の構文が独特なため、1行完結のiptablesコマンドに慣れている場合は習得に少し時間がかかる。
なぜnftablesが最も信頼できる防御壁なのか?
ネットワークセキュリティの基本原則は、「防御壁はエンドポイントのアプリケーションから独立していなければならない」という点です。VPNソフトウェアに不具合が発生しても、カーネル層の防壁はそのまま有効であり続ける必要があります。
カフェのWi-Fiや不安定なモバイル回線を利用していると、VPN接続が切断されてから1〜3秒で自動再接続することがよくあります。このわずか数秒の隙間に、システムは通常のネットワークカードを経由して何十ものDNSクエリやTCPパケットを密かに送信してしまいます。nftablesを使えば、「VPNサーバーへの接続ポートを除き、すべての外部トラフィックをブロックする」というデフォルトポリシーを定義できます。これにより、データ漏洩のリスクを根本から排除できます。
nftablesによるKill Switchの構築手順
ステップ1:ネットワーク情報の確認
ターミナルを開き、既存のネットワークインターフェース一覧を確認します:
ip -brief link
# enp3s0 UP 52:54:00:12:34:56 <BROADCAST,MULTICAST,UP,LOWER_UP>
# wg0 UNKNOWN
環境に合わせて以下のパラメータを事前に把握しておきます:
- インターネット接続用の物理インターフェース:
enp3s0(Wi-Fiの場合はwlan0など) - 仮想VPNインターフェース:
wg0(WireGuard)またはtun0(OpenVPN) - VPNサーバーのIPアドレス:
203.0.113.50 - VPNポートおよびプロトコル:
51820 UDP(WireGuard)または1194 UDP(OpenVPN) - ローカルLANのサブネット:
192.168.1.0/24(プリンター、NAS、ルーターへのアクセス用)
ステップ2:nftablesのインストール
Debian、Ubuntu、Linux Mintの場合は、次のコマンドを実行します:
sudo apt update && sudo apt install -y nftables
sudo systemctl enable nftables
ステップ3:ブロッキングルールの作成
nftablesの設定ファイルを開きます:
sudo nano /etc/nftables.conf
ファイルの内容を以下の標準ルールセットに置き換えます:
#!/usr/sbin/nft -f
flush ruleset
table inet vpn_killswitch {
chain output {
# デフォルトですべてのアウトバウンドトラフィックを破棄
type filter hook output priority filter; policy drop;
# 1. ローカルループバックを許可
oifname "lo" accept
# 2. 確立済みの正常な接続を維持
ct state established,related accept
# 3. DHCPによる内部IP割り当て要求を許可
udp dport { 67, 68 } oifname "enp3s0" accept
# 4. ローカルネットワークリソース(プリンター、ルーター、NAS)へのアクセスを許可
ip daddr 192.168.1.0/24 oifname "enp3s0" accept
# 5. 物理ポート経由のVPNサーバーとのハンドシェイク接続のみを許可
ip daddr 203.0.113.50 udp dport 51820 oifname "enp3s0" accept
# 6. VPNトンネル経由のすべての通信を許可
oifname "wg0" accept
}
chain input {
# 不正なインバウンドトラフィックを破棄
type filter hook input priority filter; policy drop;
# ループバックおよび確立済み接続の応答を許可
iifname "lo" accept
ct state established,related accept
# ローカルルーターからのDHCP応答を許可
udp sport { 67, 68 } iifname "enp3s0" accept
# LANサブネットからのパケットを許可
ip saddr 192.168.1.0/24 iifname "enp3s0" accept
}
}
ステップ4:設定の反映と有効化
システムを再起動することなく、ルールセットを即座に適用します:
sudo nft -f /etc/nftables.conf
カーネル上で現在有効なルールセットを確認します:
sudo nft list ruleset
ステップ5:漏洩防止の実機テスト
設定しただけで安心せず、必ずテストを行いましょう。以下の3ステップで切断状態をシミュレートします:
- VPNが正常に動作している状態での確認:
curl -4 ifconfig.me # VPNサーバーのIPアドレス(203.0.113.50)が返ってくることを確認 - VPN切断障害のシミュレーション:
sudo wg-quick down wg0 curl --connect-timeout 5 https://ifconfig.me5秒後にターミナルに
Connection timed outまたはCould not resolve hostと表示されれば、Kill Switchは正常に機能しています。enp3s0を経由する外部宛てパケットは、カーネルによって完全に遮断されています。 - IPv6漏洩対策の確認:
多くのプロバイダではIPv4と同時にIPv6も自動割り当てされます。この設定では
table inetでpolicy dropを適用しているため、VPNを経由しないIPv6による名前解決やデータ通信もすべて遮断され、IPv6からの身元特定リスクも防ぐことができます。
設定ファイル1つだけで、カーネル層での堅牢な保護機構を実現できます。これにより、安全なVPNトンネルが稼働している間だけデータが外部へ送信されるようになります。

