本投稿は TECOTEC Advent Calendar 2021 の17日目の記事です。
決済認証システム事業部の下江です。 今年の夏ごろ、ふとサービスを作りたいなと思い、仮想レース配当サービスを個人で作っていた時に起きたDB情報を全部抜かれた話をしていこうと思います。
<2021.12.17 追記>
※本記事はあくまで個人開発上で起きた問題であり、弊社開発ではセキュリティ専門の部隊がこの要な事態が発生しないよう対応しています。
構成
OS: Ubuntu 20.04.2 LTS
フレームワーク:Laravel
フロント : blade
デザイン : TailwindCSS
DB情報が抜かれるまでの流れ
サーバの初期設定を行い、動作確認のためBasic認証を掛けて知り合い内共有して、 いくつか細かい問題の修正を行いとりあえず動作するところまで終わらせた後就寝しました。
翌日、知り合いから「500出てるよ」と連絡があり調査を行ったところ、サーバのエラーログにUnknow Database の文字列がずらり。
dbを確認しに行くと、メインのデータベースが消されており正体不明のReadmeデータベースが作成されていました。
中身には要約すると、データ取ったから返して欲しかったらここに振り込んでねと書いてありました。
ひえ…
原因
ポート
幸い知り合い内で動作確認を行っている段階だったので軽傷で済んだのですが、もちろんこのままリリースする訳はいかないので原因調査開始。
laravelの脆弱性で良く話題に上がる、debug modeをオンにしていたことが原因だと考えて調査していたのですが、特にこれといった問題なく、成果なし。
そうしているとき再度友人から、ポートが空いてるけど大丈夫?と連絡があり確認を行うと
3306のポートが開いたままになっていることが確認されました。
なぜ....
ファイアウォール設定
さすがにリリース前にファイアウォール設定をしていない訳は無いので設定を再確認。 今回はufwを利用して設定を行っていました。 画像の通り設定は、7614/80/443のホワイトリストになっています。
iptables
ufwでは、iptablesにufwの設定を書き込んでいるのでその部分を調査
Chain INPUT (policy DROP) target prot opt source destination ufw-before-logging-input all -- anywhere anywhere ufw-before-input all -- anywhere anywhere ufw-after-input all -- anywhere anywhere ufw-after-logging-input all -- anywhere anywhere ufw-reject-input all -- anywhere anywhere ufw-track-input all -- anywhere anywhere Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere (省略) Chain OUTPUT (policy ACCEPT) target prot opt source destination ufw-before-logging-output all -- anywhere anywhere ufw-before-output all -- anywhere anywhere ufw-after-output all -- anywhere anywhere ufw-after-logging-output all -- anywhere anywhere ufw-reject-output all -- anywhere anywhere ufw-track-output all -- anywhere anywhere Chain DOCKER (2 references) target prot opt source destination Chain DOCKER-ISOLATION-STAGE-1 (1 references) target prot opt source destination DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (2 references) target prot opt source destination DROP all -- anywhere anywhere DROP all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination RETURN all -- anywhere anywhere (省略) Chain ufw-user-input (1 references) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:7613 ACCEPT tcp -- anywhere anywhere tcp dpt:http ACCEPT tcp -- anywhere anywhere tcp dpt:https (省略)
以上のようになっていました。
docker...?
docker
ということで、上のiptablesの設定を見て察しの良い方は気づかれるかもしれませんが、ufwのユーザ設定とdockerのユーザ設定が並列で並んでいます。
つまり、ufwでいくらホワイトリスト設定していても、dockerで開けたポートは空きっぱなしになってしまいます。
結論、
「docker-compose.ymlのport指定がグローバルアドレスになっていた」
ということでした。(DBのキーパス周りの設定もしていなかったのも悪かった)
対応
とりあえず、dbを作り直した後、 dockerファイルでポートの指定を
3306:3306 ↓ 127.0.0.1:3306:3306
とすることで、想定通りの動作をするようになりました。
まとめ
dockerはufwに穴を空けるので気を付けよう。
リリース終わったらちゃんと外部からのポート確認を行おう。
そもそもdbにちゃんとキーパスつけておこう。
皆さん良い個人開発ライフを