요구 조건에 부합하는 Forward Proxy 구성하기
2021-2022 기간동안 스타트업에서 데브옵스 엔지니어로 일할 때 개인 노션에 트러블슈팅을 기록했던 내용을 블로그로 옮깁니다.
Forward Proxy
회사에서 광고 시스템과 관련하여 내부적인 이유로 포워드 프록시를 구성해야하는 일이 발생했다.
Squid Proxy vs Nginx
단순한 포워드 프록시의 기능을 수행하기 위해 무엇을 쓸지 리서치를 했다. Squid Proxy와 Nginx 중에서 고민을 많이 했다. 일단 Squid Proxy는 Forward Proxy로 가장 많이 쓰이고 있는 기술이였다. 하지만 Squid의 큰 장점인 캐싱을 효과적으로 사용할 수 없을 것이라고 예측했다. 내가 해야하는 작업은 광고 관련 작업이였고 도메인의 특성 상 캐싱한 뒤 원본 요청을 뒤로 내보내지 않으면 문제가 발생할 수 있었다. 그래서 고민을 많이 했던 것 같다. 양쪽 기술 모두 대중적으로 많이 쓰이는 기술이였기 때문이다. 하지만 구축이 가볍고 빠르다는 장점이 있었고, 반대로 Nginx는 모듈을 별도로 빌드하는 등 커스텀 작업이 많이 들어간다는 사실을 알게되었다. 당장 고객들이 계속해서 들어오는 상황이였기 때문에 빠르게 구축하기 위해서 Squid Proxy를 선택했다. 별도의 큰 설정 없이도 바로 포워드 프록시로 동작할 수 있을 것으로 예상했다.
Squid Proxy
하지만 곧바로 난관에 부딪혔다. 분명 나는 yum
을 이용해서 정상적으로 설치를 했고 설정도 제대로 넣어줬는데, 아무리 설정을 바꿔보아도 Host Header가 Forward Proxy의 주소로 변경되어서 날아가는 문제가 발생했다. url_rewrite_host_header off
를 해주었음에도 불구하고 문제가 해결되지 않았다. 검색 결과 똑같은 문제를 찾을 수 있었지만 해결책들이 통하지 않았다. 우리는 시간이 없었고, 빠르게 Nginx로 변경하기로 했다.
관련 레퍼런스 - squid proxy overrides my host header, what can I do?
Nginx로 Forward Proxy를 구성하기
처음엔 금방 될 줄 알았다. ngx_http_proxy_connect_module
을 받아서 nginx source와 해당 모듈 source를 따로 받아서 patch 해주고 다시 make install해주었다. git, patch, pcre, openssl 등 여러 라이브러리와 도구들을 깔아주고… nginx를 빌드한다.
$ yum install git
$ yum install pcre pcre-devel
$ yum install openssl
$ yum install net-tools
$ yum install patch
$ yum install gcc gcc-c++
$ yum install autoconf automake
$ wget http://nginx.org/download/nginx-1.20.1.tar.gz
$ tar -xzvf nginx-1.20.1.tar.gz
$ git clone https://github.com/chobits/ngx_http_proxy_connect_module.git
$ cd nginx-1.20.1/
$ patch -p1 < ../ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_1018.patch
$ ./configure --add-module=../ngx_http_proxy_connect_module
$ make && make install
빌드하고 나면, /usr/local/nginx
경로에 nginx가 생성된다.
sbin
폴더 안에 nginx
바이너리 파일이 들어있는데, 이것이 완성된 Forward Proxy용 Nginx다.
conf
폴더 안에 nginx.conf
파일이 들어 있고, 수정한 뒤에는 nginx -s reload
해주면 된다.
관련 레퍼런스 - Nginx를 이용한 forward proxy 구현
관련 레퍼런스 - [NGINX] forward proxy와 reverse proxy
nginx.conf 설정
- location 부분의 proxy_set_header 설정을 통해서 헤더를 그대로 살릴 수 있었다.
server {
listen 3128;
server_name 'IP';
access_log logs/access.log;
resolver 8.8.8.8;
proxy_connect;
proxy_connect_allow 80 443 563;
proxy_connect_connect_timeout 12s;
proxy_connect_read_timeout 10s;
proxy_connect_send_timeout 10s;
location / {
proxy_set_header Host $http_host;
proxy_pass $scheme://$host$uri$is_args$args;
}
}
배운 점
- nginx를 잘 쓰고 싶다면… nginx의 변수도 잘 써먹어야 한다는 점.
- 패킷 분석 맛보기(?) Squid Proxy 오류를 찾으면서 동료분에게 와이어샤크를 배워서 조금 써봤다.