동일한 네트워크에서 한 IP에서 다른 IP로 포트를 전달하는 방법은 무엇입니까?


77

NAT에서 일부 작업을 수행하고 싶습니다 iptables. 그래야 모든 패킷은 오는 192.168.12.87와 포트 80로 전달됩니다 192.168.12.77포트 80.

iptables로 이것을하는 방법?

또는

같은 것을 달성하는 다른 방법이 있습니까?


@Matthewlfe, 어떤 이유로 든 모든 아파치 요청을 (192.168.12.87)에서 (192.168.12.77)로 전달해야합니다.
앉아

1
@ Matthewlfe, 두 개의 프로덕션 서버가 있습니다. 하나는 공개 정적 IP 주소에 연결되어 있습니다. 일부 연결 문제로 인해에서 DB 및 기타 시스템에 연결할 수 없습니다 192.168.12.87. 따라서 모든 요청을에 전달해야합니다 192.168.12.77.
앉아

@lain, 나는 익숙하지 않다 iptables. 그리고 몇 가지 예를 보았습니다. 그러나 두 개의 이더넷이 필요한 것 같습니다. 링크 : revsys.com/writings/quicktips/nat.html
앉아

웹 서버 구성에서 프록시 모드를 사용하여 192.168.12.87에서 192.168.12.77로 요청을 보낼 수도 있습니다 (웹 서버에서 지원하는 경우)
krisFR

답변:


74

이 규칙은 iptables서버에서 실행되고 있다고 가정하면 작동 합니다 192.168.12.87.

#!/bin/sh

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -F
iptables -t nat -F
iptables -X

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77:80
iptables -t nat -A POSTROUTING -p tcp -d 192.168.12.77 --dport 80 -j SNAT --to-source 192.168.12.87

포트 80에서 들어오는 트래픽을 DNAT해야하지만 트래픽을 다시 SNAT해야합니다.


대안 (및 최선의 접근법 IMHO) :

웹 서버 (Apache, NGinx)에 따라 프론트 엔드 서버 (192.168.12.87)에서 HTTP 프록시를 고려해야합니다.


포트가 ufw에서 허용하더라도 ufw가 비활성화되어있는 한 작동하지만 ufw가 활성화 된 경우이 전달 기능이 작동하지 않습니다.
Sudhir N

1
훌륭한 답변이 담긴 훌륭한 질문. 이것이 유용한 또 다른 유스 케이스는 모든 클라이언트를 재구성 할 필요없이 원래 서비스에 대한 유지 보수를 수행하기 위해 한 서비스 (예 : 오징어)로 들어오는 모든 트래픽을 다른 IP / 포트로 일시적으로 리디렉션해야하는 경우입니다! 매우 편리합니다!
PF4Public

3
"하지만 트래픽을 다시 가져와야합니다." -> 당신은 내 하루를 저장했습니다. 감사합니다
obayhan

이 솔루션은 저에게 효과적이지 않습니다. eth0에서 KVM-guest가 사용하는 가상 네트워크 (virb0)로 전달해야합니다. -i 및 -o 옵션을 추가하려고했지만 -o를 사전 라우팅 할 수 없습니다. 어떤 제안?
lostiniceland

이 솔루션에주의하십시오. 원격 컴퓨터에 대한 액세스가 완전히 끊어졌습니다.
Sören

28

명백하게 iptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77작동하지 않는 이유는 리턴 패킷이 라우팅되는 방법입니다.

192.168.12.87로 전송되는 패킷이 단순히 192.168.12.77로 NAT되도록하는 규칙을 설정할 수 있지만 192.168.12.77은 회신을 클라이언트로 직접 보냅니다. 이러한 응답은 iptables 규칙이 NAT를 수행하는 호스트를 통과하지 않으므로 한 방향의 패킷은 변환되지만 다른 방향의 패킷은 변환되지 않습니다.

이 문제를 해결하는 방법에는 세 가지가 있습니다.

  1. 첫 번째 호스트에서는 DNAT뿐만 아니라 SNAT도 수행하여 반환 트래픽이 첫 번째 호스트를 통해 다시 전송되도록합니다. 규칙은 다음과 같이 보일 수 있습니다iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
  2. IP 계층이 아닌 이더넷 계층에서 DSR로드 밸런싱 및 패킷 DNAT로부터 영감을 얻으십시오. 패킷의 대상 MAC을 192.168.12.77의 MAC으로 바꾸고 IP 계층을 건드리지 않고 이더넷으로 전송하면 192.168.12.77은 더미 인터페이스에 192.168.12.87을 구성하여 TCP 연결을 종료 할 수 있습니다 클라이언트에게 알려진 서버 IP로.
  3. 첫 번째 호스트에서 순진하지만 작동하지 않는 솔루션을 사용하십시오. 그런 다음 리턴 트래픽에서 SNAT를 수행하여 두 번째 호스트에서 리턴 패킷을 처리하십시오. 규칙은 다음과 같습니다iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87

이 세 가지 솔루션 각각에는 단점이 있으므로이 특정 전달을 실제로 수행해야하는 경우 신중하게 고려해야합니다.

  1. SNAT를 사용하면 클라이언트 IP가 손실되므로 호스트 번호 2는 모든 연결이 192.168.12.87에서 온 것으로 생각합니다. 또한 모든 응답 패킷에 호스트 번호 1을 통해 대역폭을 사용하므로 다른 접근 방식과보다 직접적인 경로가 사용됩니다.
  2. DSR 접근 방식은 두 노드 간의 다른 모든 통신을 중단합니다. DSR 접근 방식은 서버 주소가 호스트의 기본 IP가 아닌 경우에만 실제로 적절합니다. 각 호스트에는 DSR IP가 아닌 기본 IP가 있어야합니다.
  3. 한 호스트에서 연결 추적을 사용하여 한 방향으로 변환하고 다른 호스트에서 연결 추적을 사용하여 다른 방향으로 변환하는 것은 쉽지 않으며 여러 가지 방법으로 중단 될 수 있습니다. 예를 들어, 포트 번호가 어느 호스트에서든 NAT에 의해 수정되면이를 재구성 할 방법이 없습니다. 또한 첫 번째 패킷이 ACK가 아닌 SYN-ACK 인 경우 연결 추적이 올바르게 작동한다는 것도 알 수 없습니다.

세 가지 접근법 중 첫 번째 방법이 가장 효과적이라고 생각합니다. 따라서 클라이언트 IP 주소를 알 필요가없는 경우 이것이 좋습니다.

또한 NAT를 잊어 버리고 MAC 또는 IP 계층의 문제를 해결하지 않도록 선택할 수도 있습니다. HTTP 계층까지 올라가서 해결책을 찾을 수 있습니다. 이 경우 찾을 수있는 솔루션은 HTTP 프록시입니다. 192.168.12.87에 HTTP 프록시를 설치하고 적절하게 구성하면 요청을 192.168.12.77로 전달하고 응답을 다시 전달할 수 있습니다. 또한 원래 클라이언트 IP를 유지하는 X-Forwarded-For 헤더를 삽입 할 수 있습니다. 192.168.12.77의 서버는 192.168.12.87의 X-Forwarded-For 헤더를 신뢰하도록 구성해야합니다.


나는 -j MASQUERADE여기에 언급되지 않은 것에 놀랐다 . DNAT의 일반적인 접근 방식이 아닙니까?
remram

3
@remram 나는 SNAT대신 MASQUERADE문서에 언급 된 것이므로 언급 했습니다 . 설명서의 정확한 문구는 다음과 같습니다.It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
kasperd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.