web-dev-qa-db-ja.com

LAN内からDNATを使用したWebサーバーにアクセスする

ローカルネットワーク内のインターネット、サーバー、一部のワークステーションへの接続を維持するルーターを備えた小規模なネットワークがあります。

Network map

サーバーはインターネットからアクセスするためのもので、次のようにルーターのiptablesにいくつかのDNATエントリが設定されています。

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

外部パケットはppp0インターフェース経由でルーターに送信され、内部パケットは実際にスイッチとWLANアダプターを含むbr-lanから送信されます。問題は、外部アクセスは正常に機能しているが、DNS解決の外部IP(ppp0に割り当てられている)を使用してLAN内からサーバーにアクセスしようとすると失敗することです。

私が発明できた唯一の解決策は、内部IPを指すルーターの/etc/hostsに静的エントリを追加することですが、ワイルドカードがないため(およびそのシステムに割り当てられている少なくとも3つのトップレベルドメインがあり、カウントされません)数十のサブドメイン)、それはかなりカリカリで失敗しがちです。もっと良いものを提案できますか?

私はこれだけ question を見つけましたが、あまり役に立ちませんでした。

それが適切であれば、ルーターはdnsmasqでOpenWRT 10.03 Kamikazeを実行します。

12
whitequark

OpenWRTでデフォルトで使用されているUCI構成システムを使用して正しい方法でこれを行う方法を誰も説明していないのに、ほぼ8年後のことです。

スティーブン・マンデーの答えは正しいですが、iptablesコマンドを直接使用しています。これは、UCI構成システムよりも下位の層であり、可能であれば、ほとんどのOpenWRTユーザーには触れないでおくことをお勧めします。

UCIの別の内部ホストからパブリックIP /ポートコンボを介して内部サーバーにアクセスする正しい方法は、ファイル/etc/config/firewallの特定の各DNATターゲットで構成オプションreflectionを有効にすることです。この動作は文書化されています here

例えば:

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はデフォルトで有効になっています。私のテストでは、そうではありませんでした。

3
vittorio88

正解であると確信していなかったため、元の回答を削除しました。それ以来、問題のネットワークをシミュレートするために、VMの小さな仮想ネットワークをセットアップする時間がありました。以下は、私のために機能したファイアウォールルールのセットです(natテーブルの場合のみ、iptables-save形式で):

-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ルールと2番目のPOSTROUTINGルールは一緒に適切なNATを確立するため、外部からの接続か内部からの接続かに関係なく、外部IPアドレスを介したサーバーへの接続が可能になります。 LAN。 LAN上のクライアントが外部IPアドレスを介してサーバーに接続すると、サーバーはルーターの内部IPアドレス(192.168.2.1)からの接続を認識します。

興味深いことに、2番目のPOSTROUTINGルールにはいくつかのバリエーションがあり、これも機能します。ターゲットが-j SNAT --to-source 192.168.2.1に変更された場合、その効果は(驚くことではありませんが)MASQUERADEと同じです。サーバーはローカルLANクライアントからの接続をルーターの内部 = IPアドレス。一方、ターゲットが-j SNAT --to-source 89.179.245.232に変更された場合でも、NATは機能しますが、サーバーはローカルLANクライアントからの接続をルーターのexternal IPアドレス( 89.179.245.232)。

最後に、元のPREROUTING/DNATルールと-i ppp0を組み合わせたルールは機能しないことに注意してください。これは、ルールがLANクライアントからのパケットと一致しないためです(これらはルーターに入らないためです) ppp0インターフェース経由)。内部LANクライアント専用の2番目のPREROUTINGルールを追加することで機能させることは可能ですが、これは洗練されておらず(IMO)、外部IPアドレスを明示的に参照する必要があります。

現在、「ヘアピンNAT」(または「NATループバック」、「NATリフレクション」、またはそれを呼び出すのに好むもの)ソリューションを詳細にレイアウトした後でも、スプリットホライズンDNSソリューションは、 -外部クライアントが外部IPに解決し、内部クライアントが内部IPに解決する場合は、より適切なルートを選択します。どうして? NATの仕組みを理解するよりもDNSの仕組みを理解する人が多く、優れたシステムを構築する上で重要な部分は、保守可能な部品の使用を選択することです。DNSの設定は理解される可能性が高く、したがって、難解なNAT設定(もちろんIMO)よりも)が正しく維持されます。

15
Steven Monday

一般的な解決策は、これらのホスト名の正しい「内部」アドレスを返すローカルDNSサーバーで内部ホストをポイントすることです。

もう1つの解決策-そして私たちがCiscoファイアウォールで作業しているときにこれを使用しています-は、これらのアドレスに対応するファイアウォールのDNS応答を書き換えることです。今のところ、これを行うLinux用のツールはないと思います。

ゲートウェイでルーティングを構成して、正しいことを行うことができるはずです。外部にマップされたIPアドレスを認識するようにサーバーを構成する必要がある場合があります(たとえば、ダミーインターフェイスに割り当てることにより)。この構成では、ある内部システムから別の内部システムへの通信(その「外部」アドレスを使用)がルーターを経由します。

3
larsks

あなたが求めているのはNAT Loopbackそして、SNATルールを追加して、LANからサーバーに送信されるパケットがルーターを経由するようにする必要があります。

-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
2
SiegeX

Dnsmasqを使用して、サーバーの実際のDNSエントリを上書きし、内部IPアドレスを使用する必要があります。

サーバーがwww.example.comで、IPアドレスが1.2.3.4の場合、OUTSIDEからは次のようになります。

Name:    www.example.com
Address:  1.2.3.4

ただし、ネットワークの内側では、www.example.comが192.168.2.10を指す必要があるため、外側と同じ名前を使用してアクセスできるため、nslookupはLAN上でこれを返す必要があります。

Name:    www.example.com
Address:  192.168.2.10

なぜそれらのパケットがLANを「離れる」だけで戻ってくるのですか?私はそれを成功させることはあまりありませんでした。しかし同時に、それをする理由もありませんでした。エンディアンファイアウォールや、Cisco ASAデバイスやさまざまな異なるDNSサーバーの背後に隠された大規模で複雑なネットワークなど、他の多くの構成で同じ操作が行われるのを見てきました。

インターネットがサーバーに到達する方法を知っていて、内部ホストがサーバーに到達する方法を知っている限り(ローカルDNSサーバーのDNSエントリを上書きすることによって)、それは重要なことです。

0
Corey S.

ゲストネットワークを、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ネットワーク内の接続自体に対して設定されますが、トラフィックを分離するために複数のインターフェースを作成した場合は、他のネットワークに対しては設定されません。 Webインターフェースから転送ルールを設定してみましたが、すべてのトラフィックがゲストネットワークからそのLANホストへのポートに送信されます。上記は、すべてのネットワークトラフィックではなく、WAN IPへの要求のみをインターセプトします。

これの代わりに内部DNSを使用することもできますが、すべてのポート転送が単一のホストにしか行かない場合のみです。異なるポートを転送する複数のホストがある場合、異なるポートのルールを異なるtgthost IPおよびポートに繰り返すことができます。

0
BMitch

larsksは、namespace\domainの内部バージョンのホスティングについてコメントしているため、これまでこの問題に対処してきました。もちろん、これを行うには内部的にDNSサーバーが必要です。

0
CurtM