藉由 MFA 增強 AWS CLI 的安全性
前言
什麼是 MFA 呢? MFA 可增加額外的安全,因為它會要求使用者在存取 AWS 網站或服務時,除了標準登入資料外,從 AWS 支援的 MFA 機制提供唯一的身份驗證有以下:
-
虛擬 MFA 裝置
-
U2F 安全金鑰
-
硬體 MFA 裝置
-
SMS 簡訊式 MFA
什麼是 AWS-CLI? AWS CLI 是開放原始碼工具,可讓您在命令列 shell 中使用命令來與 AWS 服務互動。只需最少的組態,就可以在喜愛的終端程式中,從命令提示字元開始使用相當於瀏覽器型 AWS Management Console 所提供的功能。
情境
透過 AWS CLI 可以在命令列 shell 中使用命令來與 AWS 服務互動,於是我們可以透過指令碼將服務自動化,但是要怎麼確認使用 AWS CLI 與 AWS 的服務互動是安全的呢?在 AWS CLI 當中的設定若為永久授權,會不會有風險呢? 於是我們希望使用臨時憑證和 MFA 提高我們的安全性。
步驟
一、 使用 AWS CLI 與 AWS 服務互動之前,須先擁有 AccessKeyID、SecretAccessKey ,若您在 AWS CLI 當中使用 root account ,我們強烈建議使用 IAM ,新增 User ,並且給予需要的權限,如此可以 使用 User 代替 root account,增加安全性 。
二、 Add user -> 輸入 User name : TEST-CLI 然後勾選 Programmatic access -> Next: Permissions。
三、 可以將此 User 加入到想套用的群組當中,或是從已經存在其他使用者複製權限,也可以選擇直接 Attach Policy 到 User ,在此範例當中 Attach AmazonS3ReadOnlyAccess -> Next: Tags。
只需要給予這個 User 相對應的權限即可。
四、 Next: Review -> Create user -> Download.csv ,新增 User 完成後,點選剛剛新增好的 User 。
五、 Assigned MFA device -> Manage -> Select Virtual MFA device -> Continue 。
六、 可以在您的行動裝置下載 Authenticator -> Show QR code -> 接著使用行動裝置開啟 Authentucator 掃描 QRcode -> 輸入 MFA Code。 > 在這個教程當中我們使用 Google Authenticator App 掃描 QR Code。
七、 輸入 MFA code , MFA code 每隔 30 秒會重新產生一組,在此需要連續輸入兩組 -> Assign。
八、 成功之後 Assigned MFA device 會出現如下圖所示的 arn 。
接著我們就能將此 User 的設定套用到 AWS CLI,透過 AWS CLI 與 AWS 的服務互動。
九、 將 AccessKeyID、SecretAccessKey 設定到 .aws/Credential 描述檔 ,打開 Terminal,輸入指令:aws configure,依序輸入 :
$ aws configure Aws Access Key ID: Aws Secret Access Key: Default region name[us-east-1]: Default output format[None]:
十、 設定完畢之後可以藉由 get-session-token 搭配 MFA,取得臨時憑證,並且可以設定臨時憑證有效時間。get-session-token(詳細內容請參閱網址)。
$ aws sts get-session-token --duration-seconds XXX --serial-number <your mfa arn> --token-code YYYYYY</your>
十ㄧ、 憑證有效時間以秒為單位,最少為 900 秒 (15分鐘),預設為 12 小時,時間是格林威治標準時間。
十二、 如果您使用的是 MFA 硬體裝置, ARN 值類似於 GAHT12345678。 如果您正在使用虛擬 MFA ,則該值類似於 arn:aws:iam::123456789012:mfa/user。
十三、 你將會得到類似底下的回覆:
{
"Credentials": {
"AccessKeyId": "XXXXXXXXXXXXXXXXX",
"SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
"SessionToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"Expiration": "2019-01-29T07:43:51Z"
}
}
十四、 此臨時憑證的權限與 User 相同。
十五、 在資料夾~/.aws/credentials
和 ~/.aws/config
記錄著相關 AWS 的資訊,例如:AccessKey、SecretAccessKey以及Region。在此將拿到的臨時授權憑證打進 .aws/credential 描述檔裡,格式如下:
[Your-Profile-Name]
aws_access_key_id = your-AccessKeyId
aws_secret_access_key = your-SecretAccessKey
aws_session_token = your-SessionToken
十六、 在 credential 描述檔裡 可以有多個 Profile , [Your-Profile-Name] 可以自己命名。在使用 CLI 操作時可以在指令後段加上--profile Your-profile-name
指定 Profile,否則皆會以 [default] 執行該段指令,以下為實際使用:
$ aws s3 ls --profile your-profile-name
十七、 我們也可以將臨時授權憑證設定為環境變數,如此在 CLI 當中對 AWS 資源的操作都會以環境變數的描述來執行,當然也能夠覆蓋、更換或是移除原本的環境變數,在那之前請先取消原先的環境變數設定:
$ unset aws_access_key_id
$ unset aws_secret_access_key
$ unset aws_session_token
十八、 設定環境變數:
$ export aws_access_key_id = your-AccessKeyId
$ export aws_secret_access_key = your-SecretAccessKey
$ export aws_session_token = your-SessionToken
$ export aws_profile = your-profilename
十九、 當我們使用的臨時憑證過期,就必須得重新設定環境變數或是更改~/.aws/credential
內的描述檔
二十、 用臨時憑證存取 AWS 服務,例如: aws s3 ls --profile [profilename]
,請記得更改 profilename ,否則會以描述檔中 Default 的身份執行。
二十一、 臨時憑證過期出現訊息如下:
$ aws s3 ls --profile MFA
An error occurred (ExpiredToken) when calling the ListBuckets operation:
The provided token has expired.
二十二、 若臨時憑證過期,重新下指令:
$ aws sts get-session-token --duration-seconds XXX --serial-number <your mfa arn> --token-code YYYYYY</your>
為特定 API 綁定 MFA
二十三、 並且可以透過 MFA 為一些重要、敏感的 API 多一層防護 -> Configuring MFA-Protected API Access。
二十四、 在我們尚未將 MFA 加上 AWS CLI 時,我們可以在 Terminal 下指令,由於我們還未將操作各項服務的限制加上,這讓我們可以直接透過 CLI 直接操作、使用 AWS 資源,例如輸入底下指令:
$ aws s3 ls
二十五、 會直接將 S3 當中所有的 Bucket 一一列出。
二十六、 在某些情況之下,我們希望我們特定的 API 操作也需要經過 MFA 的認證才得以進行,這時可以在 Policy 當中加上 Condition 限制,舉例來說:我將一些服務掛載在 EC2 上,我不希望管理這些服務的技術人員可以直接 Call API 將運行服務的 EC2 終止,於是我們將 TerminateInstances 的操作加上 MFA,以此保護我的 EC2 不會被終止。
二十七、 這裡使用 S3 Bucket 作為示範,到 AWS IAM 內新增一個 Policy,內容如下,再將此 Policy Attach 到 User,如此一來,該 User 在執行 ListBucket、GetObject API 操作時,必須先通過 MFA 驗證。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
二十八、 接著我們運行以下這段 Python 程式碼(參考自AWS官方文件),執行成功並且輸入正確的 MFA Code,會列出你指定的 Bucket內的物件:
import boto
from boto.s3.connection import S3Connection
from boto.sts import STSConnection
# Prompt for MFA time-based one-time password (TOTP)
mfa_TOTP = input("Enter the MFA code: ")
# The calls to AWS STS GetSessionToken must be signed with the access key ID and secret
# access key of an IAM user. The credentials can be in environment variables or in
# a configuration file and will be discovered automatically
# by the STSConnection() function. For more information, see the Python SDK
# documentation: http://boto.readthedocs.org/en/latest/boto_config_tut.html
sts_connection = STSConnection()
# Use the appropriate device ID (serial number for hardware device or ARN for virtual device).
# Replace ACCOUNT-NUMBER-WITHOUT-HYPHENS and MFA-DEVICE-ID with appropriate values.
tempCredentials = sts_connection.get_session_token(
duration=3600,
mfa_serial_number="<YOUR-MFA-ARN",
mfa_token=mfa_TOTP
)
# Use the temporary credentials to list the contents of an S3 bucket
s3_connection = S3Connection(
aws_access_key_id=tempCredentials.access_key,
aws_secret_access_key=tempCredentials.secret_key,
security_token=tempCredentials.session_token
)
# Replace BUCKET-NAME with an appropriate value.
bucket = s3_connection.get_bucket(bucket_name="<your -BUCKET-NAME>")
objectlist = bucket.list()
for obj in objectlist: print (obj.name)
請記得替換 “< YOUR-MFA-ARN >”, “< YOUR-BUCKET-Name> “
二十九、 當運行這段程式碼時,會被要求給予 MFA Code,必須輸入正確 MFA Code 才會執行該 API 操作。否則則會出現錯誤訊息。
三十、 實際運行該段程式碼結果如圖:
三十一、 輸入正確的 MFA Code 後則會成功列出所有在此 Bucket 內的物件
三十二、 MFA Code 如果輸入錯誤則會顯示:
結論
現在你可以使用 IAM,創建 User ,而非使用 root account ,並且給予 User 相對應的權限與特定 AWS 的服務互動,並且設置 Virtual MFA 為你的 User 多設一道防護。在使用 AWS CLI ,與 AWS 的服務互動時,也能透過 MFA 驗證,並且將永久授權置換為臨時憑證的授權,並且設定有效時間,定期更換臨時憑證,提升使用 AWS CLI 時的安全性。也學會了為比較敏感、重要的 API ,加上 MFA 的保護。