반응형
1. Target Architecture Details
1-1. Network Topology
1-2. VPC CIDR
💡VPC CIDR
- VPC 생성
- VPC: 192.168.0.0/16
- 서브넷 생성
- Azone
- Public Subnet: 192.168.10.0/24
- Nat Subnet: 192.168.110.0/24
- Private Subnet: 192.168.210.0/24
- Czone
- Public Subnet: 192.168.20.0/24
- Nat Subnet: 192.168.120.0/24
- Private Subnet: 192.168.220.0/24
- Azone
- 추가 자원 생성
- Internet Gateway
- NAT Gateway
- 라우팅 테이블 생성
- RT-Public Subnet (PublicSubnet - A/Czone 연결, 0.0.0.0/0 IGW 연결)
- RT-NAT Subnet-Azone (NatSubnet-Azone 연결, 0.0.0.0/0 NATGW Azone)
- RT-NAT Subnet-Czone (NatSubnet-Czone 연결, 0.0.0.0/0 NATGW Czone)
- RT-Private Subnet
2. Network 구성
2-1. VPC 생성 (vpc-web-3tier)
2-2. 서브넷 생성
AZone, CZone
- 각각 서브넷 3개씩 생성
subnet-web-3tier-public-Azone
Public Subnet - AZone
:192.168.10.0/24
, AZ:ap-northeast-2a
subnet-web-3tier-nat-Azone
NAT Subnet - AZone
:192.168.110.0/24
, AZ:ap-northeast-2a
subnet-web-3tier-private-Azone
Private Subnet - AZone
:192.168.210.0/24
, AZ:ap-northeast-2a
subnet-web-3tier-public-Czone
Public Subnet - CZone
:192.168.20.0/24
, AZ:ap-northeast-2c
subnet-web-3tier-nat-Czone
NAT Subnet - CZone
:192.168.120.0/24
, AZ:ap-northeast-2c
subnet-web-3tier-private-Czone
Private Subnet - CZone
:192.168.220.0/24
, AZ:ap-northeast-2c
2-3. 인터넷 게이트웨이 생성 (IG-web-3tier)
생성
VPC에 연결
2-4. NAT 게이트웨이
AZone, CZone
- 각각의 Public Subnet에 NAT Gateay 생성
- 탄력적 IP 할당하기
NAT Gateway (NAT-web-3tier-AZone)
NAT Gateway (NAT-web-3tier-CZone)
2-5. 라우팅 테이블
Public Subnet 라우팅 (RT-web-3tier-public)
- 생성 후 subnet-web-3tier-public-Azone, subnet-web-3tier-public-Czone 서브넷 연결
- 라우트 편집
- 0.0.0.0/0 → 대상: 인터넷 게이트웨이 (IG-web-3tier) 추가
NAT Subnet 라우팅 (RT-web-3tier-nat-Azone)
- 생성 후 subnet-web-3tier-nat-Azone 서브넷 연결
- 라우트 편집
- 0.0.0.0/0 → 대상: NAT 게이트웨이 (NAT-web-3tier-Azone) 추가
NAT Subnet 라우팅 (RT-web-3tier-nat-Bzone)
- 생성 후 subnet-web-3tier-nat-Czone 서브넷 연결
- 라우트 편집
- 0.0.0.0/0 → 대상: NAT 게이트웨이 (NAT-web-3tier-Czone) 추가
Private Subnet 라우팅 (RT-web-3tier-private)
- 생성 후 subnet-web-3tier-private-Azone, subnet-web-3tier-private-Czone 서브넷 연결
- 라우트 편집 X (완전 폐쇄망)
2-6. 최종 리소스맵
3. OpenVPN
3-1. OpenVPN 사용 이유
AWS Client VPN
- 사실 AWS에는 AWS Client VPN이라는 공식 VPN 서비스가 있다.
- 기업 내부 직원들이 IAM, SAML, Active Directory(AD) 등을 통해 인증이 가능하며,
- 사용자별 접근 권한을 세밀하게 제어가 가능허다.
- 하지만, 보통 AD 같은 복잡한 인증 시스템이 필요하며 비용적인 문제도 있다.
Site-to-Site
- Site-to-Site VPN은 기업 내부망(온프레미스)과 AWS VPC를 안전하게 연결하는 방식의 VPN이다.
- 기업 네트워크에서 VPN 장비가 필요하며, IPSec VPN을 지원하는 네트워크 장비 설정 필요하다..
- 구축의 어려움
OpenVPN
- 간단하게 유저 계정을 생성해서 운영할 수 있고, 상대적으로 쉽게 설치하고 유지보수할 수 있다.
- AWS 사설망을 편하게 사용할 수 있도록 있도록 도와주는 도구이다.
- → 소규모 스타트업 및 테스트 사설망 접근 구현
- 로컬 개발 시에 개발 환경에 있는 DB나 Redis에 직접 연결해서 개발할 수 있다면 아무래도 개발 생산성에 도움이 되는 건 사실이니…
실습 목적
- OpenVPN을 사용하면 내 로컬 PC가 AWS 내부 네트워크의 일부처럼 동작하며, Private Subnet 내 자원과 직접 통신할 수 있게 된다.
- 운영자가 Private Subnet의 EC2, DB 등에 접근하도록 하기 위해 OpenVPN을 사용해보자.
주의
- 현재 실습용으로 OpenVPN을 사용하지만, 접근이 편한만큼 보안적인 위험 또한 존재한다.
- 현재 빠르게 구축하기 위해 개별 사용자 인증 기능은 제외했다.
- 하지만, OpenVPN 에도 LDAP을 이용한 개별 사용자 인증이 가능하다.
- 실제 업무에서는 좀 더 안전하게 환경을 꾸리기 위해 인증 기능을 붙이는 것이 좋다.
3-2. OpenVPN Access Server 배포 (AWS Marketplace)
AWS Marketplace에서 "OpenVPN Access Server" 검색
- 인스턴스 시작 시 구독
인스턴스 설정
- 인스턴스 유형: t2.medium or t3.micro (무료 티어)
- 키 페어 생성 및 본인 꺼 쓰기
- 중요
- VPC : vpc-web-3tier
- 서브넷: subnet-web-3tier-public-Azone (192.168.10.0/24)
- 퍼블릭 IP 자동 할당 활성화
- 스토리지 설정: 기본 값 유지 (30GB)
참고
- Root 계정이 아닌 IAM 계정으로 해당 인스턴스를 생성하면 다음 에러를 마주할 수도 있다…
- Marketplace 구독 실패: An internal error has occurred.
- 권한 정책에서 다음 권한을 직접 추가해주자 : AWSMarketplaceFullAccess
OpenVPN 초기 설정 (약관동의)
- 인스턴스 접속 (콘솔)
- 첫 질문 (약관동의) : yes
- Please enter 'yes' to indicate your agreement [no]: yes
- 나머지 Enter
- 중간에 Should Client DNS traffic be routed by default : yes
- 나머지 Enter
OpenVPN 클라이언트 설치 및 연결
- OpenVPN 포털 사이트 들어가기
https://<Elastic-IP>:943/
- OpenVPN (관리자 계정)으로 로그인
- OpenVPN 클라이언트 설치
- dmg → 설치
- 나의 퍼블릭 주소와 같은 Profiles 수정
- 편의상 Save password : 아까 Password 입력
- 연결 완료
오류 해결
- 만약 OpenVPN 클라이언트 설치 후 Profiles가 없다면?
- 아래 Yourself (use-locked profile) 다운로드 후
- 좌측 메뉴 → Import Profile → 해당 파일 import
3-3. Connection 테스트
보안그룹 Inbound에 ICMP(Ping) 허용
- Ping이 가능하도록 EC2의 보안 그룹 수정
- 유형(Type): 모든 ICMP - IPv4
- 프로토콜(Protocol): ICMP
- 포트(Port Range): All
- 소스(Source): 0.0.0.0/0 (모든 네트워크에서 Ping 허용)
- ⇒ 이제 내 로컬 PC가 OpenVPN을 통해 AWS 네트워크의 일부가 되었다!
- 로컬에서 EC2 인스턴스의 private ip로 Request를 보내보자.
OpenVPN 안 켰을 때
- 당연히 로컬에서 직접 접근이 안된다.
OpenVPN 켰을 떄
- 접근 가능.
3-4. 반영된 아키텍처
4. LoadBalancer
4-1. NAT 구간에 인스턴스 올리기
- NAT Subnet에 Instance 하나 올리기
인스턴스 생성
- OS : Amazon Linux
- VPC : vpc-web-3tier
- 서브넷 : subnet-web-3tier-nat-Azone
- 퍼블릭 IP 자동 할당 : 비활성화
- 어차피 NAT로 나감
- 보안그룹 : HTTP 0.0.0.0/0 추가
- 생성 완료
4-2. 반영된 아키텍처
4-3. 대상 그룹 (Target Group) 생성
- EC2 → 로드 밸런싱 → 대상 그룹
- [대상 그룹 생성]
- 대상 유형 : 인스턴스
- 프로토콜 : HTTP, 버전 : 1
- VPC : vpc-web-3tier
- 상태검사 : Default
- 대상 추가 (Add Targets)
- 대상 그룹에 EC2 인스턴스 추가
- NAT Subnet 에 배포한 애플리케이션 서버 EC2 (EC2-web-3tier-nginx) 선택
- 포트 80 지정 후 [아래에 보류 중인 것으로 포함]
- [대상 그룹 생성]
- 대상 상태가 healthy가 되면 정상적으로 연결된 것
- 아직 애플리케이션 서버(ex. nginx)를 올리지 않았기 때문에, 초기 상태 (Initial)일 것이다.
4-4. 로드 밸런서 생성
ELB란?
- ELB(Elastic Load Balancer)는 AWS에서 제공하는 로드 밸런서 서비스
- 들어오는 트래픽을 여러 대상(Target)으로 분산하여 서버의 부하를 줄이고 가용성을 높이는 역할
- ELB에는 3가지 종류가 있다.
- ALB (Application Load Balancer) : L7 (HTTP/HTTPS) 기반
- 웹 애플리케이션 및 마이크로서비스
- NLB (Network Load Balancer) : L4 (TCP/UDP) 기반의 로드 밸런서
- 금융 시스템, VPN, 고속 네트워크 트래픽
- CLB (Classic Load Balancer, 현재 거의 사용되지 않음)
- ⇒ 즉, ALB는 L7 계층에서 HTTP 요청을 처리하는 ELB의 한 종류!
로드 밸런서 생성
- AWS 콘솔 접속
- EC2 → 로드 밸런싱 → 로드 밸런서
- [로드 밸런서 생성] 클릭
로드밸런서 설정
- 로드 밸런서 유형 선택: Application Load Balancer (ALB)
- 이름: alb-web-3tier
- 인터넷 경계, IPv4
- VPC 선택: vpc-web-3tier
- 가용 영역 선택:
- subnet-web-3tier-public-Azone (192.168.10.0/24)
- subnet-web-3tier-public-Czone (192.168.20.0/24)
- 보안 그룹(Security Group) : SG-web-3tier-nginx
리스너(Listener) 설정
- HTTP: 80
- 대상 그룹 선택: TG-web-3tier(방금 생성한 대상 그룹)
- 검토 & [생성]
4-5. 애플리케이션 서버 올리기
Private Subnet에 접근하기
- NAT Subnet에 NGINX를 올려야 하는데, 퍼블릭 서브넷에 없기 때문에 직접 접근이 불가능한 상황
1. Bastion Host (Jump Server) 사용
- 퍼블릭 서브넷에 Bastion Host (Ubuntu EC2) 배포 → 거쳐서 Private Subnet의 Nginx EC2로 SSH 접속
2. OpenVPN을 사용하여 직접 접근
- [실습 상황] 관리자 HOST PC에서 OpenVPN을 연결해놓았으니,
2번 방법으로 접근해보자. - OpenVPN을 Connection 하고, SSH 접속
- 본인 터미널 or Terminus 등 활용
ssh -i <your-key.pem> ubuntu@{EC2-web-3tier-nginx의 프라이빗 IP 주소}
- 참고
- Amazon Linux:
ec2-user
- Ubuntu:
ubuntu
- CentOS:
centos
- Debian:
admin
또는debian
- RHEL:
ec2-user
또는root
- Amazon Linux:
NGINX 설치
- 간단하게 NGINX를 올려보자.
sudo yum update -y
sudo yum install nginx -y
sudo service nginx start
4-6. 접속 테스트
ALB 헬스 체크 정상 여부 확인
로드 밸런서의 DNS로 접속 테스트
4-7. 반영된 아키텍처
4-8. 궁금증 및 동작원리
Q. 사용자 입장에서 AWS 네트워크의 입구는 어디인가?
- 사용자가 AWS 내부로 접근할 수 있는 "입구"는 인터넷 게이트웨이(IGW)이다.
- 그렇다면 왜 IGW로 보내는 것이 아니라 ALB로 보내는가?
- IGW는 단순한 "인터넷과 VPC를 연결하는 네트워크 장치 개념"일 뿐이다.
- 서브넷의 라우팅 테이블에 IGW로 향하는 경로가 있으면 해당 서브넷이 퍼블릭 서브넷이 되는 것.
- 실제로 "어떤 리소스"에 접근할지는 퍼블릭 서브넷에 배포된 ALB(또는 OpenVPN)가 결정한다.
- 즉, 사용자는 결국 퍼블릭 서브넷에 있는 리소스(OpenVPN / ALB)를 통해야만 AWS 내부와 통신 가능.
- IGW는 단순한 "인터넷과 VPC를 연결하는 네트워크 장치 개념"일 뿐이다.
- → IGW는 단순한 인터넷과 AWS 네트워크를 연결하는 통로일 뿐, 직접적으로 트래픽을 라우팅하지 않는다.
(…개념적인 오해였다.. IGW는 IP도 없는데 어디로 보낼라구…)
Q. ALB도 퍼블릭 IP가 있긴 한가? 왜 DNS로 제공될까?
- OpenVPN은 퍼블릭 IPv4 주소가 할당되어 이 주소로 접근이 가능했다.
- 다만, LB를 보면 DNS로써 주소가 제공된다.
- LB는 퍼블릭 IP가 내부적으로 있지만, 사용자가 직접 접근하지 못함
- ALB는 퍼블릭 서브넷에 배포되지만, 탄력적 IP(EIP)를 할당할 수 없음.
- AWS가 자동으로 ALB에 퍼블릭 IP를 할당하지만, 직접 노출되지 않음.
- 대신 ALB는 DNS 이름(Amazon 제공)으로만 접근 가능
- AWS가 내부적으로 ALB에 여러 개의 퍼블릭 IP를 사용하여, 장애 대응 및 다중 AZ 지원.
- [내부적으로 알아서 해줄게]
Q. Amazon Route 53을 사용한 ELB 트래픽 라우팅
- DNS 이름 옆의 “정보”를 눌러보니, 다음과 같은 참고 사항이 있다.
💡 사용자 지정 도메인을 로드 밸런서의 DNS 이름과 연결할 수 있습니다. DNS 서비스 설명서를 참조하거나, Amazon Route 53을 DNS 서비스로 사용하는 경우 ELB 로드 밸런서로 트래픽 라우팅하기를 참조하세요.
- 현재 구성 (Route 53 없이 직접 ALB DNS 사용)
- 사용자가 ALB의 DNS로 접근한다.
- 요청이 IGW를 통해 퍼블릭 서브넷의 ALB 로 들어감
- ALB가 Private Subnet의 EC2로 트래픽 전달
- AWS에서 제공하는 기본 DNS를 그대로 사용
- Route 53을 사용한 ELB 트래픽 라우팅
- 사용자가 맞춤 도메인 (https://myapp.com)을 사용하여 접근
- Route 53이 https://myapp.com 요청을 받아서 ALB의 DNS로 트래픽을 라우팅
- 이후 ALB가 Private Subnet의 EC2로 요청 전달
- ⇒ 맞춤 도메인을 사용하려면 [Route 53]를 사용!!!
Q. ALB, OpenVPN이 둘 다 비슷한 역할을 한다는데 어떻게 다를까?
- ALB와 OpenVPN은 "네트워크 트래픽을 내부로 전달하는 역할”을 하는 것은 공통점이다.
- 차이점
- ALB: HTTP(S) 요청을 Private Subnet에 있는 백엔드 EC2로 전달하는 역할
- HTTP 트래픽을 라우팅하는 목적
- OpenVPN: VPN 연결을 통해 사용자가 Private Subnet의 리소스에 접근할 수 있도록 해주는 역할
- 클라이언트는 VPN 터널을 통해 Private Subnet에 속한 것처럼 동작
- 모든 네트워크 트래픽 가능
- 클라이언트가 Private Subnet에 직접 접근 가능!
- 로드 밸런싱 기능 없음 (그냥 네트워크 연결을 해주는 역할만 함)
- ALB: HTTP(S) 요청을 Private Subnet에 있는 백엔드 EC2로 전달하는 역할
Q. 외부에서 Private Subnet의 EC2로 요청을 보낼 수 있게 해주는 건 ALB야? NAT Gateway야?
- ALB가 하는 역할
- 외부에서 Private Subnet으로 HTTP 요청을 라우팅하는 역할
- ALB는 퍼블릭 서브넷에 배치되며, IGW를 통해 외부 트래픽을 받음
- ALB는 Target Group을 통해 Private Subnet의 EC2로 요청을 전달
- 즉, HTTP 요청을 Private Subnet으로 보낼 수 있도록 해주는 역할을 함
- ⇒ HTTP 요청을 Private Subnet으로 보낼 수 있는 이유는 ALB 때문이다.
- NAT Gateway가 하는 역할
- NAT Gateway는 Private Subnet의 EC2가 외부로 나가는 트래픽을 담당
- 즉, "Private → Public" 방향의 트래픽을 처리하는 역할
- Private Subnet의 EC2가 인터넷과 통신할 수 있도록 Outbound 트래픽을 라우팅함
- ⇒ NAT Gateway는 "Private → Public" 방향의 요청을 허용하는 역할.
- ⇒ Private Subnet의 EC2가 외부 인터넷을 사용할 수 있도록 해줌
- 예를 들어, Private Subnet에 있는 EC2가 패키지 업데이트 (apt-get update 같은 것)를 하려면 NAT Gateway를 통해야 한다.
5. RDS
5-1. 서브넷 그룹
- 어떤 서브넷에 RDS 인스턴스를 생성할 것인가?
- 우리는 Private Subnet에 올릴 것임.
- vpc : vpc-web-3tier
- 서브넷 가용영역 : Azone & Czone
- 서브넷 선택: Private Subnet (AZone, CZone)
- subnet-web-3tier-private-Azone (192.168.210.0/24)
- subnet-web-3tier-private-Czone (192.168.220.0/24
- (참고)
5-2. 보안 그룹 (Security Group)
보안그룹 기본 설정
- 이름 : SG-web3-tier-db
- 설명 : ~
- vpc : vpc-web-3tier
인바운드 규칙
- Private Subnet에 RDS (MySQL) 인스턴스를 배포하는 경우, 외부 인터넷과 완전히 단절된 상태이므로 보안그룹 설정이 중요하다.
- NAT Subnet에 올라와있는 EC2가 MySQL(3306) 포트로 접근을 해야하기 때문에,
- [소스]에서 [포트]로 접근하는 [인바운드] 요청에 대해 Allow 해줘야 한다.
- [인바운드 규칙 추가]
- [포트] : MySQL(3306)
- [소스] : RDS에 접근할 리소스
- 소스 작성 방법
- 특정 Private Subnet(NAT Subnet)의 보안 그룹
- = RDS에 접근하는 EC2 인스턴스가 특정 보안그룹을 사용한다면,
해당 보안그룹을 소스로 지정
- = RDS에 접근하는 EC2 인스턴스가 특정 보안그룹을 사용한다면,
- 특정 Private Subnet(NAT Subnet)의 CIDR 블록
- = 해당 Subnet에 올라와있는 모든 인스턴스들이 접근 가능하다.
- 만약, 여러 Subnet에 있는 인스턴스에 대해 허용하고 싶다면?
- 1번과 같이 보안그룹을 소스로 지정하고
- 허용할 인스턴스들이 해당 보안그룹을 공유해서 사용하면 된다.
- 특정 Private Subnet(NAT Subnet)의 보안 그룹
- 현재는 NAT Subnet에 올라와 있는 EC2가 ‘SG-web-3tier-nginx’ 보안그룹을 가지고 있으니,
해당 보안그룹을 소스로 설정해준다.
- [생성]
5-3. 데이터베이스 생성
설정
- 방식: 표준 생성
- 엔진 옵션: MySQL
- 템플릿: 개발/테스트
- 가용성 및 내구성: 단일 인스턴스
- 식별자: db-web-3tier
- 자격 증명 설정 : 자체 관리
- ID / PW 따로 메모해두세요
- 예시)
- admin
- admin123
- 인스턴스 구성: 버스터블 클래스
- 테스트이기 때문에 작게, db.t3.small (2 cCPUs / 2 ~ 4Gib RAM 정도)
- 스토리지 : 20 (테스트용)
- 추가 스토리지 구성 → 스토리지 자동 조절 끄기! (활성화되어 있으면 돈 많이 나올 수 있다)
- 연결
- EC2 리소스에 연결 안함
- vpc : vpc-web-3tier
- DB 서브넷 그룹 : web-3tier-rds
- 퍼블릭 엑세스 : 아니요
- VPC 보안 그룹 : 기존 항목 선택
- default 해제
- 위에서 만든 “SG-web3-tier-db” 선택
- 테이터베이스 인증 : 암호 인증
- 추가 구성 - 데이터베이스 옵션
- 초기 이름 : web3tier
- 자동백업 : 해제 (테스트용)
- 유지 관리
- 마이너 버전 자동 업그레이드 사용 : 비활성화
- 삭제 방지 활성회 : 비활성화
5-4. RDS 연결 테스트
- OpenVPN 켜고, NAT Subnet으로 접근
- Amazon Linux OS로 인스턴스를 올렸음
- → dnf = apt나 yum과 같음
sudo dnf install -y https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
sudo dnf config-manager --enable mysql80-community
sudo dnf update -y
sudo dnf install -y mysql-community-client
접근 시도
mysql -h {rds 엔드포인트} -u {admim} -p
5-5. 최종 리소스 맵
반응형