NGINX로 SSL을 지원하는 리버스 프록시 설정하기

NGINX

미크로틱의 web proxy로 리버스 프록시를 구현해 아이피 하나로 여러 서버를 도메인에 연결해서 사용하고 있는데요.

서버에 SSL을 적용하려 보니 미크로틱은 SSL을 지원하지 않아 대안으로 윈도우에 NGINX를 설치하고 리버스 프록시로 활용해봤습니다.

NGINX 파일 구조

nginx_reverse_proxy_00

아래 옵션부분에서 파일을 include 할때 상대경로를 사용했는데 참고로 파일의 위치를 보여주기 위한 스크린 샷입니다.

NGINX 리버스 프록시 설정 파일

NGINX는 윈도에 설치하였으며 설정과 파일구성은 리눅스 스럽게 해봤습니다.

worker_processes  2;

events {
    worker_connections  1024;
}

http {
    include            mime.types;
    default_type       application/octet-stream;

    include            proxy_params.conf;
    include            conf-available/*.conf;

    sendfile           on;

    keepalive_timeout  65;

    access_log         off;

    upstream web {
server 127.0.0.1:80;
    }

    upstream web-ssl {
server 127.0.0.1:443;
    }
   
    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

우선 전체적인 설정을 담은 nginx.conf 파일입니다.

각 서버에 접속 로그가 남기때문에 nginx에 접속로그를 남기는건 자원낭비인것 같아 엑세스 로그는 하지 않고 에러 로그만 수집하게 설정했습니다. 만일 엑세스 로그까지 수집하고 다면 access_log off; 부분을 삭제하거나 로그를 접속하는 경로별로 지정해 저장할수도 있지만 이 포스팅에서는 각 옵션에 대해 심도있게 다루진 않을것이므로 (홈서버 레벨에서…) 기회가 된다면 세부 옵션을 다뤄보겠습니다.

윈도용 nginx의 상대경로는 conf 폴더가 있는 곳을 루트로 하기 때문에 c:로 시작하는 절대경로를 작성할 필요가 없습니다. 코드 길이가 너무 길어지고 지저분해지니까요.

프록시에 관련된 설정은 proxy_params.conf 파일에 저장하고 불러오는 방식으로 설정했고 각 서버 연결에 대한 설정은 conf-available 폴더 하위의 conf  파일을 읽어옵니다.

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_pass_header Server;
client_max_body_size 10G;

proxy_params.conf 파일입니다.

리눅스에 nginx를 설치하면 기본으로 있는 proxy_params 파일인데 윈도용은 포함이 되어 있지 않네요. 기본 설정에서 약간만 추가해줬습니다.

Host 에 대한 파라미터를 $host 로 받을경우 시놀로지가 연결이 되지 않기때문에 $http_host 로 값을 넘겨받습니다. 그리고 client_max_body_size 역시 시놀로지 때문에 크게 잡아줬습니다.

강조된 6번째 라인은 리버싱된 서버의 정보를 헤더에 보일것인지, nginx의 서버 헤더를 보일것인지이 대한 옵션입니다. 만일 아파치 서버를 nginx로 위장하고 싶으면 6번째 라인은 지우면 됩니다.

nginx_reverse_proxy_01
nginx_reverse_proxy_02

(위 이미지는 proxy_pass_header 가 적용되지 않은 헤더 정보, 아래는 proxy_pass_header 가 적용된 헤더 정보)

ssl_protocolsTLSv1 TLSv1.1 TLSv1.2;
ssl_ciphersHIGH:!aNULL:!MD5;
keepalive_timeout 60;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout10m;

ssl.conf 파일입니다. 위의 proxy_params.conf 와 같이 SSL에 관련된 옵션을 따로 저장해서 코드가 중복되지 않고 관리하기 편하게 저장합니다.

server {
listen 80;
server_name mystor.net www.mystor.net blog.mystor.net;

location / {
proxy_pass http://웹서버내부아이피:80/;
proxy_redirect off;
}
}

server {
listen 80;
server_name pluto.mystor.net;

location / {
proxy_pass http://시놀로지1내부아이피:80/;
}

}

server {
listen 5000;
server_name pluto.mystor.net;

location / {
proxy_pass http://시놀로지1내부아이피:5000/;
}

}

server {
listen 443;
server_name pluto.mystor.net;

ssl on;
ssl_certificatessl/pluto/pluto.crt; # SSL 인증서 경로
ssl_certificate_keyssl/pluto/pluto.key; # SSL 인증키 경로
includessl.conf;

location / {
proxy_pass https://시놀로지1내부아이피:443/;
}
}

server {
listen 5001;
server_name pluto.mystor.net;

ssl on;
ssl_certificatessl/pluto/pluto.crt;
ssl_certificate_keyssl/pluto/pluto.key;
includessl.conf;

location / {
proxy_pass https://시놀로지1내부아이피:5001/;
}
}

server {
listen 80;
server_name neptune.mystor.net;

location / {
proxy_pass http://시놀로지2내부아이피:80/;
}

}

server {
listen 5000;
server_name neptune.mystor.net;

location / {
proxy_pass http://시놀로지2내부아이피:5000/;
}

}

server {
listen 443;
server_name neptune.mystor.net;

ssl on;
ssl_certificatessl/neptune/neptune.crt;
ssl_certificate_keyssl/neptune/neptune.key;
includessl.conf;

location / {
proxy_pass https://시놀로지2내부아이피:443/;
}
}

server {
listen 5001;
server_name neptune.mystor.net;

ssl on;
ssl_certificatessl/neptune/neptune.crt;
ssl_certificate_keyssl/neptune/neptune.key;
includessl.conf;

location / {
proxy_pass https://시놀로지2내부아이피:5001/;
}
}

server {
        listen 80;
        listen 443;
        server_name *.mystor.net 서버의외부아이피;

        location / {
              deny all;
        }
}

다음은 conf-available 폴더 안에 있는 리버스 프록시의 설정 파일 (mystor.conf) 입니다.

간단하게 설명하자면 각 포트로 전달받은 요청을 nginx에서 해당 주소로 연결해주는 설정입니다. 시놀로지의 포트들 때문에 길어보이지만 사실 별거 없습니다. 중요한 부분은 nginx와 시놀로지가 같은 ssl 인증서를 가지고 있어야 문제없이 작동하기 때문에 시놀로지에 설정한 SSL 파일을 적당한 위치에 복사 후 ssl에 대한 정보를 입력해 주는 것입니다. 그리고 ssl.conf 에서 설정한 ssl 관련 정보를 include로 불러옵니다.

포트에 대한 설정같은 경우는 흔히 80번포트를 nginx에 설정하고 연결되는 서버를 8080등의 비정규 포트를 사용하는데 그럴필요가 전혀 없습니다. 그냥 정규포트를 연결해도 nginx가 알아서 교통정리를 하기 때문에 문제가 되지 않습니다.

그리고 시놀로지의 경우 DSM에 SSL을 적용시 웹 서비스 (80번 포트를 사용하는 서비스 : ex 포토 스테이션, 메일 스테이션)도 SSL을 꼭 적용해야 리디렉션에 오류가 없습니다.

위의 설정을 복사해서 적당히 수정하면 간단하게 nginx로 SSL이 적용된 리버스 프록시를 구성할수 있습니다.

9 댓글. Leave new

  • 처음부터 리버스 프록시로 교통정리를 하면 좋았을껄, 추후에 추가하려고 보니 좀 막막합니다. 이미 몇몇의 vm들이 letsencrypt나 self signed ssl을 가동하고 있는데 하 머리 아프네요. 현재는 그냥 공유기 포트포워딩으로 처리하는 중인데, 나중에 vm 데이터스토어 스토리지 업그레이드 해주면서 vm 재설치등을 통해 깔끔히 정리를 좀 해줘야겠어요.

    응답
    • 현재는 포트별로 나눠 사용하고 계신가요? 웹서버 앞단에 리버스 프록시를 적용하면 관리가 편해서 작업이 귀찮더라도 도입하시는게 좋습니다.

      조만간 이사를 가는데 홈서버라 IP가 외부에 노출되는게 꺼려지던 차에 어짜피 이사가면 IP 바뀔꺼 외부에 프록시를 놓고 돌리자! 라는 마음으로 어제, 오늘 이틀간 리버스 프록시 서버를 집밖으로 빼는 작업을 했습니다. (이틀간 서버 상태가 개판이였던건 비밀)

      클라우드 플레어 무료는 너무 느리고 플랜을 쓰자니 비싸고…. VPS $5 짜리 만들어서 세팅했습니다 ㅋ 근데 생각보다 더 속도가 느리네요. ㅠㅠ

    • 하 몇시간의 작업 끝에 일단은 리버스 프록시 적용 완료한거 같습니다. 며칠 더 보긴 해야겠지만요. 외부 프록시는 아니고 vm을 만들어 내부 네트워크에서 받아서 보여주는 방식으로 적용했습니다. 블로그 외에 다른 웹서비스도 https가 적용되니 마음이 편하네요.

      이 방식을 쓰며 워드프레스에서 캐쉬 플러그인을 쓰면 이중 캐쉬가 되는게 아닌가 싶긴 합니다.

    • 저도 괴ㅈ님 처럼 내부에서 사용하다 옮겼습니다 하핫

      워드프레스는 플러그인은 사용하지 않고(Minify 같은 처리가 너무 느려서) 최대한 백엔드에서 처리해보자 해서 Minify는 Perl로, 캐시도 NGINX fastcgi cache 로 사용하고 있는데 이번에 옮기면서 프록시단에도 proxy cache를 세팅해서 테스트중입니다.

      말씀하신대로 이중캐시인데 NGINX Plus 같은 경우 Purge를 자체적으로 지원해 컨트롤이 쉬워보이는데 무료버전은 갱신시 Purging이 잘 안먹혀서 연구중입니다

    • 방금 wp super cache 플러그인 disable하고 nginx 프록시에서 캐쉬 해보라고 했습니다…….만은, 이게 잘 작동되는지 테스트하기가 어렵네요 하하 어차피 브라우저에서 캐쉬를 하다보니…

    • NGINX에서 캐시 설정할때 헤더 정보를 넣으면 확인하기 편합니다.

      add_header Cache $upstream_cache_status;

      페이지(PHP) 처리 결과값을 서버단에서 캐싱하는 것이라 속도 차이가 꽤 납니다.

    • curl -I 로 확인해보니 이미지 파일들은 확실히 캐슁이 되고 있네요. 웹페이지는 굉장히 빠르게 expire 되는데, 귀찮아서 그냥 캐쉬 플러그인도 다시 켰습니다. 이렇게 해서 이미지 파일만 프록시 선에서 보내주고 나머지는 워드프레스에서 캐쉬된 static html로 보내지면 좋겠네요. ㅋㅋㅋ

  • 안녕하세요
    약2년전 댓글뿐이어서 망설이다가 문의를 드려봅니다

    저는 윈도우 2016 서버 > IIS 환경에 웹서버를 구동시키고 Let’s Encrypt 까지 설정해놓았습니다
    검색을 통해 많은 시행착오를 겪다보니 꽤나 오랜시간이 걸렸지만 도메인을 입력하면 사이트가 뜨는것 까지는 완성된 상태입니다

    그런데, 80포트를 다양하게 활용하고 싶다보니 문제에 직면하게 되었습니다
    예를 들어 도메인으로 80포트를 활용하고 있으면, XPEnology로 설정해놓은 NAS를 도메인:포트 조합으로 사용할 수 밖에 없다는걸 알게되었습니다

    물론 IP를 여러개 보유하고 있다면 고민거리가 되지 않겠지만, 다수의 IP는 역시 많은 부담이 있어 해소방법을 찾던중에
    익스트림메뉴얼을 통해 IIS를 구현한 윈도우에 NginX 를 추가하여 리버스프록시를 구현하면 된다는 힌트를 얻게 되었습니다

    물론 이런 설명이 있는 곳도 이곳이 유일한 상황입니다 ^^;

    그런데 리눅스에 대한 지식이 없고 그림과 설명을 읽고 따라하다보니 NginX를 다운받아 실행시키고 localhost에 접속하여 잘 돌아가는지 확인한 이후로 전혀 손을 대지 못하고 있습니다 ㅠㅠ;

    혹시 윈도우 서버 환경에서 리버스 프록시를 구현하기 위한 조금 더 자세한 포스팅 계획이 있으시거나,
    질문답변이 가능한 공간이 있을까 하여 이렇게 글을 남기게 되었습니다

    현재로서는 80포트는 IIS 를 위한 웹서버에 할당하고 나머지 포트들은 테스트중엔 여러개의 XPEnoloyg에 할당하여 리버스 프록시로 도메인만 입력하여도 각각의 XPEnology 를 잘 찾아갈 수 있도록 하는것이 목표입니다

    혹여나 보시게 된다면 답변 부탁드리겠습니다
    읽어주셔서 감사합니다
    즐거운하루 되세요- ^^

    응답
    • 안녕하세요 테루님

      NGINX 백엔드에 IIS를 두더라도 위 설정에서 달라지는 것은 없습니다.

      포인트는 80/443 포트에 응답하는 웹서버가 NGINX이고 이 NGINX에 리버스프록시를 설정해서 도메인과 내부 IP를 연결해 교통정리를 하는 것인데… 처음 설정하신다면 헤깔릴 수 있겠죠. ^^;

      여름엔 개인적으로 바쁜 시즌이라 긴 설명이 필요한 글을 작성하기 어려운 점 이해 부탁드리며 9월중에 step by step 형식으로 nginx 리버스 프록시에 대한 글을 작성해 보겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Fill out this field
Fill out this field
유효한 이메일 주소를 입력해주세요.

nginx title 03
NGINX WebDAV 설정 방법
WebDAV(Web Distributed Authoring and Versioning)는 http를 이용해 웹서버에 저장되어 있는 파일을 여러 사용자가 편집하기 위해 고안된 프로토콜입니다. 실제로는 FTP 대용으로…
windows nginx php setting title
윈도우 NGINX PHP 연동 및 서비스 등록 방법
이전 포스트에서 윈도우에 NGINX를 설치하고 서비스에 등록하는 방법까지 알아봤는데요. NGINX를 개발 환경 또는 웹서버 환경으로 만들기 위해서 PHP를 설치해야 하는…