Nginx Reverse Proxy 설정하는 법 정리

HD.Y·2024년 1월 27일
0

한화시스템 BEYOND SW

목록 보기
48/58

Nginx Reverse Proxy 란 ❓

  • 먼저, 설정에 앞서 Nginx Reverse Proxy를 설정하는 이유에 대해 생각해보고자 한다.

  • Proxy 란 ❓
    다른 서버에서 리소스를 찾는 클라이언트의 요청에 대한 중개자 역할을 하는 서버이다. 프록시 서버는 클라이언트와 클라이언트가 찾고 있는 데이터를 호스팅하는 실제 서버 사이에 위치한다.

  • Nginx Reverse Proxy 란 ❓
    리버스 프록시란 클라이언트와 웹 서버 간의 중개자 역할을 하는 서버로, 클라이언트로부터의 요청을 대신 받아 웹 서버에 전달하고, 웹 서버의 응답을 클라이언트에게 전달하는 역할을 한다. 이를 통해 리버스 프록시는 웹 서버의 부하를 분산시키고, 보안을 강화하는 등 다양한 기능을 수행할 수 있다.

    기본 작동 원리는 클라이언트가 Reverse Proxy에 요청을 보내면, Reverse Proxy는 요청을 웹 서버에 전달한다. 그다음, 웹 서버는 요청된 데이터를 처리한 후 응답을 보낸다. 그리고 Reverse Proxy는 웹 서버로부터 받은 응답을 클라이언트에게 전달하는 방식으로 동작한다.

  • Nginx Reverse Proxy의 필요성 🧐

    서버 부하 분산 (Load balancing)
    웹 서비스에 동시에 많은 사용자가 접속할 경우, 서버에 부하가 집중되어 성능 저하 및 서비스 중단이 발생할 수 있다. 리버스 프록시는 들어오는 요청을 여러 대의 서버로 분산시켜 각 서버의 부하를 줄이고, 서버의 가용성을 높여 안정적인 서비스 제공이 가능하도록 한다.

    보안 강화
    리버스 프록시는 외부에서 직접 서버에 접근하지 못하도록 하여 웹 서비스의 보안을 강화한다. 클라이언트 요청은 먼저 리버스 프록시를 거쳐 서버로 전달되며, 이 과정에서 리버스 프록시는 악성 요청 필터링, 접근 제한 등의 역할을 수행하여 서버를 보호한다.

    캐싱 및 가속화
    리버스 프록시는 자주 사용되는 정적 파일들(이미지, CSS, JavaScript 등)을 캐시에 저장하여 빠르게 제공할 수 있다. 이로 인해 서버의 부하를 줄이고 응답 시간을 단축시켜 웹 서비스의 성능을 향상시킬 수 있다.


  • 리버스 프록시의 장점 🔥

    1) 로드 밸런싱 : 여러 서버에 트래픽을 분산시켜 서버 부하를 줄이고 가용성을 높일 수
               있다.
    2) 보안 강화 : 리버스 프록시는 외부 요청을 필터링하여 보안을 강화한다.
    3) 캐싱 : 정적 콘텐츠를 캐시하여 응답 시간을 개선하고 서버 부하를 줄인다.
    4) 웹 서버 최적화 : 리버스 프록시를 사용하여 웹 서버의 설정 및 성능을 최적화할 수
                 있다.

  • 리버스 프록시의 단점 🔥

    1) 추가적인 서버 설정과 관리 : 리버스 프록시를 사용하려면 추가적인 서버 설정과
                   관리가 필요하다.
    2) 네트워크 지연 : 리버스 프록시를 통과하는 모든 요청에 대해 약간의 네트워크 지연이
              발생할 수 있다.
    3) 복잡성 증가 : 리버스 프록시가 있는 아키텍처는 일부 경우에 복잡성이 증가할 수
             있다.


사전 준비사항 💻

  • 실습은 수업때 진행되는 내용을 바탕으로 진행하다 보니, 아래와 같이 사전에 진행한 내용이 있었다.

  • AWS 1개의 EC2에 백엔드 서버를 배포하고, 해당 EC2 퍼블릭 IP 주소에 대한 도메인을 발급 받아 놓는다. ( 인증까지 완료하면 좋다. )
    설정법 참고


🦁 Nginx Reverse Proxy 설정하기

  • 먼저 프론트 엔드의 백엔드로 호출하는 JS 코드들을 모아놓은 JS 파일에 백엔드로 요청하는 URL을 아래와 같이 발급 받은 도메인 주소/api로 변경한다.

    const backend = 'https://www.test.kro.kr/api';

    ➡ 그러면 웹페이지에서 요청이 나갈때 https://www.test.kro.kr/api/user/signup
      같은 URL로 요청이 보내질 것이다.

  • 다음으로, 프론트 페이지들을 만든 것을 Nginx 에 적용시켜야 된다. 그러기 위해선 예전에 이용한 FileZilla 프로그램을 사용하였다.

  • 사용하면서 문제가 됬던 것은 작성한 HTML, CSS, JS 파일들을 모두 nginx 의 /var/www/html 폴더로 옮겨야 되는데, FileZilla에서 자꾸 전송을 실패하는 것이다.
    알고보니 해당 폴더로 파일을 옮기려면 root 계정으로 우분투 서버를 연결해야 가능했다.


    root 계정으로 연결하는 방법

    1) 일단 Putty를 이용하여 접속 후 root 권한으로 바꿔준다 : sudo su - root

    2) SSH 설정 파일을 편집해 줘야 한다 : vi /etc/ssh/sshd_config

    3) 설정 파일의 33번째 줄 밑에 아래와 같이 PermitRootLogin yes 를 추가해준다.

    4) 그런다음 암호키를 복사한다
      ➡ sudo cp /home/ubuntu/.ssh/authorized_keys /root/.ssh

    5) 다음으로 SSH를 재시작한다 : sudo service ssh restart

    6) FileZilla에서 root 로 연결한다.
      ➡ 연결은 기존 방식과 동일하나 기존에는 사용자를 ubuntu로 했다면, 이번엔
         root로 적으면 된다.

    7) 연결이 성공적으로 됬다면, 리모트 사이트에서 /var/www/html 을 검색하여 해당
      디렉토리에 작성한 HTML, CSS, JS 파일들을 드래그하여 옮겨주면 된다.


  • 마지막으로 nginx 서버 설정에서 Reverse Proxy 설정 및 nginx 의 디폴트 페이지를 바꿔주면 된다.

  • 서버 설정 파일 열기 : sudo vi /etc/nginx/sites-available/default

  • 디폴트 페이지 설정 ( 도메인주소로 접속했을때 가장 먼저 뜨는 페이지 지정 )

    ➡ 44번째 줄의 index.html 글자 앞에 내가 넣어주고 싶은 페이지를 적으면 된다. 나는
      index.html 을 그냥 한번 더 적어봤다.

  • 마지막으로, Reverse Proxy 설정은 위의 그림의 박스 친 것처럼 설정해주면 된다. 코드는 아래에 있다.

  • 그림에는 rewrite 줄에 ?$args 가 포함되어 있지만 이것은 오류가 있어 빼야된다!! 아래 코드를 사용하자❗

		location /api {
                rewrite ^/api(.*)$ $1 break;
                proxy_pass   http://localhost:8080;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP $remote_addr;
        }

    ➡ 해당 설정이 의미하는 내용은 /api 를 달고 들어오는 요청을 받아서 proxy_pass 에
     지정한 url
로 /api를 빼고 보낸다는 의미이다.

    ➡ 이와 같이 밑으로 여러개를 더 추가할 수 있다. 예를 들어 /api 가 아닌 /test를 달고
     오는 url
을 처리해주기 위해서는 location /test 로 설정을 추가해주면 된다.


  • 이렇게 설정하면, 이제 클라이언트가 웹페이지에서 서버로 요청을 보내면 nginx에서 Reverse Proxy로 요청이 가고, url을 통해 해당하는 백엔드 서버를 찾아서 그 주소로 요청을 보내게 된다.
  • Reverse Proxy 설정 간에 프록시 설정이 잘 되지 않아서, 502 Bad GateWay 에러가 처음에는 계속 떴었다. 그 이유는 백엔드 서버의 주소를 http://localhost:8080 이 아닌 동일한 EC2에서 백엔드 서버를 운영하고 있으니, 해당 도메인 주소를 써보고, 퍼블릭 ip 도 써보고 했었는데, 알고보니 localhost를 그냥 쓰면 되는 거였다.

  • 나는 localhost:8080 이 EC2 가 아닌 내 원래 컴퓨터의 로컬 IP 주소를 의미하는 것으로 착각해서 EC2의 백엔드 서버로 계속 요청을 보내야되는데로 고민을 길게 했던 것이다.

  • 그때, EC2가 무엇일까란 생각이 들면서 결국 EC2가 가상의 컴퓨터를 만들어준다는것이 생각났다.

  • 결국, localhost 라는 것이 어떤 시스템에서든 자기 자신을 나타내는 호스트 이름으로 웹서버를 실행하는 해당 서버 자체를 가리킨다는 것을 말하는데, EC2 인스턴스는 가상의 컴퓨터이고, 그곳에서 백엔드 서버를 실행중이라면, 이 서버에서 사용한 localhost가 EC2 인스턴스 IP 인 것이나 다름없는 것이다.


EC2 접속 종료시에도 서버를 유지하는 방법

  • 실습을 마무리하고, 갑자기 든 생각으로 Putty 접속을 종료했을 때, 동작중인 백엔드 서버가 꺼지기 때문에, 그럼 어떻게 컴퓨터를 종료하고도 항상 서버가 유지되도록 하지? 라는 의문이 들었다. 그것을 가능하게 해주는 것이 nohup 명령어라는 것을 알았다.

  • nohup 명령어는 로그아웃 등과 같이 터미널과의 세션 연결이 끊기더라도, 프로세스가 계속 동작되도록 해준다.

  • 일반적으로 터미널과의 세션 연결이 끊기게 되면, 리눅스에서는 해당 세션에서 실행된 프로세스들에게 HUP(Hang Up,끊다) 시그널을 전달하여 프로세스들이 종료되도록 한다.

    이 때, nohup 명령은 “세션이 종료되더라도 계속 실행하게 하고 싶은 프로세스에는 HUP 시그널을 전달하지 않도록(No Hang Up,끊지마) 한다"는 의미이다.

  • 사용방법은 아주 간단합니다. 프로그램 실행 명령어 앞에 nohup 만 붙여주면 된다.

    ➡ 기존 실행 명령어 : java -jar [jar 파일명]

    백그라운에서 실행 시 : nohup java -jar [jar 파일명] &

  • 실행하면 스프링 부트 서버가 백그라운드에서 동작하게 된다. 따라서 에러가 떠도 로그가 출력되지 않는데, 이것은 명령어를 실행한 경로에 "nohup.out" 이라는 log파일이 생성되기 때문에 해당 로그 파일을 조회하면 로그를 볼 수가 있다.

    로그 확인 명령어 정리

    1) 로그 조회 : cat nohup.out
    2) 실시간 로그 출력 : tail -f nohup.out
    3) 마지막 10줄 조회 : tail -n 10 nohup.out
    4) 파일의 10번째 줄 이후 부터 출력 : tail -n +10 nohup.out

  • 그러나, 필요 이상의 로그를 화면에 계속해서 출력하게 되면 nohup.out 파일의 용량이 매우 커지기 때문에, 디스크 공간을 낭비하게 될 수도 있다고 한다. 따라서, 꼭 필요한 로그만 출력하거나 로그를 남기는 것이 불필요한 경우 nohup.out 파일을 생성하지 않도록 하는 것이 좋을 수도 있다.

    nohup.out 파일 생성하지 않고 백그라운드 실행 명령어
      nohup [실행파일명] 1>/dev/null 2>&1 &

      // 0 : 표준 입력,     1 : 표준 출력,     2 : 표준 에러
      // 1> /dev/null : 표준 출력(1)의 결과를 /dev/null(버림)으로 전달
      // 2>&1 : 표준 에러(2)를 표준 출력(1)이 전달되는 곳(/dev/null)으로 동일하게 전달

    표준 출력과, 표준 에러 로그를 따로 관리하고 싶을 때
      nohup [실행파일] 1>[파일1] 2>[파일2] &

  • 마지막으로, 실행한 프로세스를 종료하기 위해서는 PID 값을 찾아서 종료 시켜줘야된다.
    ➡ PID 찾기 ( java -jar 로 된 것 ) : ps -ef | grep [실행파일명]
    ➡ 프로세스 종료 : sudo kill -9 [찾은 PID 번호]


Vue 프로젝트 배포 시 nginx 설정 파일 (24. 2.10. 추가)

  • Vue로 배포할때는 nginx 설정파일이 또 달라지는데 그 내용은 아래와 같다.

        location / {
                index index.html;
                try_files $uri $uri/ @rewrites;
        }

        location @rewrites {
                rewrite ^(.+)$ /index.html last;
        }

        location /api {
                rewrite ^/api(.*)$ $1 break;
                proxy_pass   http://localhost:8080;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP $remote_addr;
        }

  • 여기서 중요한게 rewrite 부분이라고 생각된다. /api 를 달고 오는 요청에 대한
    처리인데 이부분을 조금만 잘못 적어도 요청이 제대로 처리가 되지 않았다.
profile
Backend Developer

0개의 댓글