공인 IP와 사설 IP, 서버에 주소가 두 개인 이유
EC2 인스턴스에는 퍼블릭 IP와 프라이빗 IP가 함께 붙는다.
두 주소가 각각 어디서 통하는지, 사설 IP만 가진 서버가 NAT을 거쳐 밖과 통신하는 방식, VPC 대역을 고를 때 주의할 점을 다룬다.
이 글의 목차IP 주소는 패킷이 찾아갈 목적지다7
EC2 인스턴스를 만들고 세부 정보 화면을 열면 IPv4 주소가 두 개 보인다.
퍼블릭 IPv4 주소와 프라이빗 IPv4 주소다.
우리말로는 흔히 공인 IP, 사설 IP라고 부른다.
어느 쪽이 진짜 주소인지 헷갈리기 쉬운데, 둘 다 이 서버의 주소다.
하나는 인터넷에서 쓰이고, 다른 하나는 AWS 안에 있는 내 네트워크에서 쓰인다.
IP 주소는 패킷이 찾아갈 목적지다
네트워크로 오가는 데이터는 패킷이라는 작은 조각으로 나뉘어 전달된다.
패킷마다 보내는 쪽과 받는 쪽의 주소가 붙어 있는데, 이 주소가 IP(Internet Protocol) 주소다.
패킷은 목적지까지 한 번에 가지 않고 라우터를 여러 번 거친다.
라우터는 패킷의 받는 주소를 보고 다음에 넘길 곳을 정하는 장비다.
이렇게 길을 정해 넘기는 일을 라우팅이라고 한다.
인터넷의 규칙은 RFC라는 공개 문서로 정리된다.
1981년에 나온 RFC 791은 IPv4 주소를 32비트 고정 길이로 정했다.
보통 0부터 255까지의 숫자 네 개를 점으로 이어 203.0.113.10처럼 적고, 만들 수 있는 주소는 약 43억 개다.
203.0.113으로 시작하는 주소는 문서와 예시에 쓰라고 떼어 둔 대역이라서, 튜토리얼에 이런 주소가 나오면 예시로 적은 값이다.
43억 개로는 모자랐다
연구 기관 몇 곳이 컴퓨터를 잇던 시절에는 넉넉해 보이는 숫자였다.
개인용 컴퓨터와 휴대폰이 인터넷에 붙으면서 주소가 모자라기 시작했다.
대책은 두 가지였다.
하나는 주소를 훨씬 길게 늘린 새 체계 IPv6를 준비하는 것이었고, 다른 하나는 이미 있는 IPv4 주소를 아껴 쓰는 것이었다.
아껴 쓰는 방법 가운데 하나가 사설 주소다.
1996년 2월에 나온 RFC 1918은 주소 세 구간을 떼어 각 조직이 내부 네트워크 안에서만 쓰도록 예약했다.
세 구간은 10으로 시작하는 주소 전체, 172.16부터 172.31까지로 시작하는 주소, 192.168로 시작하는 주소다.
사설 주소로 가는 경로 정보는 조직 바깥으로 퍼뜨리지 않고, 사설 주소가 적힌 패킷도 바깥으로 넘기지 않는 것이 규칙이다.
그래서 사설 주소로는 인터넷 너머의 기계에 닿지 못한다.
그 대신 서로 떨어진 네트워크가 같은 사설 주소를 써도 부딪히지 않는다.
한 집의 공유기 뒤에 있는 노트북이 192.168.0.10을 쓰고 다른 집 노트북이 같은 주소를 써도 문제가 없는 것은 이 때문이다.
이렇게 아껴 써도 IPv4는 결국 바닥났다.
2011년 2월, 인터넷 주소를 총괄해 배정하는 IANA가 마지막 IPv4 주소 묶음을 지역별 주소 등록 기관에 나눠 주면서 더 나눠 줄 주소가 남지 않았다.
EC2의 두 주소는 이렇게 이어진다
AWS에서 서버는 VPC(Virtual Private Cloud) 안에 만든다.
VPC는 AWS 안에 따로 떼어 받은 나만의 가상 네트워크다.
VPC의 주소 범위는 다시 서브넷이라는 작은 구간들로 나뉜다.
인스턴스는 자기가 들어간 서브넷의 범위에서 프라이빗 IPv4 주소를 받는다.
같은 VPC 안의 서버끼리는 이 주소로 통신한다.
퍼블릭 IP는 서버의 어디에 있을까.
서버에 접속해 운영체제의 네트워크 설정을 열어 보면 프라이빗 IP만 보인다.
퍼블릭 IP는 서버 바깥에서 붙는 주소이기 때문이다.
인스턴스는 VPC 안의 사설 주소만 알고, 인터넷 게이트웨이가 공인 주소와 사설 주소를 일대일로 바꿔 준다.
인터넷 게이트웨이는 VPC를 인터넷과 연결하는 AWS 구성 요소다.
나가는 패킷은 출발지 주소가 공인 주소로 바뀌어 인터넷으로 나간다.
공인 주소로 들어온 패킷은 받는 주소가 사설 주소로 바뀌어 인스턴스에 닿는다.
이렇게 주소를 고쳐 적는 일을 NAT(Network Address Translation, 네트워크 주소 변환)이라고 한다.
인스턴스를 중지했다가 다시 시작하면 퍼블릭 IP가 바뀌어 있다.
퍼블릭 IP 자동 할당으로 받은 주소는 중지할 때 반납되고, 다시 시작할 때 새 주소가 붙는다.
프라이빗 IP는 인스턴스를 종료할 때까지 그대로다.
바뀌지 않는 공인 주소가 필요하면 탄력적 IP(Elastic IP)를 할당해 붙인다.
공인 주소에는 비용도 따른다.
2024년 2월부터 AWS는 인스턴스에 붙은 것까지 모든 퍼블릭 IPv4 주소에 시간당 요금을 받는다.
| 주소 | 언제 바뀌나 | 이것만 믿으면 생기는 일 |
|---|---|---|
| 프라이빗 IP | 인스턴스를 종료할 때까지 그대로 | 인터넷에서는 이 주소로 닿을 수 없다 |
| 자동 할당 퍼블릭 IP | 중지 후 다시 시작하면 바뀐다 | 이 주소를 적어 둔 DNS 레코드나 접속 설정이 옛 주소를 가리킨다 |
| 탄력적 IP | 직접 해제할 때까지 그대로 | 할당만 해 두고 쓰지 않아도 요금이 나간다 |
사설 IP만 가진 서버가 밖으로 나가는 길
애플리케이션 서버나 데이터베이스처럼 인터넷에서 직접 접속할 일이 없는 서버에는 퍼블릭 IP를 붙이지 않는 것이 보통이다.
그런데 이런 서버도 업데이트를 받거나 외부 API를 불러야 할 때가 있다.
이때도 NAT을 쓴다.
이번에는 사설 IP만 가진 여러 서버가 공인 주소 하나를 나눠 쓰는 방식이다.
NAT 장비는 나가는 패킷의 출발지 주소와 포트 번호를 자기 공인 주소와 새 포트로 바꾸고, 그 대응을 표에 적어 둔다.
이 표를 상태 테이블이라고 하며, 응답이 돌아오면 NAT 장비는 이 표를 보고 원래 서버로 넘긴다.
포트 번호는 한 주소 안에서 여러 연결을 구분하는 번호다.
여러 서버의 연결이 같은 공인 주소로 나가도 포트 번호가 서로 다르니 응답을 제자리로 돌려보낼 수 있다.
바깥에서 먼저 연결을 걸어오면 사정이 다르다.
표에 맞는 항목이 없으니 NAT 장비는 이 패킷을 안쪽 어느 서버에 넘길지 정하지 못한다.
그래서 이런 NAT을 거치는 연결은 안쪽에서 바깥으로 향하는 한 방향으로만 시작된다.
AWS에서는 NAT 게이트웨이가 이 일을 맡는다.
NAT 게이트웨이를 거치면 프라이빗 서브넷의 인스턴스는 밖으로 연결할 수 있지만, 인터넷에서 먼저 걸어오는 연결은 받지 않는다.
어떤 서브넷이 퍼블릭이 되는지는 서브넷과 라우팅 테이블 글에서 이어진다.
NAT 뒤에 두면 안전할까
밖에서 먼저 들어올 수 없으니 NAT 뒤에 두면 안전하다고 생각하기 쉽다.
그런데 NAT은 보안을 위해 만든 장치가 아니다.
밖에서 못 들어오는 것은 주소를 나눠 쓰는 구조에서 생긴 부수 효과다.
안쪽 서버가 악성 코드에 감염돼 스스로 바깥으로 연결을 열면, 그 연결도 표에 기록되고 응답도 그대로 들어온다.
NAT은 어떤 연결을 막을지 판단하지 않는다.
서버 A와 B는 사설 주소만 있고, 밖으로 나갈 때 NAT 장비의 공인 주소 203.0.113.20 하나를 함께 쓴다. 서버 A는 업데이트 서버에, 서버 B는 처음 보는 외부 주소에 연결한다.
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 줄 없음안쪽 서버: 안쪽에서 연 연결이 아직 없음
서버 A · 서버 B
사설 주소만 있음공인 주소는 NAT 장비에만 있음
바깥과 주고받은 패킷
아직 없음상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 줄 없음안쪽 서버: 안쪽에서 연 연결이 아직 없음
바깥에서 먼저 온 패킷
22번 포트로 도착안쪽에서 연 연결이 아님
상태 테이블 조회
맞는 줄 없음넘길 서버를 정하지 못함
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50001번 업데이트 서버와 연결안쪽 서버: 서버 A · 10.0.2.15
서버 A가 연 연결
50001번 포트로 나감업데이트 서버와 연결
돌아온 응답
서버 A에게 전달50001번 줄을 따라감
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50001번 업데이트 서버와 연결안쪽 서버: 서버 A · 10.0.2.15
바깥에서 먼저 온 패킷
22번 포트로 도착안쪽에서 연 연결이 아님
상태 테이블 조회
맞는 줄 없음넘길 서버를 정하지 못함
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50002번 처음 보는 외부 주소와 연결안쪽 서버: 서버 B · 10.0.2.16
서버 B가 연 연결
50002번 포트로 나감처음 보는 외부 주소와 연결
돌아온 응답
서버 B에게 전달50002번 줄을 따라감
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50002번 처음 보는 외부 주소와 연결안쪽 서버: 서버 B · 10.0.2.16
바깥에서 먼저 온 패킷
22번 포트로 도착안쪽에서 연 연결이 아님
상태 테이블 조회
맞는 줄 없음넘길 서버를 정하지 못함
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50001번 업데이트 서버와 연결안쪽 서버: 서버 A · 10.0.2.15
- 공인 주소의 포트: 50002번 처음 보는 외부 주소와 연결안쪽 서버: 서버 B · 10.0.2.16
서버 A가 연 연결
50001번 포트로 나감업데이트 서버와 연결
돌아온 응답
서버 A에게 전달50001번 줄을 따라감
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50001번 업데이트 서버와 연결안쪽 서버: 서버 A · 10.0.2.15
- 공인 주소의 포트: 50002번 처음 보는 외부 주소와 연결안쪽 서버: 서버 B · 10.0.2.16
서버 B가 연 연결
50002번 포트로 나감처음 보는 외부 주소와 연결
돌아온 응답
서버 B에게 전달50002번 줄을 따라감
상태 테이블 · 공인 주소 203.0.113.20
- 공인 주소의 포트: 50001번 업데이트 서버와 연결안쪽 서버: 서버 A · 10.0.2.15
- 공인 주소의 포트: 50002번 처음 보는 외부 주소와 연결안쪽 서버: 서버 B · 10.0.2.16
바깥에서 먼저 온 패킷
22번 포트로 도착안쪽에서 연 연결이 아님
상태 테이블 조회
맞는 줄 없음넘길 서버를 정하지 못함
NAT 장비는 안쪽 서버가 연결을 열 때마다 공인 주소의 포트와 그 서버를 짝지어 상태 테이블에 적고, 응답은 그 줄을 따라 돌려보낸다. 서버 B가 처음 보는 주소로 연 연결도 똑같이 기록된다. 바깥에서 먼저 온 패킷에는 맞는 줄이 없어 넘길 서버가 없다.
상태 테이블이 비어 있다. 서버 A와 B는 사설 주소만 있고, 밖으로 나갈 때는 공인 주소 203.0.113.20 하나를 함께 쓴다.
포트 번호는 예시 값이고, 안쪽 서버 쪽 포트는 표에서 뺐다. 포트 전달 설정이 없는 NAT이며, 연결이 끝난 줄이 지워지는 시간과 보안 그룹 같은 방화벽 규칙은 다루지 않는다.
무엇을 허용하고 무엇을 막을지는 방화벽 규칙으로 따로 정한다.
AWS에서는 보안 그룹이 그 역할을 맡는데, 기초는 포트와 방화벽 글에서 다룬다.
반대로 퍼블릭 IP를 붙였는데 밖에서 접속이 안 될 때도 있다.
공인 주소가 있어도 서브넷의 라우팅 테이블에 인터넷 게이트웨이로 가는 경로가 있고, 보안 그룹이 그 포트를 허용하고, 서버 안에서 그 포트로 연결을 기다리는 프로그램이 있어야 접속된다.
VPC 대역은 처음부터 겹치지 않게 고른다
VPC를 만들 때는 10.0.0.0/16처럼 주소 범위를 직접 정한다.
이런 표기를 CIDR라고 하는데, 슬래시 뒤의 숫자는 앞에서 몇 비트를 고정하는지를 뜻한다.
/16이면 앞의 두 숫자를 고정하니 6만 5천여 개의 주소가 들어간다.
앞에서 본 세 사설 대역을 이 표기로 적으면 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16이다.
VPC 대역은 보통 이 안에서 고르고, AWS의 VPC 대역 문서도 그렇게 권한다.
사설 주소는 겹쳐 써도 된다고 했으니 아무 범위나 골라도 될 것 같다.
문제는 나중에 두 네트워크를 이어야 할 때 드러난다.
두 네트워크의 대역이 겹치면 겹친 범위의 주소로 가는 패킷을 어느 쪽으로 보낼지 정할 수 없다.
AWS에서도 IPv4 범위가 같거나 겹치는 VPC끼리는 피어링 연결을 만들지 못한다.
피어링은 두 VPC를 사설 주소로 직접 잇는 기능이다.
이 문제는 사설 주소가 생길 때부터 예상됐다.
RFC 1918은 사설 주소를 쓰는 조직끼리 나중에 연결하면 주소가 겹칠 수 있다며, 내부에 나눠 쓸 범위를 예약 대역 안에서 무작위로 고르라고 강하게 권한다.
공인 주소는 꼭 필요한 곳에만 붙인다
웹 서비스라면 인터넷에서 직접 연결을 받아야 하는 것은 대개 여러 서버 앞에서 요청을 나눠 주는 로드밸런서 하나다.
애플리케이션 서버와 데이터베이스는 프라이빗 서브넷에 사설 IP만 가진 채로 두고, 밖으로 나갈 일이 있으면 NAT 게이트웨이를 거치게 한다.
VPC 대역은 회사 네트워크나 앞으로 이어질 다른 VPC와 겹치지 않게 미리 나눠 둔다.
VPC를 만들 때 정한 첫 대역은 나중에 떼어 낼 수 없다.
그래서 튜토리얼의 범위를 그대로 쓰기 전에, 조직 안에서 대역을 어떻게 나눌지부터 정해 둔다.