firewalldを設定する（特定のネットワークから自サーバの特定のサービスへのアクセスを許可する）(IPをグループ化するipset機能を使う)

firewalld の設定について復習を兼ねて書いていきます。思いつきで書いているので順番バラバラです。内容間違ってたらすいません。
* 常に恒久的な設定として使いたいので、--permanent オプションを使います。一時的に使いたいだけなら --permanent を除去してください。
* 環境は Redhat9系です。AlmaLinux9で設定しています。
* firewalld は起動してください。 systemctl start firewalld
* selinux は切って(disable)ください。分かる人は有効に。

### 今回のパターン
* サーバのNICは ens0p3 という名前 (VirtualBoxだったので)
* このサーバで稼働している HTTPとHTTPSとSMTP サービスへの通信を許可したい。
* 全てのネットワークではなく 172.16.3.0/24 と172.16.5.0/24と 172.18.22.0/24 からのアクセスのみ許可したい。ただ、許可するネットワークは今後も増えるかもしれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785184/361e3801-a90b-9000-50ba-51156f8081a0.png)

アクセス対象のネットワークやサービスが増えてくると、firewall許可のルール設定の管理が大変になってきます。単純にネットワーク数が３つ，許可するサービス数が３つだと３☓３で９つのルールを追加しなくてはいけません。
そこで、ipset機能でネットワークをグループ化し、設定するルールの数を減らしていこうという魂胆です。

### 1.ゾーンの選定
前回に引き続き externalを使用します。

### 2.externalゾーンから不要なサービスを削除します（前回やったのと一緒なので実行済みならやる必要なし）
* ゾーンexternalの通信OKサービスから ssh を削除する
firewall-cmd --permanent --zone=external --remove-service=ssh

### 3.アクセスを許可するネットワークをipset機能でグループ化します。
ipset機能を使うと、複数のネットワークをまとめてグループ化することができます。グループに名前をつけてリッチルールでアクセス元として指定できます。

* ipset名「accessok」を作成します。タイプはネットワークタイプとします。
※タイプは色々あるので気になる人は調べてみて。
firewall-cmd --permanent --new-ipset=accessok --type=hash:net
* ipset「accessok」にネットワークを追加していきます。
firewall-cmd --permanent --ipset=accessk --add-entry=172.16.3.0/24
firewall-cmd --permanent --ipset=accessk --add-entry=172.16.5.0/24
firewall-cmd --permanent --ipset=accessk --add-entry=172.16.22.0/24

### 3.リッチルールを使って通信OKなサービスとアクセス元を許可設定する
アクセス元をipset名で指定することによって、単純化できます。

コマンド(1)
firewall-cmd --permanent --zone=exnternal --add-rich-rule='rule family=ipv4 source ipset=accessok service name=http accept'
##### コマンドの意味
ゾーンexternalに対し以下のリッチルールを指定する
リッチルールの内容
* IPv4(family=ipv4)で、アクセス元IPとしてipset名「accessok」を指定し、HTTPサービスへのアクセス (service name=http)を許可 (accept)

コマンド(2)
firewall-cmd --permanent --zone=exnternal --add-rich-rule='rule family=ipv4 source ipset=accessok service name=https accept'
##### コマンドの意味
ゾーンexternalに対し以下のリッチルールを指定する
リッチルールの内容
* IPv4で (family=ipv4)、アクセス元IPとしてipset名「accessok」を指定し、HTTPSサービスへのアクセス (service name=https)を許可 (accept)

コマンド(3)
firewall-cmd --permanent --zone=exnternal --add-rich-rule='rule family=ipv4 source ipset=accessok service name=smtp accept'
##### コマンドの意味
ゾーンexternalに対し以下のリッチルールを指定する
リッチルールの内容
* IPv4で (family=ipv4)、アクセス元IPとしてipset名「accessok」を指定しSMTPサービスへのアクセス (service name=smtp)を許可 (accept)

### 3.ゾーンexternalを インターフェース enp0s3 に割り当てる(すでにやっていたら不要)
firewall-cmd --permanent --zone=external --change-interface=enp0s3

### 4. 設定を有効化する
firewall-cmd --reload

### 5. externalの設定内容を確認する
firewall-cmd --info-zone=external
```
external (avtive)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services:
  ports:
  protocols:
  forward: yes
  masquerade: yes
  forward-ports:
  source-ports:
  itmp-blocks
  rich rules:
        rule family="ipv4" source ipset="accessok" service name=http accept
        rule family="ipv4" source ipset="accessok" service name=https accept
        rule family="ipv4" source ipset="accessok" service name=smtp accept
```

### 6. ipsetの設定内容を確認する
firewall-cmd --info-ipset=accessok
```
accessok
  type: hash:net
  options:
  entries: 172.16.3.0/24 172.16.5.0/24 172.16.22.0/24
```

以上で accessokに指定したIPアドレスから、HTTP、HTTPS、SMTPでのアクセスができるようになりました。
今後、アクセスを許可するネットワークが増えた場合はipsetのaccessok に追加すればOK。
また、アクセスを許可するサービスが増えれば リッチルールを増やせばOKということで、ネットワークとサービスの管理が分離して楽になりました。

### 7. ファイルによる設定変更
ipsetを追加・修正すると、/etc/firewalld/ipsets の中に「ipset名.xml」ファイルができていきます。このファイルをエディタで直接編集し、firewall-cmd --reload することで、大量の変更だったりが楽になります。

cat /etc/firewalld/ipsets/accessok.ml
```
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:net">
  <entry>12.16.3.0/24</entry>
  <entry>12.16.5.0/24</entry>
  <entry>12.16.22.0/24</entry>
</ipset>
```