tfsecの基本的な使い方を説明します
Terraform利用のお供にtfsecをおすすめしたい
みなさん、こんにちは。
クラウドエースでいつだってごきげん
をキャッチフレーズにSREをしている、長野と申します。
今回はtfsecを使ってみたので、その紹介をさせて頂きたいと思います。
ちなみにtfsecは、Terraformのコードをセキュリティ上の問題や一般的なベストプラクティスに基づいてスキャンする静的解析ツールです。
aquasecurity/tfsec: Security scanner for your Terraform code
どんなチェックができるのか
今回はTerraformでGoogle Cloudのリソースを作成しようとした際に、tfsecがどんな指摘をしてくれるのかという観点で確認をしていきたいと思います。
まずデフォルトの設定では以下のようなGoogle Cloudサービスに対して、セキュリティ上望ましくない設定をしていたら注意をしてくれるようになっています。
詳細は以下のリンクをご確認ください。
tfsecを使ってみる
IAMやBigQueryに対して、セキュリティ上望ましくない設定をしていたら注意をしてくれる、と言われてもあまりピンとこないので、ひとまずtfsecを動かして挙動を確かめてみましょう。
実行したいtfファイルがあるディレクトリに以下のように.tfsecディレクトリ
を用意し、その中に設定ファイルを配置することでtfsecが実行されます。
[補足] .tfsecディレクトリがなくても、tfsecの実行は可能です。その場合、デフォルトの設定で解析が行われます。今回はデフォルトの設定を制御するために(方法は後述)、このディレクトリを用意しています。
src
├── .tfsec
│ ├── config.yaml
│ ├── test_tfchecks.yaml
├──main.tf
├──versions.tf
├──backend.tf
今回 tfsecのチェック対象になる「main.tf」には以下のようにIAMを設定する内容を記載してみました。
resource "google_project_iam_member" "project" {
project = "tnagano-test-prj"
role = "roles/storage.objectAdmin"
member = "user:jane@example.com"
}
では、上記のディレクトリ構成にあるsrcディレクトリに移動して、以下のようにtfsecを実行をしてみます。
tfsec .
すると以下のような警告が表示されました。
この指摘は、IAMの設定をする際にユーザーアカウントにIAMロールを付与しようとすることへの注意となっています。
そして、検知のIDはgoogle-iam-no-user-granted-permissions
と記載されていますね。
確かにGoogle Cloudのベストプラクティスを確認してみると、可能であれば、個々のユーザーではなく Google グループにロールを付与してください。
とあるので、このベストプラクティスについての指摘をしてくれた、ということになります。
つまりmember = "user:jane@example.com"
の箇所が指摘されたことになります。それでは、この指摘の対応としてmember = "group:jane@example.com"
に修正してみます。
resource "google_project_iam_member" "project" {
project = "tnagano-test-prj"
role = "roles/storage.objectAdmin"
member = "group:jane@example.com"
}
そしてtfsecを実行してみると結果はOKとなりました。
tfsecの設定ファイルについて
さて、上記のような結果を出力するために欠かせないのが、tfsecの設定ファイルでして、種類が2つあります。
- tfsecのデフォルトの設定をカスタマイズするための設定ファイル(
config.yaml
もしくはconfig.json
) - ユーザー定義のカスタムチェックを追加するための設定ファイル(サフィックス(接尾辞、末尾)に
_tfchecks.yaml
もしくは_tfchecks.json
がついたファイル)
例えば、今回試した検知の中で、検知IDgoogle-iam-no-user-granted-permissions
は検知しなくてもいいなという場合は以下のように除外設定をconfig.yaml
に記載します。
exclude:
- google-iam-no-user-granted-permissions
また、そもそも重要度がMEDIUM
のものを検知したくないとなったら、以下のように記載します。これでHIGH以上が検知対象になります。
minimum_severity: HIGH
このように、IDを指定して自分たちの運用にあったものだけを検知したり、重要度単位で大まかな除外設定をしたりなどのカスタマイズがconfig.yaml
で、できるというわけです。
しかし、config.yamlは、tfsecのデフォルトルールのカスタマイズしかできません。
では、デフォルト以外のルールを定義したい場合はどうすればよいでしょうか?
そこで利用されるのがサフィックスに_tfchecks.yaml
がついた設定ファイルというわけです。例えば以下のようなカスタムチェックを作成することが可能です。これは付与対象のIAMロールに編集者(roles/editor)が含まれていることを検知するというカスタムチェックになっています。
checks:
- code: CUS001
description: Don't use roles/editor
impact: roles/editor is a security risk due to wide range of permissions
resolution: Grant Least Privilege Role
requiredTypes:
- resource
requiredLabels:
- google_*
severity: CRITICAL
matchSpec:
name: role
action: notContains
value: roles/editor
全体の動作概要としては、以下のようになります。
- 検査するブロックを
requiredTypes
で記載する - そのブロックのオブジェクトを
requiredLabels
で定義する -
matchSpec
でブロック内の値を検査する - そして、違反した場合のseverityを
severity
に定義する
具体的にはrequiredTypes:
を - resource
とすることで、Terraformのresource
で始まる部分を対象にするようにしています。
その上でrequiredLabels:
を- google_*
と記載することで、以下のようなTerraformコード内の"google_project_iam_member"
を検知の対象とすることができます。
そして、今回はこのカスタムチェックに違反した場合にseverity:CRITICAL
として検知するようにしています。
では上記で利用したmain.tf
と以下のような config.yaml
と test_tfchecks.yaml
を用意してtfsecを実行してみたいと思います。
resource "google_project_iam_member" "project" {
project = "tnagano-test-prj"
role = "roles/editor"
member = "user:jane@example.com"
}
ここではmember = "user:jane@example.com"
としているのでデフォルト設定であればseverityがMEDIUMとなり検知がされるのですが、以下のconfig.yaml
で除外設定を入れているので検知はされません。
minimum_severity: HIGH
exclude:
- google-iam-no-user-granted-permissions
一方 test_tfchecks.yaml
でカスタムチェックの設定を入れているので、ロールが編集者(roles/editor)
であることと、その検知のseverityがCRITICAL
であることから、カスタムチェックの内容で検知がされる結果となるはずです。
checks:
- code: CUS001
description: Don't use roles/editor
impact: roles/editor is a security risk due to wide range of permissions
resolution: Grant Least Privilege Role
requiredTypes:
- resource
requiredLabels:
- google_*
severity: CRITICAL
matchSpec:
name: role
action: notContains
value: roles/editor
ではtfsecを実行してみましょう。
結果は以下のようになりました。想定通りにカスタムチェックで警告が出ています。
まとめ
今回はtfsecの基本的な利用方法を紹介しました。
デフォルトで用意されている設定を元に採用するルールを考えることで、今までなんとなく気をつけたほうがいいかなくらいに考えていた設定を意識的に見直すことができるので、セキュリティ意識の向上という観点でtfsecの利用を推進すべきと感じました。一方で全部のルールを採用すると運用がしづらくなる可能性もあるので、severity(重要度)で線引をするのは1つの考え方かなとも思いました。
また、デフォルトのルールでは足りない場合の独自ルールの作り方もそんなに難しいことはないと感じたので、自分たちの運用にあったルールを遵守するためにも積極的にtfsecを導入していきたいと考えています。
Discussion