실습 로그 / AWS 인프라 10단계

AWS 4단계 · VPC·보안 설정

지금까지 만든 서버가 어떤 네트워크 위에 올라가 있는지 확인하고, 퍼블릭 주소를 고정한 뒤 접근 권한을 필요한 만큼으로 좁힌다.

진행 과정은 실습 내용을 AI와 함께 정리했고, 배운 점은 그걸 보고 제가 이해한 대로 직접 썼습니다. 배운 점 바로가기 ↓

네트워크보안

목표

지금까지 만든 서버가 어떤 네트워크 위에 올라가 있는지 확인하고, 퍼블릭 주소를 고정한 뒤 접근 권한을 필요한 만큼으로 좁힌다.

A. 네트워크 구조 확인

EC2 인스턴스 상세정보에서 VPC ID·서브넷 ID 확인

EC2 인스턴스 상세정보의 VPC ID·서브넷 ID 화면

VPC 대시보드 → 서브넷 목록 확인

  • 서브넷 4개, 각각 다른 가용 영역(2a, 2b, 2c, 2d)에 배치
  • IPv4 CIDR은 /20 단위로 분할, 사용 가능한 주소 4,091개 (4,096개 중 AWS 예약 5개 제외)
  • 4개 서브넷 모두 동일한 라우팅 테이블(<라우팅 테이블 ID>) 사용

VPC 대시보드 서브넷 목록 화면

서브넷 상세(CIDR·가용 영역·라우팅 테이블) 화면

라우팅 테이블 (규칙들이 담긴 표) → 라우팅 탭에서 규칙 확인

목적지         →  보낼 곳
172.31.0.0/16  → local
0.0.0.0/0      → <IGW ID>

라우팅 테이블의 라우팅 탭(local, IGW 규칙) 화면

확인한 내용

  • 172.31.0.0/16 → local : VPC 내부 주소는 외부로 나가지 않고 내부에서 처리
  • 0.0.0.0/0 → igw : 그 외 모든 목적지는 인터넷 게이트웨이로 전달
  • 이 두 번째 규칙이 있기 때문에 브라우저에서 서버에 접속할 수 있었던 것이며, 이 규칙의 유무가 퍼블릭 서브넷과 프라이빗 서브넷을 구분함

배운 점

  • 리전 → VPC → 서브넷(가용 영역별) → EC2 → 보안 그룹으로 이어지는 AWS 네트워크 계층 구조
  • 서브넷 하나는 반드시 가용 영역 하나에 속하며, 기본 VPC에는 AZ마다 서브넷이 자동 생성됨
  • 보안 그룹은 서브넷의 하위 요소가 아니라 인스턴스에 붙는 방화벽
  • 퍼블릭/프라이빗 서브넷의 구분 기준은 라우팅 테이블의 0.0.0.0/0 → IGW 규칙 유무 하나
  • 3단계에서 만들었던 장애들이 이 경로 중 어느 지점에서 끊겼는지에 따라 서로 다른 에러를 냈던 것

B. 탄력적 IP로 퍼블릭 주소 고정

진행 과정

현재 퍼블릭 IP 확인 → <퍼블릭 IP 1>

인스턴스 상세정보의 현재 퍼블릭 IP 화면

인스턴스 중지 후 상태 확인

  • 퍼블릭 IPv4 주소: – (사라짐)
  • 프라이빗 IPv4 주소: <내부 IP> (유지)

인스턴스 중지 후 퍼블릭 IP가 사라지고 프라이빗 IP는 유지된 화면

인스턴스 재시작 후 확인

  • 퍼블릭 IPv4 주소: <퍼블릭 IP 2> ← 다른 주소로 변경됨
  • 프라이빗 IPv4 주소: <내부 IP> (그대로)

인스턴스 재시작 후 퍼블릭 IP가 다른 주소로 바뀐 화면

탄력적 IP 할당

  • EC2 콘솔 → 네트워크 및 보안 → 탄력적 IP → 탄력적 IP 주소 할당
  • 할당받은 주소: <탄력적 IP>

인스턴스에 연결

  • 작업 → 탄력적 IP 주소 연결 → 리소스 유형: 인스턴스 → my_first_nginx 선택

탄력적 IP 주소 연결 화면(리소스 유형·인스턴스 선택)

탄력적 IP 연결 완료 화면

검증 — 다시 중지 후 재시작

  • 중지 상태에서도 퍼블릭 IP <탄력적 IP> 유지됨 (탄력적 IP 없을 때와 대비)
  • 재시작 후에도 <탄력적 IP> 그대로

탄력적 IP 연결 후 인스턴스 중지 상태에서 퍼블릭 IP 유지 화면

탄력적 IP 연결 후 재시작 시 퍼블릭 IP 유지 화면

탄력적 IP 주소로 브라우저 접속 확인 화면

브라우저에서 http://<탄력적 IP> 접속하여 페이지 정상 표시 확인


결과 비교

상황 인스턴스 중지 시 재시작 후
탄력적 IP 미사용 퍼블릭 IP 사라짐 (–) 다른 주소로 변경 (<퍼블릭 IP 1> → <퍼블릭 IP 2>)
탄력적 IP 연결 주소 유지 동일 주소 유지 (<탄력적 IP>)

배운 점

  • 기본 퍼블릭 IP는 AWS가 임시로 할당하는 주소로, 인스턴스를 중지하면 반납되고 재시작 시 새로 배정됨
  • IPv4 주소 자원이 한정적이라 AWS가 사용하지 않는 주소를 회수해 재분배하는 구조
  • 프라이빗 IP는 VPC 내부 전용 주소이므로 중지·재시작과 무관하게 유지됨
  • 퍼블릭 IP가 바뀌면 도메인 연결, 외부 시스템의 IP 허용 설정 등이 모두 무효화되므로 실제 서비스에서는 고정이 필요
  • 탄력적 IP는 특정 주소를 계정에 예약해 인스턴스에 고정 연결하는 기능

비용 주의사항

상황 요금
실행 중인 인스턴스에 연결됨 무료
할당만 받고 미연결 요금 발생
인스턴스 중지 상태에서 연결됨 요금 발생
인스턴스 삭제 후 탄력적 IP만 남음 요금 발생

인스턴스를 삭제해도 탄력적 IP는 자동으로 해제되지 않으므로, 프로젝트 종료 시 별도로 릴리스해야 함 (탄력적 IP → 연결 해제 → 릴리스)

C. 보안 그룹 최소 권한 적용

진행 과정

변경 전 인바운드 규칙 확인

  • HTTPS(443) — 0.0.0.0/0
  • HTTP(80) — 0.0.0.0/0
  • SSH(22) — 0.0.0.0/0 ← 전 세계 어디서든 접속 시도 가능한 상태

변경 전 인바운드 규칙(443·80·22 모두 0.0.0.0/0) 화면

SSH 규칙의 소스를 내 IP로 변경

  • 인바운드 규칙 편집 → SSH(22) 줄의 소스를 Anywhere-IPv4 → 내 IP로 변경
  • <퍼블릭 IP>/32로 자동 입력됨 (/32는 해당 주소 하나만 허용)
  • HTTP·HTTPS는 웹 방문자용이므로 그대로 유지

SSH 규칙 소스를 내 IP로 변경하는 인바운드 규칙 편집 화면

규칙 저장 후 목록 확인

규칙 저장 후 인바운드 규칙 목록 화면

웹 접속 테스트 → http://<탄력적 IP> 정상 표시 (HTTP 규칙은 변경하지 않았으므로 영향 없음)

SSH 규칙 변경 후 브라우저 웹 접속 정상 화면

터미널 접속 테스트 → EC2 Instance Connect 접속 실패

Failed to connect to your instance
Error establishing SSH connection to your instance. Try again later.

EC2 Instance Connect 접속 실패 오류 화면

원인 파악

  • EC2 Instance Connect는 내 컴퓨터에서 직접 접속하는 방식이 아니라, AWS의 중계 서버를 거쳐 SSH로 연결되는 구조
  • 따라서 실제 접속 출발지는 내 IP가 아닌 AWS Instance Connect 서비스의 IP
  • SSH를 내 IP만 허용하도록 좁히면서 AWS 중계 서버까지 함께 차단된 것
  • 보안 설정 자체는 의도대로 작동했으나, 사용 중이던 접속 경로까지 막힌 상황

해결 — Instance Connect 서비스 IP 대역 추가 허용

  • 서울 리전(ap-northeast-2)의 EC2 Instance Connect 대역: 13.209.1.56/29
  • 인바운드 규칙 편집 → 규칙 추가 → SSH / 사용자 지정 / 13.209.1.56/29
  • 설명란에 용도 기재

Instance Connect 대역 SSH 규칙 추가 화면

규칙 저장 후 최종 상태 (인바운드 규칙 4개)

유형 포트 소스 용도
HTTPS 443 0.0.0.0/0 웹 방문자
HTTP 80 0.0.0.0/0 웹 방문자
SSH 22 <퍼블릭 IP>/32 내 컴퓨터에서 직접 접속
SSH 22 13.209.1.56/29 브라우저 Instance Connect

최종 인바운드 규칙 4개 목록 화면

터미널 재접속 성공 — 접속 로그에서 출발지 IP 확인

Last login: Thu Jul 30 05:39:22 2026 from 13.209.1.61

허용한 13.209.1.56/29 대역 안의 주소로 접속된 것이 확인됨. 브라우저 터미널이 AWS 중계 서버를 통해 연결된다는 점이 서버 로그로 직접 증명됨

터미널 재접속 성공 후 Last login 출발지 IP 로그 화면


배운 점

  • 최소 권한 원칙 — 필요한 만큼만 열고 나머지는 차단. 웹 포트(80·443)는 모두에게 열려야 하지만 관리용 포트(22)는 특정 출발지로 제한해야 함
  • /32는 주소 하나, /29는 8개를 의미하며, 0.0.0.0/0(전체 허용)에 비해 훨씬 좁은 범위
  • EC2 Instance Connect는 내 컴퓨터가 아닌 AWS 중계 서버가 SSH로 접속하는 구조이므로, 해당 서비스의 IP 대역을 별도로 허용해야 함
  • 보안을 강화할 때 관리자 본인의 접근 경로까지 차단되지 않도록 함께 확인해야 함
  • Last login ... from 로그로 실제 접속 출발지를 확인할 수 있음
  • 보안 그룹의 "내 IP" 옵션은 현재 접속 중인 회선의 공인 IP를 자동 입력하는 기능. 집 안 모든 기기는 공유기의 공인 IP 하나로 인터넷에 나가므로 개별 기기가 아닌 회선 전체를 가리킴
  • 가정용 회선은 대부분 동적 IP라 공인 IP가 바뀔 수 있으며, 그 경우 등록해둔 SSH 허용 규칙이 무효가 되어 접속이 차단됨. 다른 장소에서 접속할 때도 동일

4단계 용어

4단계에서 처음 나온 개념. A → B → C 진행 순서대로 정리했다.

A. 네트워크 구조 확인

용어 한 줄 설명
VPC AWS 안에서 내 계정 전용으로 격리된 사설 네트워크 구역
가용 영역(AZ) 같은 리전 안에서 물리적으로 분리된 개별 데이터센터
서브넷 VPC를 더 작게 쪼갠 구역. 반드시 가용 영역 하나에 속한다
인터넷 게이트웨이(IGW) VPC와 인터넷을 연결하는 출입구
라우팅 테이블 목적지 주소를 보고 어디로 보낼지 결정하는 규칙표
local 라우팅 테이블에서 외부로 나가지 않고 VPC 내부에서 처리하라는 의미의 예약어
퍼블릭 서브넷 라우팅 테이블에 0.0.0.0/0 → IGW 규칙이 있는 서브넷
프라이빗 서브넷 위 규칙이 없어 인터넷에서 직접 접근할 수 없는 서브넷

퍼블릭과 프라이빗을 가르는 것은 서브넷 자체의 속성이 아니라 라우팅 테이블에 IGW로 가는 길이 있느냐다.

주소 표기

용어 한 줄 설명
CIDR 172.31.0.0/16처럼 네트워크 범위를 표기하는 방식
프리픽스(/16, /24, /32) CIDR에서 네트워크 주소로 고정되는 비트 수. 숫자가 클수록 범위가 좁다
0.0.0.0/0 모든 IP를 의미하는 표기

요청이 도달하는 경로

사용자 → 인터넷 → IGW → 라우팅 테이블 → 서브넷 → 보안 그룹 → EC2 → Nginx

이 경로 중 한 곳이라도 막힐 수 있으며, 장애 진단 시 순서대로 확인한다.


B. 탄력적 IP로 퍼블릭 주소 고정

용어 한 줄 설명
프라이빗 IP VPC 내부에서만 사용하는 주소. 인스턴스를 재시작해도 유지된다
사설 IP 대역 인터넷에서 직접 쓰이지 않는 내부 전용 범위 (10.x, 172.16~31.x, 192.168.x)
탄력적 IP(Elastic IP) 계정에 고정 예약해 인스턴스에 연결하는 퍼블릭 IP. 재시작해도 주소가 바뀌지 않는다

인스턴스를 중지 후 재시작하면 퍼블릭 IP는 바뀌지만 프라이빗 IP는 유지된다. 탄력적 IP는 인스턴스에 연결되어 있지 않으면 요금이 발생하므로 사용하지 않을 때는 릴리스해야 한다.


C. 보안 그룹 최소 권한 적용

용어 한 줄 설명
인바운드 외부에서 서버로 들어오는 트래픽 (수신)
아웃바운드 서버에서 외부로 나가는 트래픽 (송신)
최소 권한 원칙 필요한 만큼만 허용하고 나머지는 차단하는 보안 원칙
보안 그룹 소스 허용 대상을 IP가 아니라 다른 보안 그룹으로 지정할 수 있다. 해당 그룹에 속한 리소스가 자동으로 대상이 된다

HTTP(80)·HTTPS(443)는 외부 공개가 목적이므로 0.0.0.0/0으로 두지만, SSH(22)는 내 IP로 좁히는 것이 최소 권한 원칙에 맞다.

단, EC2 Instance Connect는 내 컴퓨터가 아니라 AWS 중계 서버가 접속하므로, SSH를 내 IP로만 제한하면 브라우저 터미널이 막힌다. 해당 리전의 Instance Connect 대역을 별도로 허용해야 한다.

배운 점

직접 작성
  • A : 네트워크 구조
    • VPC에는 4개의 서브넷 (2a 2b 2c 2d (2는 리전번호) ) 이 있는 걸 확인했다.
    • 현재 우리는 2c만 사용하고 있으며 라우팅 테이블에 IGW와 LOCAL 주소가 있는 것도 확인했다.
      • IGW는 0.0.0.0/0 으로 외부에서도 접속할 수 있게 해주는 출입이고 LOCAL 주소는 외부로 나가지 않고 VPC 내부에서 처리하는 규칙이다.
      • 외부에서 HTTP, HTTPS 로 처리할 수 있었던 이유는 IGW 규칙이 있었기 때문이다.
  • B : 탄력적 IP
    • 우리는 IPv4를 사용하고 있으며 Public IP 와 Private IP 두 개로 구분지을 수 있다.
    • 인스턴스를 계속 실행하고 있다면 두 개 IP다 변동이 없지만 중지시키고 다시 실행하면 Public IP 는 다른 IP로 변동되는 걸 확인했고 Private IP는 변하지 않았다.
      • 이 점을 해결하기 위해 탄력적 IP를 설정해주었다.
        • 설정 후 인스턴스에 할당을 하면 탄력적 IP 할당받은 주소가 Public IP가 된다.
        • 탄력적 IP를 할당하면 이제 재실행 해도 변하지않고 Public IP가 그대로인 걸 확인 할 수 있었다.
          • 탄력적 IP는 인스턴스에 연결되어 있지 않으면 요금이 발생하므로 사용하지 않을 때는 릴리스해야 한다.
  • C : 인바운드 규칙
    • 인바운드 (외부에서 서버로 오는 트래픽) 규칙은 총 3개가 있다.
      • HTTP(80) , HTTPS (443) , SSH (22).
    • 셋 다 IP는 0.0.0.0/0을 가르키고 있으며 HTTP와 HTTPS는 외부에서 접속해야하기 때문에 그냥 두었고 SSH은 보안문제로 인바운드 규칙을 변경해주었다.
      • anywhere IPv4 에서 내 IP로 변경하였고 주소는 Public IP로 자동으로 할당해주었다.
      • <퍼블릭 IP>/32 이 주소가 할당돼었고 , 내 서버의 22번 포트에, 내 공인 IP에서 오는 접속만 허용 이라는 뜻이다.
      • 문제점이 내 IP로 할당을 해서 EC2 터미널을 이용을 할 수 없었다.
        • 브라우저 터미널은 내 컴퓨터가 아니라 AWS 중계 서버가 접속하는 방식이기 때문에 접속이 안 됐다.
        • 그래서 EC2에 접속할 수 있는 13.209.1.56/29 ("AWS가 공개한 서울 리전 Instance Connect 대역) 을 규칙 밑에다가 추가해줬다.
  • 퍼블릭 IP = 인터넷에서 통용되는 주소. 서버든 니 집이든, 인터넷에 나가려면 다 하나씩 갖고 있어야 함.