简体   繁体   English

在 Terraform 中隐藏秘密

[英]Hide secret in Terraform

I am trying to create IPSEC tunnels on Palo Alto using Terraform.我正在尝试使用 Terraform 在帕洛阿尔托创建 IPSEC 隧道。 The code would the be pushed via a pipeline.代码将通过管道推送。 I want all information of the tunnels to be readable, except for the pre_shared_key .我希望隧道的所有信息都是可读的,除了pre_shared_key I understand how I could encrypt it for one instance, but as there is going to be several tunnel, how can encrypt the key, and map it to its instance?我了解如何为一个实例加密它,但是由于将有多个隧道,如何加密密钥并将 map 加密到它的实例?

vpns.yml: vpns.yml:

vpns:
  - name: "Test"
    template: "template_name"
    ip_type: "IP"
    ip_remote: "1.1.1.1"
    firewall_interface: "vlan.xxxx"
    local_ip: "public_ip/24"
    ikev2_profile: "VerySecure"
    tunnel_interface: "tunnel1"
    pre_shared_key: "*******"

The module for the tunnel on which I iterate looks like this:我迭代的隧道模块如下所示:

locals {
  tunnel = yamldecode(file(var.vpn_file))
}


resource "panos_panorama_ike_gateway" "gateway" {
  for_each = { for e in local.tunnel : e.Name => e }

  name                         = each.value.name
  template                     = each.value.template
  version                      = "ikev2-preferred"
  peer_ip_type                 = each.value.ip_type
  peer_ip_value                = each.value.ip_remote
  interface                    = each.value.firewall_interface
  local_ip_address_type        = "ip"
  local_ip_address_value       = each.value.local_ip
  pre_shared_key               = each.value.pre_shared_key
  ikev2_crypto_profile         = each.value.ikev2_profile
  enable_dead_peer_detection   = true
  dead_peer_detection_interval = "10"
  dead_peer_detection_retry    = "3"
  liveness_check_interval      = "5"
}

Gruntwork's guide to managing secrets covers a lot of this so is probably worth reading through. Gruntwork 的机密管理指南涵盖了很多内容,因此可能值得一读。

Ideally you'd use an external secrets manager such as Hashicorp Vault or AWS SSM Parameter Store/Secrets Manager and generate the key using random_password , stashing it in your secret store with one side of the tunnel and then retrieving it from the secret store when applying the other side of the tunnel.理想情况下,您将使用外部密钥管理器(例如 Hashicorp Vault 或 AWS SSM Parameter Store/Secrets Manager)并使用random_password生成密钥,将其存储在隧道一侧的密钥存储中,然后在应用时从密钥存储中检索它隧道的另一边。

If you intend to create both sides of the tunnel with a single terraform apply (eg you keep the configuration for both in the same directory) then you don't even need the secrets store and can just rely on the fact that the secret is only ever stored in Terraform state and never in your repo which only has the input of the random_password resource.如果您打算使用单个terraform apply程序创建隧道的两侧(例如,您将两者的配置保存在同一目录中),那么您甚至不需要秘密存储并且可以只依赖于秘密仅曾经存储在 Terraform state 中,并且永远不会存储在只有random_password资源输入的存储库中。

In your case you'd have something like the following:在您的情况下,您将拥有以下内容:

locals {
  tunnel = {
    "vpns" = [
      {
        "firewall_interface" = "vlan.xxxx"
        "ikev2_profile"      = "VerySecure"
        "ip_remote"          = "1.1.1.1"
        "ip_type"            = "IP"
        "local_ip"           = "public_ip/24"
        "name"               = "TestLeft"
        "template"           = "template_name"
        "tunnel_interface"   = "tunnel1"
      },
      {
        "firewall_interface" = "vlan.xxxx"
        "ikev2_profile"      = "VerySecure"
        "ip_remote"          = "2.2.2.2"
        "ip_type"            = "IP"
        "local_ip"           = "public_ip/24"
        "name"               = "TestRight"
        "template"           = "template_name"
        "tunnel_interface"   = "tunnel1"
      },
    ]
  }
}

resource "random_password" "pre_shared_key" {
  length = 32
}

resource "panos_panorama_ike_gateway" "gateway" {
  for_each = { for e in local.tunnel : e.Name => e }

  name                         = each.value.name
  template                     = each.value.template
  version                      = "ikev2-preferred"
  peer_ip_type                 = each.value.ip_type
  peer_ip_value                = each.value.ip_remote
  interface                    = each.value.firewall_interface
  local_ip_address_type        = "ip"
  local_ip_address_value       = each.value.local_ip
  pre_shared_key               = random_password.pre_shared_key.result
  ikev2_crypto_profile         = each.value.ikev2_profile
  enable_dead_peer_detection   = true
  dead_peer_detection_interval = "10"
  dead_peer_detection_retry    = "3"
  liveness_check_interval      = "5"
}

An alternative option would be to either encrypt the whole of the YAML file in your repo using something like GPG or age , selectively encrypt parts of the file using something like SOPS or Ansible Vault or separate out the secret into another file that is fully encrypted with any of the above options, leaving the rest of the non secret configuration in plain text.另一种选择是使用GPGage之类的东西加密你的 repo 中的整个 YAML 文件,使用SOPSAnsible Vault之类的东西选择性地加密文件的一部分,或者将秘密分离到另一个完全加密的文件中以上任何选项,将非机密配置的 rest 保留为纯文本。 You could then decrypt the relevant secret before running Terraform commands.然后,您可以在运行 Terraform 命令之前解密相关密钥。

You will need to make sure that you secure access to and encrypt your Terraform state files because these will hold the secret in plain text.您需要确保安全访问并加密 Terraform state 文件,因为这些文件将以纯文本形式保存秘密。 Terraform remote state backends commonly provide ways to do this such as specifying a KMS key for encrypting state files in S3. Terraform 远程 state 后端通常提供执行此操作的方法,例如指定用于加密 S3 中的 state 文件的 KMS 密钥。

From Terraform 0.14 onwards you can also mark variables as sensitive which will mask them when writing them to stdout.从 Terraform 0.14 起,您还可以将变量标记为敏感,这将在将它们写入标准输出时屏蔽它们。 With the above pattern of using random_password this is automatically handled for you but if you were to input the pre-shared key as a variable then you'd want to explicitly mark it as sensitive:使用上述使用random_password的模式会自动为您处理,但如果您要将预共享密钥作为变量输入,那么您需要明确地将其标记为敏感:

variable "pre_shared_key" {
  description = "The pre-shared key for the VPN tunnel"
  type        = string
  sensitive   = true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM