(출처 : 네이버 지식백과)
사전 정의에 따르면 프록시란 “타인을 위하여 행동하거나 발언할 권한을 부여받은 사람이다”, 여기서 “타인을 위하여 행동”, 즉 “대리한다, 대신한다”라는 키워드에 집중하면 될 것이다.
(출처 : 네이버 지식백과)
일단 먼저 컴퓨터 세계에서 “프록시”라는 워딩을 사용하는 곳이 상당히 많다(웹 프록시 서버, 프록시 객체 등…). 여기서는 “웹 프록시 서버”를 대상으로 이야기할 것이다.
컴퓨터 세계에서 프록시는 역시 현실세계의 추상화된 개념을 조금 구체화할 뿐이다. 핵심은 다른 서버로의 요청을 프록시 서버가 “대신”처리하는 것이다.
위 사진에서 왼쪽의 인터넷 서버를 “A”, 오른쪽의 인터넷 서버를 “B”라고 가정하자. “A”서버가 “B”서버에게 요청을 보낼 때, “B”서버에게 직접 요청하는 것이 아닌 중간의 “프록시 서버”에게 요청을 보낸다.
그런데, 애초에 요청을 보낼거면 A서버가 B서버에게 직접 요청을 하면 되지 않을까? 왜 번거롭게 프록시 서버를 통해 한 곳을 더 거쳐 요청을 보낼까?
프록시 서버의 종류에는 대표적으로 포워드 프록시와 리버스 프록시가 존재한다. 이 두 개념을 설명하면서 프록시 서버를 사용하는 이유를 설명하도록 하겠다
포워드 프록시는 클라이언트와 인터넷 사이에 위치하며, 클라이언트의 요청은 인터넷에 곧바로 접속하지 않고 포워드 프록시에 보내진 뒤 포워드 프록시에서 인터넷에 요청을 하는 형태이다.
포워드 프록시는 클라이언트가 요청한 내용을 캐싱한다.
만약 클라이언트 A의 요청에 대한 응답을 서버에서 전달 받으면, 해당 내용을 응답할 때 프록시 내부에 해당 요청과 답변을 캐싱한다. 이후 클라이언트 B가 같은 요청을 보내면 포워드 프록시는 캐싱 정보를 통해 응답한다.
캐싱을 통해 서버는 전송 시간을 절약할 수 있고, 불필요한 외부 전송을 막을 수 있다. 따라서 네트워크가 병목되는 현상까지도 방지할 수 있는 장점이 있다.
그러나 만약 캐싱한 정보가 서버에서 갱신되면 어떻게 될까? 이는 캐시의 유효 기간을 설정하거나, 유효 시간 이후 브라우저가 리소스의 마지막으로 수정된 시간을 저장해 두고 서버의 리소스 수정 시간과 비교하는 요청을 보내거나, 식별자 태그를 활용하는 방법 등이 있다.
어떤 클라이언트가 요청을 보냈는지 서버에게 감출 수 있다. 서버는 응답 받은 요청을 누가 보냈는지 알 수 없다. 서버가 받는 요청 ip는 프록시 서버의 ip이기 때문이다.
이를 통해 사용자의 개인 정보를 보호할 수 있고, 클라이언트의 네트워크를 외부에서 파악할 수 없어 보안 강화에 도움이 된다.
추가적으로 특정 ip 주소로부터의 접근을 제어하는 등의 이점도 포워드 프록시를 통해 가져갈 수 있다.
리버스 프록시는 다음처럼 요청을 수령하는 프록시 서버가 실제 서버와 인터넷 서버의 중간에 존재한다. 포워드 프록시와 비슷한 형태이다
위의 포워드 프록시와 동일하다.
서버의 정보를 클라이언트로부터 숨길 수 있다. 클라이언트가 요청을 할 때 어떤 서버로 요청을 보내는지 모르고, 클라이언트 입장에서 리버스 프록시로만 요청을 보낸다. 클라이언트는 리버스 프록시의 ip만 알기 때문에 실제 서버의 ip가 안전하게 보호된다
사용자가 많을 때, Scale out(서버 증설)을 통해 증설된 여러 개의 서버로 트래픽을 분산한다. 이는 다음 포스팅에서 자세히 설명하도록 하겠다.
리버스 프록시를 사용해 여러 서버를 보유하고 있다면, 한 대의 서버를 배포를 위해 중단해도 다른 서버가 계속해서 서비스를 수행할 수 있어 무중단 배포가 가능하다.
공격자가 디도스 등으로 서버를 공격하려 할 때, 리버스 프록시를 활용하면 실제 서버를 대상으로 공격을 수행할 수 없다. 리버스 프록시 서버의 위치만 드러나고 실제 서버의 위치는 숨겨지기 때문이다. 따라서 리버스 프록시 서버만 공격할 수 밖에 없다.
-> 포워드 프록시와 리버스 프록시는 누가 구성하냐에 따라 다르다. 포워드 프록시는 클라이언트 쪽, 즉 보내는 쪽에서 구성한다. 예를 들면 특정 회사에서 외부 인터넷에 접속하게 할 때 무조건 포워드 프록시를 통해 거쳐가게 함으로써 부적절 접근을 차단하게 하거나, 외부 ip에 클라이언트 ip를 숨기는 것이다. 리버스 프록시는 받는 서버 쪽에서 구성한다. 이는 그냥 nginx를 생각하면 편하다.