【问题标题】:Hide secret in Terraform在 Terraform 中隐藏秘密
【发布时间】:2021-02-03 22:41:09
【问题描述】:

我正在尝试使用 Terraform 在帕洛阿尔托创建 IPSEC 隧道。代码将通过管道推送。我希望隧道的所有信息都是可读的,pre_shared_key 除外。我知道如何为一个实例加密它,但由于会有多个隧道,如何加密密钥并将其映射到它的实例?

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: "*******"

我迭代的隧道模块如下所示:

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"
}

【问题讨论】:

  • 哪部分要保密?只是不将其以纯文本形式存储在存储库中?还是其他地方,例如 Terraform 输出?
  • 理想情况下两者都是,但它不会以纯文本形式存储这一事实似乎是最重要的。

标签: terraform


【解决方案1】:

Gruntwork's guide to managing secrets 涵盖了很多内容,因此可能值得一读。

理想情况下,您应该使用 Hashicorp Vault 或 AWS SSM Parameter Store/Secrets Manager 等外部机密管理器,并使用 random_password 生成密钥,将其存储在隧道一侧的机密存储中,然后从应用隧道另一端时的秘密存储。

如果您打算使用单个 terraform apply 创建隧道的两侧(例如,您将两者的配置保存在同一个目录中),那么您甚至不需要秘密存储,只需依赖以下事实秘密只存储在 Terraform 状态中,永远不会存储在只有 random_password 资源输入的存储库中。

在您的情况下,您将有以下内容:

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"
}

另一种选择是使用GPGage 之类的东西加密你的repo 中的整个YAML 文件,使用SOPSAnsible Vault 之类的东西有选择地加密文件的部分内容或分离出来将秘密放入另一个使用上述任何选项完全加密的文件中,将其余非秘密配置保留为纯文本。然后,您可以在运行 Terraform 命令之前解密相关的机密。

您需要确保安全访问和加密您的 Terraform 状态文件,因为这些文件将以纯文本形式保存机密。 Terraform 远程状态后端通常提供执行此操作的方法,例如指定用于加密 S3 中的状态文件的 KMS 密钥。

从 Terraform 0.14 开始,您还可以 mark variables as sensitive 在将它们写入标准输出时屏蔽它们。上面使用random_password 的模式会自动为您处理,但如果您将预共享密钥作为变量输入,那么您需要明确地将其标记为敏感:

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

【讨论】:

  • 我读过这篇文章,但他总是加密整个文件(我不想要)。我也不管理隧道的两端,因此生成随机密钥不是一种选择。 (不过我确实喜欢这个主意!)我想到了使用 Ansible,但是为了另一个应用程序的好处,只加密 YAML 文件的一部分然后解密 oit 并不是很疯狂......结果 SOPS 允许只加密文件的一部分,这正是我想要的!但是,必须始终使用 SOPS 修改文件。有点缺点,但我会活下去。感谢您的帮助!
  • 您可以使用 Ansible-Vault (docs.ansible.com/ansible/latest/user_guide/…) 加密文件中的特定块,但是您仍然需要使用用于加密它的工具来编辑/解密它。
猜你喜欢
  • 2020-02-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2013-10-18
  • 2021-10-26
  • 2014-10-31
  • 2020-12-04
  • 2017-04-18
相关资源
最近更新 更多