HTTP 완벽 가이드 스터디를 진행하며 프록시에 관한 내용을 정리한 것과 이를 프로젝트에 어떻게 실제로 적용하였는가에 대한 문서화이다.
프록시 (Proxy) 란?
정보처리기사나 네트워크 전공 수업을 들은 이라면 '프록시'라는 단어에 대해 한번쯤은 들어보았을 것이다.
"프록시가 뭐야?" 라고 물어본다면 예전의 나라면 "실제 서버의 대리 객체아니야?"라고 답했을 것이고, "더 자세히 얘기해봐!"에는 분명 답을 못했을 것이다.
"서버의 대리 객체", 이 말이 틀린 말일까? 틀린건 아니지만, 나는 스터디를 통해 프록시에 대해 더 깊게 학습하게 되었고 해당 경험을 통해 실제 프로젝트에 충분한 이유와 함께 적용할 수 있었다.
결론부터 말하면 프록시는 "서버의 대리 객체"가 맞다.
실제 서버가 해야하는 일들 ( ex : 캐시, 인터셉트,
클라이언트와 직접 통신 )의 일부를 프록시가 해주고 있기 때문이다.
프록시 서버의 종류
프록시 서버는 클라이언트에게서의 기능과 용도에 따라 캐시 프록시, 인터셉트 프록시, 리버스 프록시로 나눌 수 있다.
1. 캐시 프록시
캐시 프록시는 말 그대로 사용자가 자주 쓰는 리소스를 임시로 가지고 있는 프록시이다.
개인 캐시가 아닌 공용 캐시를 저장하는 데 사용되며, 캐시 프록시에서는 사용자의 요청에 따라 캐시되었는지 확인한 후에, 해당 리소스가 최신 버전인지 서버로부터 확인한다.
만약 최신이라면 그대로 사용자에게 응답하고, 최신 버전이 아니거나 캐시되어 있지 않은 경우에 서버로부터 최신 버전의 리소스를 다시 받아온다.
2. 인터셉트 프록시
인터셉트 프록시는 말 그대로 사용자의 요청을 중간에 가로채 리버스 프록시 또는 원 서버에 도달하지 못하게 하고 즉시 응답을 하도록 하는 것이다.
해당 프록시는 사용자의 요청이 보안에 적합하지 않거나 부적절한 경우에 즉시 반환시킨다.
여기서 말하는 부적절의 경우에는 "인증 실패, 콘텐츠 필터링" 등이 있다.
이때 사용자는 인터셉트 프록시 서버의 유무를 알지 못해야 하며, 원 서버와 통신을 한 것으로 생각하게 된다
3. 리버스 프록시
"프록시"를 생각하면 바로 떠오르는 녀석이 이 "리버스 프록시" 일 것이다.
리버스 프록시는 클라이언트가 어떠한 경우에도 원 서버와 직접적으로 소통하지 못하도록 하는 역할을 한다.
모든 클라이언트의 요청은 리버스 프록시에게 집결되며, 리버스 프록시는 해당요청을 가지고 원 서버와 통신하며 이후 응답을 받아 클라이언트에게 응답한다.
이러한 과정에서 클라이언트는 리버스 프록시 서버와만 통신하기에 원 서버가 어디에 존재하는지 절대 알 수가 없으며 리버스 프록시 서버의 트래픽 중앙 관리는 불특정 다수 트래픽으로부터 원 서버를 보호하는 역할을 한다.
뿐만 아니라 원 서버의 트래픽 부하 관리를 위해서 클러스터와 같은 멀티 프로세스를 적용하는 경우에 로드 밸런싱의 역할도 리버스 프록시에 적용할 수 있다.
그런데 학습하면서 신기한 점이 있었다.
리버스 프록시도 "캐싱" 을 한다는 것이었다.
"리버스 프록시" 와 "캐시 프록시" 에서의 캐싱 의미
리버스 프록시 와 캐시 프록시는 모두 캐싱을 하는데 각각에서의 캐싱은 의미가 다르다.
리버스 프록시에서의 캐싱은 "정적 컨텐츠"에 대한 캐싱이다.
다시 말해, Web Server를 의미한다고 할 수 있는데, 사용자의 요청에 따라 동적으로 응답하는 Web Application Server와 다르게 Web Server에서는 특정 요청에 대해서 항상 같은 응답만을 하면 되므로 정적 컨텐츠를 캐싱하는 것이다.
그에 반해, 캐시 프록시의 경우에는 사용자가 최근에 사용한 리소스를 캐싱하는 것이므로 두 프록시에서의 캐싱은 의미가 확연히 다르다고 할 수 있다.
두 캐싱 모두 서버의 부하를 줄이는 역할을 하지만, 캐시 프록시의 경우에는 추가로 네트워크 트래픽도 더 줄이는 것이다.
프로젝트에서 프록시 서버 적용해보기
위에서 학습한 내용을 바탕으로 프로젝트를 진행하며 프록시 서버를 적용하기로 했다.
"리버스 프록시"를 먼저 적용했는데, 서버에 HTTPS 프로토콜을 적용하기 위해서 SSL 인증서를 보관하기 위한 Web Server를 두게 되면서 해당 Web Server를 Reverse Proxy로 만들기로 했다.
같은 VPC에 존재하는 WAS, DB, Web Server 중 Web Server만이 PORT번호 443 INBOUND 규칙을 열어 요청을 받으면 해당 요청을 WAS로 전달하는데, 이때 WAS는 웹서버 IP 주소로부터의 요청만 허용을 하여 클라이언트에서의 직접 접근이 불가능하도록 설계하였다.
이 때, Web Server 및 Reverse Proxy의 역할을 하기 위해서 Nginx를 사용하였다.
Ncloud에 Nginx public 서버를 하나 구축한 후에, Nginx서버에 대한 설정을 진행해야 했다.
Nginx의 설정 파일 ( ex : Nginx.conf ) 는 주로 /etc/nginx 폴더 내에 위치했기에
Ubuntu 환경에서 아래의 명령을 통한 conf 파일 수정을 진행했다.
sudo vi /etc/nginx/nginx.conf
파일 내에서 http 단락에 리버스 프록시 역할을 위해서 전달할 서버의 location 정보를 적어야 했다.
proxy_pass 를 통해 요청을 was로 전달하는 것인데, 당연히 이 글에서 was의 IP는 적지 않았다.
http {
client_max_body_size 10M; #클라이언트로 부터 받을 데이터 사이즈 크기
server {
server_name www.~~~~; #서버의 도메인! 나는 안알려줄거임
location / {
proxy_pass http://WAS IP:포트번호;
proxy_set_header Connection ""; #504 Bad GateWay 문제 방지
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/www.was도메인/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.was도메인/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
최종 서버 어플리케이션 통신 과정
