Physical Address
South Korea
Physical Address
South Korea


안녕하세요! 인프라를 구축하거나 웹 서비스를 운영하다 보면 한 번쯤 “웹 서버(WEB)와 와스(WAS)를 왜 굳이 나눠야 하지?”라는 의문이 들 때가 있습니다.
최근에 제가 진행한 프로젝트에서도 WEB(Nginx)과 WAS(Tomcat)에서 각각 독립된 도메인을 사용할 수 있도록 인프라를 바꿀 일이 있었는데요. 도메인을 분리하면 초기 세팅이나 관리 측면에서 조금 복잡해지는 건 사실입니다. 하지만 어플리케이션 관점에서 서비스를 확장하거나 유지보수할 때 얻는 장점이 훨씬 크기 때문에 결국 리버스 프록시(Reverse Proxy) 구성을 선택하게 되었습니다.
오늘은 RHEL 9.6 환경에서 Nginx를 활용해 Tomcat 리버스 프록시를 직접 구축하며 겪은 과정과, 저를 깊은 빡침(?)에 빠뜨렸던 트러블슈팅 경험을 생생하게 공유해 보려고 합니다.

이론적인 이야기보다 실제 체감한 장점을 위주로 말씀드릴게요. 우리가 흔히 아는 ‘프록시(Forward Proxy)’는 회사나 학교 PC에서 외부 인터넷을 나갈 때 거치는 중개자라면, 리버스 프록시는 반대로 외부 사용자가 우리 서버에 들어올 때 최전방에서 요청을 맞이하는 ‘문지기’ 역할을 합니다.
사용자가 웹사이트 주소를 치고 들어오면 Tomcat으로 바로 꽂히는 게 아니라, 최전방에 있는 Nginx가 요청을 먼저 받아서 내부 네트워크에 있는 Tomcat에 전달해 주는 구조죠.
인터넷에 찾아보면 장점이 참 많이 나오는데, 제가 실무에서 느끼는 핵심 장점은 크게 4가지입니다.
리버스 프록시를 두면 외부 사람들은 오직 Nginx의 IP만 볼 수 있습니다. 실제 핵심 데이터와 비즈니스 로직이 돌아가는 Tomcat 서버의 IP와 포트 번호는 꽁꽁 숨겨지기 때문에, 해커들이 직접 Tomcat을 공격하는 걸 원천 차단할 수 있습니다.
요즘 HTTPS(SSL/TLS) 적용은 선택이 아닌 필수죠. 그런데 이 암복호화 과정이 서버 자원을 은근히 많이 잡아먹습니다. 이걸 Tomcat이 직접 처리하게 하면 성능이 떨어지는데, 고성능 Nginx가 앞에서 SSL 인증 처리를 전담(Termination)해 주면, Tomcat은 오롯이 비즈니스 로직 처리에만 집중할 수 있어서 전체 시스템이 쾌적해집니다.
서비스가 잘 되어서 사용자가 몰리면 서버 한 대로 감당하기 힘들어집니다. 이때 리버스 프록시 뒤에 Tomcat 서버를 2대, 3대 늘려두고 Nginx가 요청을 골고루 나눠주도록(Load Balancing) 설정할 수 있습니다. 무중단 서비스를 위한 첫걸음인 셈이죠.
이미지, CSS, 자바스크립트 같은 정적 파일은 굳이 무거운 Tomcat이 일일이 응답할 필요가 없습니다. 이런 정적 파일 서빙은 Nginx가 기가 막히게 잘하거든요. 정적 파일은 Nginx가 그 자리에서 바로 던져주고, DB 조회가 필요한 동적 요청만 Tomcat으로 토스해 주면 페이지 로딩 속도가 눈에 띄게 빨라집니다.
백문이 불여일견이니 바로 세팅해 보겠습니다. RHEL 9 환경은 최신 패키지를 안정적으로 제공하는 AppStream 저장소를 기본으로 써서, 귀찮은 소스 컴파일 없이 dnf 명령어로 아주 깔끔하게 설치할 수 있습니다.
먼저 시스템 패키지들을 최신으로 정리하고 Nginx를 설치해 줍니다.
Bash
# 시스템 패키지 업데이트
sudo dnf update -y
# Nginx 설치
sudo dnf install nginx -y
설치가 끝났다면 서버가 불의의 사고로 재부팅되더라도 Nginx가 알아서 살아서 켜지도록 자동 시작(enable) 설정을 해줍니다. --now 옵션을 붙이면 활성화와 동시에 서비스가 시작됩니다.
Bash
# 서비스 시작 및 부팅 시 자동 시작 등록
sudo systemctl enable --now nginx
# 서비스 상태 확인
sudo systemctl status nginx
화면에 초록색 불로 active (running) 상태가 보인다면 일단 첫 단추는 잘 꿴 것입니다.
RHEL 시스템은 보안이 깐깐해서 기본적으로 문을 다 닫아두고 있습니다. 우리가 웹 서비스를 하려면 외부에서 들어오는 HTTP(80)와 HTTPS(443) 포트를 열어주어야 합니다.
Bash
# 80(HTTP) 및 443(HTTPS) 서비스 허용
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# 변경 사항 시스템에 적용
sudo firewall-cmd --reload
이제 브라우저를 켜고 서버 IP 주소로 접속했을 때 Nginx 환영 페이지(Welcome to nginx)가 뜬다면 네트워크 길은 뚫린 겁니다.
이제 이번 작업의 하이라이트입니다. 클라이언트가 80번 포트(HTTP)로 접속하면, Nginx가 이걸 받아서 내부에서 돌고 있는 8080 포트(Tomcat)로 싹 넘겨주는 설정을 해보겠습니다.
기본 nginx.conf 파일을 직접 수정해도 되지만, 나중에 도메인이 늘어나거나 관리를 편하게 하려면 /etc/nginx/conf.d/ 디렉토리에 독립된 설정 파일을 만드는 것이 정석입니다. 저는 proxy.conf라는 이름으로 파일을 만들었습니다.
Bash
sudo vi /etc/nginx/conf.d/proxy.conf
파일 안에 아래 내용을 싹 복사해서 넣어줍니다. 그냥 주소만 넘기는 게 아니라, 실제 접속한 사용자의 진짜 정보를 Tomcat이 알 수 있도록 헤더 값을 함께 넘겨주는 게 포인트입니다.
Nginx
server {
listen 80;
server_name example.com; # 본인의 실제 도메인이나 서버 IP를 적으세요.
location / {
# 같은 서버 안에서 돌고 있는 Tomcat(8080) 주소로 요청 전달
proxy_pass http://127.0.0.1:8080;
# 중요: 클라이언트의 진짜 정보를 백엔드 서버에 보존해서 전달
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;
# 타임아웃 설정: 대용량 처리나 느린 네트워크 대응을 위해 90초 설정
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
}
}
자, 이렇게 설정을 다 하고 Nginx를 재시작한 뒤 접속해 보면 10명 중 8명은 502 Bad Gateway 라는 시뻘건 에러 페이지를 마주하게 됩니다. Nginx 설정도 완벽하고 Tomcat도 분명 8080 포트로 잘 뜨고 있는데 말이죠.
인터넷 커뮤니티나 지식인에 “Nginx 토캣 연동 안 돼요”라고 올라오는 질문의 대부분이 바로 이 문제입니다. 원인은 RHEL 계열(CentOS, Rocky, Alma 포함)의 강력한 보안 형님인 SELinux가 Nginx가 내부 네트워크 소켓(8080 포트)에 접근하는 것을 깡그리 차단하고 있기 때문입니다.
이 문제를 해결하려면 SELinux에게 “Nginx가 다른 네트워크에 연결할 수 있게 허락해 줘”라고 명령어 한 줄을 내려줘야 합니다.
Bash
# Nginx의 네트워크 연결 허용 (재부팅해도 유지되도록 -P 옵션 필수)
sudo setsebool -P httpd_can_network_connect 1
이 명령어 하나면 그동안 속 썩이던 502 에러가 눈 녹듯 사라지고 Tomcat 페이지가 깔끔하게 열리는 것을 볼 수 있습니다. (진짜 이거 몰라서 밤새우는 분들 많습니다.)
마지막으로 모든 조각이 제대로 맞춰졌는지 확인하고 서비스를 반영할 차례입니다.
우선 Tomcat이 8080 포트에서 정상적으로 요청을 받을 준비(Listen)가 되었는지 확인합니다.
Bash
ss -tlpn | grep 8080
설정 파일을 고치고 나서 무턱대고 서비스를 재시작했다가 오타라도 있으면 웹서버가 죽어버립니다. 실무에서는 서비스를 내리기 전에 반드시 문법 검사를 하는 습관이 중요합니다.
Bash
# 설정 파일 문법 검사
sudo nginx -t
화면에 nginx: the configuration file ... syntax is ok와 test is successful이라는 문구가 나오면 안심하셔도 됩니다. 이제 설정을 적용해 줍니다.
Bash
# Nginx 재시작
sudo systemctl restart nginx
모든 설정을 마쳤는데도 접속이 안 된다면 당황하지 말고 아래 4가지 항목과 명령어를 통해 하나씩 점검해 보세요.
| 점검 항목 | 확인할 내용 | 확인 명령어 |
| Nginx 설치 | 패키지가 정상적으로 설치되었는가? | dnf list installed nginx |
| 서비스 상태 | Nginx가 활성화되어 돌고 있는가? | systemctl status nginx |
| SELinux 보안 | 네트워크 연결 권한이 허용(1)되었는가? | getsebool httpd_can_network_connect |
| 네트워크 방화벽 | 80, 443 포트가 외부로 열려있는가? | firewall-cmd --list-all |
이번 가이드를 통해 RHEL 9 환경에서 Nginx를 앞단에 세우고 Tomcat을 리버스 프록시로 엮는 전 과정을 살펴보았습니다.
초기 세팅할 때 SELinux나 방화벽 때문에 약간 손이 가긴 하지만, 이렇게 구조를 잡아두면 나중에 사용자가 많아져서 서버를 증설할 때(로드 밸런싱)나, Certbot을 이용해 Let’s Encrypt 공짜 SSL 인증서를 적용할 때 정말 상상 이상으로 편해집니다.
서버 인프라의 기초 체력을 기른다고 생각하시고 천천히 적용해 보세요. 진행하다가 막히는 부분이 있다면 언제든 문의해 주세요!
[RHEL 9.6 환경에서 OpenVPN 서버 구축 및 DBA를 위한 활용 가이드]
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy