はじめに
- OCIに限った話ではありませんが、お付き合いいただければ幸いです
背景
- TL;DR
- 2024年最も関心を集めたセキュリティインシデントと言えば2024年6月の、あの出来事しかないでしょう
- 起きてしまった事を対岸の火事ではなく、十分に起きえる身近な事として捉え、何がやれるのかを考えてみた
結論
- 銀の弾丸はないでしょう
- とは言え、やれることを一つづつ地味にやり続けるしかない
- 未然防止の観点で、Todo itemを決め、実行するしかない
- 短期的に効果が見込めそうで、着手コストが低いものから
- 中長期的な視点では経営層を巻き込んで、インシデント発生コストを見極め、根治的改善策を履行する事が望ましいでしょう
何ができそうか?
- 上記の結論2.に関して、サーバリソース内で実行されるコマンドを補足する事にした(特に特権ユーザ)
- 出来る限りリアルタイムにコマンド履歴を補足して、悪意あるものから出来る限り手が届かないところへ証跡を残す
どうしてそうしたか?
- 認証認可の隙間に落ちているセキュリティ諸課題を「埋める何か」が必要があるように筆者が感じていた
- セキュリティ対策は様々な形でコストをかけて実装されているが、OSユーザのコマンド履歴をカジュアルに追う手段が以外に少ない
- こっそりやられるのはしゃくだし、だったらこっそりと覗き続けてやればいい
概要設計
- 対象OSはLinux系OSとし、任意のユーザがTerminalへ入力するコマンドを捕捉・キャプチャし、syslogへ記録する
- syslogに依存する形で、外部へコマンドキャプチャしたものをforwardする
- forward先から任意の形で「転送」したり「保存」を行ってコマンド実行履歴を外部保管する
- 転送先で任意のアクションを実装する・出来るようにする
実装
- これはこの記事からアイデアをいただきました
1.コマンドを補足・キャプチャする
- 任意のユーザ.bashrcに次の仕込みを行います
whoami="$(whoami)@$(echo $SSH_CONNECTION | awk '{print $1}')"export PROMPT_COMMA
ND='RETRN_VAL=$?;logger -p local6.debug "$whoami [$$]: $(history 1 | sed "s/^[ ]
*[0-9]\+[ ]*//" ) [$RETRN_VAL]"'
2.syslogの設定
- rsyslogへ下記の3行を追記を行い、rsyslogをリスタートする
### 10.0.0.9はsyslog受けサーバ
local6.debug @10.0.0.9:5140
### end of the forwarding rule ###
- 参考にしたQiita記事ではファイルへ吐き出す実装でしたが、今回はファイル経由はせずに、syslog転送とします。理由は
- ローカルファイルに出力すると悪意ある攻撃者に改竄されるリスクがある
- また、即時に転送を行う事で攻撃者から「証跡」を保護出来る
- syslog転送を即時実行し、コマンドキャプチャをリアルタイムで捕捉可能な形に「加工」出来る
- また、syslog転送を使う副次的なメリットとして
- syslog受けにfluentが使える
- fluentを使う事で転送先でアクションを記述出来る
- fluentの豊富なプラグインの恩恵を受けれる
3. syslog受け側設定(リモートサーバ設定)
- fluent + syslog pluginで実装する
- fluent を docker で起動、syslog plugin を有効にする
[opc@ol8 fluentd]$ tree . |_config |_ fluent.conf docker-compose.yml Dockerfile 1 directory, 3 files [opc@ol8 fluentd]$ cat docker-compose.yml version: '3.3' services: fluentd: #image: fluent/fluentd:v1.17.1-1.0 image: fluentd-v1.17-s3:latest volumes: - ./config:/fluentd/etc ports: - 24224:24224 - 24224:24224/udp - 5140:5140 - 5140:5140/udp [opc@ol8 fluentd]$ cat Dockerfile FROM fluentd:v1.17.1-1.0 USER root RUN gem install fluent-plugin-s3 USER fluent [opc@ol8 fluentd]$ docker build . [opc@ol8 fluentd]$ docker image list [opc@ol8 fluentd]$ docker-compose up -d
4. fluent(syslogサーバとして)で受け取った結果
- clientは ol8-arm64とol79-fluentの2台
- opcの実行したコマンドをリアルタイムにfluent + syslogで受信
2024-11-22 01:14:20.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366220","message":"opc@XXX.XXX.XXX.186export [366169]: sudo -s [0]"}
2024-11-22 01:14:21.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366224","message":"opc@XXX.XXX.XXX.186export [366169]: sudo -s [0]"}
2024-11-22 01:14:21.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366228","message":"opc@XXX.XXX.XXX.186export [366169]: sudo -s [0]"}
2024-11-22 01:14:21.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366232","message":"opc@XXX.XXX.XXX.186export [366169]: sudo -s [0]"}
2024-11-22 01:14:24.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366237","message":"opc@XXX.XXX.XXX.186export [366169]: ls -l [0]"}
2024-11-22 01:14:26.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366242","message":"opc@XXX.XXX.XXX.186export [366169]: ls -l [0]"}
2024-11-22 01:14:27.000000000 +0000 terminal.local6.debug: {"host":"ol8-arm64","ident":"opc","pid":"366247","message":"opc@XXX.XXX.XXX.186export [366169]: ls [0]"}
2024-11-22 01:15:20.000000000 +0000 terminal.local6.debug: {"host":"ol79-fluent","ident":"opc","message":"root@XXX.XXX.XXX.186export [6544]: python [0]"}
2024-11-22 01:15:21.000000000 +0000 terminal.local6.debug: {"host":"ol79-fluent","ident":"opc","message":"root@XXX.XXX.XXX.186export [6544]: python [0]"}
2024-11-22 01:15:21.000000000 +0000 terminal.local6.debug: {"host":"ol79-fluent","ident":"opc","message":"root@XXX.XXX.XXX.186export [6544]: python [0]"}
期待した効果に対して得た物
- opcユーザの挙動などを把握できた
- rootに昇格後、pythonで何かを行っている様子がみれてとれる
- .bashrcとrsyslogを使うだけなので、OracleLinux7.9, 8.10 いずれでも動く
- 証跡としての実行履歴を、リアルタイム外部保管できた
- 「何か合った時」に後から調べるではなく、準リアルタイムに検出アクションを仕込めそう
- 申し訳ありません、時間無くてアクションを仕込むまでやれませんでした(反省)
残される課題
- 次の3点が健全である事が前提の実装となっている
- .bashrcを編集されない事
- コマンドを記録したいホストでsyslogが生きている事
- syslog 受け側が正常に稼働している事
まとめ
- ほぼリアルタイムにコマンド実行を補足するまでを確認できました
- OCIであればLogging Analyticsやobject Storageへfluent plugin経由で保存する事も可能です
- 同様に、aws cloudwatch logsへ転送したり、DataDogにも転送が可能になります
以上
追記:
object Storageへfluent plugin経由で保存する事も可能です
上記の件、OCI Object Storageへデータ連携を確認 にまとめました。どうして、AWS s3 pluginで、敢えてOCI Object Storageを使うのか?という内容にさせていただいていますので、ご確認いただけると幸いです。
追記、以上です。