January 17, 2021

SSHログインをSlackに通知する

Linux サーバーへのSSHログインをSlackに通知する方法を調べました。
ログイン元のIPアドレス制限や、SSHの基本的なセキュリティ設定を実施していれば、滅多なことでは望まない攻撃者がログイン成功することはないはずですが、意図しないログインを直ちに知るために。

用意するもの

  • 通知先となるSlackのワークスペース
  • SlackのWebhook URLを叩ける、外部通信可能なCentOS Stream 8 またはCentOS Linux 7 サーバー
    • Debianとか他のディストリビューションでも使えるはず

Slack側

  1. Slackにサインイン
    ワークスペースにサインインするか、まだ無ければ新規にワークスペースを作る
    画面のとおりに進めば迷わないはず。
  2. Incoming Webhook を追加
    slack app directoryからIncoming WebhookをSlackに追加する。
    1. チャンネルへの投稿
      SSHログインしたことを通知するチャンネルを選択するか、新しいチャンネルを作成する。
      にっしーは login-notification という専用チャンネルを作成しました。
    2. 「Incoming Webhook インテグレーションの追加」ボタンをクリック
  3. Webhook URLのテスト
    上記手順で追加ボタンをクリックすると下の方に設定があるが、その前に「セットアップの手順」を読んでテストメッセージを送ってみる。
    「例」に書いてあるcurlコマンドを実行するだけでチャンネルに投稿されるはず。
  4. Incoming Webhook の設定
    1. 下にスクロールすると「インテグレーションの設定」があるので、「Webhook URL」をコピーしておく。
    2. 諸々設定して「設定を保存する」ボタンをクリック。
      後からでも変更可能なので、とりあえず設定変えずに保存してしまっても構わない。
      後から変えたい時は、ワークスペースにサインインして左下の「アプリを追加する」をクリックすると、右ペインに追加済みアプリが表示されるのでクリック→設定ボタンをクリック→「説明」の右にある「設定」をクリック→鉛筆ボタンをクリック で変えられる。

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

https://vninja.net/homelab/logging-ssh-logins-to-slack/

© 2020 nissy-lab.com