ipv6 NATをnftables
v4 の masquerade は次のようになっていた。
nft を使ってv4 を作る単純な例は次のようになる。
# テーブル追加 nft add table my_nat44 # テーブルにフィルタチェーンを追加 nft add chain my_nat44 postrouting { type nat hook postrouting priority 100 \; } # masquerade する nft add rule my_nat44 postrouting oifname "eth1" masquerade
これは省略形が含まれる。familyを省略せずに書くと、次のようになっている。
nft add table ip my_nat44 nft add chain ip my_nat44 postrouting { type nat hook postrouting priority 100 \; } nft add rule ip my_nat44 postrouting oifname "eth1" masquerade
消す場合は
nft delete table ip my_nat44
ip は IPv4 のことで、IPv6 の場合は ip6と書くので ip -> ip6
に変える
nft add table ip6 my_nat66 nft add chain ip6 my_nat66 postrouting { type nat hook postrouting priority 100 \; } nft add rule ip6 my_nat66 postrouting oifname "eth1" masquerade
nft の一般例で「ipは省略される」
を思い出すのが大事。ipはIPv4を表し、IPv6はip6と記述する。これを思い出しておく、neftablesを扱うときは常に省略に注意を払う。
実際にやってみる。
次のような構成を作る。
構成を作る(LXD)
router としてのマシン作る
lxc launch ubuntu: router01
lan 側のnicn をrouter に挿し込む
lxc config device add router01 mytap0 nic nictype=macvlan parent=eth0 lxc exec router01 dhclient -v eth1
クライアントを作成する
lxc launch ubuntu: client01
2台分をアップデートすると時間がもったいないので、apt-cacherを使う。
echo 'Acquire::HTTP::Proxy "http://apt-cacher.lan:3142";' |sudo tee /etc/apt/apt.conf.d/01proxy apt update apt upgrade -y
メイン ルーター
メインルータにアドレスを追加。
ip addr add fd11:0801::1/64 dev br-lan
router01にアドレスを追加
ip addr add fd11:0801::2/64 dev eth1 ip addr add fc33:3e1f::1/64 dev eth0
client01 にアドレスを追加
ip addr add fc33:3e1f::2/64 dev eth0
疎通チェック
ssh main-router -- ping fd11:0801::1 lxc exec router01 -- ping fd11:0801::1 lxc exec router01 -- ping fc33:3e1f::2 lxc exec client01 -- ping fc33:3e1f::1
まだこの状態では、NATをしていないので、パケットが通らないこと粉を確認
lxc exec client01 -- ping fd11:0801::1
パケットを転送する
router01 がv6 をForwardするように構成。これで、v6パケットが転送される。
lxc exec router01 -- sysctl -w net.ipv6.conf.all.forwarding=1
eth0 から受けたパケットをeth1へ転送するようにする。
経路を変える。
デフォルトのルートを削除する。
lxc exec client01 -- ip -6 route del default
v6アドレスは、すべてrouter01 へ向けてやる
lxc exec client01 -- ip -6 route add default via fc33:3e1f::1
この状態では、メインルータにICMP6が届くが、アドレス変換が掛かってない。そのため、メインルータは戻りパケットの送信先がわからない。
lxc exec client01 -- ping fd11:0801::1
ルータはにはパケット届いているのがわかる。
root@# ssh main-router -- tcpdump -n -i br-lan icmp6 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on br-lan, link-type EN10MB (Ethernet), capture size 262144 bytes 18:20:56.536041 IP6 fc33:3e1f::2 > fd11:801::1: ICMP6, echo request, seq 4, length 64
この状態で通信するためには、選択肢は2つある。1つは戻りパケット経路を入れる、もう一つはNATする。この2つである。今回は、マスカレードを調べているので、NATする。
NAT・Masqueradeする。
router01 でマスカレードを構成すれば、通信できるはず。
lxc shell router01
nft / nftables をする。マスカレードする。
nft add table ip6 my_nat66 nft add chain ip6 my_nat66 postrouting { type nat hook postrouting priority 100 \; } nft add rule ip6 my_nat66 postrouting oifname "eth1" masquerade
疎通を確認する
lxc exec client -- ping fd11:0801::1
ちゃんとパケットの応答が出てくる。
PING fd11:0801::1(fd11:801::1) 56 data bytes 64 bytes from fd11:801::1: icmp_seq=1 ttl=63 time=1.71 ms 64 bytes from fd11:801::1: icmp_seq=2 ttl=63 time=1.34 ms 64 bytes from fd11:801::1: icmp_seq=3 ttl=63 time=1.21 ms
念のためにtcpdump で、NATしていることを確認する
メイン・ルータで確認
root# ssh router 'tcpdump -n -i br-lan icmp6' tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on br-lan, link-type EN10MB (Ethernet), capture size 262144 bytes 18:27:27.517512 IP6 fd11:801::2 > fd11:801::1: ICMP6, echo request, seq 1, length 64
中間にいる router01で確認
lxc exec router01 -- tcpdump -n -i eth1 icmp6 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes 09:28:53.183917 IP6 fd11:801::2 > fd11:801::1: ICMP6, echo request, id 62941, seq 1, length 64 09:28:53.184916 IP6 fd11:801::1 > fd11:801::2: ICMP6, echo reply, id 62941, seq 1, length 64
ちゃんと、NATしていることがわかる。
結論
nftablesでも3行あれば、IPv6 でもNAT変換して 'Unique Local Unicast' をグローバルユニキャストに変換してネットに出ていけることがわかる。
ポエム。nat66 による匿名性とセキュリティ
NATがないと、匿名性の確保が困難になる。また別の経路での通信(VPN)が困難である。すべてのIPv6端末にファイアウォール設定が必要になる。
ユーザ追跡が容易に可能になる。そのため、プライバシー面で問題だと思う。IPv6の使い捨てアドレスを追加で割り当てたとしてもプレフィックスは変わらない。なので、使い捨てアドレスがあってもNATしても、ユーザー追跡性は同じようなものである。NATを否定する理由にならない。
グローバルv6アドレスでグローバル通信を許可すると、機器はNAT制御の中にない。自宅のIP通信機器へ、世界中からアクセスすることが可能になる。このときに、保護はどうしたら良いのでしょうか。ネットに繋がる端末があふれる自宅になりつつあります。Google HomeやNestのような据え置き端末、食洗機や照明と言ったIoT機器がそれぞれが「機器自体でv6フィルタ機能を持つ」というセキュリティ機能が要求される。
しかし通信機器がフィルタ機能を持っていない。サポート面でも貧弱だ。さらに怖いことに、通信機器(IoT家電)のファイアウォールが脆弱性を抱えていた場合に非常に面倒になる。アップデートが提供され続ける機器ならいいが、アップデートを怠るメーカやユーザーにより危険性が増す。脆弱性を突かれ、IoT機器は外部から操作されてしまう。そうならないよう、外部からの通信を遮断し、内部から外部への通信を許可し応答パケットだけを許可する必要がある。この設定を機器利用の全家庭に仕込まなくてはいけない。可能だろうか。
家庭用ルータでは機器から外部への通信(と応答パケット)を許可する設定を入れているとしても、その設定がルーターに入っているかどうか。安価なルータの説明書に書いてあるのでしょうか。アップデートは提供されるのでしょうか。そしてそれは一般人にわかるように説明書に記載ができるのでしょうか。
「内と外」という境界型のセキュリティは結局のところ必要になるし、境界型というのは「人間の肌感覚」にマッチしているので、SNATを使えば「アドレスが長くなっただけ」と認識できる。既存の知識の人たちには理解しやすいと思うのです。すべての機器にグローバルアドレスを割り当てる意味、懐疑的に見ています。一般市民にはGWもNATも無いグローバル接続は難しいのではないか。そう考えるとNAT-6-6でGWを作るのは悪くない選択肢だと思うのです。