いつもnatの設定を忘れてしまうのでここに残しておきたい

ss@kong:~$ sudo sysctl -w net.ipv4.ip_forward=1 && \
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.10.0/24 -o enp9s0 -j MASQUERADE && \
sudo iptables -A FORWARD -i tun0 -o enp9s0 -s 10.8.0.0/24 -d 192.168.10.0/24 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT && \
sudo iptables -A FORWARD -i enp9s0 -o tun0 -s 192.168.10.0/24 -d 10.8.0.0/24 -m state --state ESTABLISHED,RELATED -j ACCEPT

backupのトンネルの方はこっち

rr@kong:~$ sudo sysctl -w net.ipv4.ip_forward=1 && sudo iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -d 192.168.10.0/24 -o enp9s0 -j MASQUERADE && sudo iptables -A FORWARD -i tun1 -o enp9s0 -s 10.10.0.0/24 -d 192.168.10.0/24 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT && sudo iptables -A FORWARD -i enp9s0 -o tun1 -s 192.168.10.0/24 -d 10.10.0.0/24 -m state --state ESTABLISHED,RELATED -j ACCEPT
net.ipv4.ip_forward = 1

これ、一応意味書いておくか。

これが NAT の本体(超重要)

iptables -t nat -A POSTROUTING \
  -s 10.10.0.0/24 -d 192.168.10.0/24 \
  -o enp9s0 -j MASQUERADE

何をしているか

  • 送信元が 10.10.0.0/24
  • 宛先が 192.168.10.0/24
  • enp9s0 から出ていく直前(POSTROUTING)に
  • 送信元IPを enp9s0 のIP(例: 192.168.10.2)に書き換える

つまり

Before NAT:
10.10.0.5  → 192.168.10.3

After NAT:
192.168.10.2 → 192.168.10.3

になるので、宛先の192.168.10.3はNatによって変更されたパケットの送信元192.168.10.2 に返せる(存在を知っているので)

行き(SYN)を通すルール

iptables -A FORWARD \
  -i tun1 -o enp9s0 \
  -s 10.10.0.0/24 -d 192.168.10.0/24 \
  -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

何をしているか

  • tun1 から入ってきた
  • 192.168.10.0/24 宛の通信を
  • enp9s0 に転送することを許可

帰り(SYN-ACK / ACK)を通すルール

iptables -A FORWARD \
  -i enp9s0 -o tun1 \
  -s 192.168.10.0/24 -d 10.10.0.0/24 \
  -m state --state ESTABLISHED,RELATED -j ACCEPT

何をしているか

  • 192.168.10.3 → 192.168.10.2(NAT後)で返ってきた通信を
  • conntrack が「さっきの通信の続き」と認識
  • NAT を元に戻して(逆NAT)
  • tun1 に返す

ちょっと軽くcontrackにも触れておきたい。

conntrack とは何か(軽くまとめ)

一言でいうとconntrack(connection tracking)とは、Linux カーネルが「通信の文脈(状態)」を覚えておく仕組み。

IP や UDP/TCP は本来ステートレスだが、NAT や stateful firewall を成立させるためにカーネル内部で通信状態を記録する層が conntrack。

conntrack が見ているもの

conntrack は通信を L4 まで見て識別する。

基本となるキーは: (protocol, src IP, src port, dst IP, dst port)

いわゆる 4-tuple + protocol。

NAT がある場合の重要ポイント

NAT が入ると、1つの通信は 2つの姿を持つ。

例:

original direction:
10.10.0.5:52341 → 192.168.10.3:9100

NAT後(reply視点):
192.168.10.2:40001 → 192.168.10.3:9100

conntrack はこれを 1つの通信エントリとしてペアで保持している。 つまり: 変換前の 4-tuple 変換後の 4-tuple

の両方を覚えている。

「さっきの通信の続き」とはどういう意味か

返ってきたパケット:

192.168.10.3:9100 → 192.168.10.2:40001 を見たとき、conntrack は: あ、これは 10.10.0.5:52341 → 192.168.10.3:9100 の返事だな

と判断する。

この判断ができるから:

state = ESTABLISHED と認識できる

逆NAT(192.168.10.2 → 10.10.0.5)ができる

正しい IF(tun1)に返せる