docker nginx로 proxy 다루기

김성준·2022년 3월 2일
3

Docker

목록 보기
6/6
공부하면서 작성한 내용이라 부정확할 수 있습니다.😀

Proxy server란

  • 일반적으로 서버와 클라이언트가 직접 요청과 응답을 주고받는데, 프록시라는 서버를 서버와 클라이언트 사이에 두어서, 클라이언트가 다른 네트워크 서비스에 접속할 수 있도록 해줄 수 있다.

Forward Proxy

  • 클라이언트가 직접 외부 인터넷에 접근하는 것이 아니라, 프록시 서버가 대신 외부 인터넷에 접근 요청을 하고, 그 결과를 클라이언트에게 전달해주는 역할. (중국처럼 ㅋ)

Reverse Proxy

  • Forward proxy처럼 외부 인터넷과 클라이언트 사이를 중계하는 것이 아니라, 내부 서버와 클라이언트 사이를 중계해준다.
  • 클라이언트가 Reverse Proxy에 요청을 하면, Reverse Proxy가 적절한 내부 서버에 접속하여, 결과를 받은 후, 클라이언트에 전달해준다.
  • 상용화를 할 때 꼭 필요한 기능

nginx로 reverse proxy 테스트하기

테스트폴더는 docker compose 파일 1개
nginx.conf(웹서버 설정파일)를 포함하고 있는 폴더 1개
로 이루어진 폴더로 진행합니다.

1. 포트로 구분하기

(location 기능을 사용하여 reverse proxy 구현 가능)

  • nginx reverse proxy 서버에 포트를 두 개 오픈한 후, 각 포트 접속시, 각 내부 서버에서 결과를 가져오도록 구성
  • 포트로 reverse proxy를 구분할 때,
    • 우선, docker compose로 컨테이너를 세개 만들고(A,B,C) A컨테이너에만 포트를 오픈한다. 그리고 나머지 두개의 컨테이너에는 A 컨테이너에 depend on 설정을 해 둔다.
    • 웹서버 설정(nginx.conf)로 가서, reverse proxy를 제외한 컨테이너의 수만큼 upstream설정을 만들어준다.
    • 포트별로 각각의 server를 만들고, listen에 연결하고 싶은 포트를 할당해준다.

docker-compose.yml:
nginx/nginx.conf : ↑보통 이 부분은 건들지 않고, ↓이 다음 부분부터 바꿔준다.

proxy header 설정에 관한 부분은 바꾸어 줄 일이 없이, 복붙한다고 적어놨는데, 이 설정이 존재하는 이유를 먼저 알아야 한다.

reverse proxy와 내부 서버 사이에 http 통신을 하고 난 후 서버의 로그를 살펴보면, 프록시 서버가 단순히 내부 서버에 접속했다고만 뜨지, 어떠한 클라이언트가 언제 어디로 접속했는지는 전혀 뜨지 않는 문제점이 있다.
따라서 위의 설정은 내부서버에 리버스 프록시 서버가 접속 할 때 같이 넘겨줄 클라이언트에 관한 정보에 대한 설정이다.
따라서, 굳이 손대지 않고 디폴트로 놔두어도 잘 돌아간다.

설정해설
proxy_redirect서버 응답 헤더의 주소 변경
Host$hostHost 헤더가 없다면, server_name
X-Real-IP클라이언트 IP 주소
X-forwarded-For(XFF)클라이언트 IP 주소를 식별하기 위한 설정으로, 클라이언트 IP부터 중간 서버 IP들을 리스트로 작성해서 송부함
X-Forwarded-Host중간 서버가 아닌, 실제 클라이언트의 호스트 이름을 기록함
X-Forwarded-Proto클라이언트와 reversed proxy 접속시 사용한 프로토콜 설정(https)
(-> 클라이언트가 HTTPS로 요청을 했다고 하더라도 reverse proxy는 HTTP로 내부 서버에 접속을 할 수 있기 때문에,
본래 클라이언트의 프로토콜을 담는다.

2. 경로로 구분하기

위의 설정을 기반으로 합니다.
docker-compose.yml :

nginx/nginx.conf :

nginx 웹서버를 설치하고 나서, default 설정에 의한 root 폴더 내에 경로명과 같은 blog, community 폴더를 만든 다음, 그 내에 html 파일을 넣어 놓아야 경로로 이동을 했을 때 HTML 페이지가 사용자에게 보여질 것이다.

3. 경로로 구분하기(내부 서버에 요청하는 경로는 변경하기)

이 예시를 배우는 이유 : 만약 기존에 구축해 놓았던 서비스에서 새로운 서버를 추가로 더 증축하였을 때, 단순히 경로만으로 구분을 한다면, 추가한 규모만큼 폴더와 파일을 만들거나 변경해야 하기 때문에, 많이 번거롭다.
하지만 경로명을 reverse server에서 자의적으로 바꾸어 준다면, 이러한 과정을 거치지 않고도 경로를 지정해 줄 수 있다.

예를 들어,
사용자가 자신의 reverse server에 localhost/blog/index.html을 요청했을 때, reverse server는 내부서버에 localhost/index.html을 요청한 것처럼 변경해 주는 것이다.

이렇게 경로를 변경하기 위해서는, nginx/nginx.conf 설정파일의 server항목에서 rewrite 설정만 추가를 해주면 된다.

rewrite <regex> <변경할 URL> < 옵션>
정규식해설
^/blogblog로 시작하는 경로 의미
(.*)한 글자 이상의 문자(. : 한글자, * : 0회 이상)
$끝나는 문자열
$1(.*)괄호로 되어 있는 부분을 의미/ 여기서는 /blog/이후의 문자열

즉, ^/blog(.*)$ $1 break; 는 '/blog로 시작하는 문자열의 시작부터 끝까지를 $1로 대체하라'라는 의미이다.
예) http://13.208.45.243/blog/test.html
http://13.209.45.243/test.html
로 변경된 채로 내부 서버에 경로가 전달이 된다.

(주로 쓰는 옵션으로는 break가 있는데, 이는 정규표현식에 의해 변경된 UR이 다른 location으로 연결되어 무한로딩되는 것을 막아준다.)

참고) 새롭게 만든 nginx 웹서버 컨테이너에서 HTML 파일 확인 방법
1. docker-compose로 만든 컨테이너에 접속을 하여
2. etc/nginx/conf.d/default.conf를 cat하여
3. 확인하고자 하는 경로의 root를 확인해보면
4. 서버에서 보여줄 HTML에 관련된 파일이 어디에 있는지를 확인해 볼 수 있다.

참고2)
nginx location match tester

nginx.conf에서 여러 개의 location으로 경로를 설정했을 때, 어떠한 URL로 접속을 해야 해당 경로로 연결이 되는지를 보여주는 사이트.
.conf의 server 항목만 복붙을 하면 된다.

0개의 댓글