
Proxy 프로토콜 수락
이 문서에서는 Proxy 프로토콜을 수락하고, Load Balancer 또는 Proxy의 IP 주소를 Proxy 프로토콜 헤더에 수신된 주소로 다시 쓰고, 클라이언트 IP 주소의 간단한 로깅을 구성하고, NGINX와 TCP Upstream 서버 간에 Proxy 프로토콜을 사용하도록 NGINX 및 NGINX Plus 를 구성하는 방법에 대해 설명합니다.
목차
1. 소개
2. 전제 조건
3. Proxy 프로토콜을 수락하도록 NGINX 구성하기
4. Load Balancer의 IP 주소를 클라이언트 IP 주소로 변경하기
5. 원본 IP 주소 로깅
6. Upstream에 대한 TCP 연결을 위한 Proxy 프로토콜
7. 예제
1. 소개
Proxy 프로토콜
을 사용하면 NGINX와 NGINX Plus 가 Proxy 서버를 통해 전달된 클라이언트 연결 정보를 수신하고 HAproxy 및 Amazon Elastic Load Balancer(ELB)와 같은 Load Balancer를 사용할 수 있습니다.
Proxy 프로토콜을 사용하면 NGINX는 HTTP, SSL, HTTP/2, SPDY, WebSocket, TCP에서 원본 IP 주소를 학습할 수 있습니다. 클라이언트의 발신 IP 주소를 아는 것은 웹사이트에 특정 언어를 설정하거나, IP 주소 거부 목록을 유지하거나, 단순히 로깅 및 통계 목적으로 유용할 수 있습니다.
Proxy 프로토콜을 통해 전달되는 정보는 클라이언트 IP 주소, Proxy 서버 IP 주소 및 두 포트 번호입니다.
이 데이터를 사용하여 NGINX는 여러 가지 방법으로 클라이언트의 원본 IP 주소를 얻을 수 있습니다.
- Proxy 프로토콜 주소와 포트는 원래 클라이언트 IP 주소와 포트를 캡처하는
$proxy_protocol_addr
및$proxy_protocol_port
변수를 사용합니다.$remote_addr
및$remote_port
변수는 Load Balancer의 IP 주소와 포트를 캡처합니다. RealIP
모듈을 사용하면$remote_addr
및$remote_port
변수의 값을 다시 작성하여 Load Balancer의 IP 주소와 포트를 원래 클라이언트 IP 주소와 포트로 대체합니다.$realip_remote_addr
및$realip_remote_port
변수는 Load Balancer의 주소와 포트를 유지하며,$proxy_protocol_addr
및$proxy_protocol_port
변수는 원래 클라이언트 IP 주소와 포트를 그대로 유지합니다.
2. 전제 조건
- Proxy 프로토콜 v2, NGINX Plus R16 이상 또는 NGINX Open Source 1.13.11 이상을 수락하려면 다음과 같이 하세요.
- HTTP용 Proxy 프로토콜을 수락하려면 NGINX Plus R3 이상 또는 NGINX Open Source 1.5.12 이상이 필요합니다.
- TCP 클라이언트 측 Proxy 프로토콜 지원의 경우, NGINX Plus R7 이상 또는 NGINX Open Source 1.9.3 이상이 필요합니다.
- TCP용 Proxy 프로토콜을 수락하려면 NGINX Plus R11 이상 또는 NGINX Open Source 1.11.4 이상이 필요합니다.
- HTTP 및 Stream TCP용 Real-IP 모듈은 기본적으로 NGINX Open Source에 포함되어 있지 않으므로 자세한 내용은 NGINX Open Source 설치하기를 참조하세요. NGINX Plus에는 추가 단계가 필요하지 않습니다.
3. Proxy 프로토콜을 수락하도록 NGINX 구성하기
Proxy 프로토콜 헤더를 허용하도록 NGINX를 구성하려면 http { }
또는 stream { }
블록의 server
블록에 있는 listen
지시문에 proxy_protocol
파라미터를 추가합니다.
http {
#...
server {
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
#...
}
}
stream {
#...
server {
listen 12345 proxy_protocol;
#...
}
}
이제 클라이언트 IP 주소와 포트에 $proxy_protocol_addr
및 $proxy_protocol_port
변수를 사용하고, $remote_addr
및 $remote_port
변수에 있는 Load Balancer의 IP 주소를 클라이언트의 IP 주소 및 포트로 대체하도록 HTTP 및 stream RealIP 모듈을 추가적으로 구성할 수 있습니다.
4. Load Balancer의 IP 주소를 클라이언트 IP 주소로 변경하기
Load Balancer 또는 TCP Proxy 주소를 Proxy 프로토콜에서 수신한 클라이언트 IP 주소로 대체할 수 있습니다. 이 작업은 HTTP 및 stream RealIP 모듈을 사용하여 수행할 수 있습니다. 이러한 모듈을 사용하면 $remote_addr
및 $remote_port
변수는 클라이언트의 실제 IP 주소와 포트를 유지하고, $realip_remote_addr
및 $realip_remote_port
변수는 Load Balancer의 IP 주소와 포트를 유지합니다.
Load Balancer의 IP 주소에서 클라이언트의 IP 주소로 IP 주소를 변경하려면 다음과 같이 하세요.
1. Proxy 프로토콜 헤더를 수락하도록 NGINX를 구성했는지 확인하세요. Proxy 프로토콜을 수락하도록 NGINX 구성을 참조하세요.
2. NGINX 설치에 HTTP 및 Stream Real-IP 모듈이 포함되어 있는지 확인하세요.
nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'
그렇지 않은 경우 이러한 모듈을 사용하여 NGINX를 다시 컴파일하세요. 자세한 내용은 NGINX Open Source 설치하기를 참조하세요. NGINX Plus에는 추가 단계가 필요하지 않습니다.
3. HTTP, Stream 또는 둘 다에 대한 set_real_ip_from
지시문에서 TCP Proxy 또는 Load Balancer의 IP 주소 또는 주소의 CIDR 범위를 지정합니다.
server {
#...
set_real_ip_from 192.168.1.0/24;
#...
}
4. http { }
컨텍스트에서 proxy_protocol
매개변수를 real_ip_header
지시문에 지정하여 Load Balancer의 IP 주소를 Proxy 프로토콜 헤더에서 수신한 클라이언트의 IP 주소로 변경합니다.
http {
server {
#...
real_ip_header proxy_protocol;
}
}
5. 원본 IP 주소 로깅
클라이언트의 원래 IP 주소를 알고 있으면 올바른 로깅을 구성할 수 있습니다.
1. HTTP의 경우, proxy_set_header
지시문과 함께 $proxy_protocol_addr
변수를 사용하여 클라이언트 IP 주소를 Upstream 서버에 전달하도록 NGINX를 구성합니다.
http {
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
2. log_format
지시문(HTTP 또는 Stream)에 $proxy_protocol_addr
변수를 추가합니다.
http
블록에서.
http {
#...
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
}
stream
블록에서.
stream {
#...
log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
}
6. Upstream에 대한 TCP 연결을 위한 Proxy 프로토콜
TCP Stream의 경우, NGINX와 Upstream 서버 간의 연결에 PROXY 프로토콜을 활성화할 수 있습니다. Proxy 프로토콜을 활성화하려면 stream { }
Level의 server
블록에 proxy_protocol
지시문을 포함하세요.
stream {
server {
listen 12345;
proxy_pass example.com:12345;
proxy_protocol on;
}
}
7. 예제
http {
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
#...
server {
server_name localhost;
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/public.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/public.example.com.key;
location /app/ {
proxy_pass http://backend1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
}
}
stream {
log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
#...
server {
listen 12345 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
proxy_pass backend.example.com:12345;
proxy_protocol on;
}
}
이 예제에서는 들어오는 모든 HTTPS 트래픽을 처리하는 Load Balancer(예: Amazon ELB)가 NGINX 앞에 있다고 가정합니다. NGINX는 포트 443(listen 443 ssl;
)에서 HTTPS 트래픽을 수신하고, 포트 12345에서 TCP 트래픽을 수신하며, Load Balancer에서 전달된 클라이언트의 IP 주소(http { }
및 stream { }
블록 모두에서 listen
지시문에 대한 proxy_protocol
매개변수)도 Proxy 프로토콜을 통해 수신합니다.
NGINX Terminate는 HTTPS 트래픽(ssl_certificate
및 ssl_certificate_key
지시문)을 해독하고 해독된 데이터를 Backend 서버로 Proxy합니다.
- HTTP의 경우:
proxy_pass http://backend1;
- TCP의 경우:
proxy_pass backend.example.com:12345
여기에는 클라이언트 IP 주소와 포트가 proxy_set_header
지시문과 함께 포함됩니다.
log_format
지시문에 지정된 $proxy_protocol_addr
변수는 클라이언트의 IP 주소도 HTTP와 TCP 모두에 대해 로그에 전달합니다.
또한 TCP 서버( stream { }
블록)는 자체 Proxy 프로토콜 데이터를 Backend 서버(proxy_protocol on
지시문)로 전송합니다.