以前 Syslog について以下のような記事を書きました。Syslog とはこんなやつだよーという記事です。
Syslog について。ファシリティ/シビアリティ/プライオリティの違い
今回はそれの続き、Linux に焦点を絞って syslog について解説し、rsyslog の具体的な構築手順を紹介します。
Contents
rsyslog のインストール
CentOS 7.6 の場合、rsyslog の8系が標準パッケージとしてインストール済みです。
rsyslog がインストール済みなのか、バージョンはいくつなのか、を確認するには以下のコマンドを実行します。
/sbin/rsyslogd -v
また、rsyslog は既定でアクティブになっています。確認するには以下のコマンドを実行します。
systemctl is-active rsyslog
「active」と表示されるはずです。その他の操作コマンドも記載しておきます。
systemctl stop rsyslog // rsyslog デーモンの停止
systemctl start rsyslog // rsyslog デーモンの起動
systemctl status rsyslog // rsyslog デーモンの状態確認
なぜ rsyslog なのか
従来の syslog(BSD syslogd)と比較して、rsyslog は主に以下の点で優れています。これらの特徴から CentOS 7.6 以外にも多くのディストリビューションで標準採用されています。
TCP を使ったログメッセージの転送が可能
BSD syslogd ではログメッセージの転送に UDP しか使えなかった為信頼性がありませんでした。
データベースに保存可能
基本はテキストファイルに吐き出しますが、ログメッセージの保存先に MySQL や PostgreSQL といった DBMS を利用することができます。BSD syslogd でも可能ですが、外部プログラムを必要としていました。ちなみに rsyslog はデータベース抽象化レイヤを利用することで SQL Lite や Oracle などのデータベースにも対応することができます。
SSL/TLS でログメッセージの転送が可能
BSD syslogd でも SSH ポートフォワーディングや SSL/TLS ラッパーといった手法で可能でしたが、rsyslog ならモジュールを追加するだけで TLS 転送が可能です。
ログメッセージの圧縮転送が可能
rsyslog ならクライアントからサーバへのログ転送時にデータを圧縮することができます。
ログメッセージがカスタマイズ可能
出力されるログメッセージのフォーマットを自由に定義できます。例えばログメッセージの生成日付やログを輩出したプログラム、ホスト名など細かく定義可能です。
任意のシステムログを作ってみる
システムログは logger というコマンドを利用することで手動で作成可能です。
例えば以下の様に実行すると /var/log/messages に記録されます。
# logger -p daemon.crit rsyslog deamon log
/var/log/maillog に記録したい場合は以下の様に実行します。
# logger -p mail.crit rsyslog mail log
見てわかると思いますが、「logger -p ファシリティ.シビアリティ ログ本文」です。
Linux のログは全て rsyslog?
前回の記事と重複する部分もありますが、rsyslog への理解を深めるために重要な部分なので抑えておきましょう。
ネットワーク機器の情報・ログは、基本的に Syslog でログを吐き出すか snmp で情報を送信するかくらいですが、Linux(CentOS7.6前提として)にはログと言っても様々なログがあります。
例えば /var/log/messages などのイベントメッセージや yum のログ、プロキシサーバソフトウェアの squid のログなんかもあります。
これらのログは全て rsyslog が記録しているのでしょうか。Linux の本などでは「Linux のシステムログを収集するソフトウェアの1つとして、rsyslog が使われます」なんて書かれることもあります。
システムログを収集するLinuxのソフトウェアとして、syslog、rsyslog、syslog-ng、systemd-jounaldがあります。
標準テキスト CentOS 7 構築・運用・管理パーフェクトガイド より引用
標準テキスト CentOS 7 構築・運用・管理パーフェクトガイド
posted with ヨメレバ有限会社ナレッジデザイン 大竹 龍史/市来 秀男 SBクリエイティブ 2017年03月23日
Linux のような UNIX 系 OS は、 稼働中に発生するさまざまな情報をログとして出力します。こうしたログを収集してファイルに保存したり、他のサーバーに転送したりするのに「Syslog(シスログ)」を利用します。
rsyslog 実践 ログ管理入門 より引用
実際には rsyslog は全てのログの収集に使われるわけではありません。上記で言うと、rsyslog が停止している場合 /var/log/messages のログは記録されませんが、/var/log/yum.log と /var/log/suiqd/access.log は記録されます。これらは各アプリケーションが独自に記録しているログのため rsyslog は関係ありません。
では rsyslog がどのログファイルと関連しているのか確認する方法があるのか、ということになりますが、あります。それは rsyslog の設定ファイルである「/etc/rsyslog.conf」を見ることです。以下のように記載されています。
#kern.* /dev/console
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg :omusrmsg:*
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
上記に記載されているファイルに関しては rsyslog がログを書き込むファイルと思って結構です。と言いたいんですが、「:omusrmsg:*」は rsyslog が停止していても動きます。
「:omusrmsg:*」について
「omusrmsg」は「User Message Output Module」というログイン中ユーザのコンソールに通知を行うための rsyslog のビルトインモジュールです。
例えば、rsyslog が起動している状態で「logger -p kern.emerg emergency!」と実行すると下図のようになります。
ユーザに対して通知が実行されています。次に rsyslog を停止した後に同じコマンドを実行してみます。rsyslog が停止しているため、何も表示されないかエラーが帰ってきそうなものです。
rsyslog が停止していてもほぼ同じ結果になってしまいました。出力されたテキストをよく見てみると以下のように出力されています。
Broadcast message from systemd-journald@LINUX-SV01
つまり、rsyslog ではなく systemd-journald というデーモンが「logger -p kern.emerg emergency!」に反応していたということです。
これは CentOS7 において、systemd-journald と rsyslog という2つのログ管理サービスが稼働しているということを示しています。
systemd-journald とは
参考サイト:
RHEL7/CentOS7のjournaldでシステムログを一元管理 | CTC
rsyslogd と journald の違い・住み分け | えいのうにっき
ログの表示、管理及び転送 | SIOS TECH.LAB
上記の3つのサイトを確認すると理解ができるかと思います。
要約すると、RHEL7/CentOS7 においては、ログは journald(正式名称:systemd-journald)が収集しています。journald は RFC3164 で定義されているシステムログ以外にも、様々なログを収集し独自のデータベースで管理しています。また、journald のログはバイナリで管理されるため、確認は journalctl コマンドで行います。
rsyslog では、imjournal モジュールを使用して journald から情報を受け取ってログを出力しています。これが /var/log 配下にある messages ファイルなどです。
また、journald のログは再起動すると失われます。これは設定で変更可能です。つまり journald のログ保管期間の設定を変更すれば rsyslog 無しで運用することも可能です。今後は journald のみが標準搭載されるディストリビューションが登場する可能性も高いようです。
実際に logger コマンドを使用して journald と rsyslog の動きを確認してみます。rsyslog を停止したうえで「logger -p kern.info journald and rsyslog test」と実行してみると以下のような結果になりました。
rsyslog が停止している為 /var/log/messages には出力が無いものの、journald にはログが残っています。
/var/log/boot.log はまた特別?
/etc/rsyslog.conf には「local7.* /var/log/boot.log」という記載もあります。rsyslog がログを書き込みそうなものですが、rsyslog が停止していても起動時のログが書き込まれていきます。
いったい誰が書き込んでいるのかという話ですが、正直調べてもわかりませんでした。なのでここからは推測です。
journald が書き込むということはないと思います。journald の書き込み先はデータベースのはずなので、テキストファイルに直接書き込むということはないだろうという考えです。
systemd-journald を停止すればいいのでは?
systemd-journald が /var/log/boot.log に書き込みを行っていないことを確認するために停止しようとも思ったのですが、systemd-journald は停止することができません。停止しようとしてもエラー文が返ってくるだけで active のままです。設定でログの保管期間等を 0 にすることで無効化するようです。
参考サイト:journaldを経由してrsyslogへのsyslog受取りをやめて直接rsyslogにsyslogを流す方法 | Qiita
rsyslog は停止しているのでもちろんありえません。
おさらいですが、rsyslog は journald からシステムログを受け取ります。であれば、journald の前にも何かがいて、直接ログを書き込みにいってもおかしくはない気がします。
参考サイト:RedHat 系 OS のログの流れ | Qiita
上記のサイトでは journald の前にカーネルログを出力する printk というカーネル関数が journald へログを渡していると説明されています。つまり journald の前にも何かがいるということで、「rsyslog が停止していてもログが書き込まれる」という現象にそこまで頭を悩ませる必要はありません。
シスログサーバにおける journald の扱い
まとめると、確かに CentOS7 においては rsyslog は journald から転送されたシステムログをテキストファイルに書き込む役割になっています。
ただし、あくまで「syslog」というプロトコルを使用してログを転送するのは rsyslog や syslog-ng といったシステムログ転送プロトコルです。
なので「シスログサーバの構築」においては journald は気にしなくていいです。実際に rsyslog でシスログサーバを構築するとわかりますが、別ホストから転送されてきたシステムログは journald のログデータベースには保存されません。受け取るのは rsyslog です。
journald は RFC3164 で定義されているログ転送のプロトコルとは別物です。「自ホストのログ管理には journald を使っているんだな~」程度に考えて問題ないと思います。
rsyslog で 別の Linux からのログを収集する
実際に CentOS7.6 で rsyslog を使ったシスログサーバを作成し、同じく CentOS7.6 のホストからのログを収集してみます。
rsyslog は標準でインストールされている為、後は設定だけです。
受信(Syslogサーバ)側の設定
必須の設定は以下の2つのみです。なお、ファイアウォールは無効化するか指定したポートの穴あけをしてください。
- UDP もしくは TCP を受信するためのモジュールを組み込む行のコメント解除
- ポート番号を指定する行のコメント解除
/etc/rsyslog.conf の以下の行がコメントアウトされている為、# を削除してください。
UDPを使用する場合
$ModLoad imudp //TCP でログメッセージを受信するためのモジュールを組み込む
$UDPServerRun 514 //サービスポート番号の指定
TCP を使用する場合
$ModLoad imtcp //TCP でログメッセージを受信するためのモジュールを組み込む
$InputTCPServerRun 514 //サービスポート番号の指定。UDP と若干書式が違うが同じ意味
基本的には上記の設定だけで動きます。ただし、このままでは誰からのログも受け取ってしまう状態ですので、最低限の設定としてアクセス許可を設定しましょう。
/etc/rsyslog.conf の適当な場所に以下の行を追加してください。
UDP を許可する場合
$AllowedSender UDP, IPアドレス or ホスト名 or ドメイン名
TCP を許可する場合
$AllowedSender TCP, IPアドレス or ホスト名 or ドメイン名
※IP アドレスにはネットワークアドレスを指定することも可能です
※ホスト名を FQDN で指定する場合、名前解決が出来なかった際は AllowedSender の対象から除外されます
送信側の設定
送信側ではシスログサーバへ転送するファシリティとシビアリティの組合せを決定し、転送先にシスログサーバを指定します。
例:UDP で 192.0.2.10 のシスログサーバへ転送する場合
*.info;mail.none;authpriv.none;cron.none @192.0.2.10
例:TCP で 192.0.2.10 のシスログサーバへ転送する場合
*.info;mail.none;authpriv.none;cron.none @@192.0.2.10
※ポート番号を 514 から変更している場合、「192.0.2.10:5140」のようにポート番号を指定してください。
以上で送信側の設定も終了です。なお、/etc/rsyslog.conf を編集した後には「systemctl restart rsyslog」を実行しなければ設定は反映されないので注意してください。
reload ではない理由
rsyslog を reload した場合、以下のエラーが出力されます。
[root@localhost ~]# systemctl reload rsyslog
Failed to reload rsyslog.service: Job type reload is not applicable for unit rsyslog.service.
See system logs and ‘systemctl status rsyslog.service’ for details.
これは CentOS7.6 インストール直後でも出力されるエラーなので気にしないで下さい。restart してください。
実際に動かしてみる
以下の設定を行った2台の CentOS7.6 を用意したので動かしてみます。
シスログサーバ(192.0.2.10)
$ModLoad imtcp
$InputTCPServerRun 514
$AllowedSender TCP, 192.0.2.20
クライアント(192.0.2.20)
*.info;mail.none;authpriv.none;cron.none @@192.0.2.10
クライアントから「logger test-message」を実行した結果は以下のようになりました。
クライアント
- /var/log/message:ログが残らない
- journalctl:ログが残る(再起動まで)
シスログサーバ
- /var/log/message:ログが記録される
- journalctl:ログは記録されない
期待通りの結果ですね。クライアントに関しては rsyslog.conf でログの転送先をシスログサーバに設定しているものの、システムログは journald からの転送なので journalctl コマンドを実行するとログが確認できます。
シスログサーバに関しては rsyslog がシステムログを受け取る為 journalctl コマンドを実行してもクライアントからのシステムログは確認できません。
まとめ
シスログサーバの構築方法と構築にあたっての事前知識を書きなぐりましたが、お分かりのようにただログを集めるだけであればほとんど設定することなく動きます。
ただし、rsyslog はログの出力内容を設定(テンプレート)したり、キューイングの設定を変更したりといった細かい設定も可能です。深追いすると戻れなくなりそうなので今回はこの辺りまでにします。