AWS SSM으로 Private Subnet EC2 접근하기
이번 글에서는 Amazon EC2 Systems Manager (SSM)를 활용하여 프라이빗 서브넷(Private Subnet)에 구축된 EC2 인스턴스에 접근해보도록 하겠다.
1. 왜 AWS SSM을 활용해서 접근해야 하는가?
Private Subnet에 구축된 EC2 인스턴스는 퍼블릭 IP주소가 없고 프라이빗 IP주소만 가지고 있다. 그렇기 때문에 외부에서는 해당 EC2 인스턴스로 접근할 수가 없다. 프라이빗 IP주소만 가지고 있는 EC2 인스턴스에 접근하기 위해서는 1)바스티온 서버를 통해 접근하거나 2)AWS SSM 을 통해 접근 해야한다.
바스티온 서버를 통해 접근하는 방법은 프라이빗 서브넷 위의 EC2 인스턴스와 동일한 VPC의 퍼블릭 서브넷에 바스티온 서버를 구축한 후 SSH를 통해서 EC2 인스턴스로 접근하는 방법이다. 바스티온 서버를 통해서 접근하게 되면 SSH접근을 위한 RSA 키페어 파일(.pem) 등을 바스티온 서버에서 관리해야 하고, 여러 서버에서 워커 노드 서버로 접근하려고 한다면 여러 서버에서 RSA 키페어 파일을 관리해야 하기 때문에 보안상으로 문제가 될 수 있다. 또한 VPC 외부에서 프라이빗 서브넷에 접근하기 위해서는 바스티온 서버를 경유해야 한다.
하지만 AWS SSM을 통해서 EC2 인스턴스에 접근하게 되면 RSA 키페어 파일 없이 접근이 가능하기 때문에 좀 더 수월하게 EC2 인스턴스로 접근할 수 있다. 두 방법 중 좀 더 알맞은 방법을 활용하면 되지만 이번 글에서는 AWS SSM을 통해서 EC2 인스턴스에 접근해 볼 것이다.
2. AWS SSM을 통한 Private Subnet 접근
이번 실습은 아래 순서로 진행될 것이다.
0. (사전조건)IAM 역할이 연결되지 않은 EC2 인스턴스를 퍼블릭 서브넷에 1개, 프라이빗 서브넷에 1개 생성
1. 퍼블릭 서브넷에 생성한 EC2 인스턴스에 Session Manager Plugin 설치
2. 퍼블릭 서브넷에 셍성한 EC2 인스턴스에 IAM 역할 부여(ssm:StartSession, ssm:TerminateSession, AmazonSSMManagedInstanceCore)
3. 프라이빗 서브넷에 생성한 EC2 인스턴스에 System Manager Agent (SSM Agent) 설치
4. 프라이빗 서브넷에 생성한 EC2 인스턴스에 IAM 역할 부여(AmazonSSMManagedInstanceCore)
2-1. 퍼블릭 서브넷에 생성한 EC2 인스턴스에 Session Manager Plugin 설치
우선 퍼블릭 서브넷에 EC2 인스턴스 1개를 만들고, 프라이빗 서브넷에 EC2 인스턴스를 한개 만들자.
그리고 퍼블릭 서브넷에 구축한 EC2 인스턴스에 Session Manager Plugin 을 설치해보도록 하자.
$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm"
$ sudo yum install -y session-manager-plugin.rpm
설치가 완료되었으면 Session Manager Plugin을 통해서 프라이빗 EC2에 접속해 보도록 하자.
Session Manager Plugin를 통해서 프라이빗 EC2에 접속하는 명령어는 다음과 같다.
$ aws ssm start-session --target [접속할 EC2 인스턴스의 인스턴스ID] --region [접속할 EC2 인스턴스가 있는 리전]
그럼 프라이빗 EC2 인스턴스에 접속해보도록 하자.
$ aws ssm start-session --target i-0663e5a5cfe2774d7 --region ap-northeast-2
Unable to locate credentials. You can configure credentials by running "aws configure".
위와 같이 Unable to locate credentials 에러가 발생하게 된다. aws configure를 통해서 계정정보 설정을 하지 않았다는 에러메시지인데, ssm:StartSession 과 ssm:TerminateSession 역할을 가진 계정정보를 설정하거나, EC2 인스턴스의 IAM 역할에 ssm:StartSession 과 ssm:TerminateSession 역할을 연결해주면 해결된다. 해당 작업은 2-2에서 진행해보도록 하자.
2-2. 퍼블릭 서브넷에 생성한 EC2 인스턴스에 IAM 역할 부여(ssm:StartSession, ssm:TerminateSession, AmazonSSMManagedInstanceCore)
퍼블릭 서브넷의 EC2 인스턴스에 IAM 역할을 부여해보자.
우선 새로운 IAM 역할을 생성한다. 이 때 해당 역할에는 아무런 정책도 연결하지 않는다.
역할 생성을 완료한 후, [인라인 정책 추가] -> [JSON]을 선택한 후 정책을 추가해준다.
정책은 아래와 같이 입력한다. 여기서 Resource에는 arn:aws:ec2:[리전명]:[AWS 계정]:instance/[접근할 EC2 인스턴스 ID]를 입력한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:ap-northeast-2:003144002222:instance/i-0d3465cdf4815c6dd"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession"
],
"Resource": "arn:aws:ssm:*:*:session/${aws:username}-*"
}
]
}
그리고 퍼블릭 EC2 인스턴스의 [인스턴스 설정] -> [IAM 역할 수정]으로 이동한 후 방금 전 생성한 IAM역할을 등록해준다.
그리고 접속을 수행해보자.
$ aws ssm start-session --target i-00fb435a11a39a76b --region ap-northeast-2
An error occurred (TargetNotConnected) when calling the StartSession operation: i-00fb435a11a39a76b is not connected.
에러 메시지가 바뀌었지만 여전히 프라이빗 서브넷에 구축된 EC2 인스턴스에는 접속을 못하고 TargetNotConnected 에러가 발생하고 있다. 해당 에러를 해결하기 위해서는 소스(퍼블릭 EC2 인스턴스)가 아닌 타겟(프라이빗 EC2 인스턴스)에 추가 작업을 해줘야 한다. 해당 작업은 2-3에서 진행해보자.
2-3. 프라이빗 EC2 인스턴스에 System Manager Agent (SSM Agent)설치
소스 서버(접속을 시도하는 서버)에 Session Manager Plugin이 설치되어 있어야 한다면, 타겟 서버(접속을 하려는 서버)에는 System Manager Agent가 설치되어 있어야 한다. 하지만 Amazon Linux 2 AMI로 생성된 EC2 인스턴스에는 기본적으로 System Manager Agent가 설치되어 있기 때문에 별도로 설치할 필요는 없다(하지만 만약 EKS 워커 노드에 접속을 하고 싶다면 EKS의 워커 노드에는 System Manager Agent가 설치되어 있지 않기 때문에 별도로 설치해줘야 한다).
설치를 확인하는 방법은 해당 서버에 접속해서 아래 명령어를 통해 확인할 수 있다.
$ sudo systemctl status amazon-ssm-agent
2-4. 프라이빗 서브넷에 구축한 EC2 인스턴스에 IAM 권한 부여(AmazonSSMManagedInstanceCore)
프라이빗 서브넷에 구축한 EC2 인스턴스에 System Manager Agent가 설치되었다. 하지만 EC2 인스턴스가 System Manager에 접근하려면 AmazonSSMManagedInstanceCore라는 IAM 권한이 추가적으로 필요하다.
IAM으로 이동하여 IAM 신규 역할을 생성한다. 그리고 AmazonSSMManagedInstanceCore 권한을 연결시킨다.
다음으로 [인스턴스 설정] -> [IAM 역할 수정]으로 이동하여 프라이빗 EC2 인스턴스에 해당 IAM 역할을 연결한 후 해당 인스턴스를 재부팅하자.
그리고 약 1분정도 기다린 후 프라이빗 EC2 인스턴스에 연결해 보면 연결이 정상적으로 수행되는 것을 확인할 수 있다.
$ aws ssm start-session --target i-00fb435a11a39a76b --region ap-northeast-2
Starting session with SessionId: i-04cccba7e67085582-0c68f56ca40f2bcea
sh-4.2$
3. 기타 에러 건
aws ssm start-session 수행 시 AccessDeniedException 에러 발생 :
EC2 인스턴스에 aws configure 명령어를 통해 IAM 유저가 설정되어 있는데 해당 유저에 ssm:StartSession 권한이 없는 경우에AccessDeniedException 에러가 발생했다.
$ aws ssm start-session --target i-00fb435a11a39a76b --region ap-northeast-2
An error occurred (AccessDeniedException) when calling the StartSession operation: User: arn:aws:iam::003144002265:user/eks-cluster is not authorized to perform: ssm:StartSession on resource: arn:aws:ec2:ap-northeast-2:003144002265:instance/i-00fb435a11a39a76b
이럴 경우 유저의 IAM 인라인 정책에 ssm:StartSession 역할을 추가해 주던가, 혹은 설정된 aws configure를 삭제하고, ssm:StartSession 권한이 있는 역할이나 유저로 EC2 인스턴스를 재설정하면 정상 접속되었다.
aws configure 설정을 삭제하는 방법은 해당 유저의 홈 디렉토리에서 .aws 디렉토리를 삭제해주면 된다.
참고
sarc.io/index.php/aws/1973-aws-systems-manager-session-manager
aws.amazon.com/ko/premiumsupport/knowledge-center/install-ssm-agent-ec2-linux/
musma.github.io/2019/11/29/about-aws-ssm.html