LoginSignup
0
1

More than 3 years have passed since last update.

メールサーバに LDAP サーバに対するヘルスチェックを組み込む

Last updated at Posted at 2020-03-19

概要

Postfix で3000人規模の利用者がいるメールサーバを運用しています。利用者の登録情報(誰が登録されているか、転送先アドレスは何処か、など)は、別サーバで稼働している LDAP サーバに格納されています。

メールサーバ管理者と LDAP サーバ管理者が別人の場合、連絡不行届などが理由で、LDAP サーバは停止しているのに、メールサーバを起動してしまうことが有り得ます。このような事故が発生すると、Postfix は接続元に対して一時的エラーを通知してメールを受け取らないという挙動をするはずですが、そもそも Postfix を止めてしまった方が良いという場合もあります。筆者の場合は、停電からの復電作業手順書に、メールサーバと LDAP サーバの電源投入順序に制約を追加し、作業時間を増やしたくないという動機です。

本稿では、そのような LDAP サーバに対するヘルスチェック付きのメールサーバを構築する方法を述べます。

設定手順

ヘルスチェックスクリプトのインストール

ldap-health-check スクリプト/usr/local/bin/ に置いて下さい。
そのスクリプトの引数として、Postfix の LDAP 設定ファイルを指定する --conffile オプションと --debug オプションの2つを指定して実行し、LDAP サーバと通信できていることを確認してください。

$ /usr/local/bin/ldap-health-check --conffile /etc/postfix/your-using-ldap-config --debug
DEBUG: LDAP search success: dn=ou=users,dc=example,dc=net
^C

ヘルスチェックサービスの作成

以下のようなサービス定義ファイル /etc/systemd/system/ldap-health-check.service を用意します。

/etc/systemd/system/ldap-health-check.service
[Unit]
Description = ldap-health-check daemon

[Service]
ExecStart = /usr/local/bin/ldap-health-check --conffile your-using-ldap-configuration-file
Type = simple
Restart = always
StartLimitBurst = 1

[Install]
RequiredBy = postfix.service

この設定では、Restart = always と指定して「常に再起動を試みる」、かつ StartLimitBurst = 1 と指定して「1回再起動を試みて失敗したら、そこで諦める」という指定をしています。ここで、「諦める」という指定になっているのが重要です。本稿の目的として、このヘルスチェックサービスが停止したら、その時点で Postfix も停止したいわけですが、うっかり StartLimitBurst = 0 と設定して、無期限に再起動を試みるという指定をすると Postfix は停止してくれません。ヘルスチェックサービスの再起動を試行している間は、RequiredBy によって指定した依存関係が満たされていると見なされて、Postfix は停止されないようです。ですから、StartLimitBurst を適当に指定して、ヘルスチェックサービスを明示的に 失敗 させる必要があります。

作成した定義ファイルを systemd に読み込ませます。

$ sudo systemctl enable ldap-health-check.service
$ sudo systemctl start ldap-health-check.service

この状態で、以下のようなメッセージが表示されるはずです。

$ systemctl status ldap-health-check.service
● ldap-health-check.service - ldap-health-check daemon
   Loaded: loaded (/etc/systemd/system/ldap-health-check.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2020-03-19 22:03:25 JST; 32min ago
 Main PID: 23220 (ldap-health-che)
    Tasks: 1 (limit: 4698)
   Memory: 11.8M
   CGroup: /system.slice/ldap-health-check.service
           └─23220 /usr/bin/perl /usr/local/bin/ldap-health-check

LDAP サーバが応答していない時、Postfix が停止することを動作確認

LDAP サーバの IP アドレスが、198.51.100.8 であるとします。メールサーバから LDAP サーバへの通信を禁止するには、メールサーバ上で、以下のようにダミーの経路を設定することがもっとも簡単です。

$ sudo ip route add blackhole 198.51.100.8

ダミーの経路が設定されると、ldap-health-check スクリプトが、以下のようにエラーで異常終了するようになります。

$ systemctl status ldap-health-check.service
● ldap-health-check.service - ldap-health-check daemon
   Loaded: loaded (/etc/systemd/system/ldap-health-check.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2020-03-19 22:46:15 JST; 9s ago
  Process: 36413 ExecStart=/usr/local/bin/ldap-health-check (code=exited, status=1/FAILURE)
 Main PID: 36413 (code=exited, status=1/FAILURE)

すると、Postfix も以下のように異常終了しているはずです。

$ systemctl status postfix.service
● postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Thu 2020-03-19 22:46:15 JST; 3min 53s ago
 Main PID: 31077 (code=exited, status=0/SUCCESS)

Mar 19 22:21:14 mx1.example.net systemd[1]: Starting Postfix Mail Transport Agent...
Mar 19 22:21:14 mx1.example.net systemd[1]: Started Postfix Mail Transport Agent.
Mar 19 22:46:15 mx1.example.net systemd[1]: postfix.service: Succeeded.
Mar 19 22:46:15 mx1.example.net systemd[1]: Stopped Postfix Mail Transport Agent.
Mar 19 22:46:15 mx1.example.net systemd[1]: Stopping Postfix Mail Transport Agent...
Mar 19 22:46:15 mx1.example.net systemd[1]: Dependency failed for Postfix Mail Transport Agent.
Mar 19 22:46:15 mx1.example.net systemd[1]: postfix.service: Job postfix.service/start failed with result 'dependency'.

末尾から2行目に Dependency failed と出力されていることがポイントで、ヘルスチェックサービスが停止しているために Postfix サービスを開始できないことが分かります。

LDAP サーバが復活した時、Postfix が再開することを動作確認

以下のような cron を設定して、10分に少なくとも1回は、Postfix の起動を試みるようにします。

/etc/crontab
3,13,23,33,43,53 * * * *    root    /usr/bin/systemctl status postfix >/dev/null || /usr/bin/systemctl start postfix

LDAP サーバへのダミーの通信経路を削除して、正常に通信できるようにします。

$ sudo ip route del blackhole 198.51.100.8

すると、10分以内に cron により Postfix の起動が試行されます。

先ほどのヘルスチェックサービスの設定で、StartLimitBurst = 1 と指定して、「再起動に1回失敗したら諦める」と設定してありますが、systemctl start postfix コマンドが実行されると、その時点で、Postfix サービスが依存している別サービスの失敗回数カウンタもリセットされるので、少なくとも1回はヘルスチェックサービスの再起動が試行されます。したがって、この時点でヘルスチェックが成功すれば、Postfix も無事に起動されます。

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1