AWSなどのクラウドサービスでは、データベースやファイルシステムなどの各種リソースを操作するためのアカウント(IAM)を発行して権限管理を行うことがありますが、このアカウント情報をGitのリポジトリに登録してしまうと、意図せず流出し悪い人に悪用されてしまう場合があります。
定期的にネット上で話題になりますが、最終的に仮想通貨のマイニングなどに利用され多額の請求がやってくるパターンが多いようです。
- 【実録】アクセスキー流出、攻撃者のとった行動とその対策 | DevelopersIO
- AWSが不正利用され300万円の請求が届いてから免除までの一部始終 - Qiita
- 初心者がAWSでミスって不正利用されて$6,000請求、泣きそうになったお話。 - Qiita
このような悲劇を防ぐために、Gitのリポジトリへ特定のパターンの文字列を登録できくなくするgit-secretsを導入してみます。なおこのツールはAmazon製ということもありAWSとの相性がバッチリです。
結論
macOSでAWSのIAMのクレデンシャルをGitのリポジトリに登録したくない場合は以下のようにします。
まずはインストール。
$ brew install git-secrets
Gitのリポジトリに移動し2つコマンドを叩けば完了。たったこれだけで防ぐことができます。
$ cd (Gitのリポジトリ) $ git secrets --install $ git secrets --register-aws
注意点としてはプロジェクトの全員がこの設定を行う必要がありますので、開発環境を移行したり新人さんが入ってきた場合はお忘れなきよう。
より詳細な情報が知りたい方はこの先の解説をどうぞ。
インストール
Linux
Gitのリポジトリをcloneした後にmake
を実行します。make時に/usr/local/binの下にファイルがコピーされるためsudo
を付けています。
$ git clone https://github.com/awslabs/git-secrets.git
$ cd git-secrets
$ sudo make install
Makefileを読むと実際にインストールされるのは本体であるBashのプログラムと、man
とgit help
で表示するためのドキュメントの2つのファイルがコピーされるだけのシンプルな構成のようです。
macOS
HomeBrewで一発です。簡単ですね。
$ brew install git-secrets
macの場合もLinuxと同じ挙動になるようです。git-secretsの中身は先ほどと同じBashです。
$ which git-secrets /usr/local/bin/git-secrets
Windows
Linuxのときと同様にGitのリポジトリhttps://github.com/awslabs/git-secrets.git
をcloneした後にPowerShellを起動しインストールを行います。
ただしWindowsの設定がデフォルトのままだとセキュリティに引っかかってしまいインストール用のスクリプトが起動しません。そのため最初に設定をゆるくします。以下のコマンドを実行すると本当に実行して良いか聞かれるので「Y」を入力。
PS C:\Users\katsube> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
あとはcloneしたリポジトリへ移動し install.ps1 を実行すれば完了です。
PS C:\Users\katsube> cd Documents\git-secrets PS C:\Users\katsube\Documents\git-secrets> .¥install.ps1
PowerShellを閉じると先ほどゆるくしたセキュリティの設定はもとの厳しい状態に戻っています。
このあたりの設定は以下のページを参考にさせていただきました。 qiita.com
Gitリポジトリに設定する
初期設定
適当なディレクトリを作成し、Gitのリポジトリとして初期化します。もしくはgit secretsを適用したい既存のリポジトリへ移動します。
$ mkdir repos; cd repos; $ git init
git secretsをリポジトリに適用します。
$ git secrets --install
✓ Installed commit-msg hook to .git/hooks/commit-msg
✓ Installed pre-commit hook to .git/hooks/pre-commit
✓ Installed prepare-commit-msg hook to .git/hooks/prepare-commit-msg
拒否するパターンを登録
各コマンド実行時に--global
オプションを追加すると~/.gitconfig
に設定が記録され、付けない場合は各リポジトリの.git/config
に記録されます。
ここから先の実行例ではいずれも付けていませんが、よく利用するパターンは--global
を付けておいた方が設定作業が減って楽ちんです。
AWS
Amazon製ということもありAWSのIAMで利用されているクレデンシャルのパターンを弾く専用のオプションが用意されています。
$ git secrets --register-aws
任意のパターン
egrep
で利用される正規表現を用いたパターンを登録できます。以下ではpassword
から始まる文字列の登録を禁止します。
$ git secrets --add '^password'
例外パターンを登録
例えばVISAカードのクレジットカード番号(4[0-9]{15}
)は拒否したいが、テスト用のカード番号4111111111111111
は許可したいといった場合には以下のように--allowed
オプションで指定します。
$ git secrets --add '4[0-9]{15}' $ git secrets --add --allowed '4111111111111111'
登録済みパターンの一覧
--list
オプションで現在のリポジトリに登録されているすべてのパターンが表示されます。
$ git secrets --list secrets.providers git secrets --aws-provider secrets.patterns (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16} secrets.patterns ("|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)("|')?\s*(:|=>|=)\s*("|')?[A-Za-z0-9/\+=]{40}("|')? secrets.patterns ("|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')?\s*(:|=>|=)\s*("|')?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}("|')? secrets.allowed AKIAIOSFODNN7EXAMPLE secrets.allowed wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY secrets.patterns 4[0-9]{15} secrets.allowed 4111111111111111
登録済みパターンを編集・削除する
git secrets
で登録したパターンは各リポジトリの.git/config
または、--global
オプションを付けて実行した場合は~/.gitconfig
に記録されていますので、これらのファイルを開いて直接編集することで変更や削除が行なえます。
$ cat .git/config [core] (中略) [secrets] providers = git secrets --aws-provider patterns = (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16} patterns = (\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\\s*(:|=>|=)\\s*(\"|')?[A-Za-z0-9/\\+=]{40}(\"|')? patterns = (\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\"|')?\\s*(:|=>|=)\\s*(\"|')?[0-9]{4}\\-?[0-9]{4}\\-?[0-9]{4}(\"|')? allowed = AKIAIOSFODNN7EXAMPLE allowed = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY patterns = ^password patterns = 4[0-9]{15} allowed = 4111111111111111
試してみる
ここではgit secrets --add '^password'
が実行されているとして実験します。
エラーになることを確認
では必ずNGになる内容のファイルを用意します。
$ echo 'password' > foo.txt
そしてGitへcommitしようとすると無事にエラーを出してリポジトリへの登録を防いでくれました。
$ git add . $ git commit -m 'secrets test' foo.txt:1:password [ERROR] Matched one or more prohibited patterns
ここからリカバリするには?
まだステージ上に登録されたままですので、いったんresetしてから修正します。
$ git reset
エラーにならない文字列に修正し、もう一度commitします。
$ echo 'not-password' > foo.txt $ git add . $ git commit -m 'secrets test' [master (root-commit) 63155d0] commit 1 file changed, 1 insertion(+) create mode 100644 foo.txt
今度は無事にcommitされましたね! 同様の方法でAWSのクレデンシャルも拒否することが可能です。
その他
一時的に無効にしたい
commit時に--no-verify
オプションを付けるとgit secretsのチェックを無効にすることができます。
$ git commit -m '強制的にcommitしたいでござる' --no-verify
既存のリポジトリをスキャンする
現在のファイル
--scan
オプションを付けて実行すると、リポジトリ内のすべてのファイルをその場でチェックしてくれます。途中からgit secretを導入する場合に活躍してくれそうですね。
$ git secrets --scan
以下のように特定のファイルやディレクトリのみを対象としたり、
$ git secrets --scan file.txt
標準入力から渡すことも可能です。
$ cat *.ini | git secrets --scan
すべての履歴
--scan-history
オプションの場合は、過去の履歴をすべてスキャンしてくれます。問題があった場合はハッシュ値とファイル名が表示されます。
$ git secrets --scan-history 9f49d13c48d7de921549417be0faf1506d7cceb3:card.txt:1:4111111111111112 [ERROR] Matched one or more prohibited patterns