[아마존 EC2 01] 아마존 EC2 접속 패턴 살펴보기
EC2 인스턴스를 구축해보고, 맥OS과 윈도우 환경에서의 접속 방법까지 알아보았습니다. 하지만 EC2 인스턴스를 퍼블릭 환경에 배치하고 인터넷에 노출시키면 보안 문제가 발생할 수 있습니다. 이럴 때 EC2 인스턴스 배치 방법에 따라 접속 방법이 달라지게 되는데 , EC2 인스턴스 배치에 따른 다양한 접속 패턴을 알아보겠습니다.
1. 인터넷을 통한 EC2 인스턴스 접속
조금 전 맥OS과 윈도우에서 시도했던 접속 방법은 다음 이미지와 같습니다.
터미널 혹은 테라텀을 이용해서 인터넷을 통해 EC2 인스턴스로 접근합니다. 이외에도 EC2 Instance Connect를 이용하여 접속할 수도 있습니다.
01 단계 ➊ EC2 인스턴스 연결 화면에서 [EC2 인스턴스 연결]을 클릭합니다. ➋ [퍼블릭 IP를 사용하여 연결]을 선택하고 [연결]을 클릭하여 접속을 시도합니다.
해당 연결 방법을 통해 AWS 관리 콘솔에서 키 페어 없이 EC2 인스턴스에 접속할 수 있습니다. 별도로 키 페어를 사용할 필요가 없어 편리해보이지만, EC2 인스턴스에 퍼블릭 IP 주소가 할당되어 있어야 하며, 반드시 EC2 인스턴스가 퍼블릭 서브넷에 배치되어 있어야 합니다. 인터넷을 통한 접속 방법은 가장 심플한 접속 방법이지만 EC2 인스턴스를 인터넷에 노출시키고 있기 때문에 권장 방법은 아닙니다.
[퍼블릭 IP를 사용하여 연결] 기능은 과거에는 [EC2 Instance Connect]라는 이름으로 불렸으며, 현업에서는 여전히 이 명칭으로 자주 사용됩니다.
2. EC2 인스턴스 연결 엔드포인트 이용
이어서 소개할 방법은 EIC(EC2 Instance Connect Endpoint)를 활용한 접속 방법입니다. EIC는 2023년 6월 공개된 엔드포인트 서비스로 인터넷 게이트웨이, NAT 게이트웨이 없이 EC2 인스턴스로 접속할 수 있는 서비스입니다. EIC 사용에 대한 추가 비용은 없으며 표준 데이터 전송 요금만 적용됩니다.
▼EC2 인스턴스 연결 엔드포인트 접속 예
01 단계 EC2 인스턴스 연결 엔드포인트를 생성하는 클라우드포메이션 yml 파일은 다음과 같습니다.
```EC2 인스턴스 연결 엔드포인트을 생성하는 클라우드포메이션 yml 파일
파일 이름 : VPC.yml, Security_Group.yml, EC2.yml
클라우드포메이션 스택 생성 순서 : VPC.yml → Security_Group.yml → EC2.yml
```
EC2 인스턴스를 생성하는 클라우드포메이션 전체 코드는 깃허브 리포지터리에서 [chapter4] → [EC2] → [chapter4.4.2-Create-EIC] 폴더에서 확인할 수 있습니다.
클라우드포메이션으로 생성할 구성은 다음과 같습니다.
사용자는 인터넷 게이트웨이 혹은 NAT 게이트웨이를 통해 EC2 인스턴스로 접근하는 것이 아닌, EC2 인스턴스 연결 엔드포인트를 통해 EC2 인스턴스로 접근합니다. EIC를 이용한다면 인터넷 게이트웨이와 NAT 게이트웨이 생성은 불필요하지만 외부로의 접근이 완전히 차단된 상황이기 때문에 yum 패키지 사용 등이 필요하다면 NAT 게이트웨이를 생성해야 합니다. 이런 이유로 NAT 게이트웨이를 함께 배치하거나, 더 이상 yum 패키지 사용이 불필요하다면 생성한 NAT 게이트웨이를 제거하여, 비용 문제를 해결하거나 외부로의 접근을 차단할 수 있습니다.
02 단계 이번에 생성할 클라우드포메이션 스택의 경우 전체적으로 구성이 변하는 것은 없습니다. 다만, EC2 인스턴스가 퍼블릭 서브넷에서 프라이빗으로 이동되었기 때문에 더 이상 퍼블릭 IP를 할당할 필요가 없습니다.
```EC2.yml
SecurityGroupIds: # ➊
- Fn::ImportValue: !Sub ${EnvName}-ec2-sg
SubnetId: # ➋
Fn::ImportValue: !Sub ${EnvName}-web-subnet-1a
```
➊ 퍼블릭 IP를 할당하는 NetworkInterfaces의 AssociatePublicIpAddress을 사용할 필요가 있었으나, 퍼블릭 IP 할당이 불필요하게 되었으므로 NetworkInterfaces와 AssociatePublicIpAddress를 삭제하여 서브넷과 보안 그룹을 개별적으로 설정합니다. ➋ EC2 인스턴스를 프라이빗 서브넷으로 배치하기 위해 ${EnvName}-public-subnet-1a을 ${EnvName}-web-subnet-1a로 변경합니다.
03 단계 EC2 인스턴스 연결 엔드포인트에서 사용할 보안 그룹을 생성합니다.
```VPC.yml
EicSg:
Type: AWS::EC2::SecurityGroup # ➊
Properties: # ➋
GroupName: !Sub ${SystemName}-${EnvName}-sg-eic
GroupDescription: !Sub ${SystemName}-${EnvName}-sg-eic
VpcId: !Ref VPC
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
```
➊ EC2 인스턴스 연결 엔드포인트의 보안 그룹을 생성합니다. ➋ EC2 인스턴스 연결 엔드포인트의 보안 그룹은 아웃바운드로 제어하기 때문에 인바운드 규칙은 지정할 필요 없습니다. 반대로 아웃바운드0.0.0.0으로 모든 트래픽을 허용해도 상관없지만, 접속하고자 하는 특정 EC2 인스턴스의 보안 그룹만을 허용하여 범위를 좁힐 수도 있습니다.
04 단계 EC2 인스턴스 연결 엔드포인트를 생성합니다.
```VPC.yml
Eic:
Type: AWS::EC2::InstanceConnectEndpoint # ➊
Properties: # ➋
SecurityGroupIds:
- !Ref EicSg
SubnetId: !Ref WebSubnet1a
```
➊ EC2 인스턴스 연결 엔드포인트 생성을 위해 타입에는 AWS::ec2::InstanceConnectEndpoint를 입력합니다. ➋ EC2 인스턴스 연결 엔드포인트 속성을 입력합니다. 속성은 보안 그룹을 지정할 SecurityGroupIds와 서브넷 지정을 위한 SubnetId이 있습니다. 보안 그룹은 조금 전 생성한 EC2 인스턴스 연결 엔드포인트의 보안 그룹을 지정하고, 서브넷은 프라이빗 서브넷에 EIC가 생성되도록 프라이빗 서브넷을 지정합니다.
05 단계 EC2 인스턴스 연결 엔드포인트의 접속을 허용하도록 EC2 인스턴스의 보안 그룹을 수정합니다.
```Security_Group.yml
SecurityGroupIngress: # ➊
- IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId:
Fn::ImportValue: !Sub ${EnvName}-sg-eic
```
➊ 마지막으로 EC2 인스턴스의 보안 그룹을 수정합니다. 이전에는 0.0.0.0을 설정하여 모든 트래픽을 허용했지만 이번에는 EC2 인스턴스 연결 엔드포인트의 보안 그룹을 허용하여, EC2 인스턴스 연결 엔드포인트 접속만을 허용합니다.
퍼블릭과 프라이빗 서브넷 배치에 상관없이 엔드포인트는 모든 EC2 인스턴스에서 접근할 수 있습니다.
06 단계 생성한 EC2 인스턴스의 보안 그룹과 EIC의 보안 그룹을 확인할 수 있습니다.
07 단계 EIC의 아웃바운드 규칙에서 EC2 인스턴스의 보안 그룹만을 허용하여 접속을 제한할 수도 있습니다.
08 단계 마지막으로 VPC 콘솔 화면에서 엔드포인트 카테고리로 들어가, 생성된 EIC를 확인할 수 있습니다.
09 단계 ➊ [프라이빗 IP를 사용하여 연결]을 클릭합니다. ➋ 조금 전 생성한 엔드포인트를 선택합니다.
[프라이빗 IP를 사용하여 연결] 명칭은 [EC2 Instance 연결 엔드포인트]라는 이름으로 불리며, 현업에서는 여전히 이 명칭으로 자주 사용됩니다.
10 단계 ➊ 사용자 이름은 기본값을 유지합니다. 터널 기간(EC2 인스턴스에 연결할 수 있는 시간)은 최대 1시간으로 1시간이 지나면 연결이 끊어집니다. 이어서 조금 전 생성한 엔드포인트를 선택합니다. ➋ [연결]을 클릭합니다.
11 단계 EC2 인스턴스 연결 엔드포인트를 생성하여 EC2 인스턴스로의 접속이 성공적으로 확인되었습니다.
▼EC2 인스턴스 연결 엔드포인트를 통해 EC2 인스턴스에 접속에 성공한 화면 예
3. 세션 관리자 이용한 콘솔에서의 접속
이번에는 퍼블릭 서브넷에 NAT 게이트웨이를 생성하고, EC2 인스턴스에서는 세션 관리자Session Manager를 사용할 수 있는 권한을 부여합니다. 세션 관리자는 AWS 시스템 매니저 AWS Systems Manager라는 AWS 내 리소스 구성 및 변경 관리, 파라미터 중앙 집중식 관리와 같은 다양한 관리 시스템 기능이 집합된 서비스 내에서 운영되는 서비스로 EC2 인스턴스로의 접속을 도와주는 서비스입니다.
▼세션 관리자 통신 예
세션 관리자를 사용하려면 EC2 인스턴스에 권한을 부여해야 하며, 외부에서 인터넷을 통해 EC2 인스턴스에 직접 접속하는 것이 아닌, AWS 시스템 매니저의 세션 관리자를 통해 EC2 인스턴스에 안전하게 접속하는 겁니다. 세션 관리자를 사용한다면 EC2 인스턴스 내부에서 AWS 시스템 매니저와 통신할 수 있어야 합니다. 인터넷 게이트웨이를 통해 EC2 인스턴스가 인터넷에 직접 연결되어 있거나, NAT 게이트웨이를 통해 인터넷에 연결할 수 있어야 합니다. 퍼블릭 서브넷의 라우팅 테이블에는 인터넷 게이트웨이의 라우팅을 설정하고 있으며, 프라이빗 서브넷에서는 NAT 게이트웨이의 라우팅을 설정하고 있습니다.
세션 관리자를 이용하는 데 있어, 별도의 보안 그룹 설정(인바운드 규칙)은 필요 없습니다.
세션 관리자 접속을 위한 클라우드포메이션의 yml 파일은 다음과 같습니다.
```세션 관리자 접속을 위한 클라우드포메이션 yml 파일
파일 이름 : VPC.yml, IAM.yml, Security_Group.yml, EC2.yml
클라우드포메이션 스택 생성 순서 : VPC.yml → IAM.yml → Security_Group.yml → EC2.yml
```
세션 관리자 접속을 위한 클라우드포메이션 전체 코드는 깃허브 리포지터리 [chapter3] → [EC2] → [chapter4.4.3-Create-EC2-SessionManager] 폴더에서 확인할 수 있습니다.
클라우드포메이션으로 생성할 구성은 다음과 같습니다.
01 단계 세션 관리자를 사용하기 위해 IAM 역할을 생성합니다.
```IAM.yml
EC2IAMRole:
Type: AWS::IAM::Role # ➊
DeletionPolicy: Delete
Properties:
RoleName: !Sub ${SystemName}-${EnvName}-ec2-role
```
➊ IAM 역할을 생성하는 타입으로 AWS::iam::Role을 입력하고, DeletionPolicy 옵션을 지정합니다. DeletionPolicy는 클라우드포메이션으로 생성한 스택을 삭제할 때 리소스가 함께 삭제되길 원한다면 DeletionPolicy 옵션에 Delete를 입력합니다. 반대로 삭제되지 않고 유지되길 원한다면 Retaion을 입력합니다. 기본적으로 클라우드포메이션에서는 DeletionPolicy 설정이 Delete로 설정되어 있기 때문에 스택을 삭제하면 리소스도 함께 삭제됩니다.
스택 업데이트 시, 기존 리소스를 삭제 혹은 유지할지 선택할 수 있는 UpdateReplacePolicy 옵션도 있습니다.
02 단계 세션관리자를 사용하기 위한 정책을 IAM 역할에 추가합니다.
```IAM.yml
AssumeRolePolicyDocument: # ➊
Version: “2012-10-17”
Statement:
- Effect: “Allow”
Principal:
Service:
- “ec2.amazonaws.com”
Action:
- “sts:AssumeRole”
Path: “/”
ManagedPolicyArns: # ➋
- "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
```
➊ IAM 역할에 추가할 정책을 설정합니다. ➋ 정책은 AWS 관리형 정책으로 세션 관리자 접속을 도와주는 AmazonSSMManagedInstanceCore 정책을 추가합니다.
03 단계 EC2 인스턴스에 세션 관리자를 통한 접속 권한을 부여하기 위해 IAM 역할을 생성했다면, 이를 EC2 인스턴스에 연결할 IAM 인스턴스 프로파일을 설정합니다.
```IAM.yml
Type: AWS::IAM::InstanceProfile # ➊
Properties:
InstanceProfileName: !Sub ${SystemName}-${EnvName}-ec2-role
Path: "/"
Roles:
- Ref: EC2IAMRole
```
➊ EC2 인스턴스에 IAM 역할을 추가한다면 IAM 인스턴스 프로파일을 생성해야 합니다. 인스턴스 프로파일은 EC2 인스턴스에 IAM 역할을 전달하는 역할을 수행합니다. AWS 관리 콘솔에서 생성할 때 자동으로 IAM 역할과 같은 이름으로 인스턴스 프로파일이 생성되기 때문에 인스턴스 프로파일을 수동으로 생성할 필요 없이 바로 EC2 인스턴스에 IAM 역할을 추가할 수 있습니다. 하지만 클라우드포메이션에서는 IAM 역할을 생성해도, 인스턴스 프로파일이 자동으로 생성되지 않기 때문에 수동으로 생성할 필요가 있습니다.
04 단계 EC2 인스턴스에 IAM 역할을 추가하여 세션 관리자를 활성화합니다.
```EC2.yml
IamInstanceProfile: # ➊
Fn::ImportValue: !Sub ${EnvName}-ec2-role
```
➊ EC2 인스턴스에 생성한 IAM 역할을 추가합니다.
05 단계 IAM 콘솔 화면에서 역할 카테고리로 들어오면 생성된 IAM 역할을 확인할 수 있습니다.
06 단계 세션 관리자 접속을 위해 IAM 역할에 AmazonSSMManagedInstanceCore 정책이 추가되어 있습니다.
07 단계 EC2 인스턴스에 추가한 IAM 역할을 확인하려면 EC2 인스턴스 콘솔 화면으로 진입합니다. ➊ 이어서 [작업]을 클릭하고 ➋ [보안]을 클릭합니다. ➌ 마지막으로 [IAM 역할 수정]을 클릭하여, EC2 인스턴스에 추가한 IAM 역할을 확인하거나 수정할 수 있습니다.
08 단계 EC2 인스턴스에 생성한 IAM 역할이 추가되어 있습니다.
09 단계 ➊ 인스턴스 연결에서[세션 관리자]를 클릭합니다. ➋ [연결]을 클릭합니다.
10 단계 세션 관리자를 통해 성공적으로 접속된 것을 확인할 수 있습니다.
▼세션 관리자를 통해 EC2 인스턴스에 접속에 성공한 화면 예
4. 세션 관리자 이용한 포트 포워딩 접속
인터넷에서 접속을 시도하는 패턴을 제외하고는 AWS 관리 콘솔을 이용해 접속할 수밖에 없었습니다. 하지만 포트 포워딩을 이용한다면, AWS 관리 콘솔에 로그인할 필요 없이 로컬 PC에서 EC2 인스턴스로 접속할 수 있습니다.
▼세션 관리자 이용한 포트 포워딩 접속 예
로컬 PC에서 포트 포워딩 세션을 생성하려면 AWS CLI를 이용해야 합니다. AWS CLI는 [03.2.3.2 AWS CLI 환경 구성]에서 다운로드 방법을 소개하고 있습니다. AWS CLI를 이용하여 세션 관리자 포트 포워딩 세션을 생성하면 로컬 PC와 AWS를 이어주는 세션 관리자 터널이 생성되며 로컬 PC에서 EC2 인스턴스로 안전한 통신을 활성화할 수 있습니다. 포트 포워딩 접속을 하기에 앞서 [03.3.4.3 세션 관리자 이용한 콘솔에서의 접속]을 통해 세션 관리자가 구성되어 있다는 가정하에 포트 포워딩을 접속을 실시하겠습니다.
01 단계 포트 포워딩 세션을 생성하기 위해 터미널 혹은 파워셸을 열어서 자격증명을 호출합니다.
▼자격증명 호출 명령어
```
aws sts get-caller-identity # ➊
```
➊ 자격증명을 호출합니다.
02 단계 AWS CLI를 이용하여 세션을 생성하고 포트 포워딩을 실시합니다.
▼세션 생성 및 포트 포워딩 실시
```
// ➊ 세션 생성
aws ssm start-session --target EC2인스턴스ID --document-name AWS-StartPortForwardingSession --parameters “portNumber=22,localPortNumber=8080”
// ➋ 세션 시작
Starting session with SessionId: botocore-session-xxxxxxx
Port 8080 opened for sessionId botocore-session-xxxxxxx
Waiting for connections...
```
➊ 터미널 또는 파워셸에서 aws ssm start-session 명령어로 포트 포워딩을 위한 세션을 생성합니다. –target 옵션으로는 접속하고자 하는 EC2 인스턴스의 ID를 입력하고, portNumber에는 EC2 인스턴스 접속 시 사용하는 포트 번호(리눅스는 22번, 윈도우는 3389번)을 지정합니다. 마지막으로 로컬 PC에서 사용할 포트 번호를 지정합니다. ➋ 세션을 생성하면 세션 아이디를 확인할 수 있으며, 연결 대기 중이라는 문구를 확인할 수 있습니다.
맥OS에서 접속하는 방법은 ‘03 단계’부터 윈도우에서 접속하는 방법은 ‘05 단계’부터 확인할 수 있습니다.
03 단계 맥OS에서 접속을 시도할 때는 새로운 터미널 창을 열고, 이전 SSH 접속 명령어와는 달리 EC2 인스턴스의 IP 대신 localhost를 사용하며, -p 옵션을 사용하여 방금 전에 지정한 포트 번호를 명시합니다.
▼SSH 접속 시도
```
ssh -i “gr-product-ec2-key.pem” ec2-user@localhost -p 8080 # ➊
```
➊ 세션이 시작됐다면, ssh 접속 명령어로 접속을 시도합니다.
04 단계 맥OS 환경에서 로컬 PC로 대상 EC2 인스턴스에 성공적으로 접속할 수 있습니다.
▼포트 포워딩을 통해 EC2 인스턴스에 접속에 성공한 화면 예
05 단계 맥OS에서는 터미널을 이용해 곧바로 접속할 수 있었지만, 윈도우는 테라텀을 이용해야 합니다. ➊ 호스트에는 [localhost], 포트에는 8080 포트 번호를 입력합니다. ➋ [확인]을 클릭합니다.
06 단계 ➌ 사용자 이름을 입력합니다. EC2 리눅스 환경의 기본 이름은 ec2-user입니다. ➍ 접속에 필요한 키 페어를 선택합니다. ➎ [확인]을 클릭합니다.
윈도우 환경에서 로컬 PC로 대상 EC2 인스턴스에 성공적으로 접속할 수 있습니다. 지금까지 아마존 EC2를 구성하는 옵션(인스턴스 유형, 스토리지 옵션, 보안 그룹, 키 페어)과 아마존 EC2를 어떻게 구축하고, 접속하는지에 대한 패턴 또한 알아보았습니다.
