iptablesを使ってみた

サーバを立てていると時々iptablesを稀に使う時がありました。iptablesのサイトは探せばすぐに見つかるのですが、実際使うと思ったように動作しない場合が多く、常に難儀してました。そのため、自分がよく使う設定を備忘録として残します。

# 環境

ホストは2つ、`Host-A`はクライアント役、`Host-B`はルータ役です。

```
    (  Host-A  ) <-----> (      Host-B     ) <-----> (Router) <-----> (Internet)
     Ubuntu24.02              Ubuntu24.02
IF :ens33                ens33         ens34
IP :192.168.1.1          192.168.1.2 , DHCP            DHCP
DGW:192.168.1.2                        DHCP
```

# 現在の設定の確認

```bash:
iptables -L -v -n --line-number         #filterテーブルを確認します
iptables -L -t nat -v -n --line-number  #natテーブルを確認します。
```

※line-numberは設定を個別に削除する際に参照します

# 設定を全て消去する

```bash:
iptables -F         #filterテーブルを消去する
iptables -F -t nat  #natテーブルを消去する
```

# 再起動後も設定を維持する

`iptables-persistent`を使えば簡単にできます。

```bash:
sudo apt install iptables-persistent  #インストール時の設定が保存されます。
sudo netfilter-persistenet save       #設定後に変更を行った場合は、以下のコマンドで再設定します。
```

* 別の方法

```bash:
sudo service iptables save         #設定の保存
sudo cat /etc/sysconfig/iptables   #設定の確認
```

* iptables-persistenetを使わない以前の方法（今は実行不可）
Ubuntuの前のヴァージョンでは以下の設定でいけたはずですが、今回のUbuntu24.02ではsudoでは/etcディレクトリに書き込み権限がなくなった（セキュリティ向上？）せいで使えませんでした。一応参考までに残しておきます。

```bash:
sudo iptables-save > /etc/iptables.rules
sudo echo -e '#!/bin/sh -e\niptables-restore < /etc/iptables.rules\nexit 0' > /etc/rc.local
sudo chmod +x /etc/rc.local
```

# iptablesのパラメータ

私がよく使うパラメータだけ記載します

|パラメータ|内容|使用例|
|:---|:---|:---|
|-t [テーブル] |テーブルを指定する|-t nat|
|-A [チェイン] |filterを追加する|-A INPUT|
|-D [チェイン] [番号] |filterを削除する|-D OUTPUT 3|
|-s [IPアドレス] |送信元IPを指定する|-s 192.168.1.0/24|
|-d [IPアドレス] |送信先IPを指定する|-d 192.168.1.2|
|--sport [ポート番号] |送信元ポート番号を指定する|--sport 80|
|--dport [ポート番号] |送信先ポート番号を指定する|--dport 80:81|
|-i [インターフェース] |送信元のインターフェースを指定する|-i ens33|
|-o [インターフェース] |送信先のインターフェースを指定する|-o ens34|
|-p [プロトコル] |プロトコルを指定する|-p tcp|
|--syn |TCPのSYNフラグがセットされたパケットを指定する|--syn|
|--to-destination [IPアドレス] |送信先のIPアドレスを指定したIPアドレスで上書きする|--to-destination 192.168.1.2|
|-j [ターゲット] |内容を決定する|-j ACCEPT|

否定の使用

|パラメータ|内容|
|:---|:---|
|! -s [IPアドレス] |指定した送信元IPを除くパケットを指定する|
|! -d [IPアドレス] |指定した送信先IPを除くパケットを指定する|
|! -i [インターフェース] |指定した送信元のインターフェースを除くインターフェースを指定する|
|! -o [インターフェース] |指定した送信先のインターフェースを除くインターフェースを指定する|

* -t パラメータで使用されるテーブル

|テーブル|内容|
|:---|:---|
|filter|すべてのパケットに対して適用される（デフォルト）|
|nat|ネットワークアドレス変換するパケットに対して適用される|

* -A パラメータ、-D パラメータで使用されるチェイン

|チェイン|内容|
|:---|:---|
|INPUT|入力されるパケットに適用するフィルター|
|OUTPUT|出力されるパケットに適用するフィルター|
|FORWARD|転送されるパケットに適用するフィルター|
|PREROUTING|ルーティング前のパケットに適用するフィルター|
|POSTROUTING|ルーティング後のパケットに適用するフィルター|

* -p パラメータで使用されるプロトコル

|プロトコル|内容|
|:---|:---|
|tcp|TCPに適用するフィルター|
|udp|UDPに適用するフィルター|
|icmp|ICMPに適用するフィルター|

* -j パラメータで使用されるターゲット

|ターゲット|内容|
|:---|:---|
|ACCEPT|パケットを受理し、次のチェインに転送する|
|DROP|パケットを破棄し、終了する|
|REJECT|パケットを破棄し、ICMPのエラーパケットを送信し、終了する|
|LOG|カーネルログに記録し、処理を継続する|

# 使用例

* 送信元(192.168.1.0/24)から送信先(192.168.1.2)への通信は受理する設定

```bash:
iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.2 -j ACCEPT
```

* ICMPは全て破棄する設定

```bash:
iptables -A INPUT -p icmp -j DROP
```

* 受信したデータの送信先IPアドレスを自分自身に変更する

マルウェア解析やオフラインでのシステム構築の際に、全ての通信を自前のサーバで処理したい場合に使用する

```bash:コマンド
iptables -A FORWARD -j ACCEPT
iptables -t nat -A PREROUTING --to-destination 192.168.1.2
```

※Host-B上でinetsim等の各種サーバの代わりになるものを起動させておけば、全ての通信でのレスポンスが可能になります

<!--
# 応用例

* Host-Aからの通信を、Host-BでNAPTしてInternetにつなげる場合

まず、Host-Bの`/etc/stsctl.conf`の中の下の部分を（先頭にある#を取って）有効化する
```:（Host-B) /etc/stsctl.conf
net.ipv4.ip_forward=1
```
コマンドを実行

```bash:(Host-B)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens34 -j MASQUERADE
```

設定を反映させる

```bash:(Host-B)
sudo sysctl -p
```
-->

# おまけ

そもそも、ホストに入ってくる通信を制限したいだけなら、gufwというアプリがありますので、そちらを使うことをおすすめします。

```bash:
sudo apt install gufw
```