ニーズ
DoS攻撃などを防止するため、sshguardを標準装備として各本番サーバにはインストールされている。
昨今、リモートワークが当たり前になって、従業員からのアクセスをBANされたケースが多発され(特にgitまわり)、
そのBANのIPの解除はSREメンバーが都度手動でしないといけない状況になっています。
エンジニアのtoil撲滅の一環として、これらの作業をセルフサービス化としたいのは今回のゴールである。
考慮ポイント
- 対象
- コスト
- 実装方法
- webサービス
- 実装が遅い
- 自前でユーザ認証する必要あり(リモートワーク前提ので)
- 実装まわりで経験値を大量ゲットできる
- botユーザ(chatwork)
- 実装が速い
- ユーザ認証不要(すでにchatworkの方で認証済み)
- 実装まわりで経験値少量ゲット
- webサービス
アーキテクチャ
TO:bot
専用のbotユーザにTOをつけて話しかけると、webhookが叩かれ、apigatewayに送信
- IPアドレスのみの場合、IP一覧チェックを行い、解除&更新もする
- BAN部屋のメッセージを引用された場合、IP一覧チェックを行い、解除&更新もする
- それ以外の場合、デフォルトhelpメッセージを返す
APIgateway - lambda
chatwork webhookから受信し、lambdaでtoken検証をする。
問題ないの場合、bodyの解析を行う
- IPアドレスのみの場合、IP一覧チェックを行い、解除&更新もする
- ない場合は、その旨をchatworkに返す
- BAN部屋のメッセージを引用された場合、IP一覧チェックを行い、解除&更新もする
- ない場合は、その旨をchatworkに返す
- それ以外の場合、デフォルトhelpメッセージを返す
実装ポイント
- timeout 3s要注意(apigateway仕様)
- systemmanagerとs3のSDKを使って、shell実行やipチェックを行う
- 返信メッセージを丁寧に表現
一覧チェック
現在BANされているIPアドレスの一覧リストをテキストファイルとして、s3の指定場所に格納
lambdaでs3 SDK経由、都度指定されたIPが、リストに載ってるかをチェック
- 載ってる場合、trueをlambdaに返し、その解除&更新もする
- 載ってない場合、falseをlambdaに返し、その旨をchatworkに返す
kick system manager run command
lambdaでsystemmanager SDKを利用し、指定EC2インスタンスにて、shell commandを実行
shell実行(解除&更新)
- iptables -L sshguard –line-numbers -n | grep #BANされたIP# | cut -d’ ‘ -f1 | xargs -L 1 iptables -D sshguard
- systemctl restart sshguard
- iptables -L sshguard –line-numbers -n > /tmp/sshguard_ban_ip/
hostname
.txt - aws s3 sync /tmp/sshguard_ban_ip/ s3://#S3の指定bucket名#/
実行成功/失敗後、その旨をchatworkに返す
レスポンス
↑の各ステップでのレスポンス
cloudwatch event kick system manager run command
短時間/回で、BANされたIPアドレス一覧を最新化する
shell実行(更新)
- iptables -L sshguard –line-numbers -n > /tmp/sshguard_ban_ip/
hostname
.log - aws s3 sync /tmp/sshguard_ban_ip/ #S3の指定bucket名#
一覧最新化
↑での結果が反映される
ついでに、s3バケットを静的コンテンツとして表示させるのもあり
1 | <!DOCTYPE html> |
成果物
構成は全部terraformに載っており、lambda functionはpython 3.6を使わせていただきました。
terraformコード
1 | # |
lambda functionコード
1 | import os |
誰かのご参考になって頂ければ幸いです。
ではでは〜