Dev&Ops/DevOps

[Infra] Springboot에 AWS Secrets Manager 적용해보기(3)

zeroneCoder 2023. 1. 24. 11:17

안녕하세요! zerone-code입니다.

 

앞선 Springboot에 AWS Secrets Manager 적용해보기(1)에서는 AWS Secrets Manager를 왜 적용해야 하며, 어떻게 적용되는지에 대해 알아봤었습니다. 그리고 Springboot에 AWS Secrets Manager 적용해보기(2)에서는 코드 수준과 인프라 수준에서 적용해야할 부분에 대해서도 알아봤습니다.

 

자세한 글은 아래 링크로 들어가시면 볼 수 있습니다!

 

2022.09.18 - [Dev&Ops/DevOps] - [Infra] Springboot에 AWS Secrets Manager 적용해보기(1)

2022.09.30 - [Dev&Ops/DevOps] - [Infra] Springboot에 AWS Secrets Manager 적용해보기(2)

 

 

 

[Infra] Springboot에 AWS Secrets Manager 적용해보기(2)

안녕하세요! zerone-code입니다. 지난 글에서 AWS의 Secrets Manager를 이용해서 Application의 보안 측면을 높이는 방법을 소개했습니다. AWS Secrets Manager가 무엇이고, 왜 적용해야 하며, 어떻게 적용되는지

zerone-code.tistory.com

 

2부에서는 AWS환경에서 ECS나 EC2와 같은 인스턴스로 띄울 때 적용하는 방법을 다뤄봤다면,

이번 3부에서는 EKS, 즉 Kubernetes 환경에서 Secrets Values를 처리하고 이를 SpringBoot Application에서 적용하는 방법에 대해 다뤄보겠습니다.

 

궁금한 부분은 댓글로 남겨주시면 아는 만큼 성심성의껏 답변해드리도록 하겠습니다.

잘 읽으셨다면 많은 공감과 구독 부탁드립니다!


먼저 Secrets Value를 처리하고 Springboot에 적용하기 이전에 AWS 서비스로 적용할 수 있는 IRSA와 오퍼레이터인 IRSA와 External Secret Operator 대해 알아보도록 하겠습니다. 

1.  IRSA(IAM Role for ServiceAccount)

AWS에서 EKS Cluster를 생성하고, Node Group을 생성하여 워커 노드들을 구성하게 됩니다. 이 때 Cluster와 Worker Node에 맞게 IAM Role을 할당하여 사용할 수 있습니다. 따라서 Worker Node 안의 pod들은 추가적인 IAM Role의 생성 없이 Worker Node가 사용하는 IAM Role 혹은 Cluster에서 사용하는 Role에서 특정 서비스에 대한 접근이 허용되어 있는 경우에 이 role을 사용하여 접근할 수 있습니다.

 

하지만 여기서 Node 단위로 사용할 수 밖에 없어 보안적인 측면에서 지켜야 하는 Principle of Least Privilege를 어길 수 있게 됩니다. Worker Node에는 여러 서비스들이 namespace를 기준으로 구분되어 구성될 수 지만 모든 서비스가 Worker Node의 IAM Role을 사용하게 된다면 AWS 서비스에 접근이 필요 없는 서비스 마저 같은 IAM Role을 사용하기 때문에 불필요한 권한을 가지게 될 수 있습니다.. 이렇게 된다면 보안 취약점이 생기게 될 수밖에 없게 됩니다. 여기서  각 pod 단위로 role을 부여하는 IRSA를 적용하면 각 서비스로 구성된 pod가 필요한 role을 가지기 때문에 보안 취약점이 해결될 수 있을 뿐만 아니라 권한 관리를 쉽게 할 수 있게 됩니다.

 

IRSA의 적용 순서는 아래와 같습니다.

IRSA

  1. pod에서 aws sdk에서 특정 서비스(s3, kms, etc.)에 접근하고자 serviceaccount에 할당된 JWT와 IAM Role의 arn으로 STS에게 요청을 보내게 됩니다.
  2. pod로부터 요청을 받은 STS는 AWS IAM으로 임시 자격증명을 줄 수 있는지 검증 요청을 하게 됩니다.
  3. IAM은 IAM OIDC IdP와 통신하고, pod에 할당된 serviceaccount에 IAM Role 정보가 잘 할당 되어 있는지 검증 후 IAM에게 확인 되었다는 응답줍니다.
  4. IAM은 STS에게 권한을 줘도 된다고 응답을 주게 되고 pod의 AWS SDK에게 임시 자격증명을 전달합니다.
  5. 최종적으로 pod의 어플리케이션에서는 특정 서비스에 접근해서 기능을 사용할 수 있게 됩니다.

Terraform 혹은 CDK, 콘솔 등을 활용해 IAM Role을 만들었다는 전제하에 Kubernetes 리소스로 적용할 때는 아래와 같이 적용할 수 있습니다. 

먼저 serviceaccount object를 생성하고, 이를 deployment에 spec 하위의 serviecaccount에 적용하면 deployment로 기동된 pod에 IRSA를 적용할 수 있습니다.

2.  External-Secrets Operator(ESO)

많은 레퍼런스에서 EKS환경에 Parameter Store 혹은 Secrets Manager를 적용하기 위해서는 Kubernetes-External-Secrets(KES)를 많이 예시로 들고 있습니다. 하지만 KES는 22년도 초에 Deprecated되었으며 현재는 External Secrets Operator(ESO)를 사용하도록 권장하고 있습니다.

ClusterSecretStore

ESO의 동작 순서는 아래와 같습니다.

  • ESO를 Helm 혹은 직접 설치하고 Cluster 별 혹은 Namespace 별로 SecretStore라는 Object를 생성
  • 해당 서비스에서 secrets value를 가져올 수 있는 serviceaccount 혹은 iam user credential을 사용
  • External Secret을 생성할 때 참조할 Obejct로서 secret values가 저장된 서비스(AWS Secrets Manager, AWS Parameter store)을 지정
  • External Secrets obbject를 사용하여 앞서 만든 SecretStore를 참조하여 값을 가져와 secrets object를 생성

ESO를 적용한 yaml은 아래와 같습니다. (ESO를 설치할 때 이미 test-sa라는 이름의 serviceaccount가 test-ns 적용되었다는 전제로 설명합니다.)

위와 같이 yaml을 적용하면 Cluster 전역으로 사용할 수 있는 ClusterSecretStore와 특정 namespace(test-ns)에서 사용하는 secrets을 생성할 수 있습니다.

 

자, 이제 EKS 환경에서 Secrets Value를 처리할 때 사용할 수 있는 IRSA와 External Secret Operator(ESO)를 알아봤습니다. Springboot 혹은 Application에 어떻게 적용할지도 한번 알아보도록 하겠습니다.

3.  EKS에서 Springboot에 AWS SecretsManager를 적용하려면 어떻게 해야할까?

앞에서 설명드린 IRSAExternal Secrets Operator(ESO)를 제대로 이해하셨다면 적용하는 방법이 다양하게 생각나실 수 있습니다. 크게 2가지 방법을 떠올려 볼 수 있습니다.

 

각 방법에 대해서 순서대로 생각해보도록 하겠습니다.

 

1. Serviceaccount를 적용해서 Pod에서 바로 SecretsManager에 접근하는 방법

이 방법은 앞선 글인 EC2 기준의 방법과 동일하게 적용할 수 있습니다.

바뀐 부분은 Jar 파일이 Docker Image가 된 것이고, IAM Role을 적용하는 부분이 serviceaccount로 적용되는 부분만 바뀐 것으로 생각하시면 됩니다. 

즉, 위에서 설명드린 IRSA를 적용하고 EC2와 동일한 방식으로 개발을 한 후 Docker image를 생성한다면 application에서 바로 secrets manager에 접근해서 secret value를 가져오고 kms:decrypt 권한이 있으면 이 값을 복호화 하여 사용할 수 있게 됩니다.

 

2. External Secrets을 이용해 Secret Object를 만들고 이 값을 env로 주입해주는 방법

External Secrets을 이용해서 Secret Object를 만든 뒤, Deployment의 env 부분에 적어주는 방식입니다.

valueFrome으로 secret을 참조하여 특정 property에 해당하는 값을 사용할 수 있게 됩니다.

이 방식을 적용하면 application에서 secrets manager나 parameter store로 접근할 필요가 없어지게 되고, deployment에 IRSA를 적용하지 않아도 됩니다.

 

단점으로는 env로 주입을 하게 되면 pod의 내부에서 env 명령어를 쳐보면 secret value들이 보이게 됩니다. pod로의 접근 경로를 완벽하게 제어하지 못한다면 이 부분이 좀 치명적인 단점이라고 생각됩니다.

 

지금까지 1~3부까지 Springboot에 secrets Value를 처리하는 방법을 알아봤습니다. 

요즘 해킹과 관련된 사고가 세계적으로 일어나고 있습니다. 앞선 글이나 이번 글처럼 어렵지 않은 코드 수준이나 인프라 수준에서 적용할 수 있는 보안을 반드시 적용해서 서비스를 개발하고 운영하는데 있어서 큰 사고가 안나셨으면 좋겠습니다.

 

2023년도 첫글로 이만 마치도록 하겠습니다. 이번 년도에도 다양한 글을 올려보도록 노력하겠습니다. :)

 

궁금한 부분은 댓글로 남겨주시면 아는 만큼 성심성의껏 답변해드리도록 하겠습니다.

잘 읽으셨다면 많은 공감과 구독 부탁드립니다!

 

Reference

Kubernetes External Secrets

https://github.com/external-secrets/kubernetes-external-secrets

 

GitHub - external-secrets/kubernetes-external-secrets: Integrate external secret management systems with Kubernetes

Integrate external secret management systems with Kubernetes - GitHub - external-secrets/kubernetes-external-secrets: Integrate external secret management systems with Kubernetes

github.com

External Secrets Operator

https://external-secrets.io/v0.7.2/

 

Introduction - External Secrets Operator

Introduction External Secrets Operator is a Kubernetes operator that integrates external secret management systems like AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, and many more. The operator re

external-secrets.io

IRSA(IAM Role for Service Account)

https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html

 

IAM roles for service accounts - Amazon EKS

IAM roles for service accounts Applications in a pod's containers can use an AWS SDK or the AWS CLI to make API requests to AWS services using AWS Identity and Access Management (IAM) permissions. Applications must sign their AWS API requests with AWS cred

docs.aws.amazon.com