LAN内からDNAT'ted Webサーバーにアクセスする


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のバージョンは?
コーリーS.

@Corey 10.03安定ですが、それはopenwrt自体とは何の関係もありませんよね?
ホワイトクォーク

回答:


3

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

Steven Mondayの答えは正しいですが、iptablesコマンドを直接使用しています。これはUCI構成システムよりも下位のレイヤーであり、可能な場合はほとんどの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)からの接続と見なします。

興味深いことに、2番目の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)から発信されたものと見なします。

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

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


これは完璧に機能します、ありがとうございます!DNSセットアップの方が良いことに同意しますが、同じ外部IPの異なるポートをLAN上の異なるマシンに転送することはできません。とにかく、このセットアップを維持するのは私だけなので、それで構いません。
ホワイトクォーク

これがあなたのために働いたと聞いてうれしいです!
スティーブン

「IMO」とは何ですか?国際流星機構www.imo.net?
ジョナサンコマー

@ macmadness86 IMO ==私の意見
スティーブン

3

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

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

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


うーん。サーバーのインターフェイスに外部IPを追加し、LAN内からそのサーバーに送信される外部IPにすべてのパケットを転送するようにルーターを構成することをお勧めしますか?興味深いことに、すぐにテストします。
ホワイトクォーク

構成を提案できますか?私はこれを試しました: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、それは機能していません。
ホワイトクォーク

ルーティングテーブル10の内容 内部サーバーでは、おそらくローカル192.168.xxアドレス(ローカルで通信するため)とパブリックインターフェイス(エイリアスとして)の両方をプライマリインターフェイスに持つ必要があります。
ラースク

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から来るパケットのルーティングを防ぎます(そして、それを有効にすると、パケットは間違ったソースから送られて拒否されます)。
ホワイトクォーク

試しましたか?LANから特定のポート上のサーバーIPに向かうパケットにのみ影響します。
SiegeX

はい、しました。(そして、最初のルールも変更してみました)。たとえば、digは192.168.2.1#53にパケットを送信し、ルールの有無にかかわらず、192.168.2.10#53から予期しない応答を受け取ります。
ホワイトクォーク

0

名前空間\ドメインの内部バージョンのホストに関するlarsksのコメントは、一般的に私が過去にこの問題を処理した方法です。もちろん、これを行うには内部的にDNSサーバーが必要です。


ええ、私はdnsmasqを使用していると書きました。自動置換の設定に関するアイデアはありますか?
ホワイトクォーク

OpenWRTとKamikazeについては何も知りませんが、私が読んでいるものに基づいて-あなたが/etc/dnsmasq.conf "cname = ext-hostname.domain.com、int-hostname.domain.com"に以下を追加した場合
-CurtM

さて、私が判断できた限り、dnsmasq cnameはマスクをサポートしていないため、サブドメインカウントのために私には適用できません。
ホワイトクォーク

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

これの代わりに内部DNSを使用できますが、これはすべてのポート転送が単一のホストにのみ送信される場合のみです。異なるポートを転送するホストが複数ある場合、異なるポートのルールを異なるtgthostIP とポートに繰り返すことができます。


現在のカーネルには、conntrack一致モジュールがあります。そして、あなたが問題を解決するために必要なのは、そのような単一のルールを使用している:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
アントン・ダニロフ

@AntonDanilovいいね、私はそれが好きです。私が使用したルールは、同じサブネットからの接続用のOpenWRTにすでにあるリフレクションNATルールに基づいていました。conntrackが利用可能になる前に書かれた可能性がある以外の理由が他にあるかどうかはわかりません。
BMitch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.