
概要
- サービス管理フレームワーク(
launchd
)を利用し、スクリプトを定期実行する - スクリプトで、ログイン成功を検出し、Slackへ通知する
- ライフログとして利用したり、コンピュータ紛失時のアクティビティ監視に応用できる
環境
以下の環境で、動作確認を行いました。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.11.5
BuildVersion: 15F34
ログインを検出する
LINEやAmazon、Googleなどは、ログイン時にメールやメッセージを、ユーザに送るようになりました。不正ログインによる被害を最小限にする施策です。このようなログインアクティビティの通知は、不正ログインの被害を抑えるだけでなく、ライフログとして活用できます。
今回は、日常的に利用しているMac OS XとSlackを使ってログインアクティビティの通知を行います。
Mac OS Xのログイン履歴
Macの場合、ログイン成功のログは、/var/log/accountpolicy.log
にあります1。ほかのさまざまなログは、console.app
から確認できます。
ログイン成功のログは以下のようになっています。各レコードでcompleted
という文字列を見つければよさそうです。
Oct 23 03:36:55 (73.392.1) AuthenticationAllowed completed: record "tamanobi", result: Success (0).
Oct 23 03:36:55 (73.393.1) AuthenticationAllowed completed: record "tamanobi", result: Success (0).
Oct 23 03:40:41 (73.394.1) AuthenticationAllowed completed: record "tamanobi", result: Success (0).
Oct 23 03:40:41 (73.395.1) AuthenticationAllowed completed: record "tamanobi", result: Success (0).
10秒以内にログインしていたら通知する
上記で説明したログには、日時が記録されています。チェックしたときの日時と、何秒前の記録まで通知するか決めればよさそうです。
シェルスクリプトを書いてみました。最後に出てくるwebhook.sh
は、[10分で出来る]シェルスクリプトの結果をslackに投稿を参考にしてください。
# !/bin/bash
set -eux
# 実行時の日時から、何秒前のレコードをSlack通知の対象とするか
INTERVAL=10
# ログファイルのフルパス
LOGFILENAME=$1
function dateComp()
{
# Oct 23 01:59:20 形式から経過秒に変換
ARG1_SECOND=`date -j -f "%b %d %H:%M:%S" "$1" "+%s"`
ARG2_SECOND=`date -j -f "%b %d %H:%M:%S" "$2" "+%s"`
expr $ARG1_SECOND - $ARG2_SECOND
}
# ログのレコードから、時間を"%b %d %H:%M:%S"形式で取得
function record2date()
{
RECORD=`echo $1 | awk '{print $1 " " $2 " " $3}'`
echo $RECORD
}
NOW=`date '+%b %d %H:%M:%S'`
PREV=`date -v-${INTERVAL}S '+%b %d %H:%M:%S'`
# ダブルクオーテーションがあると変数展開時に厄介なので、アスタリスクに置換
LAST_RECORD=`tail -n 1 "$LOGFILENAME" | sed -e 's/"/*/g'`
DATETIME_LAST_RECORD=`record2date "$LAST_RECORD"`
MAX_DIFF_DATETIME=`dateComp "$NOW" "$PREV"`
DIFF_DATETIME_LAST_RECORD=`dateComp "$NOW" "$DATETIME_LAST_RECORD"`
if [[ $MAX_DIFF_DATETIME -gt $DIFF_DATETIME_LAST_RECORD ]]; then
if [[ "$LAST_RECORD" =~ completed ]];then
echo "User logged in!\n$LAST_RECORD" | sh /Users/tamanobi/webhook.sh
fi
fi
定期的にログを確認して、監視をする
監視にはログインフックを利用することもできますが、定期的にログを確認するシンプルなアプローチを今回は採用します。
launchd
を利用してプログラムを定期実行する
定期実行といえば、cronですが今回は利用しません。代わりに、launchd
というサービス管理フレームワークを利用します。
以下は、launchd
でできることの一例です。
-
cron
のように任意のスクリプトを定期実行する - ファイルの変更を監視し、変更時に任意のスクリプトを実行する
プログラムを定期実行するための設定ファイルを作成する
launchd
を利用するには、XMLで書かれた設定ファイルを登録する必要があります。今回用意した設定ファイルを載せます。
記述量は多めですが、重要なのは以下の3つだけです。
- プロセスのラベル
- コマンド
- 定期実行の間隔(秒)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<!-- プロセスのラベル -->
<string>monitoringLoginActivity</string>
<key>ProgramArguments</key>
<array>
<!-- コマンド -->
<string>bash</string>
<!-- コマンドに渡す第一引数 -->
<string>/Users/tamanobi/noticeLoginActivity.sh</string>
<!-- コマンドに渡す第二引数 -->
<string>/var/log/accountpolicy.log</string>
</array>
<key>StartInterval</key>
<!-- 定期実行の間隔(秒) -->
<integer>10</integer>
<key>StandardOutPath</key>
<!-- 出力を保存するファイルへのパス -->
<string>/tmp/monitoringLoginActivity.out</string>
<key>StandardErrorPath</key>
<!-- エラーを保存するファイルへのパス -->
<string>/tmp/monitoringLoginActivity.err</string>
</dict>
</plist>
動かしてみる
登録する前に必要なファイルの確認です。以下のファイルが必要です。
- ~/Library/LaunchAgents/monitoringLoginActivity.plist
- /Users/tamanobi/noticeLoginActivity.sh
- /Users/tamanobi/webhook.sh2
launchd
に登録する
launchd
を操作するには、launchctl
コマンドを使用します。launchctl load
でplistを登録できます。登録したら、すぐに10秒ごとに監視が動き出します。
$ launchctl load ~/Library/LaunchAgents/monitoringLoginActivity.plist
エラーログや出力結果は、設定したとおり/tmp/monitoringLoginActivity.err
と/tmp/monitoringLoginActivity.out
で確認できます。
launchd
の登録を削除するには launchctl unload
を使う
登録したものはlaunchctl unload
で削除できます。
$ launchctl unload ~/Library/LaunchAgents/monitoringLoginActivity.plist
launchd
の登録一覧をみるには launchctl list
を使う
登録したものはlaunchctl list
で確認できます。量が多いので、設定したラベルでgrepすることをおすすめします。
$ launchctl list
完成!(実際にログインし直してみる)
実際にログインし直してみると、Slackに通知が来ます。

ログインアクティビティを通知する
まとめ
この記事では、MacのログインアクティビティをSlackに通知する方法を紹介しました。
一例として、Slackに通知を送りましたが、スクリプト次第で別のサービスへ通知を送ることもできます。ログインしたタイミングで、特定のビルドを走らせたり、本日の予定を画面に表示させることもできるでしょう。
また、ログインアクティビティをストレージに保存しておけば、ライフログとして活用できるでしょう。職業プログラマなら生産性の指標になるかもしれません。
参考リンク
- launchdに関するリソース制限の設定まとめ
- [10分で出来る]シェルスクリプトの結果をslackに投稿
- launchdで定期的にスクリプトを実行
- cronからlaunchdへ(より効率的なジョブ管理を目指して)
- Mac(OS X)ではcronじゃなくてlaunchdでやる
- LaunchAgent に登録して、スクリプトを自動起動する
- launchd を使ってスクリプトを自動実行してみた
-
バージョンごとに違う可能性があるので注意して下さい。 ↩
-
[10分で出来る]シェルスクリプトの結果をslackに投稿を参考にしてください。 ↩