2026年6月29日
2026年6月29日
IPIPトンネルで2台のLinuxサーバーを接続する方法|ip tunnelの設定・永続化・暗号化の注意点
IPIP(IP in IP)は、IPv4 パケットをもう1枚の IPv4 ヘッダーで包んで別のサーバーへ届ける、いちばん単純なトンネルです。Linux なら追加ソフトなしで ip tunnel コマンドだけで張れますが、通信は暗号化されません。この記事では、2台の Linux サーバーを IPIP でつなぐ手順、再起動後も残す設定、つながらないときの確認方法、そして「インターネット越しに使うなら暗号化を足すか別の方式を選ぶ」判断までを説明します。
作業前に、両サーバーのネットワーク設定ファイルを控えてください。リモートのサーバーでは、設定を誤っても戻せるように、コンソール接続(VPS のブラウザコンソールなど)を使える状態にしてから始めます。
IPIPの仕組みと向いている場面
IPIP は RFC 2003 で定められた方式で、外側の IP ヘッダーのプロトコル番号は 4 です。TCP(6)や UDP(17)とは別のプロトコルなので、ファイアウォールでは「ポート」ではなく「プロトコル番号 4」を許可します。ここを見落としてつながらない例が多くあります。
特徴を整理すると次のとおりです。
- 追加されるヘッダーは 20 バイトだけで、オーバーヘッドが小さい
- 運べるのは IPv4 のユニキャストだけ。マルチキャストやブロードキャスト、IPv6 は通せない(複数プロトコルを通すなら GRE を検討)
- 暗号化も認証もない。中身はそのまま読める状態で経路を流れる
- 送信元の IP アドレスしか確認しないため、なりすましに弱い
このため、IPIP が向いているのは、同じデータセンター内や事業者の閉じたネットワークの中で経路を作りたい場合です。Kubernetes のネットワークプラグイン Calico が IP-in-IP モードを持っているのも、こうした「信頼できる網の中での経路づくり」の用途です。Web サーバーと DB サーバーをインターネット越しにつなぐ用途なら、後述のとおり WireGuard など暗号化つきの方式を選ぶほうが安全です。
構成例と事前に確認すること
以下の例では、次の2台をつなぎます。IP アドレスは説明用の値なので、自分の環境に置き換えてください。
| サーバーA | サーバーB | |
|---|---|---|
| 外側の IP(実際の IP) | 203.0.113.10 | 198.51.100.20 |
| トンネル内の IP | 10.10.0.1/30 | 10.10.0.2/30 |
始める前に次を確かめます。
- 両サーバーが互いの外側の IP に到達できること(
ping 198.51.100.20など) - ipip カーネルモジュールが使えること。
sudo modprobe ipipを実行し、lsmod | grep ipipで表示されれば利用できます。コンテナ型の VPS などではモジュールを読み込めない場合があります - クラウドや VPS のファイアウォール(セキュリティグループなど)でプロトコル番号 4 を許可できるか。事業者によっては TCP/UDP/ICMP 以外を通さない、または管理画面で個別に許可が要る場合があるため、事業者のドキュメントで確認してください
ip tunnel でトンネルを作る
サーバーAで次を実行します。local が自分の外側 IP、remote が相手の外側 IP です。
# サーバーA
sudo ip tunnel add ipip0 mode ipip local 203.0.113.10 remote 198.51.100.20 ttl 255
sudo ip addr add 10.10.0.1/30 dev ipip0
sudo ip link set ipip0 up
サーバーBでは local と remote を入れ替えます。
# サーバーB
sudo ip tunnel add ipip0 mode ipip local 198.51.100.20 remote 203.0.113.10 ttl 255
sudo ip addr add 10.10.0.2/30 dev ipip0
sudo ip link set ipip0 up
ttl 255 は外側ヘッダーの TTL を固定する指定です。省略すると中のパケットの TTL を引き継ぐため、経路が長い環境で途中で捨てられることがあります。
状態は ip -d link show ipip0 で確認できます。表示に ipip と local / remote の値が出ていれば作成できています。MTU は通常の 1500 から 20 バイト引いた 1480 前後になっているはずです。
ファイアウォールでプロトコル4を許可する
両サーバーで、相手の外側 IP からのプロトコル 4 だけを受け付けます。すべての送信元から許可すると、第三者が偽のトンネルパケットを送り込めるため、送信元を相手に絞ります。
# iptables の例(サーバーA。サーバーBでは送信元を 203.0.113.10 にする)
sudo iptables -A INPUT -p 4 -s 198.51.100.20 -j ACCEPT
# nftables の例(inet filter テーブルと input チェーンがある前提)
sudo nft add rule inet filter input ip saddr 198.51.100.20 ip protocol 4 accept
プロトコルは番号の 4 で書くのが無難です。/etc/protocols では番号 4 が ipencap、番号 94 が ipip という名前になっていることが多く、名前で書くと別のプロトコルを許可してしまうおそれがあります。
UFW を使っている場合は、UFW の設定とは別に iptables を直接書くと再読み込みで消えることがあります。UFW の before.rules に追記するなど、使っている管理ツールの流儀に合わせてください。
疎通を確認する
サーバーAから、トンネル内の相手の IP に ping します。
ping -c 4 10.10.0.2
応答がない場合は、外側の物理インターフェースでパケットが出入りしているかを tcpdump で見ます。インターフェース名(eth0 など)は ip addr で確認してください。
sudo tcpdump -ni eth0 'ip proto 4'
- 自分から出ていくパケットしか見えない → 相手側のファイアウォール、事業者側のフィルター、相手のトンネル設定(local / remote の取り違え)を疑う
- 相手から届いているのに応答しない → 自分のファイアウォールで落ちている、またはトンネル内 IP の設定ミス
- 何も出ていかない → ipip0 が up になっていない、ping の宛先がトンネル内 IP になっていない
背後のネットワークへ経路を通す
トンネルの両端だけでなく、サーバーBの背後にある 192.168.20.0/24 にもサーバーAから届かせたい場合は、経路の追加と IP 転送の有効化が要ります。
# サーバーA:192.168.20.0/24 宛てをトンネル経由にする
sudo ip route add 192.168.20.0/24 via 10.10.0.2 dev ipip0
# サーバーB:IP 転送を有効にする(永続化は /etc/sysctl.d/ に書く)
sudo sysctl -w net.ipv4.ip_forward=1
背後のネットワーク側にも、10.10.0.0/30 宛ての戻りの経路が必要です。戻りの経路がないと、行きは届いても応答が返ってきません。また、カーネルの逆経路フィルター(rp_filter)が厳格な設定だと、トンネルから入ってきたパケットを捨てることがあります。sysctl net.ipv4.conf.all.rp_filter の値を確認し、問題がある場合は該当インターフェースだけ緩める(2 にする)ことを検討します。
再起動後も残るようにする
ip tunnel で作った設定は再起動で消えます。永続化の方法はディストリビューションのネットワーク管理方式によって異なります。systemd-networkd を直接使っている環境なら、次のように書けます。
# /etc/systemd/network/ipip0.netdev
[NetDev]
Name=ipip0
Kind=ipip
[Tunnel]
Local=203.0.113.10
Remote=198.51.100.20
TTL=255
# /etc/systemd/network/ipip0.network
[Match]
Name=ipip0
[Network]
Address=10.10.0.1/30
さらに、外側の物理インターフェース用の .network ファイルの [Network] セクションに Tunnel=ipip0 を追記します。これがないとトンネルが作られません。反映は sudo networkctl reload などで行います。
Ubuntu で netplan を使っている場合は、netplan が systemd-networkd の設定を生成するため、netplan の YAML の tunnels: で mode: ipip を指定する方法に揃えたほうが管理が混乱しません。NetworkManager の環境では nmcli の ip-tunnel 接続として作れます。どの方式も書式が版によって変わることがあるため、使っている版のマニュアルで確認してください。
インターネット越しに使うなら暗号化を足す
IPIP の中身は暗号化されないため、インターネットを経由させると、途中の経路でデータベースの通信や管理画面の Cookie が読まれるおそれがあります。インターネット越しにサーバー同士をつなぐ場合は、次のどちらかにしてください。
- WireGuard を使う。設定量は IPIP と大きく変わらず、暗号化と相手の認証がつく
- IPIP の上に IPsec(トランスポートモード)を重ねる。既存の IPIP 構成を残したい場合の選択肢
WordPress の Web サーバーから別サーバーの MySQL / MariaDB に接続する構成なら、トンネルとは別に DB 接続そのものを TLS で暗号化する方法もあります。
まとめ
- IPIP はプロトコル番号 4 を使う、IPv4 専用で暗号化なしの軽量トンネル
ip tunnel add ... mode ipip local 自分 remote 相手を両側で設定し、トンネル内 IP を割り当てる- ファイアウォールではポートではなくプロトコル 4 を、相手の IP に限定して許可する
- つながらないときは tcpdump の
ip proto 4で、どちら側でパケットが消えているかを見る - 再起動後も残すには、systemd-networkd・netplan・NetworkManager のうち使っている方式で設定する
- インターネット越しなら WireGuard か IPsec で暗号化する。時間とともに事業者のフィルター仕様や各ツールの書式は変わるため、作業時に公式ドキュメントで確認してください(2026年10月現在)