ホスト内のユーザ全員宛てにメールを送る方法

背景

集団開発環境でコミットログなどをメールで通知する事が良くあると思いますが、その際に専用のMLを作成してしまうとML加入ユーザと開発に関係するユーザが別管理になってしまうので管理上わずらわしいです。なのでいっそ開発で使うサーバをPOPサーバにしてしまい、そこに通知メールを配送すればMLのユーザ管理とサーバのユーザ管理が同期するので手間が減らせるのでは?と考えました。

ホスト内のユーザにメールを配信するに先立ち、まずは単純に「いわゆるログオンユーザ」のリストを取得することを考えました。リストさえ取得できれば後はそのユーザに配送するだけなので、このリストアップ処理が要と考えた為です。

ユーザのリストアップ方法

  1. UIDの範囲を元に/etc/passwdファイルから取得
  2. /home 以下のディレクトリをリストアップする。
    • /home/storage や /home/share など、ユーザホームでないディレクトリが存在する場合がある。
    • Maildirを使用している場合は /home/*/Maildir の有無を調べれば送信の可否は調べられるが、万能ではない気がする…。
  3. passwdファイルのシェルに /sbin/nologin や/bin/false がセットされていないユーザをリストアップする
    • 確認してみると、デーモンを動作させるユーザでもログインシェルがセットされるものがあり、取得できるユーザリストにノイズが多い。

最初の選択肢がもっとも可搬でノイズが少なそうなので採用することにしました。案に基づきユーザをリストアップするスクリプト listup_users.sh を書いてみました。(UIDの上限と下限はそれぞれFedora系とDebian系どちらかの小さいほうで統一してあります。)

#!/bin/bash

USERID_MIN=500
USERID_MAX=29999

declare -i USERID=0

while read USER_ENT
do
    USERID="`echo ${USER_ENT} | awk -F: '{print \$3;}'`"
    if [ ${USERID_MIN} -le ${USERID} -a ${USERID} -le ${USERID_MAX} ]
    then
        echo "${USER_ENT}" | awk -F: '{printf $1" ";}'
    fi
done </etc/passwd

実行してみると以下のような出力が得られます。(出力末尾には改行がつきません)

[haruki]$ ./listup_users.sh
haruki family 

メール配送

リストアップができるようになったので、/var/lib/semdmail に引数としてリストアップしたユーザのリストを渡すことで送信可能できます。配信にはリストアップとsendmail呼び出しを1つのスクリプト内にまとめた mail2localusers.sh を用意することにしました。

#!/bin/bash

USERID_MIN=500
USERID_MAX=29999

declare -i USERID=0
TO=""

while read USER_ENT
do
    USERID="`echo ${USER_ENT} | awk -F: '{print \$3;}'`"
    if [ ${USERID_MIN} -le ${USERID} -a ${USERID} -le ${USERID_MAX} ]
    then
        TO="${TO} `echo "${USER_ENT}" | awk -F: '{printf $1;}'`"
    fi
done </etc/passwd

/usr/lib/sendmail $@ ${TO}

配置先は/usr/local/lib、所有者はroot:root、権限は0755としました。(/usr/local/libに配置したのはsendmailプログラムの配置に倣ったためです。)
ホスト内のユーザ全員に送信するというアドレスを作成したい場合はaliasを用意してパイプで上記のコマンドに渡してやると良いでしょう。aliasの設定方法は以下のページを参考にしました。
postfix :: aliases (エイリアス) の設定 [Tipsというかメモ]
Homeserver on Linux – 自宅サーバーを作ろう | Just another WordPress site

/etc/aliasの記述(postfixの例)

all-users:      | "/usr/local/lib/mail2localusers.sh"

更新後newaliasesコマンドを実行するのを忘れないようにしましょう。alias更新後、以下のコマンドを実行してユーザ全員に配送されていることを確認してみます。

echo "test for \"all-users\"" | mail all-users