안녕하세요,
취미로 여행 관련 웹 서비스를 개발한지 어느덧 3개월차,
문득 이런 생각이 들더군요.
개발 지식을 갖춘 악의적인 사용자가 나의 서버에 접근하는 것을 어떻게 방어할 것인가? 실제 서비스들은 프로덕션 단계에서 어떻게 서버를 외부의 접근으로부터 보호하는가 ?
해답은 프록시 서버였습니다.
제 서비스는 React로 프론트엔드를, Django로 백엔드를 개발하고 있습니다.
정말 부끄럽지만 오늘 이전의 저는,
모든 웹은 그저 클라이언트와 서버 이렇게 두 개체 사이의 통신이라고 단순하게 생각하고 있었습니다.
이렇게 유치원생도 알 것 같은 유치한 구조로 말이죠.
물론 기본적인 구조는 저 사진과 같지만,
전 프로덕션 단계에서 프록시 서버를 배치할 생각 조차도 하지 못했습니다.
캐싱, 로드밸런싱, 암호화와 보안 자체를 생각하지 못했던 것입니다.
그래서 오늘은 proxy서버란 무엇이고, proxy서버를 서비스에 배치함으로 얻을 수 있는 이점은 무엇인지 알아보겠습니다.
proxy는 대리인을 뜻하는 영어단어입니다.
proxy 서버는 "대리 서버" 정도가 되겠네요.
그렇다면 프록시 서버는 무엇을 대신한다는 걸까요?
여러분의 이해를 돕기 위해, 제가 만든 다이어그램을 함께 살펴보겠습니다.
이렇게, 클라이언트 단에서 서버와 직접 통신하는 것이 아니라,
사이에 프록시 서버를 두어 클라이언트는 백엔드 서버가 아닌 프록시 서버와 소통하는 것입니다.
비유하자면, 백엔드 서버는 조직의 우두머리이고 프록시 서버는 조무래기입니다.
클라이언트는 대장인 백엔드 서버와 싸울 수 조차 없습니다. 앞에 부하 병사들이 가로막고 있기 때문이죠.
정리하면, 클라이언트와 서버는 직접 통신하지 않습니다. 프록시를 매개로 두 단계에 걸쳐 통신합니다.
이제 막 프록시를 이해했는데, 아직 알아야 할 내용이 많이 남아있습니다.
우선, 프록시 서버의 종류를 알아보겠습니다.
프록시 서버는 forward와 reverse이렇게 두 가지입니다.
이 둘의 차이점은, 어떤 상황에 쓰이냐에 있습니다.
forward proxy
: 클라이언트가 서버로 Request
를 보낼 때 사용됨
reverse proxy
: 서버가 클라이언트로 Response
를 보낼 때 사용됨
이해를 높이고자, 다이어그램을 하나 그려보았는데요.
함께 살펴보겠습니다.
클라이언트가 서버로 "이미지를 띄워줘!" 라는 요청을 보냈다면,
클라이언트의 요청은 우리 웹서비스의 백엔드 서버로 가는 것이 아니라,
백엔드 서버 앞단에 세워둔 대리 서버인 forward proxy서버로 갑니다.
그 후, forward proxy 서버가 받은 요청을 다시 backend server로 보냅니다.
이제, 백엔드 서버에서 Response를 보낼 땐, 바로 클라이언트로 보내지 않고,
백엔드 서버인 web application server(WAS) 앞단에 세워둔 reverse proxy server로 보내고, reverse proxy서버는 받은 응답을 다시 클라이언트에 전달합니다.
즉, 요청을 보내거나 응답을 받을 때, 클라이언트는 서버에 직접 접근하지 못합니다.
proxy 서버를 사용하면 무엇이 이득일까요?
또, 언제 사용해야 할까요?
제가 생각하기론 프록시 서버를 두는 가장 큰 이유는 사용자와 서버 및 데이터베이스 보안을 강화하기 위함이 아닌가 싶습니다.
각각에 대해 조금 더 자세히 알아보겠습니다.
포워드 프록시 서버를 배치하면, 백엔드 서버에 요청을 보낸 최종 주체는 클라이언트가 아닌 forward proxy입니다. 즉, 해커가 서버에 요청을 보낸 클라이언트의 IP를 탈피해도, 이는 포워드 프록시의 주소일 뿐입니다.
이런 방식으로, 서비스 유저들의 정보를 보호해줄 수 있습니다.
리버스 프록시 서버를 배치하면, 클라이언트와 만나 Response를 전달해주는 상대는 백엔드 서버가 아닌 리버스 프록시 서버가 됩니다. 즉, 클라이언트 단에서 응답을 보낸 상대의 IP주소 등의 정보를 얻었다 하더라도, 이는 WAS앞의 프록시의 정보일 뿐입니다.
백엔드 서버의 IP주소를 숨겼으니, DDoS공격이나 기타 공격으로부터 우리의 서버를 지킬 수 있습니다. 백엔드 서버는 데이터베이스 서버와도 연결되어 있는만큼, 보안이 정말 중요하다 생각됩니다.
어찌되었든 이렇게 하여, 서버를 클라이언트로부터 보호할 수 있습니다.
이건 reverse proxy에 해당하는 내용입니다.
실제로 대부분의 서비스는 리버스 프록시 서버에 nginx나 apache와 같은 웹서버를 배치하여 로드밸런싱을 지원하고 있다고 합니다.
트래픽이 많아지면 서버를 여러 대 구축해야 할 것이고,
병목현상이나 서버의 부하를 막기 위해 트래픽을 여러 서버에 고르게 분산시켜주는 로드밸런싱을 proxy서버에게 시킬 수 있습니다.
캐싱이란, 자주 사용되는 데이터를 임시로 저장해두는 것이란걸 모두 알고 계실 겁니다.
포워드와 리버스 모두에서, 자주 사용되는 데이터를 프록시 서버에 미리 저장해두면,
이를 다시 로드할 필요 없이 빠르게 재사용할 수 있어 자원을 절약하고 서비스를 최적화 할 수 있습니다.
예를 들어, 프론트 단에서 API로 받아온 호텔 정보를 캐싱해두어 API fetching을 다시 할 필요가 없으니 시간을 절약할 수 있습니다.
이렇게, 오늘날의 많은 서비스들은 서버와 클라이언트 사이에 프록시 서버를 두어
보안과 성능을 모두 강화하고 있습니다.
저도 조만간 제 여행 웹서비스에 reverse proxy 서버를 배치하려고 합니다.
웹 서버인 nginx를 배치하려 하는데, 조만간 nginx 포스팅 시리즈도 연재할 예정이니, 많은 관심 부탁드립니다.
감사합니다.
참고한 영상: https://www.youtube.com/watch?si=PHd_o42CwMjRgbgV&v=9t9Mp0BGnyI&feature=youtu.be
비고: 포스팅에서 "WAS" 라는 개념이 등장했는데, 이는 web application server의 줄임말입니다. 저의 경우 Django로 백엔드를 개발하고 있으니, 개발 단계에서는 Django 개발 서버가 WAS가 됩니다.
웹 애플리케이션 서버(백엔드서버)와 웹서버(리버스프록시의 역할을 자연스레 하게 됨)는 아예 다른 개념입니다.