【2023年9月版】firewalldメモ

# はじめに

自分用の firewalld メモ

# 操作

firewall-cmd で操作する

# インストール

server でインストールしたら最初から入っているけど、入っていない場合

```
sudo yum install firewalld -y
sudo systemctl enable --now firewalld
```

# 現在の設定の確認

```
firewall-cmd --list-all
```

# ゾーン

簡単な方法として、ゾーンという、ひとまとめの設定に、インターフェイスを割り当てて使う

## インターフェイス <interface-name> を、ゾーン <zone-name> に割り当てる

```
firewall-cmd --change-interface=<interface-name> --zone=<zone-name>
```

## 現在のゾーンの確認

```
firewall-cmd --get-active-zones
```

## 現在の設定の確認（すべてのゾーン）

```
firewall-cmd --list-all-zones
```

## 現在の設定の詳細確認（指定したゾーン）

```
firewall-cmd --list-all --zone=<zone-name>
```

```
firewall-cmd --info-zone=<zone-name>
```

## インターフェイスのゾーンの確認

```
firewall-cmd --get-zone-of-interface=<interface-name>
```

## ゾーンのリストの確認

```
firewall-cmd --get-zones
```

## ゾーンへのサービスの追加

```
firewall-cmd --zone=<zone-name> --add-service=<service-name>
```

## ゾーンからサービスの削除

```
firewall-cmd --zone=<zone-name> --remove-service=<service-name>
```

## ゾーンへの開放ポートの追加

```
firewall-cmd --zone=<zone-name> --add-port=<port-number/(tcp|udp)>
```

## ゾーンから開放ポートの削除

```
firewall-cmd --zone=<zone-name> --remove-port=<port-number/(tcp|udp)>
```

## デフォルトゾーンの確認

```
firewall-cmd --get-default-zone
```

## デフォルトゾーンの設定

```
firewall-cmd --set-default-zone=<zone-name>
```

## ゾーン間でのフォワード

```
firewall-cmd --zone=internal --add-forward-port=port=80:proto=tcp:toport=80:tozone=external
```

# 現在の設定（runtime）と、保存された設定(permanent)

`--permanent` をつけたら、保存された設定(permanent)を変更する。
ファイルに保存されるが、メモリには反映されていないと考えるとわかりやすい。
保存された設定は、`--reload` しないと、現在の設定(runtime)にならない。
これ、よく間違えるので注意。

## 設定を保存(permanent)、現在の設定(runtime)には影響ない

```
firewall-cmd --permanent --zone=<zone-name> --add-masquerade
```

## 保存された設定(permanent)を現在への設定(runtime)への読み込み

```
firewall-cmd --reload
```

## 現在の設定（runtime）を、保存された設定（permanent）へ

```
firewall-cmd --runtime-to-permanent
```

# リッチルール

より詳細なファイアウォールのルール

## ルールの確認

```
firewall-cmd --zone=<zone-name> --list-rich-rules 
```

## ルールの追加

```
firewall-cmd --zone=<zone-name> --add-rich-rule='rule ...'
```

## ルールの削除

```
firewall-cmd --zone=<zone-name> --remove-rich-rule='rule ...'
```

## 特定のサービスを特定のIP範囲にのみ開放する

10.0.0.0/24 からのアクセスのみ http を開放

```
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" service name="http" accept'
```

## レート制限付きのアクセス許可

1分あたり5回以上のSSH接続を試みるとブロック

```
firewall-cmd --add-rich-rule='rule service name="ssh" limit value="5/m" drop'
```

# ダイレクトルール

`nftables` のルールを直接適用するためのルール

## ルールの確認

```
firewall-cmd --direct --get-all-rules
```

## ルールの追加

```
firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -j LOG
```

## ルールの削除

```
firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -j LOG
```

# NAT、マスカレード(NAPT)

## パッケットのフォワードができるようにカーネルパラメータを設定

```
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```

## マスカレード

```
firewall-cmd --zone=<zone-name> --add-masquerade
```

## NAT（ポートフォワード）

port 80 への着信を、192.168.0.2の port 8080 へNAT(ポートフォワード）

```
firewall-cmd --zone=<zone-name> --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.0.2
```

## CONNTRACK

`FTP` などで `CONNTRACK` を利用する場合

### カーネルモジュールロード

```
sudo modprobe nf_nat_ftp
sudo modprobe nf_conntrack_ftp
```

### CONNTRACKが利用できるようにカーネルパラメータを設定

```
echo "net.netfilter.nf_conntrack_helper = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```

# サービス

## 利用可能なサービスの確認

```
firewall-cmd --get-services
```

## サービスの詳細の確認

```
firewall-cmd --info-service=<service-name>
```

## サービスのカスタマイズ

新しいサービスをカスタマイズして追加することも可能
`/etc/firewalld/services` にXML形式で新しいサービスを定義することができる

```custom-ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Custom SSH</short>
  <description>SSH on a custom port</description>
  <port protocol="tcp" port="2222"/>
</service>
```

以下のように利用する

```
firewall-cmd --reload
firewall-cmd --zone=<zone-name> --add-service=custom-ssh
```

# ロギング

ダイレクトルールで `-j LOG` によるロギングも可能だが、firewalldでも可能

```
firewall-cmd --zone=<zone-name> --add-log-target=LOG --log-prefix="firewalld-log: " --log-level=info
```

# デバッグ

サービスを止めて、debugモードで起動する

```
systemctl stop firewalld
firewalld --nofork --debug
```

# IPセット

複数のIPアドレスやネットワークを1つの名前でグループ化して、そのグループ全体に対するルールを適用することができる

```
# japan_ipsというIPセットを作成
firewall-cmd --permanent --new-ipset=japan_ips --type=hash:net
# 日本のIPアドレスを許可
firewall-cmd --permanent --ipset=japan_ips --add-entry=1.0.16.0/20
firewall-cmd --permanent --ipset=japan_ips --add-entry=1.0.32.0/19
  :
  : # 他のIP範囲も同様に追加
# 日本のIPアドレスを含んだIPセットを許可
firewall-cmd --permanent --add-rich-rule='rule source ipset=japan_ips accept'
# その他のIPを拒否（オプション。要件に応じて）
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source not ipset=japan_ips drop'
firewall-cmd --relaod
```

# denyされているログの出力設定

## 設定の確認

off なら出力されない

```
firewall-cmd --get-log-denied
```

## 設定

`all`, `unicast`, `broadcast`, `multicast`, `off` のどれかを設定する

```
firewall-cmd --set-log-denied=unicast
```

# ロックダウン

設定の変更をロックダウンして不正な変更を防ぐ

## ロックダウンの有効化

```
firewall-cmd --enable-lockdown
```

## ロックダウンの無効化

```
firewall-cmd --disable-lockdown
```

# panic モード

すべての入出力トラフィックをドロップする非常モード、システムが攻撃されていると疑われる場合などに使用

## panic モードの有効化

```
firewall-cmd --panic-on
```

## panic モードの無効化

```
firewall-cmd --panic-off
```

# エクスポート

```
firewall-cmd --zone=<zone-name> --export
```

# インポート

```
firewall-cmd --zone=<zone-name> --import=<filename>
```