Linux サーバーへのSSHログインをSlackに通知する方法を調べました。
ログイン元のIPアドレス制限や、SSHの基本的なセキュリティ設定を実施していれば、滅多なことでは望まない攻撃者がログイン成功することはないはずですが、意図しないログインを直ちに知るために。
用意するもの
- 通知先となるSlackのワークスペース
- SlackのWebhook URLを叩ける、外部通信可能なCentOS Stream 8 またはCentOS Linux 7 サーバー
- Debianとか他のディストリビューションでも使えるはず
Slack側
- Slackにサインイン
ワークスペースにサインインするか、まだ無ければ新規にワークスペースを作る。
画面のとおりに進めば迷わないはず。 - Incoming Webhook を追加
slack app directoryからIncoming WebhookをSlackに追加する。- チャンネルへの投稿
SSHログインしたことを通知するチャンネルを選択するか、新しいチャンネルを作成する。
にっしーは login-notification という専用チャンネルを作成しました。 - 「Incoming Webhook インテグレーションの追加」ボタンをクリック
- チャンネルへの投稿
- Webhook URLのテスト
上記手順で追加ボタンをクリックすると下の方に設定があるが、その前に「セットアップの手順」を読んでテストメッセージを送ってみる。
「例」に書いてあるcurlコマンドを実行するだけでチャンネルに投稿されるはず。 - Incoming Webhook の設定
- 下にスクロールすると「インテグレーションの設定」があるので、「Webhook URL」をコピーしておく。
- 諸々設定して「設定を保存する」ボタンをクリック。
後からでも変更可能なので、とりあえず設定変えずに保存してしまっても構わない。
後から変えたい時は、ワークスペースにサインインして左下の「アプリを追加する」をクリックすると、右ペインに追加済みアプリが表示されるのでクリック→設定ボタンをクリック→「説明」の右にある「設定」をクリック→鉛筆ボタンをクリック で変えられる。
- 下にスクロールすると「インテグレーションの設定」があるので、「Webhook URL」をコピーしておく。
Linux サーバー側
SSHログイン時に通知用スクリプト実行
どう呼び出すか
- /etc/ssh/sshrc → 却下
- ~/.ssh/rc でオーバーライドされてしまうので確実ではない
- sshd_configのForceCommand → 却下
- スクリプトの最後で$SHELL呼ばないとシェルに入れない
Match User
と組み合わせて、特定ユーザーにシェルログインさせずに特定コマンドだけ許可(強制)するために使うのが本来の使い方な気がする- scpできなくなる
- /etc/pam.d/sshd → 採用
/usr/local/sbin/ssh-notify.sh
を作成して実行権限を付ける。
オーナーとオーナグループはrootで、otherは権限無しで問題ない。
Webhook URLを叩くと誰でも投稿できるから、otherは落としておくのがいい。
もちろん、/usr/local/bin/
に置いて、otherに権限付けてもいい。
$ sudo touch /usr/local/sbin/ssh-notify.sh
$ sudo chmod 750 /usr/local/sbin/ssh-notify.sh
$ ls -l /usr/local/sbin/ssh-notify.sh
-rwxr-x---. 1 root root 0 Jan 17 10:33 /usr/local/sbin/ssh-notify.sh
中身は後述。
SELinuxで許可していないディレクトリにスクリプトを設置すると、SSHログインした時に
/etc/ssh/scripts/ssh-notify.sh failed: exit code 13
と表示されて、以下が記録される。
実行権限が無くてもfailedになる。
$ sudo journalctl | grep pam_exec
Jan 17 11:07:47 centos7 sshd[2816]: pam_exec(sshd:session): execve(/etc/ssh/scripts/ssh-notify.sh,...) failed: Permission denied
Jan 17 11:07:47 centos7 sshd[2813]: pam_exec(sshd:session): /etc/ssh/scripts/ssh-notify.sh failed: exit code 13
通知用スクリプトの作成
Webhook URLを叩けるなら言語は問わないみたいだけど、簡単にシェルスクリプトにする。
#!/bin/bash
if [ "$PAM_TYPE" != "close_session" ]; then
url="コピーしたWebhook URL"
MESSAGE="\"text\": \"$PAM_USER が $PAM_RHOST から $(hostname) にログインした。\""
curl -X POST --data-urlencode "payload={ $MESSAGE }" $URL &
fi
PAM設定
$ sudo sh -c 'echo "session optional pam_exec.so seteuid /usr/local/sbin/ssh-notify.sh" >> /etc/pam.d/sshd'
確認
Linux サーバーにSSHログインすると、設定したSlackチャンネルに投稿される。
スクリプトの中身を変えれば、メール通知や他の通知方法にも応用できるはず。
参考にしたサイト
https://www.pullrequest.com/blog/ssh-login-notification-in-slack/
https://medium.com/star-systems-labs/monitoring-ssh-login-via-slack-3012a16fd02b