Vault 裡 AppRole 的設計,以及怎麼解決 Secret Zero 問題

VaultHashiCorp 拿來管理各種敏感資訊的軟體,像是 API token 或是資料庫的帳號密碼。把這些資訊集中控管後就不需要把這些資訊放進 Git (超爽的?),而是在需要的時候由應用程式呼叫 Vault 取得。

而 Vault 的設計裡面要求應用程式需要「認證」後才能取得,結果這個「認證」又是一組敏感資訊,這就是 Secret Zero 問題,屬於雞蛋問題的一種。

找了一輪發現 HashiCorp 自家的說明解釋的最清楚,不過這篇是放在 blog 上的文章:「Tackling the Vault Secret Zero Problem by AppRole Authentication」。

Vault 在解決 Secret Zero 的方法是使用 AppRole,這邊的認證包括了 role_idsecret_id 的設計。比較特別的是一組 role_id 可以有多組 secret_id 對應。

在 AppRole 這樣的設計下,權限會綁在 role_id 上,而 secret_id 則可以在部屬時動態產生,像是官方提到的 TerraformChef,或是依照組織裡面使用的管理工具:

這樣就可以透過 role_id 管理權限,但不用在 Git 裡面寫死 Secret Zero 資訊,而且每台機器都有自己的 secret_id 可以提供稽核記錄,把幾個比較明顯的問題解了不少...

結果 AWS Console 對 EC2 的 IAM Role 被拔掉了...

在 console 上發現不見了,跑去 forum 上看看是不是有其他人遇到同樣的問題,結果發現被拔掉了:「Attach IAM Role to existing EC2 instance in console not available」。

On Friday, Feb 24th, we were made aware that under certain conditions, the feature was not working for customers using the EC2 console. As a result, we have temporarily removed this capability from the EC2 console, but we will enable this feature when this issue has been resolved.

Ouch... 只好先用 CLI 了...

AWS Management Console 可以修改 EC2 Role 了...

前幾天提到的「EC2 的 IAM Role 可以動態改了...」在網頁上的 AWS Management Console 可以改了:「Easily Replace or Attach an IAM Role to an Existing EC2 Instance by Using the EC2 Console」。

大賀 XDDD

EC2 的 IAM Role 可以動態改了...

EC2IAM Role 根本是開發階段最常重新啟動的理由之一 XDDD

AWS 總算把動態調整 IAM Role 的功能給做出來了:「New! Attach an AWS IAM Role to an Existing Amazon EC2 Instance by Using the AWS CLI」。

不過看到文章完全沒有截圖,心裡大概就猜得到目前 web console 還不支援了... 現在只能透過 command line 操作,像是「Attach the IAM role to an existing EC2 instance that was originally launched without an IAM role」這一段:

$ aws ec2 associate-iam-instance-profile --instance-id YourInstanceId --iam-instance-profile Name=YourNewRole-Instance-Profile

或是「Replace the attached IAM role」這段:

$ aws ec2 replace-iam-instance-profile-association --association-id YourCurrentAssociation-id --iam-instance-profile Name=YourReplacementRole-Instance-Profile

不過有進度總是比沒進度開心,這功能應該會加到 web console...

CodeDeploy 的權限設定...

這陣子在弄 AWS CodeDeploy,調整了半天才把權限壓低到合理的範圍 (AWS 給的預設值還是有點大),記錄下來之後會比較好找...

在權限部份,AWS CodeDeploy 應該有三個權限要設定:

  • IAM user:給 CI 跑完後丟上 Amazon S3 並且呼叫 AWS CodeDeploy 佈署用的,像是 Travis CI 或是之類的服務。但如果是手動到 web console 觸發的話,這個部份就不需要了。
  • Service Role:給 AWS CodeDeploy 的服務本身用的。
  • EC2 Role:給跑在機器上 AWS CodeDeploy Agent 用的。

如同前面講的,IAM user 的部份有兩個要處理,一個是讓 CI 服務把檔案傳上 Amazon S3,另外一個是讓他有權限可以呼叫 AWS CodeDeploy 佈署新版本。

後者比較簡單,直接拉 AWSCodeDeployDeployerAccess 就可以了,前者比較麻煩一點,需要透過 Policy Generator 建出對應的權限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1486156178000",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::codedeploy-testbucket/*"
            ]
        }
    ]
}

第二個的 Service Role 是最簡單的,直接拉 AWSCodeDeployRole 就可以了。

第三個的 EC2 Role 只需要給存取 Amazon S3 的權限。照 AWS 的建議用 AmazonEC2RoleforAWSCodeDeploy 是會動啦,但權限給太大了,整個帳號可以存取的 S3 bucket 他都可以拉到:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:ListObjects"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

改成自己用 Policy Generator 生,限制在 codedeploy-testbucket 上會比較好:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1486165995000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::codedeploy-testbucket/*"
            ]
        }
    ]
}

這樣權限的部份就差不多了...

Amazon Redshift 可以透過 IAM Role 直接 COPY 與 UNLOAD 了

Amazon Redshift 的這個功能等了好久啊,之前都要自己指定 key 與 secret,不只讓程式寫起來變麻煩,安全性也一直是個問題:「Amazon Redshift now supports using IAM roles with COPY and UNLOAD commands」。

之前的指令是:

COPY ... FROM ... WITH CREDENTIALS 'aws_access_key_id=access-key-id;aws_secret_access_key=secret-access-key' ...

現在都可以透過 IAM Role 省下這些功夫...