조회수: 0
목차
reverse proxy란 무엇이고 왜 쓰는가
웹을 외부에 공개할 때 서버 하나에 직접 포트를 열어두는 방식은 관리와 보안 면에서 한계가 있다. 특히 이런 상황에서 reverse proxy는 매우 유용하다.
- 여러 내부 서버를 하나의 도메인·IP로 묶어 외부에 노출
- 애플리케이션 서버는 사설망에 숨겨두고, nginx만 DMZ 또는 공인망에 배치
- SSL 종료, 압축, 캐싱, 접속 로그 등 공통 기능을 프록시 단에서 처리
여기서 말하는 reverse proxy는 “클라이언트 입장에서 보면 실제 서버처럼 보이는 프록시”다. 클라이언트는 nginx까지밖에 모르고, nginx가 내부 서버로 요청을 전달한 뒤 응답을 대신 돌려준다.
내부 서버를 외부에 공개하는 전체 구조
nginx reverse proxy로 내부 서버를 외부에 공개하는 구조를 단순화해서 그려보면 대략 이렇게 된다.
- 클라이언트(인터넷 사용자)
- 브라우저에서
https://example.com요청
- 브라우저에서
- 공인망에 있는 nginx 서버
- 공인 IP 또는 포트포워딩된 80/443 포트를 사용
- 리버스 프록시 역할로 내부 서버에 HTTP 요청 전달
- 내부망(사설망)에 있는 애플리케이션 서버
- 예: 192.168.0.10:8080, 192.168.0.11:3000
- 외부에서는 직접 접근 불가능
이 구조의 핵심은 “외부에서 직접 내부 서버에 붙지 않고, 반드시 nginx를 경유하도록 만드는 것”이다. 외부의 모든 트래픽이 nginx를 지나가기 때문에, 접근 제어·로그·SSL·리다이렉트 등 정책을 한 곳에서 통제할 수 있다.
nginx reverse proxy 기본 동작 원리
nginx가 reverse proxy로 동작할 때의 기본 흐름을 정리해 보자.
- 클라이언트가 nginx의 도메인/포트로 HTTP(S) 요청을 보낸다.
- nginx는 설정 파일의 server / location 블록에서 이 요청을 어떤 내부 서버(upstream)로 보낼지 결정한다.
proxy_pass지시어를 이용해 내부 서버로 HTTP 요청을 전달한다.- 내부 서버가 응답을 보내면 nginx가 이 응답을 받아 클라이언트에게 다시 전달한다.
이 과정에서 nginx는 다음과 같은 작업들을 추가로 수행할 수 있다.
X-Forwarded-For,X-Real-IP등 헤더를 추가해 원래 클라이언트 IP 전달- gzip 압축, 캐싱, 헤더 추가/삭제
- HTTP → HTTPS 리다이렉트
- URL 리라이트, 특정 경로만 다른 서버로 라우팅 등
기본 reverse proxy 설정 예제
가장 단순한 예제를 하나 보자. 공인 IP를 가진 nginx 서버가 있고, 내부에 192.168.0.10:8080에서 웹 애플리케이션이 동작한다고 가정한다.
/etc/nginx/sites-available/myapp.conf 예시:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://192.168.0.10: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;
}
}
여기서 중요한 포인트는 다음과 같다.
proxy_pass에 내부 서버 주소(사설 IP)를 지정Host헤더를 원래 요청 도메인으로 유지하도록proxy_set_header설정- 원래 클라이언트 IP를 내부 서버에 전달하기 위한
X-Real-IP,X-Forwarded-For
이 설정을 넣은 뒤 nginx 설정을 테스트하고 재시작한다.
sudo nginx -t
sudo systemctl reload nginx
이제 브라우저에서 http://example.com으로 접속하면, 실제로는 nginx가 내부 192.168.0.10:8080에 요청을 보내고 그 응답을 가져와 보여주게 된다.
여러 내부 서버를 하나의 nginx로 공개하기
실무에서는 보통 내부에 서비스가 여러 개 있다. 이때 nginx reverse proxy는 다음과 같이 라우팅할 수 있다.
도메인 단위로 분리
api.example.com→ 내부 192.168.0.10:8080admin.example.com→ 내부 192.168.0.11:3000
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://192.168.0.10: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;
}
}
server {
listen 80;
server_name admin.example.com;
location / {
proxy_pass http://192.168.0.11:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
경로(Path) 단위로 분리
같은 도메인에서 경로에 따라 다른 내부 서버로 보내는 것도 흔하다.
/→ 192.168.0.10:8080 (웹 프론트)/api/→ 192.168.0.11:3000 (API 서버)
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://192.168.0.11:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://192.168.0.10: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_pass 뒤에 /를 붙이느냐 마느냐에 따라 실제 전달되는 URI가 달라지니 주의가 필요하다. API 서버가 /api를 전제로 라우팅을 구성했는지, 루트(/)를 전제로 했는지에 맞춰 설정을 조정해야 한다.
HTTPS(SSL/TLS) 적용과 reverse proxy
실제 서비스에서는 HTTP만 공개하기보다는 HTTPS를 기본으로 사용하는 것이 일반적이다. nginx가 SSL 종료를 담당하게 하면 내부 서버는 HTTP로만 통신해도 된다.
기본 HTTPS 설정 흐름
- 도메인에 대한 인증서 발급 (Let’s Encrypt 등)
- nginx의 server 블록에서 443 포트 listen,
ssl_certificate설정 - 서버 내부와 nginx 간 통신은 HTTP(80 또는 다른 포트)로 유지
예시:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://192.168.0.10: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 https;
}
}
이 구조의 장점은 다음과 같다.
- 클라이언트와 nginx 사이 구간은 HTTPS로 암호화
- 내부망에서는 HTTP를 사용해 성능과 구성 단순화
- 인증서 갱신·관리도 nginx 한 곳에서만 처리하면 된다
인증서 자동 발급·갱신에는certbot을 많이 사용하며, 공식 문서는 https://nginx.org 및 https://certbot.eff.org 에서 참고할 수 있다.
내부 서버를 보호하기 위한 방화벽·네트워크 설정
“reverse proxy로 외부에 공개한다”는 말은 곧 “내부 서버는 직접 노출하지 않는다”는 뜻이기도 하다. 이 원칙을 지키려면 방화벽과 네트워크를 다음과 같이 설계하는 것이 좋다.
- 내부 서버는 80/443 포트를 외부에 열지 않는다.
- 오직 nginx 서버(또는 해당 서브넷)에서만 접근 허용
- nginx 서버는 외부에서 80/443만 열고 나머지 포트는 막는다.
- SSH, DB, 캐시 서버 등은 사설망에서만 접근 가능하게 구성
예를 들어 내부 서버에서 UFW를 쓴다면, nginx 서버 IP만 허용하는 식의 구성이 가능하다.
# 내부 서버에서 실행 (예: 192.168.0.20이 nginx 서버)
sudo ufw allow from 192.168.0.20 to any port 8080 proto tcp
sudo ufw deny 8080/tcp
이렇게 하면 nginx를 거치지 않는 8080 직접 접속은 막고, nginx에서 들어오는 요청만 받게 할 수 있다.
WebSocket, SSE 등 실시간 통신 처리 시 주의점
최근 서비스에서는 WebSocket, Server-Sent Events(SSE) 같은 실시간 통신도 많이 사용한다. nginx reverse proxy로 이 트래픽을 처리할 때는 다음 부분을 신경 써야 한다.
- WebSocket의 경우
Upgrade와Connection헤더를 그대로 전달 - 타임아웃 설정을 너무 짧게 잡지 않기
예시:
location /ws/ {
proxy_pass http://192.168.0.11:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
이렇게 하면 /ws/ 경로의 WebSocket 연결을 내부 서버로 안정적으로 프록시할 수 있다.
자주 발생하는 오류와 점검 포인트
nginx reverse proxy로 내부 서버를 외부에 공개하는 과정에서 흔히 겪는 문제들을 몇 가지 정리해 보자.
- 502 Bad Gateway
- 내부 서버가 죽었거나 포트/주소를 잘못 지정한 경우
- 방화벽에서 nginx → 내부 서버 트래픽이 막힌 경우
- 404 또는 정적 파일 누락
- 내부 서버가 기대하는 경로와 실제 proxy_pass 경로가 맞지 않을 때
- 예: 애플리케이션이
/app기준인데 nginx에서/로 넘기는 경우
- 리디렉션 루프
- 내부 서버가 HTTP→HTTPS 리디렉트를 하고 있는데, nginx에서 이미 HTTPS로 받고 있는 상황
X-Forwarded-Proto헤더를 이용해 내부 서버가 프록시 환경을 인식하도록 설정 필요
문제가 생기면 다음 순서로 확인하는 것이 보통 빠르다.
- 내부 서버에 직접 접속해서 정상 동작 여부 확인 (curl로 사설 IP:포트 테스트)
- nginx 에러 로그(
/var/log/nginx/error.log) 확인 - nginx 설정 문법 오류 여부 (
nginx -t) 재확인 - 방화벽, SELinux, 보안 그룹(클라우드 환경)의 포트 허용 여부 점검
마무리: reverse proxy를 기준으로 아키텍처를 설계하기
nginx reverse proxy로 내부 서버를 외부에 공개하는 패턴은 소규모 개인 서버부터 기업 서비스까지 폭넓게 사용된다.
정리해보면 핵심은 다음과 같다.
- 외부에서 들어오는 모든 요청은 nginx 한 곳으로 모은다.
- nginx가 도메인/경로에 따라 적절한 내부 서버로 요청을 라우팅한다.
- 내부 서버는 사설망에 숨겨두고, nginx와의 통신만 허용한다.
- HTTPS, 로깅, 접속 제어 등을 nginx에서 일괄 처리해 관리 포인트를 줄인다.
이 원리를 이해하고 기본 설정을 손으로 몇 번 써보면, 이후 서비스가 늘어나도 크게 구조를 바꾸지 않고 확장해 나갈 수 있다. nginx reverse proxy를 “외부와 내부를 나누는 관문”으로 두고 설계하는 습관이 잡히면, 보안과 운영 측면에서 모두 안정적인 웹 인프라를 구축하기가 훨씬 수월해진다.