IPアドレス範囲を別のサブネットに1:1で変換する


やりたいこと

2つのネットワークを接続したが,IPアドレスの重複があるので直接ルーティングを設定することができない.そこで接続先のIPを使われていないIP範囲に変換したい.

想定するネットワーク

Host H1(192.168.30.10)とH2(192.168.1.10)を通信させるために, 2台のLinuxサーバGW1とGW2を接続した.しかし,H2の属する 192.168.0.1/24 サブネットは Network 2で使われているため, GW1に直接ルーティングを設定して通信させることができない.

(Network 1)
    .10 192.168.30.0/24  .1     .1 192.168.1.0/24
[H1]======================[ GW1 ]================
               192.168.99.1 ||
                            ||
               192.168.99.2 ||
                       eth1 ||  .1 192.168.1.0/24  .10   
                          [ GW2 ]====================[H2] 
(Network 2)

解決策

iptables の NETMAP を使うことでNetwork 1から見たH2のIPアドレスを,Network 1で使われていない別のサブネットに変換する.

元ネタ
https://serverfault.com/questions/109569/iptables-massive-11-nat

ここでは,H2の属するサブネットのホストに, 192.0.2.x/24 でアクセスできるようにアドレス変換を行う.

アドレス変換 (192.168.1.0/24 <-> 192.0.2.0/24)

GW2に以下の設定を追加する.

iptables -t nat -A PREROUTING -d 192.0.2.0/24 -i eth1 -j NETMAP --to 192.168.1.0/24
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j NETMAP --to 192.0.2.0/24

アドレス変換を行う宛先の範囲をNetwork 1宛に限定するため, 接続しているインタフェースで対象を限定している.これがないと,Network2内の別サブネットに対してもアドレスが変換されてしまう.

ルーティング

static routingを追加する.
GW1には,192.0.2.0/24 宛のルーティングを設定する

ip route add 192.0.2.0/24 via 192.168.99.2

H1にも192.0.2.0/24 宛のルーティングを設定する.(GW1がデフォルトゲートウェイなら不要)

GW2には,192.168.30.0/24 宛のルーティングを設定する.

ip route add 192.168.30.0/24 via 192.168.99.1

H2にも192.168.30.0/24 宛のルーティングを設定する.(GW1がデフォルトゲートウェイなら不要)

ここまでの設定を行うことで, H1とH2が通信可能になる.

H1からH2へ通信: 変換後のアドレスを指定する

h1$ ping 192.0.2.10 
h1$ ssh 192.0.2.10

H2からH1へ通信: H1のアドレスをそのまま指定

h2$ ping 192.168.30.10 
h2$ ssh 1192.168.30.10

H1では, H2からの通信は変換後の192.0.2.10から接続された通信として見えます.

補足: 通信が H1->H2の片方向の場合

H1からH2方向にしか通信を開始しないのであれば, GW2にSNATを設定することでH2側のルーティング設定は不要となる.この場合はH2ではH1からの通信はGW2からの接続に見える.

GW2に以下を追加

iptables -t nat -A POSTROUTING -d 192.168.1.0/24 -j SNAT --to-source 192.168.1.1

192.168.1.1はGW2のIPアドレス

最後に

単一ホスト宛のIPを書き換える SNAT/DNATの記事は各所で見つかりますが,サブネットの範囲全体のIPアドレスを置き換える方法についての記事がなかなか見つからなかったので,こちらにまとめました.