syslogサーバー(大規模環境用)を作ってみた話

西山
2023-07-14
2023-07-14

こんにちは。日々是発見が楽しみな西山です。

弊社ではオンプレミス環境にメールサーバー群があり、常時多数のメールが送受信されています。
それらのメールログを集約するsyslogサーバーを構築したので、設定・構築のポイントや留意した内容を書き留めてみました。

「今までログ集約せずに運用してたのかよ」と言われるのはごもっともなのですが、過去にsyslogサーバーを導入した際、ログ転送が追い付かなくなり送信元・先の両方で書き込みが遅延する事故が起こってしまいました。
今回はサーバースペックや設定を慎重に詰めて再トライした記録です。

メールサーバーを運用されている方はご存じの通り、postfixはメール1通の送受信で6行のログが発生し、通数が多いとログ量が膨大になります。
前述の書き込み遅延事故の反省もあり、「各サーバーからは安定して送信」「syslogサーバー側では遅滞なく書き込み」ができるよう留意して構築しました。

ログ送信側(メールサーバー)設定

syslog転送に関するコンフィグを別ファイルにまとめ、 /etc/rsyslog.d 配下に設置しました。
こうすることで、syslogサーバーに障害が発生したり、メンテナンスでネットワークが切断される場合は、コンフィグファイルをリネームしてrsyslogを再起動すると転送を一時的に停止できます。

/etc/rsyslog.d/maillog_send.conf

mail.* action(type="omfwd"
              protocol="tcp" port="514"
              Target="203.0.113.1"
              queue.type="LinkedList"
              queue.filename="maillog_data"
              queue.maxdiskspace="1g"
              queue.saveonshutdown="on"
              action.resumeInterval="30"
              action.resumeRetryCount="-1"
)

ポイント

protocol="tcp" port="514"

syslog転送のデフォルトはUDP転送ですが、今回は「ログ欠落は許容されない」「多数のメールサーバーから常時大量のログを送信する」という特性を鑑み、TCPで転送しています。

queue.type="LinkedList"
queue.filename="maillog_data"
queue.maxdiskspace="1g"
queue.saveonshutdown="on"
action.resumeInterval="30"
action.resumeRetryCount="-1"

syslogキューを設定し、一時的に「ネットワーク接続が不安定」「syslogサーバーの書き込みが滞留」してもキューファイルで緩衝できるようにしています。

  • 「LinkedList」タイプの動的割り当てキューを使用
  • インメモリとディスク(ファイル名「maillog_data」)ハイブリッドでキュー動作
  • ディスクキューのサイズは1GB、マシンシャットダウン時は保存される
  • 転送が失敗した場合、インターバル「30秒」を空けてリトライを繰り返す(回数は無限回)

ログ受信側(syslogサーバー)設定

こちらも追加設定を別ファイルに集約しています。

/etc/rsyslog.d/remote_maillog.conf

# receive udp syslog
module(load="imudp") # needs to be done just once
input(type="imudp" port="514" ruleset="remote_maillog")

# receive udp syslog
module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514" ruleset="remote_maillog")

$umask 0022

template(name="remote_maillog" type="string"
     string="/var/log/remotelog/%HOSTNAME%/%$year%%$month%%$day%.%programname%"
    )

ruleset(name="remote_maillog"){
   *.*  action(type="omfile" DynaFile="remote_maillog" fileCreateMode="0644" dirCreateMode="0755")
   stop
}

ポイント

template(name="remote_maillog" type="string"
 string="/var/log/remotelog/%HOSTNAME%/%$year%%$month%%$day%.%programname%"
 )

転送されてきたsyslogを振り分けるルールテンプレート「remote_maillog」を定義します。

  • /var/log/remotelog 配下に、
  • 送信元サーバーのホスト名のディレクトリを作成し、
  • 「YYYYMMDD.(ログを記録したプログラム名)」という名前のログファイルを作成し書き込む
$umask 0022
ruleset(name="remote_maillog"){
   *.*  action(type="omfile" DynaFile="remote_maillog" fileCreateMode="0644" dirCreateMode="0755")
   stop
}
  • ログ調査時の作業性をよくする(rootユーザーにならなくてもログの読み取りはできる)ため、ルールセット「remote_maillog」を定義してファイル・ディレクトリ作成のパーミッションを調整
  • rsyslogのデフォルトパーミッションを「$umask 0022」で緩めた上で、fileCreateMode / dirCreateMode を指定
    ※RHEL系のrsyslogはデフォルトが「$umask 077」となっているため、これを打ち消さないと何を指定してもパーミッション「700」でしかファイルを作れない
# receive udp syslog
module(load="imudp") # needs to be done just once
input(type="imudp" port="514" ruleset="remote_maillog")

# receive udp syslog
module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514" ruleset="remote_maillog")
  • ルールセット「remote_maillog」をポート514で受ける定義
    ※念のためTCP / UDP両方で受信可能に設定

rsyslogの設定以外のポイントとしては、オンプレミス環境で毎日GB単位のログを記録するため、SSDストレージの物理サーバーを使用しました。

弊社のメールサーバー群では、トータルで1日当たり2GB~4GB(未圧縮)程度のログが日々発生していますが、今回構築したsyslogサーバーはこの量のログを全く欠落なく受信・記録できています。
また送信元・先ともに低負荷で安定稼働しており、「syslogサーバーを心配しながら運用する」という過去の悪夢を回避できてほっとしました……。

構築してみて

このsyslogサーバーを構築しながら、今作るならFluentdなど使ってもいいのでは……と考えましたが、postfixのログはFrom / To /キューIDを色々処理して回らないと一意のレコードが作れないので、今回はsyslogでまず集約を目指しました。
Fluentdなどのデータコレクタツールの活用も、今後チャレンジしていきたいと思っています。