14강 / 20강

리버스 프록시 — 뒤에 있는 앱에게 넘기기

502의 정체와 X-Forwarded-For

리버스 프록시 — 뒤에 있는 앱에게 넘기기
프런트 데스크(nginx)가 주방(앱)에 주문을 넘깁니다. 손님은 주방을 못 봅니다.

지금까지 우리 nginx는 디스크의 파일을 그대로 줬습니다. 그런데 쇼핑몰은 상품 목록을 DB에서 읽어 그때그때 만들어야 하죠. 그 일은 파이썬 앱(gunicorn)이 합니다.

그럼 손님을 앱에 직접 연결하면 되지 않을까요? 안 됩니다. 앱은 127.0.0.1:8000 에만 붙어 있으니까요(7강). 일부러 그렇게 한 거였죠.

그래서 nginx가 중간에서 대신 물어봅니다. 이것이 리버스 프록시입니다.

손님203.0.113.88
HTTP 요청 ▶
nginx0.0.0.0:80
proxy_pass ▶
gunicorn127.0.0.1:8000

포워드 프록시 vs 리버스 프록시

포워드 프록시
손님 → [프록시] → 서버
손님을 대신함. VPN·회사 차단 장비.
설정은 손님이 함
리버스 프록시
손님 → [프록시] → 서버
서버를 대신함. nginx·Cloudflare.
설정은 서버 주인이 함

그림은 같은데 누구 편인가가 다릅니다. 손님은 리버스 프록시가 있는지도 모릅니다.

위젯에서 프록시 모드로 바꾼 뒤 다시 보세요.
🖥️ 내 가상 서버 브라우저 안에서 실행 (계산용)
프록시 실습실 — 502·504를 직접 만들어 보세요
불러오는 중…

proxy_set_header — 잊으면 로그가 망가집니다

nginx가 대신 물어보면, 앱 입장에서 손님은 nginx입니다. 즉 앱의 로그에는 접속자가 전부 127.0.0.1 로 찍혀요. 누가 왔는지 알 수 없게 됩니다.

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host              $host;              ← 원래 도메인 이름
    proxy_set_header X-Real-IP         $remote_addr;       ← 손님의 진짜 IP
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;            ← http인가 https인가
}

X-Forwarded-Proto 를 빠뜨리면 재미있는 버그가 납니다. 앱은 자기가 HTTP로 서비스 중인 줄 알고 http:// 로 리다이렉트를 만들고, nginx가 그걸 다시 HTTPS로 돌리고… 무한 리다이렉트가 되죠.

X-Forwarded-For 를 끄고 켜며 로그가 어떻게 달라지는지 보세요.
💻 손님 노트북 브라우저 안에서 실행 (계산용)
502가 났을 때 진짜로 봐야 하는 파일입니다.
🖥️ 내 가상 서버 브라우저 안에서 실행 (계산용)

업로드가 413으로 잘릴 때

쇼핑몰 운영자가 자주 만나는 또 하나의 함정입니다. 상품 사진을 올리는데 413 Request Entity Too Large 가 뜬다면 nginx의 기본 업로드 한도(1MB)에 걸린 겁니다.

client_max_body_size 20M;

앱에서 아무리 크게 잡아도 nginx가 먼저 자릅니다. 프록시 뒤의 앱을 고치기 전에 항상 앞단부터 확인하세요.

🤔 확인 문제
손님에게 502 Bad Gateway 가 보입니다. 상황을 가장 정확히 설명한 것은?
🤔 확인 문제
리버스 프록시 뒤의 앱 로그에 모든 접속자 IP가 127.0.0.1 로 찍힙니다. 원인은?