それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

linuxのiptablesでルータを作る

iptablesでルータを作る

Ubuntu Linuxiptablesを使って、ネットワークの練習をする。WEBサイトに潤沢な検索結果があってとくにメモを残してない。

いつもiptablesを検索し直してて非効率なので、ここらで一旦まとめ直しておく。

今回は、lxc ホストと ip netns を使って作ることにする。

ネットワーク構成を考える。

実際の構成

ネットワーク構成をLXCと ip netns を駆使して次のように構成する。

準備 (構成を作る)

lxc でコンテナを作成し、デバイスを追加し、ip nets でネットワークを名前空間で作る。

## コンテナ作成
lxc launch ubuntu:22.04 t01
lxc config set t01 security.nesting true
lxc restart t01
lxc shell t01

## デバイス追加
ip link add name veth0 type veth peer name veth0-c01
ip netns add c01
ip link set veth0-c01 netns c01
ip netns exec c01 ip link set veth0-c01 name eth0
ip link set veth0 name eth1

## アドレス追加
ip netns exec c01 ip addr add 10.2.0.2/24 dev eth0
ip addr add 10.2.0.1/24 dev eth1

## リンクアップ
ip netns exec c01 ip link set eth0 up
ip link set eth1 up

## ルーティング
ip netns exec c01 ip route add default via 10.2.0.1 dev eth0

マスカレードを作る

準備した構成を使ってMASQURADEを作る

## マスカレード
iptables -t nat -A POSTROUTING -o eth0 -s 10.2.0.0/24 -j MASQUERADE
## パケット送信して確認
ip netns exec c01 ping 1.1.1.1

後片付け

## 後片付け
iptables -t nat -D POSTROUTING -o eth0 -s 10.2.0.0/24 -j MASQUERADE

SNAT / source NAT を作る

## SNAT
iptables -t nat -A POSTROUTING -o eth0 -s 10.2.0.0/24 -j SNAT --to-source 10.78.33.235
## 後片付け
iptables -t nat -D POSTROUTING -o eth0 -s 10.2.0.0/24 -j SNAT --to-source 10.78.33.235
## パケット送信して確認
ip netns exec c01 ping 1.1.1.1

DNAT / destination NATを作る

DNATの例 1

# eth0 に入った tcp ポート 334宛 のパケットは10.2.0.2に転送する
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 334 -j DNAT --to-destination 10.2.0.2

接続の確認

## リッスン(サーバ)
takuya@t01:~$ ip netns exec c01 nc -l 10.2.0.2 334
## 接続(クライアント)
takuya@raspi-ubuntu:~$ nc 10.78.33.235 334

DNATの例2.1

# eth0 に入った tcp://10.78.33.235:334 宛 のパケットはtcp://10.2.0.2:334に転送する
iptables -t nat -A PREROUTING -i eth0 -p tcp -d 10.78.33.235 --dport 334 -j DNAT --to-destination 10.2.0.2

DNATの例2.2

# eth0 に入った tcp://10.78.33.235:334 宛 のパケットはtcp://10.2.0.2:3304に転送する
iptables -t nat -A PREROUTING -i eth0 -p tcp -d 10.78.33.235 --dport 334 -j DNAT --to-destination 10.2.0.2:3304

DNATの例3 icmp

# eth0 に入った icmpパケットはすべて10.2.0.2に転送する
iptables -t nat -A PREROUTING -i eth0 -p icmp -j DNAT --to-destination 10.2.0.2

接続の確認

## パケット確認
takuya@t01:~$ tcpdump -n -i eth1 icmp # パケットがでていくことを確認
## パケット送信
takuya@raspi-ubuntu:~$ watch -dc -n 1 ping -c 1  10.17.238.144

DNATの例4 UDP

# eth0 に入った icmpパケットはすべて10.2.0.2に転送する
iptables -t nat -A PREROUTING -i eth0 -p udp --port 443 -j DNAT --to-destination 10.2.0.2

接続の確認

## リッスン(サーバ)
takuya@t01:~$ ip netns exec c01 nc -l -u 10.2.0.2 334
## 接続(クライアント)
takuya@raspi-ubuntu:~$ nc  -u 10.78.33.235 334

DNATを試すときの注意。

  • pingで送信しっぱなししてても、icmp_seq で継続パケットになり、送信先の切替が起きないため、watchで1回きりの送信を継続する。
  • t01 からパケット送出すると自分自身からなので、OUTPUTをとおり、PREROUTINGを取らないのでDNATにならない
  • DNATでは、-d IP を省略して -d 0.0.0.0/0すれば、eth0 を通るすべてのパケットが対象になる。
  • ncコマンドは nc -l ip porttcpサーバー nc ip portでクライアントになる。適当にキーボードを叩いてEnterする。
  • nc コマンドは nc -uUDPになる。

パケットのフォワードとルーティング・テーブルの関係

次のように、ルーティングテーブルを参照して転送される。

iptablesはこのルーティング・テーブルの前後に挟み込まれる。

制限をかける。

まとめ

ipablesのフックポイントの全体像

おまけ

ルーティング・テーブルを切り替えてみる。

iptablesはルーティング・テーブルを切り替えると、インタフェースが変わるのを体験する。

ネットワーク構成(コンテナ+bridge+netns)を作る

veth2/ br1 の2つのNICのどちらを使うかを選ぶようにする。

構成を作る

## コンテナ準備
lxc restart t01
lxc shell t01


## デバイス追加
ip link add br1 type bridge
ip link add name veth1 type veth peer name veth1-br1
ip link add name veth2 type veth peer name veth2-br1
ip link set veth1-br1 master br1
ip link set veth2-br1 master br1

## netns 作成
ip netns add c01
ip link set veth1 netns c01
ip netns exec c01 ip link set veth1 name eth0


## IP割当
ip addr add 10.2.0.1/24 dev br1
ip addr add 10.2.0.3/24 dev veth2 
ip netns exec c01 ip addr add 10.2.0.2/24 dev eth0

## リンクアップ
ip link set br1 up
ip link set veth2 up
ip link set veth1-br1 up
ip link set veth2-br1 up
ip netns exec c01 ip link set eth0 up
ip netns exec c01 ip link set lo up

## ルーティング
ip netns exec c01 ip route add default via 10.2.0.1 

netns c01 のデフォルトGWを切り替えて試す。

## パケットのフィルタリング
ip netns exec c01 iptables -t mangle -I POSTROUTING -o eth0 -j DROP 

## デフォルト・ゲートウェイの指定
ip netns exec c01 ip route add default via 10.2.0.1
## 後片付け
ip netns exec c01 ip route del default via 10.2.0.1
## デフォルト・ゲートウェイを切り替える。
ip netns exec c01 ip route add default via 10.2.0.3
## 後片付け
ip netns exec c01 ip route del default via 10.2.0.3
## veth2 経由はbr-veth間を通信として処理する。
sudo sysctl net.bridge.bridge-nf-call-iptables=0
## ipの切替時にarp/neighリフレッシュが必要かもしれない、
ip netns exec c01 ip neigh flush dev eth0

2023-10-18

DNAT書いてなかったので、書いた。