🔖

tfsecの基本的な使い方を説明します

2023/05/26に公開

Terraform利用のお供にtfsecをおすすめしたい

みなさん、こんにちは。
クラウドエースでいつだってごきげんをキャッチフレーズにSREをしている、長野と申します。

今回はtfsecを使ってみたので、その紹介をさせて頂きたいと思います。

ちなみにtfsecは、Terraformのコードをセキュリティ上の問題や一般的なベストプラクティスに基づいてスキャンする静的解析ツールです。

aquasecurity/tfsec: Security scanner for your Terraform code

どんなチェックができるのか

今回はTerraformでGoogle Cloudのリソースを作成しようとした際に、tfsecがどんな指摘をしてくれるのかという観点で確認をしていきたいと思います。

まずデフォルトの設定では以下のようなGoogle Cloudサービスに対して、セキュリティ上望ましくない設定をしていたら注意をしてくれるようになっています。

tfsec_gcp_overview

詳細は以下のリンクをご確認ください。

google - tfsec

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を設定する内容を記載してみました。

main.tf
resource "google_project_iam_member" "project" {
  project = "tnagano-test-prj"
  role    = "roles/storage.objectAdmin"
  member  = "user:jane@example.com"
}

では、上記のディレクトリ構成にあるsrcディレクトリに移動して、以下のようにtfsecを実行をしてみます。

tfsec .

すると以下のような警告が表示されました。

tfsec_granted_user

この指摘は、IAMの設定をする際にユーザーアカウントにIAMロールを付与しようとすることへの注意となっています。
そして、検知のIDはgoogle-iam-no-user-granted-permissionsと記載されていますね。
確かにGoogle Cloudのベストプラクティスを確認してみると、可能であれば、個々のユーザーではなく Google グループにロールを付与してください。とあるので、このベストプラクティスについての指摘をしてくれた、ということになります。

つまりmember = "user:jane@example.com"の箇所が指摘されたことになります。それでは、この指摘の対応としてmember = "group:jane@example.com"に修正してみます。

main.tf
resource "google_project_iam_member" "project" {
  project = "tnagano-test-prj"
  role    = "roles/storage.objectAdmin"
  member  = "group:jane@example.com"
}

そしてtfsecを実行してみると結果はOKとなりました。

tfsec_result_ok

tfsecの設定ファイルについて

さて、上記のような結果を出力するために欠かせないのが、tfsecの設定ファイルでして、種類が2つあります。

  1. tfsecのデフォルトの設定をカスタマイズするための設定ファイル(config.yaml もしくは config.json)
  2. ユーザー定義のカスタムチェックを追加するための設定ファイル(サフィックス(接尾辞、末尾)に_tfchecks.yamlもしくは_tfchecks.jsonがついたファイル)

例えば、今回試した検知の中で、検知IDgoogle-iam-no-user-granted-permissionsは検知しなくてもいいなという場合は以下のように除外設定をconfig.yamlに記載します。

config.yaml
exclude:
  - google-iam-no-user-granted-permissions

また、そもそも重要度がMEDIUMのものを検知したくないとなったら、以下のように記載します。これでHIGH以上が検知対象になります。

config.yaml
minimum_severity: HIGH

このように、IDを指定して自分たちの運用にあったものだけを検知したり、重要度単位で大まかな除外設定をしたりなどのカスタマイズがconfig.yamlで、できるというわけです。

しかし、config.yamlは、tfsecのデフォルトルールのカスタマイズしかできません。
では、デフォルト以外のルールを定義したい場合はどうすればよいでしょうか?

そこで利用されるのがサフィックスに_tfchecks.yamlがついた設定ファイルというわけです。例えば以下のようなカスタムチェックを作成することが可能です。これは付与対象のIAMロールに編集者(roles/editor)が含まれていることを検知するというカスタムチェックになっています。

test_tfchecks.yaml
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で始まる部分を対象にするようにしています。

tfsec_customcheck_01

その上でrequiredLabels:- google_*と記載することで、以下のようなTerraformコード内の"google_project_iam_member"を検知の対象とすることができます。

tfsec_customcheck_02

そして、今回はこのカスタムチェックに違反した場合にseverity:CRITICALとして検知するようにしています。

では上記で利用したmain.tf と以下のような config.yamltest_tfchecks.yaml を用意してtfsecを実行してみたいと思います。

main.tf
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で除外設定を入れているので検知はされません。

config.yaml
minimum_severity: HIGH

exclude:
  - google-iam-no-user-granted-permissions

一方 test_tfchecks.yamlでカスタムチェックの設定を入れているので、ロールが編集者(roles/editor)であることと、その検知のseverityがCRITICALであることから、カスタムチェックの内容で検知がされる結果となるはずです。

test_tfchecks.yaml
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_customcheck_03

まとめ

今回はtfsecの基本的な利用方法を紹介しました。

デフォルトで用意されている設定を元に採用するルールを考えることで、今までなんとなく気をつけたほうがいいかなくらいに考えていた設定を意識的に見直すことができるので、セキュリティ意識の向上という観点でtfsecの利用を推進すべきと感じました。一方で全部のルールを採用すると運用がしづらくなる可能性もあるので、severity(重要度)で線引をするのは1つの考え方かなとも思いました。

また、デフォルトのルールでは足りない場合の独自ルールの作り方もそんなに難しいことはないと感じたので、自分たちの運用にあったルールを遵守するためにも積極的にtfsecを導入していきたいと考えています。

Discussion