Как создавать пользовательские проверки в tfsec

#terraform #tfsec

#terraform #tfsec

Вопрос:

У меня есть следующая политика, которую я хочу реализовать при сканировании кода IaC с использованием tfsec:

Custom Check: GCP Firewall rule allows all traffic on Telnet port (23)

Ниже приведена моя пользовательская проверка в формате .json:

 {
  "checks": 
    [
      {
        "code": "CUS003",
        "description": "Custom Check: GCP Firewall rule allows all traffic on Telnet port (23)",
        "requiredTypes": 
          [
            "resource"
          ],
          "requiredLabels": 
          [
            "google_compute_firewall"
          ],
          "severity": "WARNING",
          "matchSpec": 
          {
            "name": "CUS003_matchSpec_name",
            "action": "and",
            "predicateMatchSpec": 
            [
                  {
                    "name": "source_ranges",
                    "action": "contains",
                    "value": "0.0.0.0/0"
                },
                {
                    "name": "ports",
                    "action": "contains",
                    "value": "23"
                }
            ]
          },
        "errorMessage": "[WARNING] GCP Firewall rule allows all traffic on Telnet port (23)",
        "relatedLinks": 
          [
            "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_firewall"
          ]
      }
    ]  
}
 

Я пытался использовать «not», «notContains», «equals», комбинацию «subMatch» и / или «predicateMatchSpec», но ничего не сработало.

Чтобы проверить это, я целенаправленно создал правила брандмауэра, которые должны завершаться сбоем, и другие, которые должны проходить проверки. Когда я получаю ошибки проверки, это касается всех правил, а не только нескольких. Аналогично, когда я получаю контрольные проходы, это касается всех правил, а не только нескольких.

Документы, которые могут быть полезны: пользовательские проверки tfsec

Любая помощь приветствуется. К сожалению, «tfsec» не является тегом, поэтому я надеюсь, что это проблема terraform, с которой я сталкиваюсь.

Комментарии:

1. Эй, я посмотрю на это, может быть, это ошибка. Мы действительно решаем проблемы ( github.com/tfsec/tfsec/issues ), я нашел это только по счастливой случайности, когда кто-то прислал его мне (я один из основных разработчиков).

Ответ №1:

Я думаю, что теперь, глядя на него, понятно, что source_ranges он является дочерним элементом google_compute_firewall ресурса. ports Атрибут является дочерним элементом allow . Ваша проверка предполагает, что ports это родной брат source_ranges .

Я думаю, что эта проверка достижима с помощью следующего — она выполняет проверку предиката на наличие source_range по мере необходимости, И есть блок с именем allow , с атрибутом ports, содержащим 23

 {
  "checks": [
    {
      "code": "CUS003",
      "description": "Custom Check: GCP Firewall rule allows all traffic on Telnet port (23)",
      "requiredTypes": [
        "resource"
      ],
      "requiredLabels": [
        "google_compute_firewall"
      ],
      "severity": "WARNING",
      "matchSpec": {
        "action": "and",
        "predicateMatchSpec": [
          {
            "name": "source_ranges",
            "action": "contains",
            "value": "0.0.0.0/0"
          },
          {
            "name": "allow",
            "action": "isPresent",
            "subMatch": {
              "name": "ports",
              "action": "contains",
              "value": "23",
              "ignoreUndefined": true
            }
          }
        ]
      },
      "errorMessage": "[WARNING] GCP Firewall rule allows all traffic on Telnet port (23)",
      "relatedLinks": [
        "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_firewall"
      ]
    }
  ]
}
 

Я протестировал его со следующим телом

 resource "google_compute_firewall" "default" {
  name    = "test-firewall"
  network = google_compute_network.default.name

  allow {
    protocol = "tcp"
    ports    = ["23", "8080", "1000-2000"]
  }
  source_ranges = ["0.0.0.0/0"]
  source_tags = ["web"]
}

resource "google_compute_network" "default" {
  name = "test-network"
}
 

Комментарии:

1. Спасибо вам за это! Основываясь на приведенном выше примере, слегка измененном для обратного эффекта, он работал так, как я надеялся!