トライしたかったnftablesの基本（その２）

# nftablesでNATを実現
「[トライしたかったnftablesの基本（その１）](https://qiita.com/infinite1oop/items/87c206281b5eab0308a6)」の続編。今回はNATの超基本であり、内容的には、「[今さらながらiptables基本（その２）](https://qiita.com/infinite1oop/items/51d298c9ce9e85775c7c)」と同じである。

## 参考サイト
1. [linuxのnftables(nft)でルータ機能を作る](https://takuya-1st.hatenablog.jp/entry/2023/06/23/021732)
1. [nftables](https://wiki.archlinux.jp/index.php/Nftables)
1. [Linuxにおける新たなパケットフィルタリングツール「nftables」入門](https://knowledge.sakura.ad.jp/22636/)

## ネットワークトポロジー
下記環境にて実現。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/44a5b6bd-7e35-dd21-b2b6-b83365583376.png)
左側がNAT内側、右側がNAT外側である。

## 設定
### NAT
```shell
$ sudo nft create table ip nat_filter
$ sudo nft create chain ip nat_filter dst_nat {type nat hook prerouting priority dstnat \;}
$ sudo nft create chain ip nat_filter src_nat {type nat hook postrouting priority srcnat \;}
$ sudo nft add rule ip nat_filter src_nat oif enp0s8 masquerade
```
- ”nat_filter”というテーブル作成
- ”nat_filter”テーブル内に次のNATチェーンを作成
    - ”dst_nat”というPreRoutingチェーン
    - ”src_nat”というPostRoutingチェーン
- ”src_nat”チェーン内に、NAT（masquerade）外側I/F”enp0s8”としたルールを作成

### フィルター
上記NAT設定のみの場合、NAT外側からNAT内側へのアクセスができてしまうので、それを防ぐ設定が必要となる。
```shell
$ sudo nft create chain ip nat_filter filter_1 {type filter hook forward priority 0 \; policy drop \;}
$ sudo nft add rule ip nat_filter filter_1 iif enp0s3 oif enp0s8 accept
$ sudo nft add rule ip nat_filter filter_1 ct state related,established accept
```
- ”nat_filter”テーブル内に、”filter_1”というフィルターチェーン（デフォルトDrop（破棄））を作成
- ”filter_1”内に次のルールを作成
    - NAT内側（enp0s3）からNAT外側（enp0s8）へはAccept（許可）
    - セッションを保ったものなど（”related”,”established”）はAccept（許可）（NAT外側からNAT内側）

### 最終的な設定
```shell
$ sudo nft -a list ruleset
table ip nat_filter { # handle 1
        chain dst_nat { # handle 1
                type nat hook prerouting priority dstnat; policy accept;
        }

        chain src_nat { # handle 2
                type nat hook postrouting priority srcnat; policy accept;
                oif "enp0s8" masquerade # handle 5
        }

        chain filter_1 { # handle 6
                type filter hook forward priority filter; policy drop;
                iif "enp0s3" oif "enp0s8" accept # handle 7
                ct state established,related accept # handle 10
        }
}
```

### 検証
netcat(nc)およびpingによる検証である。
#### コマンド実行
##### Client(192.168.10.10)
![NATclient.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/b2339f02-5360-92bc-5e33-8cd2c0f208cd.png)
##### Server(172.16.0.21)
![NATserver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/0246d44c-d0a9-3559-fdaa-d8ecea41d8ea.png)
##### 解説
- Server（IP address: 172.16.0.21）でTCPポート1234で待受
- Client（IP address: 192.168.10.10）から同ポートへTCPアクセス
- Clientでテキスト”From Inside”を送信
- Serverで同内容を受信
- Serverでテキスト”From Outside”を送信
- Clientで同内容を受信
- ClientでTCPセッションクローズ（Ctrl-C入力）
- ServerでClientへpingするが疎通なし

#### ネットワークキャプチャデータ
上記の状況をWiresharkで取得したもの。いずれも期待値どおりである。

##### Client
![Clientのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/4d6e7451-d735-2a7d-a154-36b5ce427120.png)
- 青枠：Client（IP address: 192.168.10.10）からServer（IP address: 172.16.0.21）への通信
- 赤枠：Serverへのテキスト”From Inside”の送信

![Client2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/a40035ae-b116-7a63-c023-63e3a3a00e0d.png)
- 赤枠：Serverからのテキスト”From Outside”の受信

##### Server
![Serverのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3e91459f-952a-2607-9fb5-fb839ec1485d.png)
- 青枠：Client（NATで変換されたIP address: 172.16.0.1）からServer（IP address: 172.16.0.21）への通信
- 赤枠：Clientからのテキスト”From Inside”の受信

![Server2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/583e2751-fb36-a91a-627b-fa1b652c0627.png)
- 赤枠：Clientへのテキスト”From Outside”の送信
- 青枠：Clientへのping応答なし

## おわりに
その３では、ebtables相当を実現予定。