iptablesを使用して外部要求をlocalhostにリダイレクトする

iptablesを使用して外部要求をlocalhostにリダイレクトする

一部のXポートの「localhost」アドレスで実行されるサービスがあります。残念ながら、アドレスを「0.0.0.0」に変更してサービスを公開することはできません。

iptablesを使用して外部要求をループバック/ localhostインタフェースに内部的にリダイレクトできますか?リダイレクトは 0.0.0.0:X -> localhost:X です。

ありがとう

ベストアンサー1

OPではファイアウォールの存在について言及していないので、単純化のために事前にファイアウォールがないとします。iptables設定が存在します:すべてのトラフィックを許可します。

DNAT次のように使用できます。nat/プリルート次のように宛先IPを127.0.0.1に変更します(UDPポート5555をリダイレクトする例)。

# iptables -t nat -A PREROUTING -p udp --dport 5555 -j DNAT --to-destination 127.0.0.1

しかし、これは、127.0.0.0/8の範囲外のシステム上のすべてのローカルIPアドレスのすべてのDNATターゲットに十分です。宛先を 127.0.0.0/8 内の IP アドレスに変更する場合には、これだけでは不十分です。

これが正しく機能するために切り替える必要がある特別な設定があります。システムのネットワークインタフェースが次のように呼び出されると仮定します。イーサネット0このコマンドは次のことを行います。

# sysctl -w net.ipv4.conf.eth0.route_localnet=1

以下の詳細な説明をご覧ください。

(オプション)特に、127.0.0.1 でリッスンするアプリケーションに 127.0.0.0/8 以外のソース IP が必要ない場合は、変更することもできます。自然/入力鎖で結ぶネットワークアドレス変換。ターゲットとソースをNATすると、同時接続数が厳しく制限されるため、必要な場合にのみ実行する必要があり、ログから実際のソースを取得できなくなります。

# iptables -t nat -A INPUT -d 127.0.0.1 -m state --ctstate DNAT -j SNAT --to-source 127.0.0.1

使い方の詳細な説明route_localnet=1

以下で問題をより詳細に説明するために、次のようにします。ホストのネットワークインタフェースは次のとおりです。イーサネット0、このインターフェイスに設定されたIPアドレスは192.0.2.100/24で、クライアント192.0.2.200からトラフィックを受信しますが、route_localnetまだアクティブではありません。

見ることができるはずです一般ネットワークのNetfilterとパケットフロー(全体のサイズを見るにはクリックしてください):

一般ネットワークのNetfilterとパケットフロー

何が起こったのかを確認してください。

  • クライアントは、192.0.2.200から192.0.2.100(UDP宛先ポート5555)にパケットを送信します。

  • nat/プリルート発生する

    ターゲットは127.0.0.1に変更されます(対応するconntrackエントリはこの変更を元に戻すために使用されます)。

  • ルーティングスタックは到着するパケットを処理します。イーサネット0送信元アドレスは 192.0.2.200、宛先アドレスは 127.0.0.1 です。

  • lo127.0.0.1はループバックインターフェイスの外側には表示されないため、ルーティングスタックはこのパケットを無効と見なします。パケットが破棄されます。

    これは以下で確認できますip route get

    # ip route get 127.0.0.1 from 192.0.2.200 iif eth0
    RTNETLINK answers: Invalid argument
    

    さらに、カーネルを有効にしたい場合火星記録sysctl -w net.ipv4.conf.eth0.log_martians=1)、この情報はDNAT中に受信された各パケットについて記録されます。iptables上記のルールが機能します。

    [728538.240893] IPv4: martian destination 127.0.0.1 from 192.0.2.200, dev eth0
    

これが必要なまれなケースでは、カーネルにはこの動作を軽減するための特定のスイッチがあり、この特定の場合と同様に、パケットに 127.0.0.1 が表示される理由は DNAT ルールによるものであることがわかります。route_localnet:

route_localnet - BOOLEAN
  Do not consider loopback addresses as martian source or destination
  while routing. This enables the use of 127/8 for local routing purposes.
  default FALSE

存在するイーサネット0:

# sysctl -w net.ipv4.conf.eth0.route_localnet=1

これで、前のip route getコマンドは次のようになります。

# ip route get 127.0.0.1 from 192.0.2.200 iif eth0
local 127.0.0.1 from 192.0.2.200 dev lo 
    cache <local> iif eth0 

もはや滴はありません。

これは逆の方法で同じ制限を緩和する。最初のステップとして、応答パケットはルーティング決定を通過します。今後DNATはnetfilterによって取り消されるので、やはり削除されます。前後のパスはroute_localnet1 に設定されます。

今後:

# ip route get 192.0.2.200 from 127.0.0.1
RTNETLINK answers: Invalid argument

後ろに:

# ip route get 192.0.2.200 from 127.0.0.1
192.0.2.200 from 127.0.0.1 dev eth0 uid 0 
    cache 

おすすめ記事