自宅サーバー構築譚：rsyslog と logrotate と logger

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築、[Ubuntu22.04LTSインストールその2](https://qiita.com/katz_engineer/items/033471b69143bf76650e)の続きです。[Hyper-Vに構築したクライアントマシンもどき](https://qiita.com/katz_engineer/items/bf9299e8f9afd19975e8)も使用します。

ログの蓄積や出力は journald を利用するのが systemd の流儀なのでしょう。私も[以前少し調べてみた事があります](https://qiita.com/katz_engineer/items/7b3f490749272663db7c)。利便性を目指して開発が進み、長所も幾つかあるようです。

でもさぁ、これは明らかな欠陥だよねぇ。大量だからってログを捨てる仕様なんてさぁ！

[短時間に大量のログが送付されると破棄する](https://qiita.com/thaim/items/5d0cc595fce4ac0858e4#%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E5%87%BA%E5%8A%9B%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E5%88%B6%E9%99%90)そうです。困るでしょう。短時間に大量のログが発生する状況というのは、異常事態が起きている可能性が非常に高い。そんな時のログは丁寧に追跡したいのが管理者の心情。それが不可能になります。

Ubuntu の中の人も同じ事を考えたかどうかは知りませんが、Ubuntu では rsyslog と logrotate と、更に logger もデフォルトでインストールされていて、journald と並行して動いている由。

恥ずかしながら rsyslog と logrotate と logger は、私、今まで利用した事がありませんでした。今回、その使い方や設定を調べたので、記事に纏めておきます。

# 参考文献

Qiita 率が高いですね。各記事の作者様に感謝。

## rsyslog

- [第19回　ログを収集する（rsyslogの設定） - シェルスクリプトマガジン](https://shell-mag.com/19st_linuxoperations/)
- [rsyslog.confの文法 - Qiita](https://qiita.com/11ohina017/items/087b1b7c4411c3b3195a)
- [【ログ出力設定】rsyslogとloggerコマンド。 - Qiita](https://qiita.com/NAKASHOU06/items/835795ee1cb3c1a87caa)
- [rsyslogでのTLS(SSL)によるセキュアな送受信 - Qiita](https://qiita.com/saeki4n/items/b30e619d9371f7808657)

rsyslog は非常に高機能だそうです。その一端が下記の参考文献で紹介されています。

- [「rsyslog」のデータベース出力機能やテンプレート機能、スクリプティング機能を活用する - さくらのナレッジ](https://knowledge.sakura.ad.jp/8975/)

## logrotate

- [logrotate入門 - Qiita](https://qiita.com/zom/items/c72c7bac63462225971b)
- [Ubuntu20.04でLogrotateを使用してログファイルを管理する方法 - 開発者ドキュメント](https://ja.getdocs.org/how-to-manage-logfiles-with-logrotate-on-ubuntu-2-4)

## logger

- [LOGGER - JM Project](https://linuxjm.osdn.jp/html/util-linux/man1/logger.1.html)

# 目標

各コマンドの使い方は、前述の参考文献を見ていただいた方が良いでしょう。とても分かり易い。枯れた技術ですし、私などがここで繰り返す意味は無さそうです。

作業目標としては、クライアントマシンから rsyslog サーバへの送信において、通信路を暗号化する事にします。家庭内 LAN での使用を前提として、成りすましは考慮しません。

その作業自体も[前述の参考文献](https://qiita.com/saeki4n/items/b30e619d9371f7808657)に纏まっていたので、それを Ubuntu22.04LTS で設定します。

# サーバー設定

まずはサーバー側を設定します。

殆ど全てが root での実行です。 root になっておきましょう。

```console:サーバー
sudo -i
```

## スナップショット

今回も新しいモジュールのインストールがありますので、[スナップショットを撮っておきます](https://qiita.com/katz_engineer/items/f3bd2f7af2ba49db156c#%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)。

```console:サーバー
zfs snapshot tank/ROOT/ubuntu@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
zfs snapshot tank/ROOT/ubuntu/var/lib/apt@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
zfs snapshot tank/ROOT/ubuntu/var/lib/dpkg@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
```

## 鍵の配置

秘密鍵と公開鍵は、既に作ってあるという事にします。作り方は以前の記事を参照して下さい。

- [自宅サーバー構築譚：オレオレ認証局 - Qiita](https://qiita.com/katz_engineer/items/ada7b08e7c0254e39126)
- [自宅サーバー構築譚：オレオレ認証局が認証する証明書 - Qiita](https://qiita.com/katz_engineer/items/1bb165f5f59c43c0ab6a)

認証局：

- 秘密鍵 ```/opt/CA/demoCA/pki/private/ca.key```
- 公開鍵 ```/opt/CA/demoCA/pki/ca.crt```

サーバーマシン secondary.home の証明書：

- 秘密鍵 ```/opt/CA/demoCA/pki/private/secondary.home.key```
- 公開鍵 ```/opt/CA/demoCA/pki/issued/secondary.home.crt```

クライアントへ送付する鍵は```ca.crt```（認証局の公開鍵）のみになります。これを送信用ディレクトリ```/srv/publickey```内の、クライアントから操作できるサブディレクトリに置きます。ついでにファイル名を調整。

```console:サーバー
cp -p /opt/CA/demoCA/pki/ca.crt /srv/publickey/publickey/demoCA.crt
```

cp コマンドに```-p```オプションを付けると、更新日時などを元ファイルと同一にしてくれます。逆に指定しない場合は、コピーした日時が更新日時になってしまいます。大抵は問題無いと思いますけども。私は気になるので。

publickey ユーザーが操作できるように権限を調整します。

```console:サーバー
cd /srv/publickey/publickey/
chgrp publickey demoCA.crt
chmod g+r demoCA.crt
```

権限を確認。

```console:サーバー
# ls -l demoCA.crt
-rw-r----- 1 root publickey 1184 Mar 10 09:05 demoCA.crt
```

サーバー側の rsyslog が参照する鍵は下記3点。

- 認証局の公開鍵 ```ca.crt```
- 証明書の公開鍵 ```secondary.home.crt```
- 証明書の秘密鍵 ```secondary.home.key```

ディレクトリ ```/etc/rsyslog.d/tls``` を作って、そこにこの3点を格納します。

```console:サーバー
mkdir /etc/rsyslog.d/tls
cd /etc/rsyslog.d/tls
cp -p /opt/CA/demoCA/pki/ca.crt .
cp -p /opt/CA/demoCA/pki/issued/secondary.home.crt .
cp -p /opt/CA/demoCA/pki/private/secodnary.home.key .
```

rsyslog が読めるように、その最小の権限を設定します。

```console:サーバー
chown syslog:syslog *
chmod 400 *
```

念の為に権限を確認。

```console
# ls -l
total 15
-r-------- 1 syslog syslog 1184 Mar 10 09:05 ca.crt
-r-------- 1 syslog syslog 4601 Mar 10 18:20 secondary.home.crt
-r-------- 1 syslog syslog 1704 Mar 10 18:19 secondary.home.key
```

## rsyslog・lmnsd_gtls モジュールのインストール

rsyslog の TLS 転送を行う為には拡張モジュール lmnsd_gtls が必要だそうです。

```console:サーバー
apt install rsyslog-gnutls
```

## rsyslog 設定

いよいよ rsyslog の設定です。ポート番号は、一般的な 514 番ポートにします。

```console:サーバー
cd /etc/rsyslog.d
cat >80-rsyslog.conf <<___
module(
 load="imtcp"
 StreamDriver.Name="gtls"
 StreamDriver.Mode="1"
 StreamDriver.Authmode="anon"
)

input(type="imtcp" port="514")

global(
 DefaultNetstreamDriver="gtls"
 DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/ca.crt"
 DefaultNetstreamDriverCertFile="/etc/rsyslog.d/tls/secondary.home.crt"
 DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/tls/secondary.home.key"
)
___
```

再起動して、エラーが発生していない事を確認します。

```console
systemctl restart rsyslog
systemctl status rsyslog
```

# クライアント設定

今度はクライアント側です。[前回構築した Hyper-V 上のゲストマシン](https://qiita.com/katz_engineer/items/bf9299e8f9afd19975e8)を設定します。

## スナップショット

こちらも[スナップショットを撮っておきます](https://qiita.com/katz_engineer/items/f3bd2f7af2ba49db156c#%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)。

```console:クライアント
sudo zfs snapshot tank/ROOT/ubuntu@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/apt@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/dpkg@$(date +%Y%m%d_%H%M%S)_before_rsyslog_tls
```

## 鍵の配置

[以前、公開鍵送付専用ユーザーを作成しました](https://qiita.com/katz_engineer/items/8c0dcbb985d4493200d2)ので、それを利用してサーバー上の鍵を持ってきます。

sftp で```publickey/demoCA.crt```を取得します。取得したら、クライアント側の責任で削除します。

```console:クライアント
sftp publickey@secondary
```

```console:クライアント：sftp操作
cd publickey
get demoCA.crt
rm demoCA.crt
exit
```

ファイルの権限は取得したユーザーになっているので、これを一般的な```/etc```内ファイルの権限に変えておきます。

```console:クライアント
sudo chown root:root demoCA.crt
sudo chmod 644 demoCA.crt
```

確認。

```console:クライアント
$ ls -l demoCA.crt
-rw-r--r-- 1 root root 1184  3月 11 15:00 demoCA.crt
```

調整した公開鍵を移動します。

```console:クライアント
sudo mkdir /etc/rsyslog.d/tls
sudo mv demoCA.crt /etc/rsyslog.d/tls/
```

## rsyslog・lmnsd_gtls モジュールのインストール

クライアント側にも拡張モジュール lmnsd_gtls が必要だそうです。

```console:クライアント
sudo apt install rsyslog-gnutls
```

## rsyslog 設定

サーバー側の設定と合わせるように、ポート番号やクライアント認証の設定を行います。
下記の設定の場合はファシリティ local0 だけがサーバー 172.16.1.3 に送信されます。

```console:クライアント
sudo -i
cat >/etc/rsyslog.d/80-local0.conf <<___
global(DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/demoCA.crt")

local0.* action(type="omfwd" protocol="tcp" port="514"
    Target="172.16.1.3"
    StreamDriver="gtls"
    StreamDriverMode="1"
    StreamDriverAuthMode="anon")
___
exit
```
再起動して、エラーが発生していない事を確認します。

```console:クライアント
sudo systemctl restart rsyslog
sudo systemctl status rsyslog
```

# 動作確認

ユーザー admin で```logger```コマンドを実行してみます。

```console:クライアント
hostname
whoami
logger -p local0.info hello,world
tail -n1 /var/log/syslog
```

クライアント側でもログが残ります。従って実行結果は、例えば下記のようになります。

```console:クライアント：実行結果例
$ hostname
hyperv
$ whoami
admin
$ logger -p local0.info hello,world
$ tail -n1 /var/log/syslog
Mar 11 16:21:55 hyperv admin: hello,world
```

サーバーにログが転送されているか、確認しましょう。

```console:サーバー
tail -n1 /var/log/syslog
```

クライアントと同じ内容が表示されれば成功です。

```console:サーバー：実行結果例
# tail -n1 /var/log/syslog
Mar 11 16:21:55 hyperv admin: hello,world
```

# 仕舞い

成功したら```/etc```の内容を```svn commit```しましょう。

```console:サーバー
svn add /etc/rsyslog.d/*
svn ci /etc -m"rsyslog over tls"
```

```console:クライアント
sudo svn add /etc/rsyslog.d/*
sudo svn ci /etc -m"rsyslog over tls"
```

これで rsyslog と logrotate と logger を家庭内LANで使う為の最低限の環境が整いました。やったね:thumbsup_tone1: