졸작 프로젝트 진행하면서 aws를 사용하여 배포중인데,
보안을 위해 private subnet에 web application server를 구축하고자 한다.
따라서 미리 vpc구조를 구축해보는 실습을 해 보고자 한다.
0. 아키텍쳐
아키텍쳐에 존재하는 public subnet의 EC2는 public subnet이 양방향 통신을 할 수 있다는 점을 표현하고, 추후 서비스에서 nginx를 사용해 리버스 프록시를 구현할 것이기 때문에 넣었다.
session manager를 사용할 것이므로 Bastion Host로도 쓰지 않을 것이기 때문에
해당 실습에서는 public 서브넷에 ec2를 만들지 않을 것이다.
1. VPC 생성
2. subnet 생성
- 2-1 생성한 vpc 를 할당
- 2-2 public subnet 설정
10.0.1.0/24 로 서브넷 할당
ap-northeast-2a 로 가용영역 설정.
- 2-3 private subnet 생성
10.0.2.0/24 로 서브넷 할당
ap-northeast-2a 로 가용영역 설정.
서브넷이 생성된 모습
3. internet gateway 생성
Public subnet은 internet gateway에 라우팅 되는 네트워크 이고,
Private subnet은 internet gateway에 직접 라우팅 되어있지 않고, NAT 게이트웨이를 통해서만 인터넷에 간접적으로 접근 가능하도록 하여 보안을 강화 할 수 있다.
- 3-1생성
- 3-2 vpc 연결
4. NAT gateway 생성
NAT gateway 는 인터넷에 연결되어야 하고, 고정된 공인 ip주소를 필요로 하기 때문에 Elastic ip를 할당해야 한다, 따라서 public subnet에 생성한다.
번역이 탄력적 IP 할당이라고 되어 있어서 뜻을 혼동 할 수 있는데,
오히려 탄력적 IP주소를 할당하지 않으면 동적 공인 IP 주소를 할당받는다.
동적 공인 IP 주소는 EC2 인스턴스가 재부팅되거나 중지되고 다시 시작되면 변경된다.
따라서 고정적인 공인 IP 주소를 할당 받고 싶다면, 탄력적 ip를 선택해야 한다.
인스턴스가 다시 시작될 때 새로운 공인 IP 주소가 할당되기 때문에, 이전의 IP 주소를 계속 사용할 수 없다.
따라서
IP 주소 자체가 변한다는 의미가 아니라, IP 주소의 할당과 재할당이 유연하다는 의미로 생각해야한다.
5. 라우팅 설정
- 5-1라우팅 테이블 생성
private subnet 용 라우팅 테이블과 public subnet용 라우팅 테이블 생성
라우팅 테이블에 subnet을 할당
[서브넷 연결 편집] 을 통해 할당한다.
현재 사진은 할당된 상태,
- 5-2 라우팅 설정
- 5-2-1 public subnet - internet gateway 연결
퍼블릭 서브넷은 인터넷 게이트웨이(IGW) 와 연결되어 있어, 인터넷과 양방향 통신이 필요할 때 사용된다. 퍼블릭 서브넷의 인스턴스는 외부로 데이터를 전송할 수 있으며 외부에서도 접근 가능하다.
따라서 이를 위한 라우팅 설정을 진행한다.
퍼블릭 서브넷이 연결된 라우팅 테이블 선택
[라우팅 편집] 선택
[라우팅 추가]
0.0.0.0/0 (모든 주소) - > 생성했던 인터넷 게이트웨이 연결
[변경사항 저장]
이를 통해 현재 라우팅 테이블에 할당 했던 서브넷이 공용 서브넷으로 설정된 것을 의미한다. (인터넷 게이트웨이와 연결)
- 5-2-1 private subnet - nat gateway 연결
프라이빗 서브넷은 NAT 게이트웨이를 사용하여 인터넷과의 직접적인 양방향 통신은 불가능하지만, 외부로 나가는 트래픽만을 허용하여 보안을 강화한다. 프라이빗 서브넷의 인스턴스는 외부에서 직접 접근할 수 없고, 요청에 대한 외부 응답만 NAT 테이블에 매핑되어 들어올 수 있다. 필요에 따라 외부로 나가는 아웃바운드 요청만 처리한다.
프라이빗 서브넷과 연결된 라우팅 테이블 선택,
[라우팅 편집] 선택
[라우팅 추가]
0.0.0.0/0 (모든 주소) - > 생성했던 nat 게이트웨이 연결
[변경사항 저장]
이를 통해 현재 라우팅 테이블에 할당 했던 서브넷이 비공개 서브넷으로 설정된 것을 의미한다.
(nat 게이트웨이와 연결함으로써 인터넷으로 나갈 수 있고, 인터넷 게이트웨이를 직접 연결하지 않음으로써 외부에서 먼저 들어오는 traffic은 private 서브넷으로는 접근 불가)
- 5-3 VPC 리소스맵 확인
vpc 리소스 맵을 통하여 의도대로 public subnet은 인터넷 게이트웨이로 연결되어 양방향 통신이 가능하고,
private 서브넷은 NAT게이트웨이로 연결되어 요청에 대한 응답이 아닌 인바운드 트래픽을 거부하게 된다.
따라서 단방향 통신만 가능하게 된다.
6. EC2 생성
private subnet의 ec2생성
- 이름 생성
- OS 이미지 선택
- 인스턴스 유형 선택
프리티어로 사용 가능한 t2.micro 선택
- 키 페어 생성(선택) 및 키 페어 설정
새 키 페어 생성 또는 기존 키 페어 선택
- 네트워크 설정
vpc 할당 및 서브넷 설정
private에 할당할 ec2인스턴스 이므로 private 서브넷으로 설정하고 퍼블릭IP를 할당하지 않는다.
NAT게이트웨이에 연결해서 아웃바운드 트래픽의 요청에대한 응답만 받을 수 있도록 했으므로
어떤 인바운드 보안 그룹 규칙도 설정하지 않는다.
생성 완료
7. SSM Session Manager 사용을 위한 설정
private subnet에 존재하는 ec2 인스턴스는 외부에서 직접 들어오는 인바운드 트래픽을 차단하기 때문에,
public subnet에 Bastion host를 생성하여 ssh 접속 후 private subnet에 존재하는 ec2로 접속하는 번거로운 과정을 거쳐야 한다.
따라서 이 과정을 간편하게 해 줄 AWS Session Manager 와 vpc endpoint를 사용한다.
EC2 인스턴스에 설치된 SSM 에이전트는 AWS Systems Manager와 통신하여 명령을 실행하거나 세션을 관리한다.
내가 설치한 ec2 인스턴스의 amazone linux 버전은 SSM 에이전트를 기본적으로 가지고 있다.
혹여나 SSM에이전트가 없어도 수동 설치하면 된다.
vpc endpoint를 통해 session manager를 private subnet에 숨겨져 있는 ec2인스턴스에 안전하게 접근할 수 있다.
vpc endpoint 는 AWS 서비스에 대한 프라이빗 연결을 제공한다. 트래픽이 인터넷을 경유하지 않고 AWS 네트워크 내에서 처리된다.
또는
vpc endpoint의 요금 부과 정책이 부담된다면,
private ec2의 https 아웃바운드 트래픽을 허용한다.
nat게이트웨이는 내부의 요청에 대한 외부 응답은 NAT 테이블을 통해 접근 가능하기 때문이다.
이를 통해 session manager로 ec2에 접근할 수 있다.
이 방식에 대해서는 포스팅 마지막에 설명하겠다.
이렇게 편한 방법이 있는데 굳이 쓰지 않을 이유가 없다.
- 7-1 Session Manager 사용을 위한 EC2용 IAM Role 생성
[역할 생성] 클릭
ssm 을 ec2에서 사용하기 위해
[AWS 서비스] 선택
[EC2]
[EC2 Role for AWS System Manager] 선택
권한 추가
이름 설정 후 생성
- 7-2 EC2에 ssm 사용을 위해 생성했던 IAM Role 적용
아직 연결되지는 않는 모습
엔드포인트를 설정해주지 않았기 때문이다.
8. VPC Endpoint 생성
엔드포인트에서 사용하기 위한 보안 그룹을 생성한다.
vpc의 엔드포인트를 설정하기 전에 DNS 호스트 이름 활성화 옵션을 켜준다.
- com.amazonaws.[region].ssm
- com.amazonaws.[region].ssmmessages
- com.amazonaws.[region].ec2messages
3가지 서비스 선택 하여 각각 생성
프라이빗 서브넷에 설정
전체 액세스로 설정
사용 가능 상태가 되기 전 까지 기다려준다.
9. 인스턴스에 Session Manager로 접속
그러나 연결 오류 발생
원인을 찾아보던 중, 대상 인스턴스에 연결된 IAM 프로필에 ssmmessages:CreateDataChannel에 대한 권한이 있는지 확인하라는 말이 있어서 확인해 보았는데 존재하는걸 보니 이 문제는 아닌 듯 하다.
ping 상태를 보면 연결이 끊기는 문제가 발생하는 것 같다.
원인
우선 연결을 확인 해 보려고 vpc endpoint에 default 보안그룹을 사용했었는데,
vpc 외부 인바운드 트래픽이 차단 되는 문제였다. 이에 대해선 포스팅 하단에서 설명하겠다.
보안그룹 생성
생성한 보안 그룹 vpc endpoint 들에 할당
또는 vpc endpoint 생성 할 때 할당
연결 성공.
private ec2가 외부 인터넷과 nat를 통해서 통신을 하는지 wget으로 테스트 해보겠다.
https https://google.com으로 요청을 보냈다.
정상 동작.
Default 보안 그룹 문제
기존에 vpc endpoint에서 보안 그룹을 설정하지 않고 생성했을 때 다음과 같이 vpc endpoint의 인바운드 규칙이 설정 되어있는걸 보고 모든 트래픽을 허용했구나 라고 대충 보고 진행했었다.
자세히 보면 소스에 이 default 보안 그룹 id가 설정되어 있었다.
이는 같은 보안그룹에 속한 Source의 인바운드 트래픽만 허용한다는 것이다.
외부에서 들어오는 트래픽이나 다른 보안 그룹에서 들어오는 트래픽은 기본적으로 차단한다는 것이다.
그래서 session manager로 접속할 수 없었던 것이다.
default 보안그룹은 기본적으로 같은 보안그룹으로부터 온 요청만 허가한다는 사실을 숙지하고
앞으로 잘 확인하면서 진행해야겠다 ㅠ
VPC endpoint 대안
vpc엔드포인트의 가격이 부담된다면
ec2의 https 아웃바운드 트래픽을 허용하여
session manager 사용.
기존 vpc endpoint가 존재한다면 session manager가 AWS 내부 네트워크로 endpoint에 접근할 것이기 때문에 삭제
https (443) outbound 트래픽만 허용하는 보안그룹을 private ec2에 설정
접속이 되는 모습!