요구 조건에 부합하는 Forward Proxy 구성하기

· Infra, Network, TroubleShooting

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 설정

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;
    }
}

배운 점