Cloud Service Practice 12
최종 구성에서 Web1과 Web2의 접속 경로가 달라지는 이유
조금 전까지 브라우저로 보이던 Web2가 왜 갑자기 직접 접속되지 않는지, 그런데 Web1을 거치면 왜 접속되는지 헷갈린다.
근거 · 교안 p109-p118
1장: Web2, 왜 갑자기 브라우저 접속이 안 될까요?
솔라는 의기양양하게 노트북을 마주했다. 방금 전, 솔라는 공들여 구축한 서버 아키텍처의 마지막 단계, 바로 Web2 서버를 퍼블릭 서브넷에서 프라이빗 서브넷으로 옮기는 작업을 마쳤다.
‘좋아. 이제 중요한 데이터베이스와 연결될 Web2 서버는 안전한 프라이빗 공간으로 옮겼으니, 보안이 한층 강화됐을 거야.’
솔라는 만족스러운 미소를 지으며 중얼거렸다. 이전에는 Web1과 Web2 두 서버 모두 외부에서 직접 접속할 수 있는 퍼블릭 서브넷에 있었다. 하지만 최종 구성에서는 외부 사용자와 직접 만나는 Web1 서버만 퍼블릭 서브넷에 남기고, 내부 로직을 처리하는 Web2 서버는 프라이빗 서브넷으로 이동시켜 외부의 직접적인 공격으로부터 보호해야 했다.
“자, 그럼 잘 작동하는지 마지막으로 확인해볼까?”
솔라는 웹 브라우저를 열어 주소창에 Web2 서버에 할당된 퍼블릭 IP 주소를 익숙하게 입력했다. 엔터 키를 누르는 손가락에 힘이 들어갔다. 당연히 ‘Hello, Web2 Server!’라는 문구가 환하게 뜰 것이라 기대했다.
하지만 화면에는 아무것도 나타나지 않았다. 브라우저 탭의 로딩 아이콘만 하염없이 빙글빙글 돌고 있었다.
“어?”
솔라의 미간이 좁아졌다. 혹시 오타가 났나 싶어 IP 주소를 다시 한번 확인하고 입력했지만 결과는 같았다. 새로고침 버튼을 몇 번이나 눌러봐도 화면은 하얀색 그대로였다. 결국 브라우저는 ‘연결 시간 초과’라는 차가운 메시지를 띄웠다.
“왜 안 되지? 분명히 서버는 켜져 있고, 퍼블릭 IP 주소도 그대로인데. 그냥 ‘프라이빗’ 환경으로 옮긴 것뿐이잖아.”
솔라는 혼란스러웠다. 솔라에게 ‘프라이빗’은 ‘보안 강화’와 동의어였다. 외부에서 함부로 들어오지 못하게 잠금장치를 더 단단하게 채우는 것과 같다고 생각했다. 그렇다고 주인이 정식으로 문을 열고 들어가려는데 못 들어갈 리는 없다고 믿었다. 퍼블릭 IP라는 ‘주소’를 알고 있으니, 당연히 접속이 되어야 했다.
그때, 거실에서 조용히 책을 읽던 언니 루나가 솔라의 낮은 탄식 소리를 들었는지 다가왔다.
“계속 새로고침만 하고 있네. 뭔가 잘 안 풀리는구나.”
“언니, 이것 좀 봐. Web2 서버를 프라이빗 서브넷으로 옮겼더니 갑자기 접속이 안 돼. 아까까지만 해도 이 IP 주소로 잘 들어가지던 페이지인데.”
솔라가 하얀 브라우저 화면이 띄워진 노트북을 가리키며 하소연했다. 루나는 잠시 화면을 들여다보더니, 빙글빙글 돌다 멈춘 로딩 아이콘을 톡 가리켰다.
“솔라, 혹시 ‘프라이빗 서브넷’을 우리 집 ‘안방’이라고 생각하고, ‘퍼블릭 서브넷’을 ‘현관문 앞’이라고 생각해 본 적 있어?”
“안방이랑 현관문 앞?”
“응. 솔라가 지금 브라우저에 입력한 퍼블릭 IP 주소는 전 세계 어디서든 찾아올 수 있는 ‘공개된 집 주소’ 같은 거야. 택배 기사님도, 우편 배달부도 이 주소를 보고 우리 집 현관문 앞까지 찾아올 수 있지.”
루나는 말을 이었다.
“그런데 ‘프라이빗 서브넷’은 그 집 안에 있는 ‘안방’이나 ‘서재’ 같은 공간이야. 외부 사람인 택배 기사님이 우리 집 현관문을 거치지 않고, 곧장 길에서부터 안방 창문으로 물건을 던져 넣을 수 있을까?”
“그건 당연히 안 되지. 담벼락도 있고, 창문도 닫혀 있을 테니까.”
솔라가 고개를 저으며 대답했다.
“바로 그거야. 서버를 ‘프라이빗 서브넷’으로 옮겼다는 건, 인터넷이라는 거대한 ‘외부 도로’에서 직접 닿을 수 없는 ‘집 안’으로 들여놓았다는 뜻이야. 이전처럼 퍼블릭 IP라는 주소를 알고 외쳐봐도, 그 소리가 더 이상 담장 안까지 닿지 않는 거지.”
루나의 설명에 솔라의 머릿속에서 무언가 번쩍했다. 아, ‘프라이빗’이라는 단어의 의미를 완전히 잘못 생각하고 있었다. 단순한 보안 강화가 아니었다. 네트워크의 구조 자체가 바뀐 것이었다.
퍼블릭 서브넷에 있을 때는 인터넷이라는 외부 도로와 직접 연결된 인터넷 게이트웨이(Internet Gateway)를 통해 누구나 퍼블릭 IP 주소로 서버의 문을 두드릴 수 있었다. 하지만 프라이빗 서브넷으로 이동한 순간, 그 연결 통로가 사라진 것이다. 외부에서는 존재 자체를 인지할 수 없는, 완벽히 격리된 공간이 되어버렸다.
“아…! 그럼 ‘프라이빗 서브넷’은 외부 인터넷에서 들어오는 길(Inbound)이 원천적으로 차단된 공간이라는 거구나. 그래서 퍼블릭 IP가 할당되어 있어도 외부에서 접속을 시도하면, 서버까지 도달하는 경로 자체가 없어서 실패하는 거였어.”
솔라는 그제야 텅 빈 브라우저 화면을 이해할 수 있었다. 자신의 시도는 잠겨 있는 문을 열려고 한 게 아니라, 아예 문이 없는 벽을 향해 문을 열어달라고 외치고 있었던 셈이다.
솔라는 고개를 끄덕이며 자신의 생각을 정리했다. 외부로부터의 직접적인 접근을 막아 내부 자원을 보호하는 것. 그것이 프라이빗 서브넷의 핵심 역할이었다.
한 가지 의문이 풀리자, 곧바로 새로운 질문이 꼬리를 물고 이어졌다.
“그런데 언니, 이상한 점이 있어. 실습 가이드 다음 내용을 보면, Web1 서버를 통해서는 Web2 서버에 접속할 수 있다고 나와. Web1은 퍼블릭 서브넷에, Web2는 프라이빗 서브넷에 있잖아. 외부에서 안 되는 게 어떻게 내부에서는 되는 거지? 마치 현관문을 통해서는 안방에 들어갈 수 있다는 말처럼 들리는데… 그건 또 무슨 원리야?”
2장: Web1을 거치면 Web2에 접속되는 이유
솔라는 잠시 생각에 잠겼다가, 노트북을 향해 다시 몸을 돌렸다. 질문만 하고 있을 게 아니라, 가이드의 다음 단계를 직접 실행해보기로 마음먹었다. 외부에서 Web2로 가는 길이 막혔다는 것은 이제 알았다. 그렇다면 정말 Web1을 통해서는 다른 결과가 나올까?
솔라는 검은색 터미널 창을 열었다. 깜빡이는 커서 앞에서 그녀는 먼저 Web1 서버의 퍼블릭 IP 주소를 확인했다. Web1은 퍼블릭 서브넷, 즉 ‘현관문 앞’에 있으니 외부인인 자신도 당연히 찾아갈 수 있어야 했다.
ssh ec2-user@[Web1의-퍼블릭-IP]
엔터 키를 누르자, 익숙한 메시지들이 빠르게 지나가며 곧 Web1 서버에 성공적으로 접속했다는 프롬프트가 떴다.
[ec2-user@ip-10-0-1-10 ~]$
“좋아, 일단 현관문까지는 들어왔고….”
솔라는 다음 단계를 위해 숨을 골랐다. 이제 이 ‘현관문’ 같은 Web1 서버 안에서, ‘안방’에 해당하는 Web2 서버로 들어가야 한다. 가이드에는 Web2의 ‘내부 IP’ 주소를 사용해 접속하라고 되어 있었다. 솔라는 고개를 갸웃했다.
‘내부 IP? 이건 그냥 우리끼리 쓰려고 붙여놓은 이름표 같은 거 아니었나? 이걸로 정말 접속이 된다고?’
솔라에게 IP 주소란 인터넷을 통해 어디든 찾아갈 수 있게 해주는 ‘공인된 주소’, 즉 퍼블릭 IP가 전부였다. 내부 IP는 그저 같은 네트워크 안에서 서로를 구분하기 위한 별명 정도로만 생각했다. 외부에서 통하지 않았던 접속이, 출발지만 바꾼다고 해서 별명 같은 주소로 가능해질 리 없다고 느꼈다.
솔라가 키보드 위에서 망설이는 것을 본 루나가 조용히 다가왔다.
“이번엔 현관문 안에서 길을 잃었나 보네.”
“언니, 가이드가 이상해. Web1 안에서 Web2의 내부 IP로 접속하래. 외부 인터넷에 연결되지도 않는 주소인데, 어떻게 이걸로 서버에 접속하라는 거지?”
루나는 솔라의 노트북 화면에 떠 있는 터미널 창과 가이드 문서를 번갈아 보더니, 미소를 지으며 말했다.
“솔라, 아까 택배 기사님 이야기 기억나? 그분은 외부 사람이니까 우리 집 안방으로 바로 들어올 수 없었지. 하지만 솔라, 너는 지금 어디에 있지?”
“나? Web1 서버 안. 그러니까… 집 안으로 치면 현관에 들어온 셈이지.”
“정확해. 넌 이제 외부인이 아니라 집 안에 들어온 가족이야. 가족이 현관에서 안방으로 갈 때, 다시 밖으로 나가서 지붕을 넘거나 창문을 부수고 들어가니?”
“아니? 그냥 복도를 걸어서 문 열고 들어가지.”
솔라의 대답에 루나는 고개를 끄덕였다.
“바로 그거야. 솔라가 지금 접속한 Web1 서버와, 접속하려는 Web2 서버는 같은 ‘집’ 안에 있어. 이 집의 이름이 바로 VPC(Virtual Private Cloud)지. 그리고 그 안에서 쓰는 내부 IP는, 집 안의 가족들끼리 통하는 ‘복도’나 ‘내선 전화번호’ 같은 거야.”
루나의 설명은 솔라의 머릿속에 엉켜 있던 생각을 단숨에 풀어주었다.
‘아…! 같은 VPC 안에 있으면, 서버들은 서로의 내부 IP 주소로 통신할 수 있는 거구나!’
퍼블릭 서브넷과 프라이빗 서브넷은 외부 인터넷과의 연결 여부만 다를 뿐, 둘 다 같은 VPC라는 큰 울타리 안에 속한 공간이었다. 따라서 울타리 안에 있는 서버들끼리는 내부 IP라는 전용 통로를 통해 자유롭게 오고 갈 수 있었던 것이다.
외부에서 Web2에 직접 접속할 수 없었던 이유는 인터넷이라는 ‘외부 도로’에서 Web2의 ‘안방’으로 이어지는 길이 없었기 때문이다. 하지만 일단 Web1이라는 ‘현관문’을 통해 VPC 내부로 들어오면, 내부 통신망이라는 ‘복도’를 이용해 Web2에 얼마든지 닿을 수 있었다.
“그럼 Web1 서버는 외부에서 내부로 들어오는 일종의 ‘환승 지점’이나 ‘경유지’ 역할을 하는 거네!”
솔라의 목소리에 자신감이 붙었다. 망설임 없이 Web2의 내부 IP 주소를 사용해 SSH 명령어를 입력했다.
ssh ec2-user@[Web2의-내부-IP]
엔터 키를 누르자, 놀랍게도 접속에 성공하며 터미널의 프롬프트가 Web2 서버의 것으로 바뀌었다.
[ec2-user@ip-10-0-2-20 ~]$
“됐다! 진짜 되네!”
솔라는 환호성을 질렀다. 외부에서는 굳게 닫혀 있던 Web2의 문이, 내부 경로를 통하자 거짓말처럼 활짝 열렸다. 이렇게 외부와 직접 연결된 서버를 발판 삼아 내부의 안전한 서버로 접근하는 방식을 ‘점프 서버(Jump Server)’ 또는 ‘배스천 호스트(Bastion Host)’라고 부른다는 루나의 부연 설명도 귀에 쏙쏙 들어왔다.
이제 모든 경로가 명확해졌다. 외부 사용자는 퍼블릭 IP를 통해 Web1에만 접근할 수 있고, 중요한 자원이 있는 Web2에는 오직 Web1을 통해서만, 그것도 내부 IP를 아는 관리자만이 접근할 수 있다. 보안과 편의성을 모두 잡은 똑똑한 구조였다.
의문이 풀린 솔라는 가이드의 마지막 확인 절차를 진행했다. Web2 서버 안에서 웹 서비스가 잘 돌고 있는지 확인하고, 이어서 외부 인터넷과의 통신 상태를 점검하는 명령어였다.
curl localhost
ping www.google.com
‘Hello, Web2 Server!’ 라는 문구가 잘 출력되었다. 그런데 이어진 ping 테스트 결과에 솔라는 다시 한번 고개를 갸웃했다. 구글 서버와 성공적으로 통신했다는 응답이 화면에 계속해서 찍히고 있었다.
“어? 이것도 이상한데. Web2는 외부에서 들어오는 길이 막힌 프라이빗 서브넷에 있다며. 그런데 어떻게 외부 인터넷 세상인 구글이랑 통신이 되는 거지? 들어오는 건 안 되는데, 나가는 건 된다고?”
3장: Private Web2, 외부 인터넷은 어떻게 통신할까요?
솔라의 터미널 화면에는 ping www.google.com 명령어의 결과가 계속해서 올라오고 있었다.
64 bytes from sea15s12-in-f14.1e100.net (142.251.46.206): icmp_seq=1 ttl=110 time=2.55 ms
64 bytes from sea15s12-in-f14.1e100.net (142.251.46.206): icmp_seq=2 ttl=110 time=2.51 ms
64 bytes from sea15s12-in-f14.1e100.net (142.251.46.206): icmp_seq=3 ttl=110 time=2.58 ms
구글 서버로부터 응답이 성공적으로 돌아오고 있음을 증명하는 초록색 줄들이었다. 하지만 솔라는 기뻐할 수가 없었다. 오히려 더 깊은 미궁 속으로 빠져드는 기분이었다. 그녀의 생각에 ‘프라이빗 서브넷’은 외부 세계와 완벽히 단절된, 마치 성벽으로 둘러싸인 고립된 성과 같아야 했다.
‘이상하다… 외부에서 성 안으로 들어오는 길은 전부 막혀 있는데, 어떻게 성 안에서 보낸 전령은 성 밖의 구글이라는 나라까지 갔다가 무사히 돌아올 수 있는 거지?’
솔라는 프라이빗 서브넷이 외부로부터의 모든 접근(Inbound)을 막는다는 사실을 이제 막 납득했다. 그런데 자신의 서버가 외부 인터넷으로 나가는 통신(Outbound)에 성공하는 이 상황은 그녀의 새로운 이해와 정면으로 부딪혔다.
솔라가 중얼거리는 소리를 들은 루나가 화면을 함께 들여다보았다.
“이번엔 또 다른 문이 나타났나 보네. 들어올 수는 없는데, 나갈 수는 있는 문.”
“언니, 말도 안 돼. 프라이빗은 외부와 격리된 공간이라며. 그런데 어떻게 외부 인터넷인 구글이랑 통신이 되는 거야? 이건 마치 안방에서는 밖으로 소리를 지를 수 있다는 거잖아. 이건 일방통행인데, 어떻게 가능한 거야?”
솔라의 혼란스러운 질문에 루나는 잠시 생각하더니, 새로운 비유를 꺼냈다.
“솔라, 우리 집 안방에 있는 네가 해외 직구 사이트에서 물건을 주문한다고 상상해봐.”
“해외 직구요?”
“응. 너는 네 방 책상에 앉아 있어. 네 방 주소는 ‘솔라네 집, 2층 왼쪽 방’이지. 이게 Web2의 프라이빗 IP 주소와 같아. 그런데 해외 쇼핑몰 판매자에게 배송 주소로 ‘솔라네 집, 2층 왼쪽 방’이라고 알려주면, 그 사람이 찾아올 수 있을까?”
“아니, 절대 못 찾지. 우리나라에 와서 ‘솔라네 집’이라는 공식적인 주소를 알아야 올 수 있잖아. 내 방 위치는 우리 가족만 아는 거고.”
솔라가 단호하게 대답했다.
“맞아. 그래서 넌 주문서에 배송 주소를 우리 집의 공식 주소, 즉 퍼블릭 IP와 같은 ‘서울시 OO구 XX로 123’으로 적을 거야. 그리고 요청 사항에 ‘2층 왼쪽 방 솔라’라고 네 정보를 남기겠지. 이 주문을 처리해 줄 특별한 존재가 있다면 말이야.”
루나는 책상 위 메모지에 간단한 그림을 그리기 시작했다.
“여기서 ‘특별한 존재’가 바로 NAT 게이트웨이(NAT Gateway)야. 우리 집의 ‘경비 아저씨’ 같은 역할이지.”
루나는 네모 두 개를 그리고 각각 ‘Web2 (솔라 방)’와 ‘인터넷 (쇼핑몰)’이라고 적었다. 그리고 그 사이에 작은 문 모양을 그리고 ‘NAT 게이트웨이’라고 썼다.
“Web2, 즉 솔라 방에 있는 네가 쇼핑몰에 주문(ping 요청)을 보내면, 이 요청은 먼저 NAT 게이트웨이로 가. 그럼 경비 아저씨는 주문서의 발신자 주소를 ‘솔라 방’에서 우리 집 공식 주소인 ‘서울시 OO구 XX로 123’으로 바꿔서 쇼핑몰에 보내. 동시에 장부에 이렇게 기록하는 거야. ‘서울시 123번지로 온 이 주문 건은, 사실 솔라 방에서 온 것임!’”
[Web2, 프라이빗 IP] ==> "구글에 ping 보내줘!" ==> [NAT 게이트웨이]
|
+-- (기록: 이 요청은 Web2가 보냄)
|
v
[인터넷 (구글)] <== "ping 보내줘!" <== [NAT 게이트웨이, 퍼블릭 IP]
“아…!”
“그리고 쇼핑몰에서 보낸 물건(ping 응답)이 우리 집 주소로 도착하면, 경비 아저씨는 장부를 보고 ‘아, 이건 솔라 방으로 가야 할 물건이구나’ 하고 네 방으로 정확하게 배달해주는 거지.”
[Web2, 프라이빗 IP] <== "응답이야!" <== [NAT 게이트웨이] <== (기록 확인: "이 응답은 Web2꺼네!")
^
|
[인터넷 (구글)] ==> "ping 응답!" ==> [NAT 게이트웨이, 퍼블릭 IP]
루나의 설명에 솔라의 눈이 동그래졌다. 모든 조각이 맞춰지는 순간이었다.
“그러니까 Web2 서버가 외부로 통신을 시작할 때, 자신의 프라이빗 IP 주소로 직접 나가는 게 아니었구나! NAT 게이트웨이라는 대리인을 통해, 게이트웨이의 퍼블릭 IP 주소를 빌려서 나가는 거였어. 외부 세계는 오직 NAT 게이트웨이만 알고 있을 뿐, 그 뒤에 숨어있는 Web2의 존재는 전혀 모르는 거고!”
이것이 바로 네트워크 주소 변환(Network Address Translation, NAT)의 원리였다. 프라이빗 네트워크에 속한 자원이 외부와 통신해야 할 때, 중간에서 주소를 변환해주는 똑똑한 문지기. 외부에서는 먼저 말을 걸 수 없지만(Inbound 불가), 내부에서 시작된 대화는 얼마든지 이어갈 수 있게(Outbound 가능) 해주는 비밀 통로.
이제 솔라는 자신이 설계한 네트워크 아키텍처의 모든 통신 경로를 꿰뚫어 볼 수 있게 되었다. 그녀는 책상 위에 놓여있던 빈 종이에 자신의 최종 아키텍처를 다시 한번 그려보았다. 그리고 세 가지 색깔의 펜을 들었다.
첫째, 파란색 펜으로 외부 사용자가 웹사이트에 접속하는 경로를 그렸다. 인터넷에서 출발해 인터넷 게이트웨이를 거쳐 Web1 서버에 도달하는, 공개된 길이었다. 외부 사용자 → 인터넷 게이트웨이 → Web1 (Public)
둘째, 초록색 펜으로 관리자인 자신이 Web2 서버에 접속하는 경로를 그렸다. Web1 서버에 먼저 접속한 뒤, 내부 IP를 이용해 Web2로 들어가는 비밀스러운 길이었다. 관리자 → Web1 (Public) → Web2 (Private)
마지막으로, 솔라는 빨간색 펜을 들었다. 방금 전까지 그녀를 괴롭혔지만, 이제는 너무나 명확해진 경로. Web2 서버가 소프트웨어 업데이트나 외부 API 호출을 위해 인터넷으로 나가는 길을 그렸다. 프라이빗 서브넷에서 출발해 NAT 게이트웨이를 거쳐 인터넷으로 나아가는, 안전한 외출 길이었다. Web2 (Private) → NAT 게이트웨이 → 외부 인터넷
세 가지 색깔로 그려진 각기 다른 접속 경로를 보며 솔라는 환하게 웃었다. 이제는 더 이상 혼란스럽지 않았다. 왜 서버를 분리해야 하는지, 어떻게 접속을 제어해야 하는지, 그리고 어떻게 안전하게 외부와 통신해야 하는지, 그 모든 원리가 하나의 그림 안에서 완벽한 조화를 이루고 있었다. 이것이야말로 안전하고 효율적인 네트워크 아키텍처의 모습이었다.