Tạm biệt long – term credentials, IAM Roles Anywhere là OK rồi

Việc sử dụng AWS access key và secret key cho các workloads như servers, containers, và các applications chạy ở môi trường bên ngoài AWS là cách làm trước đây chúng ta vẫn làm. Tuy nhiên, việc này lại kéo theo một lỗi bảo mật chết người: access key và secret key là long – term credentials, và nếu chúng ta không tự rotate thì sẽ không expire (một lần có thể dùng mãi mãi).

Có một cách để vượt qua được pain point này là sử dụng AWS Identity Center để tạo user, và lấy short term credentials. Tuy nhiên, nếu chúng ta đơn giản là không thích? Hay chúng ta cần một giải pháp an toàn hơn nữa? => IAM Roles Anywhere là thứ bạn có thể xem xét triển khai!

Để sử dụng IAM Roles Anywhere, workloads của bạn sẽ phải sử dụng X.509 certificates do cơ quan cấp chứng chỉ (CA) của bạn cấp. Bạn sử dụng chứng chỉ này để configure trust anchor để thiết lập sự tin cậy giữa public-key infrastructure (PKI) của bạn và IAM Roles Anywhere. Bạn cũng có thể sử dụng AWS Private CA để tạo CA rồi sử dụng CA đó để thiết lập IAM Roles Anywhere.

Bạn có thể sử dụng general purpose PCA hay short – live PCA. Tuy nhiên, lưu ý rằng short – live PCA sẽ không thể sử dụng ACM để generate certificate (https://docs.aws.amazon.com/privateca/latest/userguide/PcaGetCert.html), mà chúng ta phải tự issue certificate (https://docs.aws.amazon.com/privateca/latest/userguide/PcaIssueCert.html), thêm nữa short – live PCA sẽ chỉ cho chúng ta tạo end entity certificate có validity tối đa là 7 ngày.

Tuy nhiên, giá vận hành cho general là $400/ tháng, trong khi đó short-live chỉ $50/ tháng.

Chi tiết về cách sử dụng short – live PCA xem tại đây:
https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode/

Nếu bạn không dùng AWS PCA, bạn có thể generate CA cho bạn bằng OpenSSL hoặc sử dụng Hashicorp Vault. Ở bài này, mình sẽ hướng dẫn sử dụng Hashicorp Vault để generate CA.

Cài đặt Docker và chạy Hashicorp Vault:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
 "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
 $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo groupadd docker
sudo usermod -aG docker $(whoami)
export VAULT_TOKEN="abc123"
export VAULT_ADDR='http://0.0.0.0:8200'
docker run --cap-add=IPC_LOCK -e 'VAULT_DEV_ROOT_TOKEN_ID=abc123' -p 8200:8200 --name iam-roles-anywhere-test -d vault:1.11.0

Cài đặt Vault client để tương tác với Vault server:

wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault

Tiếp theo chúng ta generate root CA:

vault secrets enable -path=iam-roles-anywhere-test -description="IAM Roles Anywhere Test" pki
vault write iam-roles-anywhere-test/root/generate/internal \
common_name=example.com \
ttl=6000h

vault read -field=certificate iam-roles-anywhere-test/cert/ca > ca.pem

Copy nội dung ca.pem trên và dán vào phần trust anchor:

Tiếp theo, tạo cho chúng ta một cặp cert + private keypair sử dụng CA mới:

vault write -format=json iam-roles-anywhere-test/issue/test common_name="example.com" ttl="720h" > cert.json
jq -r .data.certificate cert.json > cert.pem
jq -r .data.private_key cert.json > private.pem

Chúng ta đặt tên các cert này là cert.pem và private.pem

Đây chính là private key và end entity certificate chúng ta dùng để client thiết lập sự tin cậy với CA trên IAM Roles Anywhere.

Chúng ta có thể kiểm tra tính hợp lệ của cert:

openssl x509 -in cert.pem -text -noout
openssl rsa -in private.pem -check

openssl x509 -in cert.pem -noout -dates

Để lấy được session và tương tác với AWS API, chúng ta sẽ làm theo tài liệu sau:

https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html

Đầu tiên, chúng ta cần tải và cấp quyền execute cho tool signing helper:

wget https://rolesanywhere.amazonaws.com/releases/1.0.4/X86_64/Linux/aws_signing_helper
chmod +x aws_signing_helper

Để có thể lấy được token:

./aws_signing_helper credential-process \
    --certificate cert.pem
    --private-key private.pem
    --profile-arn <arn IAM roles anywhere profile> 
    --role-arn <arn IAM roles chúng ta configure trong IAM roles anywhere profile> 
    --trust-anchor-arn <arn của trust anchor>

Với cert.pem và private.pem là 2 file chúng ta tạo ra từ Vault bên trên.

Để có thể tự động lấy session, chúng ta có thể sử dụng script python:

from iam_rolesanywhere_session import IAMRolesAnywhereSession
roles_anywhere_session = IAMRolesAnywhereSession(
    profile_arn="arn:aws:rolesanywhere:eu-central-1:************:profile/a6294488-77cf-4d4a-8c5c-40b96690bbf0",
    role_arn="arn:aws:iam::************:role/IAMRolesAnywhere-01",
    trust_anchor_arn="arn:aws:rolesanywhere:eu-central-1::************::trust-anchor/4579702c-9abb-47c2-88b2-c734e0b29539",
    certificate='certificate.pem',
    private_key='privkey.pem',
    region="eu-central-1"
).get_session()
s3 = roles_anywhere_session.client("s3")
print(s3.list_buckets())

(source: https://github.com/awslabs/iam-roles-anywhere-session)

Nhược điểm là Java SDK lại chưa triển khai method nào tương tự như method get_session() của boto3.

Chúng ta có thể handle việc này bằng cách configure profile cho máy chạy app của chúng ta bằng cách chỉnh sửa file ~/.aws/config:

[default]
credential_process = ./aws_signing_helper credential-process --certificate /path/to/certificate --private-key /path/to/private-key --trust-anchor-arn arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID --profile-arn arn:aws:rolesanywhere:region:account:profile/PROFILE_ID --role-arn arn:aws:iam::account:role/role-name-with-path

Vì có thử testing bằng Java, mà em cũng gặp 1 lỗi hơi dị chút: ở tài liệu của AWS thì trước chữ credential_process trong file ~/.aws/config cũng có dấu cách, mà configure có dấu cách, chạy SDK ngôn ngữ khác thì OK, còn chạy java SDK thì nó lỗi kêu không tìm được profile. Loanh quanh search Google thì thấy bảo xóa khoảng trắng là OK, em xóa đi thấy nó OK thật :v Không hiểu sao Java SDK lại bị vậy, nên hãy lưu ý điểm này ạ.

Lúc này chúng ta có thể test thử bằng câu lệnh:

aws sts get-caller-identity

sẽ thấy chúng ta đang assume role configure trên IAM Roles Anywhere profile.

Tham khảo thêm cách lấy session trong tài liệu chính thức của AWS:

https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html

Nếu bạn muốn đơn giản hóa việc quản lý private certificates thì có bài blog sau rất hay bạn có thể tham khảo hướng làm:

https://aws.amazon.com/blogs/security/use-aws-secrets-manager-to-simplify-the-management-of-private-certificates/

\=============

Tài liệu tham khảo:

https://mckinnel.me/iam-roles-anywhere-with-custom-certificate-authority.html