rsyslogの設定

`rsyslog`は、ご存じの通りシスログなどをサーバーに出力するためのサービスですが、NW機器など他の機器のシスログを受信することも可能です。

今回は、その設定方法について紹介します。

まずは要件を以下にまとめます。
* ログの受信には`UDP514`を使用する。
* ログの書き込みレートは無制限とする。
* 収集したログはホスト名、日付ごとにディレクトリを作成し、ログの切り替えはログローテーションで行う。
* `local0`で指定されたファシリティのログを収集する。
* `debug`以上のプライオリティのログを収集する。
* 受信するログに対し、定義済みであるテンプレートである以下を利用する。
　`RSYSLOG_Fileformat`

上記の要件を１つずつ設定していきます。

設定には、`rsyslog`の設定ファイルである`/etc/rsyslog.conf`を修正していきます。
rsyslog.confは、`MODULE`/`GLOBAL DIRECTIVE`/`RULES`の３つの項目に分かれています。

<font color="limegreen">・ログの受信にはUDP514を使用する。</font>
まず、`MODULE`欄から以下の記載を探します。（19,20行目）
```
# module(load="imudp") # needs to be done just once
# input(type="imudp" port="514")
```
先頭のコメントアウト（**#**）を外し、`UDP`での受信を許可します。
24,25行目にTCPの記載もありますが、今回は要件にないのでコメントアウトのままにしておきます。
<font color="red">※ここでコメントアウトを外しても、firewalldでUDP514を許可していないと受信できないので注意しましょう！</font>

<font color="limegreen">・収集したログはホスト名、日付ごとにディレクトリを作成し、ログの切り替えはログローテーションで行う。</font>
こちらの要件は`RULES`欄に記載していきますが、ここで使うのがテンプレートになります。
テンプレートのタイプには、リスト、サブツリー、ストリング、プラグインがありますが、今回は従来のテンプレートの書き方に似ているストリングを使って、以下に沿って書いていきます。
```
template　(name=”テンプレート名” “type”=string string=”/ログの保存先/ログファイル名.log")
```
今回、ログの保存先とログファイル名は以下とします。
<font color="blue">/var/log/rsyslog/ホスト名/日付.log</font>
テンプレートの名前は任意なので、今回はreceivelogとします。

これらをテンプレートに当てはめると以下になります。
`RULES`欄の一番上に記載します。
```
template　(name=”receivelog" “type”=string string=”/var/log/rsyslog/%hostname%/%$year%%$month%%$day%.log")
```
`rsyslog`では、ログの保存先ディレクトリやファイル名に日付やホスト名の変数を用いることができます。
そうすることで、ローテーションをしなくてもログファイルを日付ごとに整理することができます。
ここで指定したディレクトリは、ログを受信した際に自動的に作られるので手動での作成は不要です。
<font color="gray">※ただし、NW機器などログの送信元側でホスト名が設定されていないとディレクトリ名は送信元のIPアドレスになります。（hostsに記載しても認識されません。）
※ログローテの機能を使用してローテーションする場合は、ログファイル名に日付を付与できるオプションがあるので、ログの名前は日付にしない方が分かりやすいです。</font>

変数は上記以外にも、`fromhost-ip`(メッセージを受信したIPアドレス)で表記したり、`$hour`(時間)、`$minute`(分)などを指定することも可能です。
また、変数と変数の間にハイフンやアンダーバーを入力することも可能です。
```
%$year%%$month%%$day%.log　⇒　20220523.log
%$year%‐%$month%‐%$day%.log　⇒　2022‐05‐23.log
```
変数を使う際には、単語の最初と最後に<font color="red">**「%」**</font>が必須ですが、日付を表す変数には更に<font color="red">**「$」**</font>が必要なので注意してください！！！（これに何度も引っ掛かりました…）
これら以外の使用できる変数については、`rsyslog`の公式ページに載っているので調べてみてください。

これで保存先とログのファイル名の設定は完了です。

<font color="limegreen">・local0で指定されたファシリティのログを収集する。
・debug以上のプライオリティのログを収集する。
・受信するログに対し、定義済みであるテンプレートである以下を利用する。
　RSYSLOG_FileFormat</font>

次に、これらの要件について記載していきます。
先ほどのテンプレートのすぐ下に、以下の形式に当てはめて記載していきます。
<font color="blue"><ファシリティ>.<プライオリティ>　<アクション></font>

`ファシリティ`というのは、ログの種類を指定する箇所で、`cron`や`mail`などがあり、今回指定するlocal0（～7）は独自に使用できるファシリティになっています。
local0とlocal1に特に差異はないと思うので、分かりやすいように数字の小さい順に使用していくのが良いと思います。
ちなみに、`rsyslog.conf`を見ると、local7はデフォルトでboot.logの出力に使用されているようなので、使用できません。

`プライオリティ`はログの種類を指定する箇所で、どのレベルのログを出力させるかをここで指定します。
警告メッセージの`warning`やエラーメッセージの`err`などの種類がありますが、指定した物より重要度の高い物は全て受信するので、指定するのは1つで構いません。
（=errなどのように、=を使うと、その指定したプライオリティだけを出力させることもできるそうです）
全て受信する場合は`*`、逆に出力させたくない場合は`none`を指定します。
今回は要件にある通り`debug`を指定します。

次に`アクション`の部分を設定をします。
ここでは出力先を決めますが、ファシリティの説明で挙げた`cron`や`mail`はそれぞれ、`/var/log/cron`、`/var/log/mail`がデフォルトで設定されています。
cronのログは実際に見たことある方もいるのではないでしょうか？

今回は、前述したテンプレートの中に出力先を記載したので、出力先にテンプレート名の「receivelog」を指定します。
更に、今回は定義済みのテンプレートも使用するので、`RSYSLOG_FileFormat`も追加します。
複数指定する場合は、「**;**」を使って区切ります。

ちなみに`RSYSLOG_FileFormat`の出力例は以下になり、従来のフォーマットよりタイプスタンプとタイムゾーン情報の精度がより高い物となっています。
（例）2022-05-23T15:28:30.063083+9:00　

テンプレートを意識したことはないと思いますが、`rsyslog.conf`を見てみると、デフォルトで`RSYSLOG_TraditionalFileFormat`というテンプレートが指定されていることが分かります。
実際にシスログなどのタイムスタンプと比べて見ると分かりやすいと思います。
事前に定義されたテンプレートは他にもいくつかあるので、興味のある方は調べてみてください！

長くなりましたが、要件をまとめると記載は以下になります。前述したテンプレートのすぐ下に記載します。
```
local0.debug ‐?receivelog;RSYSLOG_FileFormat
```
テンプレート名の前にある「**?**」は、保存されるログのファイル名が動的ファイル名であることを示しています。
今回はファイル名に日付を指定していて、毎回ファイル名が変わることになるので「?」を付けます。
テンプレートで保存先に変数を使っている場合は、ログファイル名が一律ではないので付ける必要があります。

また、「**‐**」のオプションを付けた場合は、ログの書き込みが非同期となり、受信したログを一旦バッファに溜めて、まとめてディスクに書き込むことで、大量のログが出力される場合にディスクI/Oの負荷を軽減します。
ただし、マシンの電源が落ちると未書き込みのデータが欠損する恐れがあります。
逆に、このオプションを付けないとダイレクトにログが書き込まれますが、一度に膨大なログが送り込まれたときに取りこぼす恐れがあります。
これは受信するログの量などを確認し、それに合わせて設定するのが良いと思います！

設定が完了したら、設定を反映させるために`rsyslog`を再起動しますが、その前に`rsyslog.conf`の文法をチェックします。
```
# rsyslogd -N 1
```
このコマンドを実行すると、`rsyslog.conf`の設定に間違っている部分がないかを確認することができ、間違っていた場合は、○行目の△△△という記載が存在しない設定項目などのメッセージが英語で出力されます。

間違っていた場合は再度該当の部分を確認し直し、問題がなかった場合は`rsyslog`を再起動して、これで設定は完了です。
```
# systemctl restart rsyslog
```

<font color="limegreen">・ログの書き込みレートは無制限とする。</font>
最後に、この要件について記載していきます。
ログの出力には上限があり、一度に大量のログが出力され、その上限を超えてしまうとその分のログは破棄されてしまいます。

そこで今回は、ログの出力を無制限に変更しますが、実際に無制限になったのかは確認が出来なかったので、あくまで参考程度に思っていただければ。。。

まず変更するのは、`/etc/systemd/journald.conf`です。
`[Jounal]`欄の中から`RateLimitInterval`と`RateLimitBurst`の項目を探したら、先頭のコメントアウトを外し、設定値を「**0**」にします。
```
RateLimitInterval=0
RateLimitBurst＝0
```
`RateLimitInterval`で指定した期間内に`RateLimitBurst`以上のログが出力されると、その分のログが破棄されます。
`RateLimitInterval`か`RateLimitBurst`のいずれかを「0」にすると、ログが破棄されず無制限で記録されます。（両方「0」でもOKです。）

例えば、以下のような設定だった場合は、
```
RateLimitInterval=1s
RateLimitBurst=10000
```
1秒間に10000件を超えるログが出力されると破棄される、ということになります。

設定が完了したら、`systemd-journald`を再起動します。
```
# systemctl restart systemd-journald
```
次に、再度`rsyslog.conf`を修正します。

`MODULE`欄の4行目、`#module(load=”immark”)`の下の行あたりに、以下の記述を追加します。
```
$imjournalRatelimitInterval 0
$imjournalRatelimitBurst 0
```
`journald.conf`同様に、`$imjournalRatelimitInterval`で指定した期間内に`$imjournalRatelimitBurst`以上のログが出力されるとその分のログが破棄されます。
いずれかを「0」にするとログが破棄され無制限で記録されます。（両方「0」でもOK）

設定後は、前回同様`rsyslog.conf`の文法をチェックします。
<font color="gray">ちなみに、「**$**」で始まる記述は古いバージョンのrsyslogで使われていたレガシーな書き方のようですが、この設定に関する新しい記述の仕方は分かりませんでした…
レガシーな書き方をすると文法をチェックした際に警告が出る場合がありますが、この設定に関しては特にエラーなども出ていなかったので問題なさそうですが、もし最新の書き方が分かる方がいたら教えてください…</font>

文法をチェックし、問題がなかったらrsyslogの再起動をします。
これで設定は完了です。

一旦ここで要件は全て満たしましたが、ここからは一応やっておいた方が良い設定を紹介します。

<font color="blue">===番外編==========================================</font>
上記の設定で要件通りに出力されるようになりましたが、このままだとサーバーのシスログ(`/var/log/messeages`)にも同じようにNW機器のログが出力されてしまいます。
サーバー自身のシスログが見にくくなってしまうのと、二重で書き込まれてしまうことになるので、シスログには出力されないように設定したいと思います。

設定する箇所は、`rsyslog.conf`の`RULES`欄にある以下の記載に追記します。
```
*.info;mail.none;authpriv.none;cron.none;local0.none          /var/log/messages
```
前述したように、ここには受信するログのファシリティ、プライオリティ、出力先が設定されています。
上記を見ると、ファシリティに「__*__」が設定されており、全てのファシリティがシスログに出力される設定になっているので、これがNW機器のログもシスログに出力される原因になっています。

そしてこちらも前述したように、cronやmailはそれぞれ、`/var/log/cron`、`/var/log/mail`に出力されるように設定されているので、ここではシスログに出力されないように`none`が設定されています。
それを踏まえて、今回NW機器はファシリティが`local0`なので、local0のログを出力させないように`local0.none`を設定の最後に追加します。
設定後rsyslogの再起動を実施し、これでシスログに出力させない設定は完了です。
最後に、ログの送信元を制限する設定について記載していきます。

rsyslog側でログの送信元を制限するには、`AllowedSender`という項目を使用します。
Allowedから分かるようにこちらは許可設定になるので、ログの受信を許可したいホストをこの項目を使って追加していきます。
デフォルトでは全て許可される設定になっています。
<font color="gray">※ただし、この設定は下位互換性のためにサポートされている機能のようなので、firewalldで制御するのが望ましいようです。</font>

`AllowedSender`の設定方法は、`MODULE`欄の一番下の行に、許可したいホストの分だけ以下の形式に当てはめて記載していきます。
```
$AllowedSender <type>, ip[/bits], ip[/bits]・・・
```

`<type>`の項目には、`UDP`か`TCP`が入ります。
同時に両方は指定できないので、どちらも指定したい場合は行を分けて記載してください。

`ip[/bits]`の部分には、ログの受信を許可したいホストを記載します。
IPアドレスだけでなくホスト名を指定することもでき、またワイルドカードの使用も可能ですが、脆弱性が高まるため、可能な限りIPアドレスでの指定する方が良いようです。
`[/bits]`を省略すると、単一のホストと認識されます。`/0`は許可されていません。

以下に記載例を載せます。
```
$AllowedSender TCP,　127.0.0.1, 192.0.2.0/24, *.example.net, somehost.example.com
$AllowedSender UDP,　127.0.0.1, 192.0.2.0/24, *.example.net, somehost.example.com
```
繰り返しになりますが、記載して保存した後は文法をチェックし、問題がなかったら`rsyslog`の再起動をして、設定は完了です。

以上、番外編もこれにて終了です！
<font color="blue">=================================================</font>

これで皆さんもシスログの受信ができるようになりましたね！！！

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