【tfsec】Terraformの静的セキュリティスキャンを行ってみよう!
こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。
今回は、tfsecを使用して、Terraformのセキュリティスキャンを体験してみようと思います。
結論
- tfsecは、Terraformの静的なセキュリティスキャンを行うツール
- ローカル環境で動作可能な認証情報などを用意しなくていい
tfsecとは
Aqua Security社の、オープンソースツールです。
ざっくり、ご説明すると、Terraformの静的なセキュリティスキャナーです。
ローカル、CIパイプライン環境で実行できるように設計されています。
いざ実践
インストール
今回は、Macでtfsecを使用してみようと思います。
% brew install tfsec
各OSのインストール方法は、こちらからご参照ください。
スキャン実行
今回、tfsec用に、以下のtfファイルを作成しました。
VPC、パブリックサブネット、ルートテーブル、セキュリティグループを作成します。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
# source = "../modules/vpc"
version = "3.12.0"
# insert the 23 required variables here
cidr = "10.0.0.0/16"
name = "terraform-reintroduction"
public_subnets = ["10.0.0.0/24", "10.0.1.0/24"]
azs = ["ap-northeast-1a", "ap-northeast-1c"]
}
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "allow_tls"
}
}
では、実行してみます。
tfファイルを保管している、ディレクトリ内に移動して、tfsecコマンドを実行してみます。
% tfsec
Result #1 CRITICAL Security group rule allows egress to multiple public internet addresses.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
vpc.tf Line 30
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
26 │ egress {
27 │ from_port = 0
28 │ to_port = 0
29 │ protocol = "-1"
30 │ cidr_blocks = ["0.0.0.0/0"]
31 │ ipv6_cidr_blocks = ["::/0"]
32 │ }
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-vpc-no-public-egress-sgr
Impact Your port is egressing data to the internet
Resolution Set a more restrictive cidr range
More Information
- https://aquasecurity.github.io/tfsec/v1.1.5/checks/aws/vpc/no-public-egress-sgr/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Result #2 CRITICAL Security group rule allows egress to multiple public internet addresses.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
vpc.tf Line 31
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
26 │ egress {
27 │ from_port = 0
28 │ to_port = 0
29 │ protocol = "-1"
30 │ cidr_blocks = ["0.0.0.0/0"]
31 │ ipv6_cidr_blocks = ["::/0"]
32 │ }
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-vpc-no-public-egress-sgr
Impact Your port is egressing data to the internet
Resolution Set a more restrictive cidr range
More Information
- https://aquasecurity.github.io/tfsec/v1.1.5/checks/aws/vpc/no-public-egress-sgr/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Result #3 LOW Security group rule does not have a description.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
vpc.tf Lines 26-32
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
26 │ egress {
27 │ from_port = 0
28 │ to_port = 0
29 │ protocol = "-1"
30 │ cidr_blocks = ["0.0.0.0/0"]
31 │ ipv6_cidr_blocks = ["::/0"]
32 │ }
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-vpc-add-description-to-security-group-rule
Impact Descriptions provide context for the firewall rule reasons
Resolution Add descriptions for all security groups rules
More Information
- https://aquasecurity.github.io/tfsec/v1.1.5/checks/aws/vpc/add-description-to-security-group-rule/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
timings
──────────────────────────────────────────
disk i/o 23.956709ms
hcl parsing 74.834µs
evaluation 21.812586ms
adaptation 960µs
running checks 4.643584ms
total 109.267ms
counts
──────────────────────────────────────────
blocks 6
modules 1
files 9
results
──────────────────────────────────────────
ignored 0
excluded 0
critical 2
high 0
medium 0
low 1
3 potential problem(s) detected.
実行結果から、セキュリティグループ周りで、3件検知されていることが確認できます。
重要度について
tfsecでは、検知結果を4つの重要度でカテゴライズしています。
- critical
- high
- medium
- low
重要度の具体的な、選別方法は明記されていないですが、検知されたルールに、ひととおり目を通しておきましょう。
aws-vpc-no-public-egress-sgr
An egress security group rule allows traffic to /0.
Result #1, #2で、アウトバウンドルールが、フルオープンであることを検知していました。
リファレンスに、解決策や影響範囲が記載されているので、「何がどのように悪い」のか、とてもわかりやすいです。
aws-vpc-add-description-to-security-group-rule
Missing description for security group rule.
Result #3では、アウトバウンドルールに、説明書きがないことを検知していました。
たしかに、説明書きがないと、使用用途がわかりづらいため、追加した方がいいですね。
ルール検知を無視する
スキャン実行で検知されたアウトバウンドルールのフルオープンを、ignore(無視)に変更してみようと思います。
変更方法は、コード内にコメントとして、検知を無視するコードを追記します。
無視を行うコードの有効範囲は、同一行と一つ下の行までです。
Result #1のみを無視する
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
# tfsec:ignore:aws-vpc-no-public-egress-sgr
cidr_blocks = ["0.0.0.0/0"] # ignored
ipv6_cidr_blocks = ["::/0"] # critical
}
tags = {
Name = "allow_tls"
}
}
/* or
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr
# 一行開ける
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "allow_tls"
}
}
*/
Result #1,2を無視する
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr
ipv6_cidr_blocks = ["::/0"] # ignored →コードの影響範囲は1行下まで及ぶため
}
tags = {
Name = "allow_tls"
}
}
/* or
resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
description = "TLS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [module.vpc.vpc_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr
ipv6_cidr_blocks = ["::/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr
}
tags = {
Name = "allow_tls"
}
}
*/
最後に
今回は、かなり簡単ではありますが、tfsecの使い方をご紹介しました。
より応用的な使い方は、別途ブログにできたらと思います。
以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!