botterのためのgit/githubからの情報流出防止設定
こんにちは、ちゃまと申します。
最近bot作成にハマり、日々試行錯誤しております。
少し技術よりの細かい話を書いてみたくなりZennも利用してみることにしました。
ちなみに、記事タイトルは尊敬するまちゅけんさんの記事を勝手にパクらオマージュさせていただきました😇。
まちゅけんさんが書かれている記事はどれも素晴らしいのでもし読まれていない方がいたらぜひ読んでみてください。
この記事について
前提として、git/githubを利用してコード管理をされているbotterの方々は多いと思います。
この記事ではこれらのツールを利用する上で個人情報や秘密鍵などの秘匿したい情報を誤って公開しないようにするために自分がやっている設定を書いてみます。
こういう情報は下手に書くと穴があることがバレるのでちょっと怖いんですが、最低限やっておいて損はないだろうという情報は共有できた方がよいのではと思い書きました。
セキュリティの専門とかでは全くないので間違っていることとかもっと良いやり方などご存じの方いればぜひ教えてください。
この記事で説明しないこと
以下はこの記事では説明を行いません。
- git/githubとは何か
- git/githubの基本的な使い方
また、前提として以下の設定は必要に応じて行っているものとします。
- githubは2FAを設定する
- 他の人に見せたくないレポジトリはプライベートレポジトリにする
- git管理したくないファイルは個別に.gitignoreの設定を記述する
- 本番用途で使用する各種クレデンシャル情報はファイルに平文でハードコードせずKMS等を利用する
やっていること
- git-secretsをinstallする
-
~/.config/git/ignore
に全レポジトリ共通でgit管理しないファイルを設定する -
git config
のメールアドレスはダミーアドレスを設定する
順番に見ていきます。
git-secretsをインストールする
botを実際に動かす際に、秘密鍵だけでなく各種APIキーやシークレット等のクレデンシャル情報を扱うことになると思います。
これらは本来レポジトリ内に平文でハードコードせずKMS等を使用して適切に管理する必要があります。
とはいえ、ちょっとした動作確認をする場合などでプログラムに直接記述することがあったりします。
こういった場合であっても誤ってクレデンシャル情報をコミット/プッシュしないように対策を講じておきたいと思い、AWSが公開しているgit-secretsというツールを入れました。
このツールはGit hooksという仕組みを使用してコミットする直前にあらかじめ設定した正規表現でパターンマッチを確認し、該当するファイルがある場合にコミットを弾くことでシークレットがコミットに含まれることを防いでくれます。
そのため、正規表現さえ作ることができればAWSのクレデンシャル情報以外でもコミットを防ぐことは可能なのですが、AWSのクレデンシャル情報については個別に正規表現を作ったりせずコマンド一つでいい感じに設定可能です。
AWSを使用している方はひとまずこれだけでもやっておいてよさそうです。
手順は上のdocに従ってインストールした後に以下のコマンドを実行します。
git secrets --register-aws --global
これでローカルのすべてのレポジトリ共通で使用できる正規表現が設定されるので、あとはレポジトリを作るたびにそのレポジトリのルートディレクトリで以下のコマンドを実行します。
git secrets --install
注意点としては、git secrets --register-aws --global
だけだとあくまでAWSクレデンシャル情報をマッチさせる正規表現を設定するだけなので、実際にコミットを防ぐためにはレポジトリごとに都度git secrets --install
を実行する必要があります。
AWS以外のクレデンシャル情報についてもgit secrets --add '[適当な正規表現]'
などで自分で正規表現を追加することができるので、興味のある方は調べてみてください。
ちなみに、このgit-secrets
はコミット時にシークレットが含まれることを防げる点で有用ですがgithubにプッシュする段階においては、githubのシークレットスキャンという機能が各種シークレットを検知してくれているようです。
こちらはパブリックなレポジトリに対してはデフォルトで有効な機能なので特に設定の必要はないです。
とはいえプライベートレポジトリに対して使う場合は無料アカウントだと使えない点や、そもそもコミットにクレデンシャル情報を含めるべきでないことを考えると、上の設定はやっておいてよいと思いました。
~/.config/git/ignore
に全レポジトリ共通でgit管理しないファイルを設定する
コミットに秘匿情報などを含めないためによく.gitignore
が使われていると思います。
残念ながら前述のgit secretsやgithubの設定では、例えばwalletの秘密鍵をコミットに含めてしまうことを防げません。またそれ以外にも正規表現にマッチしないクレデンシャル情報はすべてコミットできてしまいます。
そのためコミットに含めたくないファイルを.gitignore
に記述するのですが、レポジトリ毎に毎回.gitignore
を書くのは面倒ですし、万一忘れた際に大事故につながるのですべてのレポジトリでignoreするための共通の設定を入れています。
やり方は~/.config/git/ignore
に設定を記述するだけです。
もしこのpathにファイルがない場合は作成してください。書き方は.gitignore
と同様です。
例えば、各レポジトリに毎回secrets/というディレクトリを作成する場合を考えます。
クレデンシャル情報はここにまとめて記載してdotenvなどで読み込むという想定です。
この場合であれば全レポジトリの共通設定としてignoreさせておくと便利です。
chamafoobar@chamafoobar:~$ echo secrets/ >> ~/.config/git/ignore
試しに確認してみます。secretsディレクトリ配下にファイルを作成した場合と、それ以外の場所にファイルを作成した場合を比較します。
chamafoobar@chamafoobar:~/workspace/check_gitignore$ tree #現在のディレクトリにはsecretsディレクトリのみ
.
└── secrets
1 directory, 0 files
chamafoobar@chamafoobar:~/workspace/check_gitignore$ git init #gitを有効化
Initialized empty Git repository in /home/chamafoobar/workspace/check_gitignore/.git/
chamafoobar@chamafoobar:~/workspace/check_gitignore$ touch secrets/ignore.txt #secretsディレクトリ配下に適当なファイルを作成
chamafoobar@chamafoobar:~/workspace/check_gitignore$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track) #変更検知されない
chamafoobar@chamafoobar:~/workspace/check_gitignore$ touch notignore.txt #それ以外の場所にファイルを作成
chamafoobar@chamafoobar:~/workspace/check_gitignore$ git status
On branch main
No commits yet
Untracked files: #notignoreのみ変更検知される
(use "git add <file>..." to include in what will be committed)
notignore.txt
nothing added to commit but untracked files present (use "git add" to track)
git config
のメールアドレスはダミーアドレスを設定する
こちらはクレデンシャル情報に関する話ではないんですが、gitを最初に使う際以下のようなコマンドで名前とメールアドレスを設定したかと思います。
git config --global user.name ${名前}
git config --global user.email ${メールアドレス}
ここで設定した名前とメールアドレスはコミットログに残ります。
そして、パブリックな設定にしているレポジトリの場合、誰でもそのレポジトリをクローンできるためコミットログも確認可能です。
サンプルとしてコミットを一度だけ行ったレポジトリのコミットログを確認してみます
chama@chama:~/commit-log-sample$ git log --pretty=fuller #--pretty=fullerはcommitor,author両方を表示するオプション
commit 6a55374b91a3647aabc142546dcce725137323a2 (HEAD -> master)
Author: chamafoobar <42685703+chama@users.noreply.github.com> #Authorの名前とメールアドレスが表示される
AuthorDate: Mon Apr 29 03:35:26 2024 +0900
Commit: chamafoobar <42685703+chama@users.noreply.github.com> #Commitorの名前とメールアドレスが表示される
CommitDate: Mon Apr 29 03:35:26 2024 +0900
first commit
現在設定されている名前とメールアドレスは以下のコマンドで確認可能です。globalオプションは適宜つけたり外したりしてください。
chamafoobar@chamafoobar:~/commit-log-sample$ git config --global user.name
chamafoobar
chamafoobar@chamafoobar:~/commit-log-sample$ git config --global user.email
42685703+chama@users.noreply.github.com
最初に本名や普段使いのメールアドレスを設定してしまった方はそれらの情報が他の人からも確認できるため変更します。(公開してOKな人はもちろん問題ありません。)
変更手順は以下です。
- git側の設定を変更する、メールアドレスはgithubが用意しているダミーのアドレスを利用する
- github側の設定を変更する
- (既存のコミットログに本名や表示したくないコミットログがある場合)コミットログを書き換える
そもそもプライベートレポジトリに設定していれば他の人からは見られませんし、設定する際の名前やメールアドレスについて見えてもよいものを設定すればよいだけではあるんですが、実施しておいて損はないと思います。
順番に見ていきます。
- git側の設定を変更する、メールアドレスはgithubが用意しているダミーのアドレスを利用する
まず名前については以下のコマンドを実行するだけです
git config --global user.name ${見えてもよい名前}
メールアドレスについては見えてもよいアドレスなら何でもよいんですが、githubのemail設定にダミーアドレスがあるのでこれを利用するのが便利だと思います。
私の場合だと42685703+chama@users.noreply.github.com
だったのでこれをconfigに設定します。
global設定が嫌な方はglobalオプションを外してください。
chamafoobar@chamafoobar:~/commit-log-sample$ git config --global user.email 42685703+chama@users.noreply.github.com
これらの設定を行った後に再度前述のコマンドを実行すると設定変更が反映されていることが確認できると思います。
- github側の設定を変更する
1の画像のところでチェックボックスにチェックが入っていると思うのですがこのチェックが入っていない方は入れるだけです。
これでgithubのweb画面から操作する際にはダミーアドレスが使用されるようです。
こちらはあくまでgithub側の設定なので1とは別で書きました。
ついでに、githubにプッシュする際にプライベートのメールアドレスが使用されていた場合にプッシュをはじきたい方はその下のチェックボックスにもチェックを入れておくのがよさそうです。
- (既存のコミットログに本名や表示したくないコミットログがある場合)コミットログを書き換える
1, 2の設定を行うことで、これからコミット/プッシュする場合にはダミーのアドレスが表示されるようになります。
そのため、これからgit/github使うよという方はこの手順は不要です。
しかし、すでにパブリックなレポジトリのコミットログに本名と普段使いのメールアドレスが載ってしまっている場合もあるかもしれません。その場合はこの手順3も実施しましょう。
手順は参考文献[2]がとても分かりやすいのでその通りにやるだけです。
詳細はそちらを見ていただくとして、流れだけ記載しておくと以下になります。
i. 対象のレポジトリをローカルにクローンする
ii. コミットログを書き換える
iii. githubに再度プッシュする
おわりに
自分がやっているgit/githubの設定をいくつかご紹介させていただきました。
他にも前述のGit hooksを利用して自前のscriptを走らせるなど、いろいろとgit/githubを利用する際のリスクを減らすための方法はあるようなので、もしこんな方法があるよという方がいらっしゃいましたらぜひ教えてもらえると嬉しいです!
防御力は高ければ高いほどいいので細かなTipsも大歓迎です。
弱いのに防御力上げてもしょうがないじゃんってマサカリ投げるのはやめてください😇
参考文献
[2]https://walkyxwalky.com/2023/01/31/gitのコミット履歴に残る個人情報の変更方法/
Discussion