LAN 내부에서 DNAT의 웹 서버에 액세스


12

라우터가있는 소규모 네트워크가 있는데, 로컬 네트워크의 인터넷, 서버 및 일부 워크 스테이션에 대한 연결을 유지합니다.

네트워크 맵

서버는 인터넷에서 액세스하도록되어 있으며 라우터 iptables에 다음과 같은 몇 가지 DNAT 항목이 설정되어 있습니다.

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10

외부 패킷은 ppp0인터페이스 를 통해 라우터로 전달 되고 내부 패킷은 br-lan스위치와 WLAN 어댑터가 실제로 포함 된에서 전송됩니다. 문제는 외부 액세스는 제대로 작동하지만 DNS 확인 외부 IP (에 할당 됨 ppp0)로 LAN 내부에서 서버에 액세스하려는 시도 가 실패 한다는 것 입니다.

내가 발명 할 수있는 유일한 해결책 /etc/hosts은 내부 IP를 가리키는 라우터의 정적 항목을 추가 하는 것입니다.하지만 와일드 카드가 없기 때문에 (그리고 시스템에 할당 된 최상위 도메인이 3 개 이상 있고 수십 개의 하위 도메인을 세지 않음), 오히려 바삭 바삭하고 실패하기 쉽습니다. 더 나은 것을 제안 할 수 있습니까?

이 질문 만 찾았 는데 도움이되지 않았습니다.

관련이 있으면 라우터는 dnsmasq와 함께 OpenWRT 10.03 Kamikaze를 실행합니다.


어떤 버전의 OpenWRT?
— Corey S.

@Corey 10.03 안정적이지만 openwrt 자체와는 아무런 관련이 없습니까?
— whitequark

답변:


3

거의 8 년이 지난 후에도 OpenWRT에서 기본적으로 사용되는 UCI 구성 시스템을 사용하여 올바른 방법을 설명하는 사람이 아무도 없습니다.

Steven Monday의 대답은 정확하지만 iptablesUCI 구성 시스템보다 낮은 계층 인 명령을 직접 사용 하고 있으며 가능한 경우 대부분의 OpenWRT 사용자는 그대로 두는 것이 가장 좋습니다.

UCI의 다른 내부 호스트에서 공개 IP / 포트 콤보를 통해 내부 서버에 액세스하는 올바른 방법 reflection은 파일의 각 특정 DNAT 대상에서 구성 옵션을 활성화하는 것 /etc/config/firewall입니다. 이 동작은 여기 에 설명되어 있습니다 .

예를 들면 다음과 같습니다.

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

참고 : 표시된 OpenWRT 설명서에 reflection따라 기본적으로 활성화되어 있습니다. 내 테스트에서는 그렇지 않았습니다.


15

정확한 답을 완전히 확신하지 못했기 때문에 원래 답변을 삭제했습니다. 그 후 문제의 네트워크를 시뮬레이션하기 위해 VM의 가상 네트워크를 약간 설정할 시간이있었습니다. 나를 위해 일한 방화벽 규칙 세트는 다음과 같습니다 ( 표의 경우에만 iptables-save형식으로 nat).

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE

첫 번째 POSTROUTING규칙은 LAN과 인터넷 연결을 공유하는 간단한 방법입니다. 나는 완전성을 위해 그곳을 떠났습니다.

PREROUTING규칙 및 제 POSTROUTING외부 IP 주소를 통해 서버에 접속하는 관계없이 LAN 연결은 내부 또는 외부에서 발생 여부에 일어날 수 있도록 함께 규칙 적절한의 NAT를 확립한다. LAN의 클라이언트가 외부 IP 주소를 통해 서버에 연결되면 서버는 라우터의 내부 IP 주소 (192.168.2.1)에서 연결이 온 것으로 간주합니다.

흥미롭게도 두 번째 POSTROUTING 규칙에는 몇 가지 변형이 적용됩니다. 대상이로 변경 -j SNAT --to-source 192.168.2.1되면 그 결과는 다음과 같습니다 (놀랍지 않게) MASQUERADE. 서버는 로컬 LAN 클라이언트의 연결을 라우터의 내부 IP 주소 에서 시작한 것으로 간주 합니다. 반면 대상이로 변경 -j SNAT --to-source 89.179.245.232되면 NAT는 여전히 작동하지만 이번에는 서버가 로컬 LAN 클라이언트의 연결을 라우터의 외부 IP 주소 (89.179.245.232)에서 시작한 것으로 간주합니다.

마지막으로, 규칙 이 LAN 클라이언트에서 오는 패킷과 일치하지 않기 때문에 원래 PREROUTING/ DNAT규칙이 -i ppp0작동하지 않습니다 ( ppp0인터페이스 를 통해 라우터에 들어 가지 않기 때문에 ). PREROUTING내부 LAN 클라이언트에 대해서만 두 번째 규칙 을 추가하여 작동 시킬 수 있지만 IMO (Inelegant)이며 외부 IP 주소를 명시 적으로 참조해야합니다.

이제 "헤어핀 NAT"(또는 "NAT 루프백"또는 "NAT 리플렉션"또는 호출하기를 원하는 모든 것) 솔루션을 자세하게 배치 한 후에도 분할 수평 DNS 솔루션은 여전히 ​​믿습니다. -외부 클라이언트가 외부 IP로 해석되고 내부 클라이언트가 내부 IP로 해석되는 경우, 더 권장되는 경로입니다. 왜? NAT가 작동하는 방식을 이해하는 것보다 DNS가 작동하는 방식을 이해하는 사람이 더 많기 때문에 우수한 시스템을 구축하는 데있어 큰 부분은 유지 관리 가능한 부분을 사용하는 것입니다. DNS 설정은 비전 NAT 설정 (물론 IMO)보다 이해하기 쉬우므로 올바르게 유지 관리 될 가능성이 높습니다.


이것은 완벽하게 작동합니다. 대단히 감사합니다! DNS 설정이 더 좋지만 동일한 외부 IP의 다른 포트를 LAN의 다른 컴퓨터로 전달할 수는 없습니다. 어쨌든, 나는이 설정을 유지하는 유일한 사람이므로 괜찮습니다.
— whitequark

이것이 효과가 있다고 들었습니다.
— Steven 월요일

"IMO"는 무엇입니까? 국제 유성기구 www.imo.net?
— Jonathan Komar

@ macmadness86 IMO == 내 의견에
— 스티븐

3

일반적인 해결책은 내부 호스트를 로컬 DNS 서버로 지정하여 이러한 호스트 이름에 대한 올바른 "내부"주소를 반환하는 것입니다.

Cisco 방화벽에서 작업 할 때이 솔루션을 사용하는 또 다른 솔루션은 이러한 주소에 해당하는 방화벽에서 DNS 응답을 다시 작성하는 것입니다. 지금 당장 Linux 용 도구가 있다고 생각하지 않습니다.

게이트웨이에서 올바른 작업을 수행하도록 라우팅을 구성 할 수 있어야합니다. 외부에서 매핑 된 IP 주소를 인식하도록 서버를 구성해야 할 수도 있습니다 (예 : 더미 인터페이스에 할당). 이 구성을 사용하면 "내부"주소를 사용하여 한 내부 시스템에서 다른 내부 시스템으로의 통신이 라우터를 통과합니다.


흠. 따라서 외부 IP를 서버의 인터페이스에 추가 한 다음 라우터를 구성하여 LAN 내부에서 해당 서버로 들어오는 외부 IP로 모든 패킷을 전달하도록 제안합니까? 흥미롭게도 곧 테스트하겠습니다.
— whitequark

구성을 제안 할 수 있습니까? 나는 이것을 시도했다 : ip rule add to 89.179.245.232 dev br-lan table 10; ip route add 89.179.245.232 via 192.168.2.10 dev br-lan table 10. 작동하지 않는다.
— whitequark

라우팅 테이블 10에 무엇입니까? 내부 서버에서는 기본 인터페이스에 로컬 192.168.xx 주소 (로컬 통신용)와 공용 주소 (별칭으로)가 모두 있어야합니다.
— Larsks

2

요청한 사항을 호출 NAT Loopback하고 LAN에서 서버로 전송되는 패킷이 라우터를 통해 다시 전달되도록 SNAT 규칙을 추가해야합니다.

-A POSTROUTING -p tcp -s 192.168.2.0/24 -d 192.168.2.10 -m multiport --dports 22,25,80,443 -j SNAT --to-source 89.179.245.232

슬프게도, 그것은 작동하지 않습니다. 나는 원래보고 싶었어 -i ppp0그 다른 체인에 의해 처리되면서 문제의 내 규칙의 옵션을; 이 규칙은 LAN에서 오는 패킷의 라우팅을 방지합니다 (사용하도록 설정하면 패킷이 잘못된 소스에서 전송되어 거부 됨).
— whitequark

사용해 보셨습니까? LAN의 패킷이 해당 특정 포트의 서버 IP로 전송되는 패킷에만 영향을 미칩니다.
— SiegeX

그래, 내가 했어. (그리고 나는 첫 번째 규칙을 변경하려고 시도했습니다). 예를 들어 dig는 192.168.2.1 # 53으로 패킷을 보낸 다음 규칙의 유무에 관계없이 192.168.2.10 # 53에서 예기치 않은 응답을받습니다.
— whitequark

0

네임 스페이스 \ 도메인의 내부 버전 호스팅에 대한 larsks 의견은 일반적으로 과거 에이 문제를 처리 한 방식입니다. 물론이를 위해서는 내부에 DNS 서버가 필요합니다.


예, dnsmasq를 사용하고 있다고 썼습니다. 자동 대체 설정에 대한 아이디어가 있습니까?
— whitequark

OpenWRT와 Kamikaze에 대해서는 아무것도 모르지만 내가 읽은 내용에 따라-/etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com"에 다음 내용을 추가하면 어떻게됩니까?
— CurtM

글쎄, 내가 결정할 수있는 한, dnsmasq cname는 마스크를 지원하지 않으므로 하위 도메인 수로 인해 나에게 적용되지 않습니다.
— whitequark

0

게스트 네트워크가 wan에서 lan 네트워크로 전달 된 포트에 연결할 수 있도록 다음 솔루션을 생각해 냈습니다. 이 스크립트는 "네트워크-> 방화벽-> 사용자 지정 규칙"섹션에 있습니다.

# lookup the public IP (DDNS resolves to this)
wanip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

# Guest network to LAN
# srcname is the guest network name, this needs to match for iptables
srcname=guest
# CIDR notation of guest and lan networks
srcnet=192.168.15.0/24
tgtnet=192.168.10.0/24
# router (openwrt) IP on lan network
tgtrouter=192.168.10.1
# host on lan network where ports are normally forwarded
tgthost=192.168.10.5
# ports to forward as a list or range
tcpports=8080,9090
udpports=12345

prechain=prerouting_${srcname}_rule
postchain=postrouting_${srcname}_rule

# reset the tables to prevent duplicate rules
iptables -t nat -F ${prechain}
iptables -t nat -F ${postchain}

iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP SNAT" -j SNAT --to-source ${tgtrouter}
iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP SNAT" -j SNAT --to-source ${tgtrouter}

재부팅을 지원하려면 openwrt의 ssh 명령 줄에서 다음을 실행해야했습니다 (그렇지 않으면 재부팅 중에 일부 규칙이 추가 된 다음 플러시되는 경쟁 조건이 있다고 생각합니다).

uci set firewall.@include[0].reload="1"
uci commit firewall

NAT 리플렉션은 트래픽을 격리하기 위해 여러 인터페이스를 만든 경우 LAN 네트워크 내에서 자체적으로 연결되도록 설정되지만 다른 네트워크로는 연결되지 않습니다. 웹 인터페이스에서 전달 규칙을 구성하려고 시도했지만 모든 트래픽을 게스트 네트워크에서 해당 LAN 호스트로 포트로 보냅니다. 위의 내용은 모든 네트워크 트래픽 대신 WAN IP에 대한 요청 만 차단합니다.

이 대신 내부 DNS를 사용할 수 있지만 모든 포트 전달이 단일 호스트로만 이동하는 경우에만 가능합니다. 다른 포트를 전달하는 호스트가 여러 개인 경우 다른 포트의 규칙을 다른 tgthostIP 및 포트로 반복 할 수 있습니다 .


현재 커널에는 conntrackmatch 모듈이 있습니다. 그리고이 문제를 해결하기 위해 필요한 것은 다음과 같은 단일 규칙을 사용하는 것입니다.iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
— Anton Danilov

@AntonDanilov 좋네요. 내가 사용한 규칙은 동일한 서브넷에서 연결하기 위해 OpenWRT에 이미 반영된 반사 NAT 규칙을 기반으로했습니다. 그들이 conntrack을 사용할 수 있기 전에 작성되었을 수있는 것 이외의 다른 이유가 있는지 확실하지 않습니다.
— BMitch
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.