firewalldの設定方法②

 前回[（firewalldの設定方法①）](https://qiita.com/sugar_salt75/items/1b6ff3443c29a7988854)の続きです。

今回は、もっと複雑な要件で`firewalld`の設定をしてみたいと思います:raising_hand:

以下に要件を記載します:writing_hand:

<font color="#ff4500">**【業務LAN(eth0)】**</font>
・シスログを受信するNW機器と、ADサーバなど運用上で通信が必要なサーバ(同セグメント)以外の通信は拒否する。
・シスログは`UDP141`で受信する。
・同セグメント内のサーバは`any`で許可する。
（内部セグメントは`192.168.0.0/24`、NW機器は`10.171.1.5`とします）

## ゾーンの作成
前回の記事で紹介したように、あらかじめ9種類のゾーンが用意されていますが、個別にゾーンを作成してそこへ定義することも可能です。
今回のように、個別に接続元IPアドレスや受信するポートを制限したいといった場合に有効です。


では、上記の要件をもとに追加ゾーンの「gyoumu」を作っていきます。
（ゾーンの名前は任意なので、今回は「業務」で作成します）

<font color="limegreen">・dropゾーンの内容をコピーして、「gyoumu」ゾーンとして使うためのひな型を作成する</font>
```
# cp /usr/lib/firewalld/zones/drop.xml /etc/firewalld/zones/gyoumu.xml
```
要件に記載があるように、今回シスログを受信するNW機器と同セグメントのサーバ以外とは通信を行わないので、今回は`drop`ゾーンの定義をコピーします。

<font color="limegreen">・作成したゾーンファイルをコマンドで扱えるようにするために、リロードする</font>
```
# firewall-cmd --reload
```
作成しただけでは、ゾーンとして認識されていない状態なので一度リロードします。

これでgyoumuゾーンの作成は完了です。

## リッチルールの追加
先ほど作成したゾーンに、要件に合わせてルールを追加していきます。

今回は、送信元ごとに許可をしたいポートが異なるので、さらに詳細な設定ができる<font color="#ff4500">「リッチルール」</font>を使います。
コマンドの構文が少し異なりますが、前述した内容とルールはほとんど同じです。

今回も設定前に、今現在の設定内容を確認しておきましょう。
```
# firewall-cmd --list-all --zone=gyoumu

gyoumu
  target: DROP
  icmp-block-inversion: no
  interfaces:
  sources:
  services: 
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```
`public`ゾーンと比べると、`target`が`DROP`になっており、`services`欄も空欄になっていることが分かります。
では、ここに設定を追加していきたいと思います。

<font color="limegreen">・sshの許可</font>
```
# firewall-cmd --permanent --zone=gyoumu --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" service name="ssh" accept'
```
要件には記載されていませんが、`ssh`を許可しないとサーバへの<font color="red">ssh接続が出来なくなってしまう</font>ので、使用する端末やサーバなど、ssh接続をする可能性があるIPアドレスは全て追加してください。

<font color="limegreen">・NW機器からのUDP141の受信を許可</font>
```
# firewall-cmd --permanent --zone=gyoumu --add-rich-rule='rule family="ipv4" source address="10.171.1.5" port protocol="udp" port="514" accept'
```
<font color="limegreen">・内部セグメントとの通信をanyで許可</font>
```
# firewall-cmd --permanent --zone=gyoumu --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" port protocol="tcp" port="0-65535" accept'
# firewall-cmd --permanent --zone=gyoumu --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" port protocol="udp" port="0-65535" accept'
```
`any`という指定は出来ないので、特に制限したいポートがない場合は全てのポート(`0-65535`)を範囲指定します。
また、`tcp`と`udp`も同時には指定できないので、それぞれでコマンドを実行します。

これで、要件通りの許可設定が完了しましたが、まだこのゾーンはどこのセグメントにも適用されていないので、最後に業務LAN(eth0)にgyoumuゾーンを適用していきます。
```
# nmcli con mod “System eth0” connection.zone gyoumu
　　※インターフェース名の指定方法は各自の環境で確認してください。
```
ゾーンは`firewall-cmd`コマンドでも変更できますが、ゾーンの変更に関してのみ、前回の記事で紹介した`--permanent`オプションを付与しても恒久的な設定になりません。
そのため、恒久的な設定にするには、`nmcli`コマンドを用いて変更します。

また、上記のコマンドは、正常終了した場合でも特に何も表示されません。
このため、設定が正しく反映されたかは下記のコマンドで確認します。
```
# firewall-cmd --get-zone-of-interface=eth0
gyoumu
```
業務LAN(eth0)にgyoumuゾーンが適用されていることが分かりました。

<font color="limegreen">・設定を反映させる</font>
```
# firewall-cmd --reload
```
以上で設定は完了です。

変更後の設定内容を確認します。
```
# firewall-cmd --list-all --zone=gyoumu

gyoumu
  target: DROP
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: 
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="192.168.0.0/24" servie name="ssh" accept
        rule family="ipv4" source address="10.171.1.5" port protocol="udp" port="514" accept
        rule family="ipv4" source address="192.168.0.0/24" port protocol="tcp" port="0-65535" accept
        rule family="ipv4" source address="192.168.0.0/24" port protocol="udp" port="0-65535" accept
```
`interfaces`に`eth0`が追加され、リッチルールの欄にも設定が追加されたことが分かります。
以上で設定は完了！！…と思いましたが、ここで１つ問題が発生します。

それは、この状態だと<font color="red">pingが通らない</font>という事です！！
ポートをanyで許可しているので関係ないと思っていましたが、pingには`ICMP`という全く別のプロトコルが使用されており、追加で`ICMP`も許可しないとpingは通らないことが判明しました。（知らなかった）（これって一般常識ですか？笑）

そこで、使用するのが以下のコマンドになります！

<font color="limegreen">・リッチルールを使用し、ICMPを許可したいIPアドレスを指定する場合</font>
```
# firewall-cmd --permanent --zone=gyoumu --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" protocol value="icmp" accept'
```
再度リロードし、設定内容を確認すると、リッチルールの欄に以下が追加されていることが分かります。（※一部抜粋）
```
rule family="ipv4" source address="192.168.0.0/24" protocol value="icmp" accept
```
また、許可するIPアドレスなどは制限せず、`ICMP`は全て許可する場合は以下のコマンドになります。
```
# firewall-cmd --permanent --zone=gyoumu --add-protocol=icmp
```
この場合、設定を反映させると以下のようにプロトコル欄にicmpが追加されます。
```
protocols: icmp
```
これで無事にpingも通るようになりました！
セキュリティ的には許可しない方が良い場合もあるようですが、死活監視などでpingが必要な場合には場面に応じて許可しましょう。

<font color="blue">===番外編==========================================</font>
ちなみに、pingの許可には以下の方法もあります。
設定内容を確認したとき、`icmp-block-inversion`と`icmp-blocks`という項目がありましたが、これは`icmp-block-inversion`が<font color="red">**yes**</font>の時に`icmp-blocks`に記載された`ICMP Type`を受け入れ、
<font color="red">**no**</font>の時は`icmp-blocks`に記載された`ICMP Type`を拒否する、というものです。

デフォルトでは<font color="red">no</font>に設定されており、`icmp-blocks`には何も記載されていませんが、この状態ではpingは許可されていません。（難しい…）
なので、pingに使用する`ICMP Type`だけを追加し、pingを許可してみたいと思います。

<font color="limegreen">・まずは、icmp-block-inversionをyesに変更する</font>
```
# firewall-cmd --add-icmp-block-inversion　--zone=gyoumu
```
<font color="limegreen">・pingで使用するICMP Typeを許可する</font>
（使用できる`ICMP Type`の一覧は`firewall-cmd --get-icmptypes`で取得できます）
```
# firewall-cmd --add-icmp-block=echo-reply --zone=gyoumu
# firewall-cmd --add-icmp-block=echo-request --zone=gyoumu
```
この方法でもpingを許可できる（はず）です！
ただ推奨はされていないかもしれないので、恒久的な設定はせず、一時的に設定を入れて試してみてください。
<font color="blue">==================================================</font>

ちなみに、設定を間違えたりして、追加した設定を削除したいなどの場合は、前述したコマンドの`--add`の部分を`--remove`に変更して実行し、追加した時と同様にまたリロードするだけです。

<font color="red">(例)</font>
```
# firewall-cmd --zone=public --remove-service=http　--permanent
```


これで皆さんも一通りfirewalldの設定ができるようになりましたね！！！
<font color="gray">もし間違っている箇所があったらこっそり優しく教えてください…</font>

**それでは、皆さんも素敵なfirewalldライフを！！！！:relieved:**