나의 잡다한 노트 및 메모
nginx의 request rewrite, response rewrite 본문
1. 요청(request) 리라이트
- 요청 리라이트는 클라이언트가 보낸 HTTP 요청을 받아서, 백엔드 서버(예: Jenkins)에 전달할 때 필요한 경우 일부 HTTP 헤더를 수정하거나 추가하는 과정을 말합니다.
- 예를 들어, 클라이언트가 Host: nice.name 으로 요청을 보내면, 프록시가 이 정보를 Jenkins에 전달할 때 그대로 전달하거나, X-Forwarded-* 헤더로 전달하여 Jenkins가 클라이언트의 원래 요청 정보를 알 수 있게 합니다.
- 잘못 구성된 요청 리라이트는 대개 페이지 자체가 전혀 표시되지 않는 등의 명백한 문제를 일으킵니다.
2. 응답(response) 리라이트의 필요성
리버스 프록시의 가장 어려운 부분은 응답에서의 리라이트인데, 특히 리다이렉트 상황에서 발생합니다.
옵션 1: 응답의 "Location" 헤더 재작성
- 상황:
Jenkins가 리다이렉트를 위해 응답의 "Location" 헤더를 보낼 때, 기본적으로는 자신의 내부 주소(예: http://actual.server:8080/jenkins/foobar)를 사용합니다. - 문제점:
클라이언트는 외부에서 접근할 때 nice.name 같은 공개된 도메인을 사용하기 때문에, 이 내부 주소로 리다이렉트되면 접근할 수 없게 됩니다. - 해결:
리버스 프록시가 이 응답의 "Location" 헤더를 수정해서 http://nice.name/jenkins/foobar와 같이 공개 도메인으로 바꿔 줍니다. - 특징:
이 방법은 요청 자체는 잘 전달되지만, 응답에 포함된 절대 URL이 잘못되면 클라이언트가 페이지를 리다이렉트할 때 문제가 생깁니다. 단, 페이지가 아예 보이지 않는 문제보다는 발견하기 어려운 문제입니다.
옵션 2: X-Forwarded-* 헤더 사용
- 상황:
리버스 프록시는 요청을 백엔드에 전달할 때, X-Forwarded-Host, X-Forwarded-Port (필요하다면) 그리고 X-Forwarded-Proto 등의 헤더를 설정할 수 있습니다. - 작동 방식:
Jenkins는 이 헤더들을 확인하여, 자신이 생성하는 모든 리다이렉트나 링크를 이 값들을 기준으로 만듭니다. 즉, 클라이언트가 원래 요청한 호스트와 프로토콜을 반영하게 됩니다. - 예시:
- 클라이언트가 https://nice.name으로 요청을 보냈다면, 프록시가 요청을 Jenkins에 전달할 때 X-Forwarded-Host: nice.name 및 X-Forwarded-Proto: https와 같이 설정합니다.
- 그러면 Jenkins는 리다이렉트 시 "Location: https://nice.name/jenkins/foobar"와 같이 올바른 URL을 생성하게 됩니다.
- 세부 옵션:
- 어떤 경우에는 단순히 원래의 Host 헤더를 X-Forwarded-Host에 복사하는 방식이 편리할 수도 있고, 경우에 따라 X-Forwarded-Port 헤더를 아예 생략하는 편이 나을 수도 있습니다.
- 만약 프록시와 클라이언트 간의 프로토콜(HTTP/HTTPS)이 다르다면, X-Forwarded-Proto를 꼭 설정해야 합니다.
'DevOps > Reverse_proxy' 카테고리의 다른 글
nginx의 프록시 관련 내장 변수, client가 요청한 포트를 나타내려면? (0) | 2025.03.20 |
---|---|
NGINX의 리버스 프록시 동작 원리 (0) | 2025.03.20 |
nginx 설정 중 proxy 관련 설정 (0) | 2025.03.19 |