-
프론트엔드(웹서버)와 백엔드(WAS)를 나눈 리버스 프록시 구성해보기(w/ubuntu, nginx)각종 학습 요약/Web 2023. 6. 20. 11:11
상황과 필요
ubuntu 22.04에서 web server로 nginx를, WAS로 tomcat(springboot의 embedded tomcat)을 사용하는 상황으로 가정한다.
프론트는 react나 vue 등이 대응하고, api 호출만 백엔드가 호출되도록 하고 싶다.쉽게 말해, 프론트와 백엔드 서버를 나눈 리버스 프록시 구성이다.
이때 https를 어떤 식으로 적용하면 좋을지 생각해보자.
가장 간단한 생각으로, '인증서를 p12 방식으로 변환하여 내장 톰캣 안에 넣어두면 되지 않나? 그러면 WAS만 띄우면 되는데'라고 생각이 들 수 있다.
하지만 그건 몇 가지 불편한 점이 있다고 생각한다.
- 어플리케이션 서버가 클라이언트에게 노출된다.
- 어플리케이션 서버의 컴퓨팅 파워는 어플리케이션을 구동하는데만 힘을 쏟는게 바람직하다. 암복호화는 무겁다.
- certbot이 발급해준 인증서를 굳이 .p12로 변환해둬야 한다.
- 프론트 작업의 산출물이 어플리케이션 프로젝트 안에 포함되어, 빌드 과정을 구성하기가 애매.
- 분리하는게 딱히 어렵지도 않다. 아무리 간단하게 구축을 하기로 해도, 정적 리소스 서빙과 어플리케이션 정도는 구분해두면 좋을 거라고 생각했다.
그밖에도 여러 이유가 있을 수 있겠지만 바로 떠오른 생각은 이 정도였다.
물론 그냥 WAS만 띄워도 무방하다. 뭔가 큰 일이 일어나지 않는다. 몇 가지 귀찮은 일이나, 일어나면 안되는 일이 일어나지 않도록 평소에 좀 더 기도를 하면 해결될 일이다.
하지만 '나는 좀 더 구성해보고 싶다'는 생각이 든다면 아래의 내용을 따라가보는 것도 괜찮다.
nginx 설치와 설정
곧 나오겠지만, 도메인과 네임서버(A레코드) 설정이 준비되어야 한다. certbot으로 인증을 진행할 때, 도메인을 사용할 것이기 때문이다.
일단 사용할 nginx부터 설치해보자.
나는 학습 목적으로 진행한 것이라, 좀 더 편하게 진행할 수 있도록 root 권한을 획득해놓고 진행했으니, 권한 문제가 생긴다면sudo
를 앞에 붙여서 해결하자. 우분투가 아닌 아마존 리눅스를 사용한다면 yum을 활용하자.apt install nginx
설정 파일을 찾아가보자. 우분투 배포판의 apache2처럼,
/etc/nginx/sites-available
에 설정파일을 작성하고 사용해도 되지만, 다음의 경로(/etc/nginx/conf.d/
)에서 설정하는 것이 권장된다고 한다.cd /etc/nginx/conf.d vi default.conf
설정파일이 열렸다. 크게 할 건 없다. 아래와 같이 고쳐주자.
server { listen 80; server_name 도메인네임.com; location / { proxy_pass http://어플리케이션ip:어플리케이션port proxy_set_header Host $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 $host; proxy_set_header X-Forwarded-Port $server_port; } }
도메인네임 부분에 구매한 도메인을 넣으면 된다. 어플리케이션 ip, port 부분에도 알맞게 넣자. private ip를 넣고 8080이 아닌 다른 포트를 넣으면 좋겠지만, 'publicIP:8080' 같은 식으로 넣어도 동작은 잘 될 것이다.
만약 프론트와 어플리케이션을 나누고 싶다면
location
부분을 다음처럼 나누면 된다.location / { root /home/project/프론트디렉토리; index index.html index.htm; try_files $uri $uri/ /index.html; } location ~ ^(/api|/oauth2|/login/oauth2) { proxy_pass http://어플리케이션ip:어플리케이션port proxy_set_header Host $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 $host; proxy_set_header X-Forwarded-Port $server_port; }
프론트, 예를 들어 리액트 빌드 결과물 디렉토리가
location /
의 root 부분에 들어가게 되면, nginx는 먼저 해당 경로에서 자원들을 찾을 것이다.
api 요청(/api
), 그리고 oauth2 인증을 위한 요청(/oauth2, /login/oauth2
)인 경우에만 업스트림으로 향할 수 있도록 한다.위의 설정파일은 매우 간단한 형태이다. 여러 upstream의 정보를 기록해두고 활용하거나, 원하는 정보를 프록시헤더를 덧붙이거나, 어플리케이션의 안정성을 위해 업스트림으로 향하는 요청의 개수를 제한할 수도 있다.
하지만 지금은 간단한 형태로 가고, 각자의 필요에 따라 추후 더해보자.
certbot 설치와 https 인증서 발급
그럼 이제 사용할 certbot을 설치해보자. certbot은 apt가 아닌 snap을 통해 설치하는 것을 권장한다.
snap install certbot --classic
설치가 끝났다면 바로 실행하기만 하면 된다.
certbot --nginx
몇몇 도메인에 한해서 인증을 받고 싶다면 이렇게 하면 된다.
certbot --nginx -d 인증받을거1.com -d 인증받을거2.co.kr -d www.인증받을거1.com
인증에 필요한 email(만료 알림 등이 여기로 온다), 그리고 동의 여부 몇 가지를 물어보고 곧바로 인증서가 설치된다. 다시 nginx 설정파일을 열어보면 변경된 것을 확인할 수 있을 것이다.
브라우저를 열어서 ssl 인증서가 제대로 설치되었는지 살펴보자. 확인이 잘 될 것이다.
하지만 이 인증서의 문제는, 타 인증기관들의 비싼 인증서보다 기간이 짧다는 것이다.
crontab, 인증서 갱신해줘
https 인증서는 만료 30일을 남기고부터 갱신이 가능하다. 만약 갱신하고 싶다면 이런 식으로 하면 된다.
certbot renew
그런데 오늘이 며칠인지 무슨 요일인지도 깜빡거리는 사람이 제대로 갱신을 챙길 거라고 확신할 수 있다면 그건 만용이거나 안전불감증이거나 면허취소의 음주 상태일 수 있다.
crontab을 이용해서 매일 매일 갱신을 체크하자.
crontab -e
새로운 cron을 install 하는 명령어다.
만약 크론을 처음 열어본다면 '어떤 에디터로 열래?'' 같은 질문이 나올 수도 있는데, 그냥 마음에 드는 걸로 열면 된다.
열었으면 아래와 같이 입력하자.
0 3 * * * certbot renew --quiet --post-hook "sudo service nginx reload"
매일 03:00에 'certbot renew 어쩌구'' 하는 명령어를 실행하는 구문이다. 뒤의 옵션은, 말 그대로 출력없이 조용히 갱신만 해달란거, 그리고 끝나면 nginx를 reload 해달라는 말이다.
정리
끝이다. 나중에 시간이 되면, 이 포스팅을 활용해서 구성한 기본적인 형태의 어플리케이션을 구성해보도록 하겠다.
출처 및 참고문헌
- 오늘의 주제를 처음 도전할 때, nginx와 https 설치 포스팅의 글에서 도움을 많이 받았습니다. 위 내용을 토대로 제가 알고 있는 것들을 추가했습니다. 좋은 글을 써주셔서 감사합니다.
- nginx의 리버스 프록시 설정을 처음 공부할 때 이 영상의 도움을 많이 받았습니다. 그밖에도 유익한 정보를 얻을 수 있는 채널이니 한번 둘러보시는 것도 좋겠습니다.
'각종 학습 요약 > Web' 카테고리의 다른 글
리눅스 가상메모리 켜기 (0) 2023.07.06 Concept: REST API의 기본 개념 이해와 활용 (0) 2022.06.08 DNS의 작동 원리를 설명하는 9분 짜리 영상 (0) 2022.06.07 flex layout에 대한 간단한 이해 (3) 2022.04.30 HTML Page Layout : Flexbox로 레이아웃 잡기 (2) 2022.04.28 HTML Page Layout : 화면을 나누는 방법 (0) 2022.04.28