14강 / 20강
리버스 프록시 — 뒤에 있는 앱에게 넘기기
502의 정체와 X-Forwarded-For
지금까지 우리 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.
설정은 서버 주인이 함
설정은 서버 주인이 함
그림은 같은데 누구 편인가가 다릅니다. 손님은 리버스 프록시가 있는지도 모릅니다.
위젯에서 프록시 모드로 바꾼 뒤 다시 보세요.
🖥️ 내 가상 서버
브라우저 안에서 실행 (계산용)
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 가 보입니다. 상황을 가장 정확히 설명한 것은?
해설 502 화면 자체를 nginx가 그려서 보내 준 것입니다. 즉 nginx는 멀쩡해요. 문제는
proxy_pass 가 가리키는 뒷단입니다.🤔 확인 문제
리버스 프록시 뒤의 앱 로그에 모든 접속자 IP가 127.0.0.1 로 찍힙니다. 원인은?
해설 앱 입장에서 실제 접속자는 nginx(127.0.0.1)입니다. 손님의 진짜 IP를 알려면 nginx가
proxy_set_header X-Forwarded-For 로 적어서 넘겨 줘야 합니다.