NGINX 및 NGINX Plus를 DSR 및 IP Transparancy 로 구성

관리자
조회수 477




 NGINX Open Source와 NGINX Plus를 업스트림 서버로의 트래픽에 대한 투명 프록시로 구성하는 방법을 설명합니다. 

투명 프록시를 사용하여 패킷의 소스 IP 주소를 스푸핑하여 IP 투명성을 구현하는 방법과 UDP 트래픽에 대한 Direct Server Return이라는 부하 분산 모드를 구현하는 방법을 설명합니다.


이 게시물의 정보는 NGINX Open Source 와 NGINX Plus 에 모두 적용됩니다. 

간결함을 위해 NGINX Plus만 언급하겠습니다.

편집자 - 이 글은 NGINX Plus R10의 새로운 기능을 심층적으로 살펴보는 일련의 블로그 게시물 중 다섯 번째입니다.

  • JWT 및 NGINX Plus를 사용하여 API 클라이언트 인증
  • NGINX Plus R10은 IBM POWER를 활용합니다.
  • OpenID Connect 및 NGINX Plus를 사용하여 기존 애플리케이션에 사용자 인증
  • NGINX JavaScript 모듈을 사용하여 클라이언트를 점진적으로 새 서버로 전환
  • NGINX 및 NGINX Plus를 투명 프록시로 사용한 IP 투명성 및 직접 서버 리턴(이 게시물)

또한 NGINX Plus R10의 새로운 기능을 소개 하는 주문형 웨비나도 꼭 확인해 보세요 .

요약

NGINX Plus는 Layer 7 역방향 프록시로 작동합니다. 

이를 통해 NGINX Plus는 관리하는 네트워크 요청에 여러 가지 최적화 및 향상을 적용할 수 있습니다.

결과적으로 업스트림(부하 분산) 서버는 모든 트래픽이 NGINX Plus 프록시의 IP 주소에서 시작된다는 것을 관찰합니다. 

업스트림 서버가 인증 또는 로깅 목적으로 실제 원점 IP 주소(원격 클라이언트의 주소)를 확인해야 하는 경우 이는 어려운 문제입니다.

X-Forwarded-ForHTTP 헤더나 PROXY 프로토콜을 사용하여 HTTP 및 HTTPS 트래픽에 대한 효과적인 해결 방법이 있습니다. 

이 문서에서는 TCP 및 UDP 트래픽에 적용되는 두 가지 추가 방법을 설명합니다.



  • IP 투명성은 업스트림 서버가 각 연결이 이를 시작한 원격 클라이언트에서 시작되었음을 관찰하도록 보장합니다. 

  • TCP‑ 및 UDP‑ 기반 프로토콜에 적용 가능합니다.

  • DSR( Direct Server Return )은 업스트림 서버의 응답이 원격 클라이언트로 직접 이동하고 

  • 중간 로드 밸런서를 우회하도록 추가로 조정합니다. UDP 기반 프로토콜에 적용 가능하며 

  • 원본 서버 또는 중간 라우터에서 NAT(네트워크 주소 변환)를 수행하여 구현할 수 있습니다.


34388d9177fc8.png

 방법 1 – 

IP 투명성방법 2a – DSR(라우터 NAT)방법 2b – DSR(원점 NAT)필수 구성투명성과 DSR을 배포하고 문제를 해결하는 것은 복잡합니다. 

표준 역방향 프록시 작동 모드가 애플리케이션이나 서비스에 충분하지 않은 경우에만 이러한 구성을 구현하세요.


소개: 표준 레이어 7 역방향 프록시의 패킷 흐름

패킷을 전달하는 스위치나 라우터와 달리 NGINX Plus는 레이어 7 역방향 프록시 로 작동합니다 . 

이 작동 모드에서 NGINX Plus는 원격 클라이언트와 선택된 업스트림 서버 간의 통신을 제어하기 위해 

별도의 클라이언트 측 및 업스트림 측 TCP 연결(HTTP 및 TCP 트래픽용) 또는 UDP 세션을 관리합니다.

다이어그램은 NGINX Plus가 역방향 프록시 서버 역할을 할 때 TCP 패킷과 UDP 데이터그램이 어떻게 처리되는지 보여줍니다.NGINX Plus를 표준 역방향 프록시로 사용하여 트래픽 처리

  1. 원격 클라이언트는 TCP 연결을 만들거나 UDP 데이터그램을 NGINX Plus 역방향 프록시에 직접 게시된 IP 주소 및 포트로 보냅니다. 
  2. NGINX Plus는 TCP 연결 또는 UDP 세션을 종료하고 그 안에서 요청 데이터를 읽습니다.
  3. NGINX Plus는 선택된 (부하 분산된) 업스트림 서버에 새로운 연결을 만들 거나 기존의 유휴 연결을 재사용합니다 .
  4. NGINX Plus가 업스트림 서버에 요청을 작성하면 연결은 NGINX Plus의 내부 IP 주소에서 시작됩니다.
  5. 업스트림 서버가 요청에 응답하면 NGINX Plus 내부 IP 주소에 데이터를 씁니다.
  6. NGINX Plus는 업스트림 측 연결에서 응답 데이터를 수신합니다. 응답을 처리하거나 수정할 수 있습니다(예: HTTP 응답에 압축 적용).
  7. 그러면 NGINX Plus가 클라이언트 측 연결에 응답 데이터를 작성합니다.

이러한 표준 역방향 프록시 작동 모드의 결과로, 

업스트림 서버는 TCP 및 UDP 트래픽이 로컬 NGINX Plus 프록시에서 발생한다는 것을 관찰합니다.

레이어 7 역방향 프록시 모드의 이점 및 제한 사항

레이어 7 역방향 프록시 작동 모드는 HTTP 및 TCP 트래픽(TCP 최적화, 버퍼링, HTTP keepalive 재사용 포함)에 

상당한 성능 향상과 효율성을 제공합니다. 

업스트림 서버가 인증 및 액세스 제어, 속도 제한, 로깅과 같은 목적으로 연결 또는 세션의 

실제 원점 IP 주소를 결정해야 하는 경우 문제가 됩니다.

X-Forwarded-For일부 프로토콜의 경우 NGINX Plus는 HTTP 헤더 또는 PROXY 프로토콜을 사용하여 

업스트림 서버에 원본 IP 주소를 제공할 수 있습니다. 

이 게시물에서는 NGINX Plus 릴리스 10(R10)<.htmla> 에서 도입된 지시문 transparent에 대한 

매개변수 로 가능해진 두 가지 추가 방법을 설명합니다 .proxy_bind

방법 1: IP 투명성

IP 투명성의 의도는 역방향 프록시의 존재를 숨겨서 

원본 서버가 IP 패킷이 클라이언트의 IP 주소에서 시작되었음을 관찰하는 것입니다. 

IP 투명성은 TCP 기반 및 UDP 기반 프로토콜과 함께 사용할 수 있습니다.


NGINX Plus 로드 밸런서에서 HTTP 역방향 프록시 서비스 생성

IP 투명성을 보여주기 위해 먼저 간단한 연결 정보로 응답하는 4개의 웹 서버로 구성된 부하 분산 클러스터를 만듭니다.


업스트림 서버 그룹 전체에 걸쳐 트래픽 부하를 분산하는 간단한 HTTP 가상 서버를 구성합니다.

# in the 'http' context
server {
listen 80;
location / {
proxy_pass http://http_upstreams;
}
}

upstream http_upstreams {
server 172.16.0.11;
server 172.16.0.12;
server 172.16.0.13;
server 172.16.0.14;
}


업스트림 서버에서 연결이 NGINX Plus 부하 분산 장치에서 시작 되었음을 확인하려면 

4 Server (172.16.0.11~172.16.01.14) 각각에 NGINX Plus 웹 서버를 구성합니다. 

여기에는 다음과 같은 연결에 대한 정보를 반환하는 간단한 가상 서버가 포함됩니다.

# in the 'http' context
server {
listen 80;
location / {
return 200 "Hello from $hostname. You connected from $remote_addr:$remote_port to $server_addr:$server_port\n";
}
}


이 구성을 테스트하면 업스트림은 연결이 로컬 NGINX Plus IP 주소(172.16.0.1)에서 시작되었다고 보고합니다.

$ for i in {1..4}; do curl http://192.168.99.10 ; done
Hello from dev1. You connected from 172.16.0.1:42723 to 172.16.0.11:80
Hello from dev2. You connected from 172.16.0.1:39117 to 172.16.0.12:80
Hello from dev3. You connected from 172.16.0.1:54545 to 172.16.0.13:80
Hello from dev4. You connected from 172.16.0.1:57020 to 172.16.0.14:80


IP 투명성을 위한 NGINX Plus 및 업스트림 구성

NGINX Plus R10 이상(및 NGINX Open Source 1.11.0 이상)은 업스트림 트래픽의 소스 주소를 스푸핑할 수 있습니다. 

지시문 transparent에 매개변수를 포함합니다 proxy_bind. 

가장 일반적으로 소스 주소를 원격 클라이언트의 주소로 설정합니다.

proxy_bind $remote_addr transparent;


하지만 이 간단한 단계는 상당한 과제를 야기합니다. 

원격 클라이언트에 대한 응답(이그레스) 트래픽이 올바르게 처리되도록 해야 하기 때문입니다. 

응답 트래픽은 NGINX Plus로 라우팅되어야 하며, NGINX Plus는 업스트림 TCP 연결을 종료해야 합니다. 

그런 다음 NGINX Plus는 클라이언트 TCP 연결을 통해 응답 트래픽을 원격 클라이언트로 전송합니다.

NGINX Plus 로드 밸런서와 각 업스트림 서버 모두에 여러 가지 구성 변경을 해야 합니다.


NGINX Plus 로드 밸런서에서 작업자 프로세스가 root업스트림 소켓을 임의의 주소에 바인딩할 수 있도록 실행되도록 구성합니다.

/etc/nginx/nginx.conf 의 기본(최상위) 컨텍스트에서 userNGINX Plus 에 대해 root 작업자 프로세스의 ID를 설정하는 지침을 포함합니다

# in the 'main' context
# 'user daemon' is the default; change to 'user root' with transparent proxy_bind
user root;


NGINX Plus 로드 밸런서에서 각 연결이 원격 클라이언트 주소에서 시작되는지 확인하세요.

가상 서버 구성에 매개변수가 proxy_bind있는 지침을 추가합니다 .transparent

# in the 'http' context
server { listen 80;
location / { proxy_bind $remote_addr transparent; proxy_pass http://http_upstreams; }
}


NGINX Plus 로드 밸런서에서iptables 업스트림 서버에서 반환 패킷을 캡처하여 NGINX Plus로 전달하도록 구성합니다 .

이 예에서 우리는 IP 범위 172.16.0.0/28로 표현되는 서버에서 포트 80의 모든 TCP 트래픽을 캡처하기 위해 iptables및 명령을 실행합니다:ip rule

# ip rule add fwmark 1 lookup 100
# ip route add local 0.0.0.0/0 dev lo table 100
# iptables -t mangle -A PREROUTING -p tcp -s 172.16.0.0/28 --sport 80 -j MARK --set-xmark 0x1/0xffffffff


다음 명령을 실행하여 mangle 테이블 -L에서 현재 구성을 나열( ) 합니다 iptables .

# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARK tcp -- 172.16.0.0/28 anywhere tcp spt:http MARK set 0x1

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination


4. 업스트림 서버에서 모든 반환 트래픽이 NGINX Plus로 전달되도록 라우팅을 구성합니다.

각 업스트림 서버에서 기존 기본 경로를 제거하고 기본 경로를 NGINX Plus 로드 밸런서/역방향 프록시의 IP 주소로 구성합니다. 

이 IP 주소는 업스트림 서버의 인터페이스 중 하나와 동일한 서브넷에 있어야 합니다.

# route del default gw 10.0.2.2
# route add default gw 172.16.0.1


라우팅 테이블이 합리적인지 확인하세요.

# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.0.1 0.0.0.0 UG 0 0 0 eth2
10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.16.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1


업스트림 서버가 외부 서버에 연결해야 하는 경우 

트래픽을 전달하고 위장하도록 새 NGINX Plus 게이트웨이도 구성해야 합니다. 

아래 업스트림이 외부 서버에 도달하도록 활성화를 참조하세요 .

IP 투명성 구성 테스트

이제 NGINX Plus에 요청을 보내 구성을 테스트할 수 있습니다. 

업스트림 서버에서 직접 라우팅할 수 없는 원격 IP 주소에서 요청을 보내고 있는지 확인하세요.

$ for i in {1..4}; do curl http://192.168.99.10 ; done
Hello from dev1. You connected from 192.168.99.1:60729 to 172.16.0.11:80
Hello from dev2. You connected from 192.168.99.1:43070 to 172.16.0.12:80
Hello from dev3. You connected from 192.168.99.1:45749 to 172.16.0.13:80
Hello from dev4. You connected from 192.168.99.1:46609 to 172.16.0.14:80


이제 연결이 NGINX Plus 로드 밸런서의 로컬 주소가 아닌 

원격 클라이언트의 IP 주소(192.168.99.1)에서 시작된 것으로 보입니다.

구성이 작동하지 않는 경우, 아래의 문제 해결을 참조하세요 .



요약: IP 투명성 구성은 어떻게 작동하나요?

  • NGINX Plus는 원격 클라이언트(192.168.99.1)로부터 HTTP 요청을 수신합니다.
  • NGINX Plus는 부하 분산 결정을 내리고 연결할 업스트림 서버(예: 172.16.0.11)를 선택합니다. 
  • NGINX Plus가 연결하기 전에 업스트림 소켓을 원격 클라이언트의 주소에 바인딩합니다.
  • 업스트림 서버는 원격 클라이언트에서 직접 온 것처럼 보이는 연결을 수신합니다.
  • 업스트림 서버가 응답하여 패킷을 원격 클라이언트 주소로 보내고 이를 NGINX Plus(기본 라우터)를 통해 라우팅합니다.
  • iptablesNGINX Plus 로드 밸런서의 규칙은 이러한 패킷을 표시하고 라우팅을 통해 이를 로컬로 전달합니다 .
  • NGINX Plus가 응답을 읽습니다.
  • 그러면 NGINX Plus가 원격 클라이언트에 응답을 전송합니다.

결과적으로, 업스트림 서버의 관점에서 볼 때 연결은 원격 클라이언트에서 직접 시작된 것처럼 보입니다.

방법 2: 직접 서버 반환

DSR(Direct Server Return)은 IP Transparency 개념의 확장입니다. 

IP Transparency에서 업스트림 서버는 원격 클라이언트에서 시작된 것처럼 보이는 패킷을 수신합니다. 

DSR을 사용하면 업스트림 서버는 원격 클라이언트에 직접 응답합니다. 

반환 패킷은 로드 밸런서를 완전히 우회합니다.

DSR은 로드 밸런서의 부하를 줄여주기 때문에 약간의 성능상의 이점을 제공할 수 있지만 

다음과 같은 몇 가지 제한이 있습니다.


  • 부하 분산 장치는 반환 패킷을 볼 수 없으므로 업스트림 서버가 응답하는지 아니면 실패했는지 감지할 수 없습니다.
  • 부하 분산 장치는 업스트림을 선택하기 전에 첫 번째 패킷을 넘어서는 요청을 검사할 수 없으므로 
  • 부하 분산 결정(콘텐츠 기반 라우팅)을 내리는 기능이 매우 제한적입니다.
  • 로드 밸런서는 SSL/TLS와 같은 어떠한 형태의 협상이나 상태 처리에도 참여할 수 없습니다.
  • 캐싱, HTTP 멀티플렉싱, 로깅과 같은 대부분의 다른 ADC(애플리케이션 전송 컨트롤러) 기능은 DSR에서는 사용할 수 없습니다.


DSR은 TCP 프로토콜에 대한 사용이 제한적이며, 어떤 경우에도 NGINX Plus의 역방향 프록시 아키텍처는 DSR/TCP에 적용될 수 없습니다.

UDP 프로토콜은 TCP의 연결 의미론이 전혀 없으므로 훨씬 더 간단합니다. 

DNS와 같은 UDP 프로토콜에 대해 DSR을 지원하도록 NGINX Plus를 구성할 수 있으며, 

이를 통해 성능 이점을 얻을 수 있습니다. 

구체적으로 DSR은 NGINX Plus가 응답 패킷을 예상하여 UDP 소켓을 열어 둘 필요가 없음을 의미하며(확장성이 향상됨), 

응답 패킷은 NGINX Plus의 레이어 7 처리를 완전히 우회할 수 있습니다(지연 시간이 감소함).


DSR 구성은 IP 투명성과 어떻게 다릅니까?

UDP 트래픽의 IP 투명성 구성과 DSR 구성 사이에는 세 가지 차이점이 있습니다.

  • NGINX Plus는 업스트림 서버로 데이터그램을 보낼 때 원격 클라이언트의 IP 주소 와proxy_bind 포트를 모두 스푸핑해야 합니다( 포트 구성).
  • NGINX Plus는 업스트림 서버로부터 응답 데이터그램을 기대하도록 구성되어서는 안 됩니다( proxy_responses 0지침).
  • 반환 데이터그램의 소스 주소를 로드 밸런서의 공개 주소와 일치하도록 다시 작성하려면 추가 단계가 필요합니다.

또한, NGINX Plus는 업스트림 서버에 대해 활성 상태 검사를 수행하도록 구성되어야 합니다. 

NGINX Plus는 서버가 건강한지 확인하기 위해 일반적인 수동 검사에 의존할 수 없습니다. 

NGINX Plus는 서버에서 보낸 응답 패킷을 관찰하지 않기 때문입니다.

표준 UDP 역방향 프록시 서비스 생성

DSR을 시연하려면 먼저 www.example.com 이라는 이름을 조회할 때 

서로 다른 IP 주소로 응답하는 4개의 DNS 서버로 구성된 부하 분산 클러스터를 만듭니다 .

DNS 서버 간 부하 분산을 위한 간단한 역방향 프록시 구성을 구성합니다 .

# in the 'stream' context
server {
listen 53 udp;
proxy_responses 1;
proxy_timeout 1s;
proxy_pass dns_upstreams;
}

upstream dns_upstreams {
server 172.16.0.11:53;
server 172.16.0.12:53;
server 172.16.0.13:53;
server 172.16.0.14:53;
}


및 지시문 proxy_responses은 proxy_timeout기본 상태 검사를 구현합니다. 

업스트림 서버가 1초 이내에 1개의 응답을 보내지 않으면 NGINX Plus는 서버가 실패했다고 가정하고 DNS 요청을 다시 시도합니다.

각 DNS 서버가 www.example.com 을 조회할 때 고유한 IP 주소로 응답하도록 구성합니다 .

$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL

example.com. IN NS ns1.example.com.

ns1 IN A 172.16.0.11
www IN A 172.16.0.11


테스트를 통해 NGINX Plus가 DNS 서버 간 요청의 부하를 분산하고 있음이 분명해졌습니다.

$ for i in {1..4} ; do dig +short @192.168.99.10 www.example.com ; done
172.16.0.11
172.16.0.12
172.16.0.13
172.16.0.14


DSR을 위한 NGINX Plus 및 UDP 업스트림 구성

NGINX Plus R10 이상(및 NGINX Open Source 1.11.2 이상)은 업스트림 트래픽의 소스 주소와 포트를 모두 스푸핑할 수 있습니다. 

지시문 transparent에 매개변수를 포함합니다 proxy_bind.

proxy_bind $remote_addr:$remote_port transparent;


이를 통해 업스트림 서버는 전체 소스 IP 주소를 관찰하여 원격 클라이언트에 직접 전송되는 응답 데이터그램을 구성할 수 있습니다.

업스트림 서버는 올바른 IP 목적지로 응답("egress") 패킷을 생성하지만 로컬 IP 주소를 소스 주소로 사용합니다. 

소스 주소는 클라이언트가 원래 연결했던 NGINX Plus 로드 밸런서의 IP 주소와 포트로 다시 작성해야 합니다.

두 가지 방법이 가능합니다.

  1. 라우터 NAT  – 중간 라우터(예: NGINX Plus 프록시)에서 송신 패킷을 다시 작성합니다.
  2. 원점 NAT  – 각 업스트림 DNS 서버를 떠날 때 이탈 패킷을 다시 작성합니다.

두 방법 모두 명령으로 구성하는 상태 없는 NAT 기능을 사용합니다 tc . 

업스트림 서버가 인터넷에 직접 연결된 경우

(토폴로지는 반환 패킷이 제어할 수 있는 중간 라우터를 통해 전송되지 않음을 의미함) 원본 NAT 방법을 선택해야 합니다 .



DSR을 위한 NGINX Plus 구성

응답 패킷은 NGINX Plus에 전달되지 않으므로 

표준 UDP 역방향 프록시 서비스 생성 에서 구성한 상태 검사를 비활성화해야 합니다 . 

지시문을 수정 proxy_responses하고 proxy_timeout지시문을 비활성화합니다. 

이제 NGINX Plus는 응답을 기다리지 않으며, 응답을 받지 못하더라도 업스트림 서버가 실패했다고 결론 내리지 않습니다. 

이 검사를 비활성화하면 NGINX Plus가 소켓 리소스를 즉시 재사용할 수도 있습니다.

또한 NGINX Plus가 업스트림 서버로 전송되는 데이터그램에서 원래 소스 주소와 소스 포트를 모두 보존할 수 있도록 

지시문 의 첫 번째 매개변수에 $remote_addr및 변수를 모두 포함합니다.$remote_portproxy_bind

# in the 'stream' context
server {
listen 53 udp;
proxy_bind $remote_addr:$remote_port transparent;
proxy_responses 0;
#proxy_timeout 1s;
}


라우터 NAT – 중간 라우터에서 송신 패킷 다시 쓰기

단일 중간 라우터에서 송신 패킷을 다시 쓸 수 있습니다. 

예를 들어, 업스트림 서버가 NGINX Plus 로드 밸런서 뒤의 

개인 네트워크에 있는 경우 로드 밸런서를 기본 경로로 사용하고 패킷이 전달될 때 다시 쓸 수 있습니다.


  1. 모든 발신 트래픽을 NGINX Plus 서버를 통해 라우팅하도록 각 업스트림 서버를 구성합니다.

    # route add default gw nginx-ip-address


  2. NGINX Plus 서버를 구성하여 IP 트래픽을 전달합니다.

    # sysctl -w net.ipv4.ip_forward=1


  3. NGINX Plus 서버를 구성하여 상태 비저장 NAT 재작성을 수행합니다.

    # tc qdisc add dev eth0 root handle 10: htb
    # tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.11 match ip sport 53 action nat egress 172.16.0.11 192.168.99.10
    # tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.12 match ip sport 53 action nat egress 172.16.0.12 192.168.99.10
    # tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.13 match ip sport 53 action nat egress 172.16.0.13 192.168.99.10
    # tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.14 match ip sport 53 action nat egress 172.16.0.14 192.168.99.10


    각 업스트림 서버의 적절한 출구 인터페이스와 적절한 IP 주소를 선택했는지 확인하세요.


Stateless NAT에 대한 자세한 내용은 tc natman 페이지를 참조하세요. 

구성에 따라 및 매개 변수 tc filter에 CIDR 마스크를 사용하여 명령을 단일 명령으로 줄일 수 있습니다 .srcegress old


현재 tc filter구성을 표시하려면 다음 명령을 실행하세요.

# tc filter show dev eth0


Origin NAT – 각 업스트림 서버에서 이그레스 패킷 다시 쓰기

업스트림 서버에서 네트워킹을 구성할 수 있다면, 특히 인터넷에 직접 연결되어 있다면 

다음 구성을 사용할 수 있습니다. 각 업스트림 서버에 적용해야 합니다.

각 업스트림 서버가 상태 비저장 NAT 재작성을 수행하도록 구성합니다.

# tc qdisc add dev eth0 root handle 10: htb
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.11 match ip sport 53 action nat egress 172.16.0.11 192.168.99.10


각 업스트림에서 적절한 인터페이스와 IP 주소를 선택했는지 확인하세요.

DSR 구성 테스트

구성을 테스트하려면 DNS 요청을 NGINX Plus 부하 분산 장치로 보내고 업스트림 서버 전체에서 부하가 분산되는지 확인합니다.

DSR에는 직접적으로 보이는 효과가 없습니다. 

NGINX Plus가 응답 패킷을 기대하지 않도록 구성하는 지시문을 사용했지만 

DNS 클라이언트가 부하 분산된 응답을 수신하는 경우 작동하고 있다고 확신할 수 있습니다 . 

아래 문제 해결 에서 설명한 대로 를 proxy_responses 0사용하여 패킷 흐름을 추가로 관찰할 수 있습니다 .tcpdump

요약: DSR 구성은 어떻게 작동하나요?

  1. NGINX Plus는 원격 클라이언트(192.168.99.1: 포트 )로부터 UDP 데이터그램을 수신합니다.
  2. NGINX Plus는 부하 분산 결정을 내리고 데이터그램 내용을 쓸 업스트림 서버(예: 172.16.0.11)를 선택합니다. 
  3. NGINX Plus가 연결하기 전에 업스트림 소켓의 로컬 측을 원격 클라이언트의 IP 주소와 포트에 바인딩합니다.
  4. 업스트림 서버는 NGINX Plus가 보낸 데이터그램을 수신하는데, 이 데이터그램은 원격 클라이언트 주소와 포트에서 직접 생성된 것으로 보입니다.
  5. 업스트림 서버는 응답하여 원격 클라이언트로 데이터그램을 다시 보냅니다. 
  6. 업스트림 서버는 응답 데이터그램의 소스 IP 주소와 포트를 자체 로컬 IP 주소와 포트로 설정합니다.
  7. 소스 IP 주소(필요한 경우 포트 포함)는 업스트림 서버( 원본 NAT 구성) 또는 중간 라우터( 라우터 NAT 구성)에 의해 다시 작성됩니다.
  8. 원격 클라이언트는 올바른 4튜플(소스 및 대상 IP 주소와 포트)로 주소가 지정된 데이터그램을 수신합니다.
  9. NGINX Plus는 응답 데이터그램을 관찰할 것을 예상하지 않으며 업스트림 소켓을 즉시 닫습니다.


결과적으로 응답 패킷은 NGINX Plus의 7계층 처리를 우회하여 원격 클라이언트로 직접 전송됩니다.

문제 해결

IP 투명성 또는 DSR이 예상대로 작동하지 않는 경우 다음 제안 사항을 사용하여 가능한 원인을 조사하세요.

실행 root

NGINX Plus 작업자 프로세스가 .로 실행되도록 구성되었는지 확인합니다 

root. 그렇지 않은 경우 NGINX Plus가 소켓을 비로컬 주소에 바인딩하려고 할 때 

다음과 유사한 오류 메시지가 오류 로그에 표시됩니다.

setsockopt(IP_TRANSPARENT) failed (1: Operation not permitted) while connecting to upstream,
client: 192.168.99.1, server: ,
request: "GET / HTTP/1.1",
upstream: "http://172.16.0.11:80/",
host: "192.168.99.10"


테스트하기

NGINX Plus 프록시에서 클라이언트와 서버를 ping할 수 있는지 확인하세요. 

필요한 라우팅 구성을 먼저 만들고 NGINX Plus 중개자가 패킷을 전달하도록 

구성하지 않는 한 업스트림 서버는 원격 클라이언트 IP 주소를 ping할 수 없습니다.

중복되는 IP 범위 없음

원격 클라이언트가 사용하는 IP 서브넷이 업스트림 서버에 직접 연결되지 않았는지 확인합니다. 

연결되어 있다면 두 가지 문제가 발생할 가능성이 있습니다.

  • Linux의 "역경로 필터링" 보호 기능은 소스 IP 주소가 다른 인터페이스의 서브넷과 연결되어 있기 때문에 
  • NGINX Plus에서 오는 패킷을 자동으로 거부할 수 있습니다.
  • 반환 패킷은 기본 경로를 사용하지 않고 대신 로컬에 연결된 원격 클라이언트에 직접 전송됩니다.

tcpdump어디에서나 사용 가능

구성을 구축하고 각 중간 단계를 테스트할 때 tcpdump각 서버에서 지속적으로 실행하여 

각 단계에서 패킷이 올바른 엔드포인트로 전송되고 수신되는지 확인하세요.

$ sudo tcpdump -i any -n tcp port 80


아래 나열된 검사를 사용하여 비정상적인 행동을 조사하세요.

라우팅 테이블 확인

각 서버의 라우팅 테이블을 주의 깊게 확인하고 특히 업스트림 서버에 주의하세요.

# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.0.1 0.0.0.0 UG 0 0 0 eth2
10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.16.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1


예상치 못한 경로가 있습니까? 흐름의 모든 패킷이 올바른 목적지로 라우팅되는지 확인할 수 있습니까? 

iptables및 라우터 NAT 구성에서 모든 이탈 패킷은 중간 NGINX Plus 프록시를 통해 라우팅되어야 함을 기억하세요.


누락된 패킷

패킷이 예기치 않게 삭제되는 경우( tcpdump한 머신에서 전송했지만 다른 머신에서 수신하지 못했음을 나타냄), 

역방향 경로 필터링이 잠재적인 침묵의 범인입니다. 역방향 경로 필터링을 일시적으로 비활성화하려면 다음 명령을 실행합니다.

# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f ; done


업스트림 서버가 외부 서버에 도달하도록 활성화

업스트림 서버가 개인 네트워크에 있고 NGINX Plus(또는 다른 서버)를 기본 게이트웨이로 사용하는 경우 

업스트림 서버가 외부(인터넷) 호스트에 접속할 수 있도록 게이트웨이를 구성할 수 있습니다.

게이트웨이가 업스트림 서버에서 패킷을 전달할 수 있도록 IP 전달을 활성화해야 합니다 . 

IP 전달은 일반적으로 기본적으로 비활성화되어 있습니다. 

서버에 라우팅 가능한 IP 주소가 없는 경우(172.16.0.0/24와 같은 개인 주소를 사용함) 

게이트웨이 서버의 외부 인터페이스에서 IP 마스커레이딩 도 구성해야 합니다.

# sysctl -w net.ipv4.ip_forward=1
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


내부 업스트림 서버에서 외부 서버에 ping을 보낼 수 있는지 확인하세요.

root@dev1:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=6.72 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=5.49 ms
^C


현재의 전달, 라우팅 및 iptables nat구성을 표시하려면 다음 세 가지 명령을 실행하세요.

# sysctl net.ipv4.ip_forward
# route -n
# iptables -t nat -L


NGINX에서 도움 받기

IP Transparency 또는 Direct Server Return의 구성은 복잡하며, 

다른 중간 네트워크 장치가 패킷을 삭제하거나 다시 작성하여 배포에 영향을 미칠 수 있습니다.