web-dev-qa-db-ja.com

NATゲートウェイでSNAT送信元アドレスを構成するポイントはありますか?

たとえば、次のネットワークトポロジがあるとします。 NAT gateway network settings

NATゲートウェイ_linux-router_には、次のSNATルールがあります。

_Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  10.99.99.50          anywhere             to:1.1.1.6
_

さらに、図に示されているように、loインターフェイスに_1.1.1.6_アドレスが構成されています。技術的には、これは必要ありません。つまり、削除しても、_linux-svr_は引き続き接続できます。したがって、NATゲートウェイでSNAT送信元アドレスを構成するポイントはありますか?_1.1.1.6_を_linux-svr_に関連付けてトレースする方が簡単なので、トラブルシューティングの目的のみです。

1
Martin

netfilterはルートに依存しません。それは、以下で何が起こるかを説明する重要なことです。netfilterのNAT処理はアドレスを変更し、場合によっては、これがルート決定の前に行われると、これがルート決定を変更します。 netfilterはルーティングの決定自体を行いません。それはルーティングスタックの役割のみです。

linux-routerには追加のfirewallingルールがないと仮定しています(デフォルトのiptablesfilterテーブル内)。これは質問で言及されていないためです。また、ケースが増えて対処するのを避けるために、10.99.99.0/24 LANでlinux-srv(およびlinux-router)以外に検討するシステムが他にないことを想定しています(それらに対処するのも難しい)。


1.1.1.6の削除について

SNATは、ルーティングが決定された後、POSTROUTINGで発生します。 SNATは、指定された基準に一致するIPを検出すると、返信を処理するためにconntrackエントリを追加します。これに似たことがlinux-routerで発生します(_conntrack -E -e NEW_を使用):

_    [NEW] tcp      6 120 SYN_SENT src=10.99.99.50 dst=8.8.8.8 sport=57490 dport=80 [UNREPLIED] src=8.8.8.8 dst=1.1.1.6 sport=80 dport=57490
_

返信が本当に返ってくるようにするのはnetfilterの仕事ではありません。これもルーティングスタックジョブです(linux-routerが制御できない外部ルーティングを含む)。

削除される前は、1.1.1.6はlinux-routerのIPでした。 Linuxは 弱いホストモデル に従っているため、このIPが追加されたインターフェイスはそれほど問題ではありませんでした。任意のインターフェイスで受信したこのIPへのクエリに応答できます。 M10iは1.1.1.6に到達するための特定のルートを持っているため、このエントリを削除しても1.1.1.6のパケットを受信できます。linux-routerに属する1.1.215.48を使用します。したがって、linux-routerはこのIPのARP要求を取得しません。M10iからのARP要求は常に1.1.215.48です(同じことを言えば、M10iのARPテーブルのみが1.1.1.6ではなく1.1.215.48をキャッシュしました)。つまり、このIPの存在は重要ではありません。linux-routerw​​illalways1.1.1.6のトラフィックを受信します。しかし、今は違いがあります:

  • 着信パケットが以前に作成されたconntrackエントリと一致しない場合

    パケットがlinux-srvからの以前のアクティビティに関連していない場合、このパケットは この回路図 に示されているように、最初のルート決定に到達します。現在のルーティングテーブルによると、これは次のようになります。

    _# ip route get from 198.51.100.101 iif eth0 1.1.1.6
    1.1.1.6 from 198.51.100.101 via 1.1.215.60 dev eth0 
        cache iif eth0 
    _

    M10i(または1.1.215.32/27 LAN内の任意のシステム)であった場合、linux-routerは、次のように、ICMPリダイレクトを随時追加します。

    _# ip route get from 1.1.215.60 iif eth0 1.1.1.6
    1.1.1.6 from 1.1.215.60 via 1.1.215.60 dev eth0 
        cache <redirect> iif eth0 
    _

    とにかく、インターネットからのパケットの場合、パケットはM10iに送り返されます。これはおそらく実装されています 厳密なリバースパス転送 :このルーティングされたパケットはM10iによってドロップされます、ソース(198.51.100.101)がルーティングテーブルの反対側にあり、Strict PathForwardingによってフィルタリングされているため。厳密なリバースパス転送がなければ、これはM10ilinux-routerの間のループを引き起こし、パケットのTTLが0にデクリメントされ、その後パケットもドロップされます。

  • 着信パケットがする場合は、conntrackによってNATおよび追跡された以前のフローと一致します。

    前の例:8.8.8.8 tcpポート80から1.1.1.6ポート57490から受信した応答パケット。これは_conntrack -E_によって追跡されます。

    _ [UPDATE] tcp      6 60 SYN_RECV src=10.99.99.50 dst=8.8.8.8 sport=57490 dport=80 src=8.8.8.8 dst=1.1.1.6 sport=80 dport=57490
     [UPDATE] tcp      6 432000 ESTABLISHED src=10.99.99.50 dst=8.8.8.8 sport=57490 dport=80 src=8.8.8.8 dst=1.1.1.6 sport=80 dport=57490 [ASSURED]
    _

    いくつかの事前ルーティングポイントで、conntrackは "de-SNAT"を処理します(注意として、このパケットは二度と通過しませんiptables 'natテーブル。これも前の回路図に記述されています:「nat」テーブルは「NEW」接続についてのみ参照されます)。宛先IPが10.99.99.50に変更され、パケットは最初のルート決定に到達します。つまり、linux-srvにルーティングされます。すべてが正常に動作します。

したがって、私は1.1.1.6を削除するとどうなるかを説明しました。インターネットクライアントとしてのlinux-srvには影響しませんが、M10ilinux-routerの間で、無関係なイングレスに若干の混乱を引き起こしますパケット。

インターネット上の一部のクライアントがlinux-routerのDNATルールを使用してlinux-srvに到達するようにしたい場合は、影響を受ける接続(例:linux-srvtcpポートのWebサーバー) 80)、すべてが中断することなく動作します。他の試みについても、M10ilinux-routerの間に小さな問題があります。


SNATルールに対するソースIPセレクター/フィルターの削除について

情報が提供されませんでした:発信インターフェイスにセレクター/フィルターもあるかどうか。以下の2つのルールは、_iptables -t nat -n -L_から同じ出力を取得します(ただし、_iptables -t nat -n -v -L_以上の_iptables-save_からは取得しません)。

_iptables -t nat -A POSTROUTING -o eth0 -s 10.99.99.254 -j SNAT --to-source 1.1.1.6
_

または

_iptables -t nat -A POSTROUTING -s 10.99.99.254 -j SNAT --to-source 1.1.1.6
_

実際、この場合、次の2つのコマンドのいずれかを使用しても問題はありません。

_iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 1.1.1.6
iptables -t nat -A POSTROUTING -j SNAT --to-source 1.1.1.6
_
  • 1.1.1.6はまだlinux-routerに属しています

    プライベートIP宛先アドレスがeth0の側からネットワーク上に来るのを見ることができないため、linux-routerは事実上one IPアドレスしかルーティングできません:linux-srvの10.99.99.50およびルーティングは、最初に10.99.99.50から開始されたときにのみ発生するため、パブリックIPにSNATされます。iptablesは最初の接続(状態NEW)でのみ新しいconntrackエントリを作成するため、この後、conntrackエントリは変更されず、すべてが正常に機能します。

  • linux-routerから削除された1.1.1.6

    • linux-srvの場合、インターネットに接続してもすべてが期待どおりに機能します。前の説明も当てはまります。

    • 外部から1.1.1.6への不明な着信接続の場合(例:198.51.100.101から):

      ルーティングスタックは、1.1.1.6をM10iにルーティングする必要があると判断します(前述の説明を参照)。暫定的なconntrackエントリが状態NEWで追加され、パケットがnat/POSTROUTINGに到達します。パケットは1.1.1.6にSNATされ、M10iに返送されます。M10iは1.1.1.6へのルートを持ち、変更されたパケットをlinux-routerに送信します。送信元IPと宛先IPの両方が1.1.1.6です(送信元はルーティングテーブルの正しい側にあるため、 Strict Reverse Path Forwardingによってもドロップされません)。linux-routerパケットを受信します...そこからバグかどうかはわかりませんが、_conntrack -E_を使用して、単一のTCP 198.51.100.101から受信したSYNパケット:

      _# conntrack -E
          [NEW] tcp      6 120 SYN_SENT src=198.51.100.101 dst=1.1.1.6 sport=48202 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=48202
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=48202 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=60062
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=60062 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=23442
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=23442 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=54429
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=54429 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=7652
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=7652 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=34503
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=34503 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=49256
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=49256 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=58399
          [NEW] tcp      6 120 SYN_SENT src=1.1.1.6 dst=1.1.1.6 sport=58399 dport=5555 [UNREPLIED] src=1.1.1.6 dst=1.1.1.6 sport=5555 dport=54522
          [...]
      _

      Netfilterの動作が正常でない場合でも、M10ilinux-routerの間で実際にループが発生しています(TTLが0に低下するまで)。


結論

ローカルIPアドレス1.1.1.6を削除しないでください。あなたはルーティングの問題を作成していますが、それらのルーティングの問題を修正するのはnetfilterの役割ではありません。これらのループを防ぐファイアウォールルールを追加したとしても、誤ったルートを使用するのは正しい動作ではありません。

同様に、SNATルールのソースIPセレクターを削除することもできますが、インターフェイスが選択されていない場合(つまり、このルールを選択した場合:_iptables -t nat -A POSTROUTING -j SNAT --to-source 1.1.1.6_)はお勧めできません。インターネット上でルーティングできないプライベートIPアドレスが機能しているため、機能しているだけです。そうでない場合、linux-routerのeth2インターフェースの背後にあるLANにアクセスしようとする外部からの接続は、1.1.1.6にSNATされます。

たとえば、linux-srvからインターネットから到達可能で、linux-srvが1.1.1.6とは異なる送信元アドレスを表示できないようにするDNATルールを追加した場合も同様です。シミュレーションの具体例を次に示します(1.1.1.6をlinux-routerに正常に復元します)。

_# ip -br a
lo               UNKNOWN        127.0.0.1/8 1.1.1.6/32 
eth0@if5         UP             1.1.215.48/27 
eth2@if4         UP             10.99.99.254/24 

# iptables -t nat -A PREROUTING -d 1.1.1.6 -p tcp --dport 80 -j DNAT --to-destination 10.99.99.50

# iptables-save | grep -v ^#
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -d 1.1.1.6/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.99.99.50
-A POSTROUTING -j SNAT --to-source 1.1.1.6
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

# conntrack -E 
   [NEW] tcp      6 120 SYN_SENT src=198.51.100.101 dst=1.1.1.6 sport=45752 dport=80 [UNREPLIED] src=10.99.99.50 dst=1.1.1.6 sport=80 dport=45752
 [UPDATE] tcp      6 60 SYN_RECV src=198.51.100.101 dst=1.1.1.6 sport=45752 dport=80 src=10.99.99.50 dst=1.1.1.6 sport=80 dport=45752
 [UPDATE] tcp      6 432000 ESTABLISHED src=198.51.100.101 dst=1.1.1.6 sport=45752 dport=80 src=10.99.99.50 dst=1.1.1.6 sport=80 dport=45752 [ASSURED]
_

明確ではないかもしれませんが、それは期待される応答が10.99.99.50から1.1.1.6(198.51.100.101ではない)であることを意味します:linux-srv実際に接続されているIPアドレスをブラインドのままにします。 1.1.1.6を参照してください。

1
A.B