Azure Load Balancer の keepalive を Linux Firewalld 側で許可する

# 1. はじめに
Azure Load Balaner を設定する際に、ターゲットとなるバックエンドプールに対して正常性プローブによる keepalive が行われます。Linux OS でサービスを行っている際に、Azure Load Balancer から発する keepalive 通信を firewalld 側で明示的に許可する必要がありますので、手順をまとめておきます。

# 2. 考慮すべきポイント
Azure Load Balancer の keepalive は送信元 IP ``168.63.129.16`` の許可が必要です。

:::note info
Azure 正常性プローブの発生元である Azure インフラストラクチャ ロード バランサーとしてタグ付けされたホストの仮想 IP アドレス。バックエンド インスタンスが構成されているときに正常性プローブに正常に応答するには、この IP アドレスからのトラフィックを許可する必要があります。
:::

https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-faqs#what-is-ip-168-63-129-16-

# 3. 設定手順
## 3.1 ステータス確認
firewalld のステータスを確認しておきます。

```bash
$ sudo systemctl status firewalld.service
```
有効化は以下で。

```bash
$ sudo systemctl enable firewalld.service
```

## 3.2 通信状況の確認
firewalld はデフォルトでは drop に対してログを出力しないため、以下で確認を行います。
ログは ``/var/log/messages`` に出力されます。

```bash
$ sudo firewall-cmd --set-log-denied=unicast
```

※以下でも良い (broadcast/muliticast も対象になるので、ログ量に注意です）
```bash
$ sudo firewall-cmd --set-log-denied=all
```

設定した後、実際にログを確認してみると Azure Load Balancer の正常性プローブで設定したポートを用いて keepalive が行われており、デフォルトの firewalld 設定では drop されているのが分かります。

```
$ tail -f /var/log/messages | grep filter
Dec  4 10:44:38 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x02 PREC=0x00 TTL=128 ID=43205 DF PROTO=TCP SPT=54531 DPT=514 WINDOW=64240 RES=0x00 CWR ECE SYN URGP=0 
Dec  4 10:44:39 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x02 PREC=0x00 TTL=128 ID=43206 DF PROTO=TCP SPT=54545 DPT=514 WINDOW=64240 RES=0x00 CWR ECE SYN URGP=0 
Dec  4 10:44:39 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x02 PREC=0x00 TTL=128 ID=43207 DF PROTO=TCP SPT=54531 DPT=514 WINDOW=64240 RES=0x00 CWR ECE SYN URGP=0 
Dec  4 10:44:40 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x02 PREC=0x00 TTL=128 ID=43223 DF PROTO=TCP SPT=54545 DPT=514 WINDOW=64240 RES=0x00 CWR ECE SYN URGP=0 
Dec  4 10:44:41 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x00 PREC=0x00 TTL=128 ID=43224 DF PROTO=TCP SPT=54531 DPT=514 WINDOW=64240 RES=0x00 SYN URGP=0 
Dec  4 10:44:42 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x00 PREC=0x00 TTL=128 ID=43225 DF PROTO=TCP SPT=54545 DPT=514 WINDOW=64240 RES=0x00 SYN URGP=0 
Dec  4 10:44:44 vmRHELAma2 kernel: filter_IN_public_REJECT: IN=eth0 OUT= MAC=00:22:48:11:ff:98:12:34:56:78:9a:bc:08:00 SRC=168.63.129.16 DST=10.1.2.13 LEN=52 T
OS=0x02 PREC=0x00 TTL=128 ID=43226 DF PROTO=TCP SPT=54701 DPT=514 WINDOW=64240 RES=0x00 CWR ECE SYN URGP=0 
```

## 3.3 firewald の許可設定

### public zone による通信許可
一般通信の許可として、public zone に対して Linux OS に対する通信許可を与えます。

```bash
$ sudo firewall-cmd --zone=public --add-service=http --permanent
$ sudo firewall-cmd --zone=public --add-service=htts --permanent
$ sudo firewall-cmd --zone=public --add-service=syslog --permanent
$ sudo firewall-cmd --zone=public --add-service=syslog-tls --permanent
```

### 指定 zone (Azure LB 許可) の通信許可
firewalld 側で Azure load Balancer の keepalive を許可する設定を行います。

- zone の作成 (この例では ``AzureLB`` としています)
```bash
$ sudo firewall-cmd --new-zone AzureLB --permanent
```

- zone に対する許可設定
```bash
$ sudo firewall-cmd --zone=AzureLB --set-target=ACCEPT --permanent
```

- zone に対するIPアドレスの指定
```bash
$ sudo firewall-cmd --zone=AzureLB --add-source=168.63.129.16 --permanent
```
- zone に対する KeepAlive プロトコルの指定
    - Azure Load Balancer 側の設定と合わせる
    - 本例では、http/https/syslog/syslog-tls を LB 側で keepalive + load balancing しているイメージで

```bash
$ sudo firewall-cmd --zone=AzureLB --add-service=http --permanent
$ sudo firewall-cmd --zone=AzureLB --add-service=https --permanent
$ sudo firewall-cmd --zone=AzureLB --add-service=syslog --permanent
$ sudo firewall-cmd --zone=AzureLB --add-service=syslog-tls --permanent
```

- 設定の反映 (reload)

```bash
$ sudo firewall-cmd --reload
```

## 3.4 無事に keepalive が通ったのかを確認
- drop ログが出ていないかを確認
```
$ tail -f /var/log/messages | grep filter
```

- Azure load Balancer 側で正常性状態を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/b94eee65-8191-701b-7040-635660599b6d.png)


## [参考] firewalld の configuration
``/etc/firewalld/zone`` 内に作成したゾーンの設定が xml 形式で保存されています。手動でこちらを編集して、反映することも出来ます。

```bash
$ cat /etc/firewalld/zones/AzureLB.xml
<?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
  <service name="http"/>
  <service name="https"/>
  <service name="syslog"/>
  <service name="syslog-tls"/>
  <source address="168.63.129.16"/>
</zone>
```

# 4.まとめ
検証では firewalld を停止することが多いと思いますが、本番環境を想定して firewalld の設定手順をまとめてみました。本記事がどなたかの参考になれば幸いです。

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。