ローカルポートにアクセスするときになぜnetfilter postroutingを経なければならないのですか?

ローカルポートにアクセスするときになぜnetfilter postroutingを経なければならないのですか?

環境:

[root@VM-32-4-centos ~]# uname -r
3.10.0-514.26.2.el7.x86_64

次のチェーンでログ印刷を設定しました。

[root@VM-32-4-centos ~]# iptables -A INPUT -p tcp --dport 8000 -j LOG --log-prefix "INPUT DPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A INPUT -p tcp --sport 8000 -j LOG --log-prefix "INPUT SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A OUTPUT -p tcp --dport 8000 -j LOG --log-prefix "OUTPUT DPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A OUTPUT -p tcp --sport 8000 -j LOG --log-prefix "OUTPUT SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -t nat -A POSTROUTING -p tcp --sport 8000 -j LOG --log-prefix "POSTROUTING SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -t nat -A POSTROUTING -p tcp --dport 8000 -j LOG --log-prefix "POSTROUTING DPORT 8000 LOGS: "

次にtelnetコマンドを実行します。

telnet 127.0.0.1 8000

tail -f /var/log/message, 以下を表示します。

May  2 23:54:47 VM-32-4-centos kernel: OUTPUT DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: POSTROUTING DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: INPUT DPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: OUTPUT SPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8000 DPT=51096 WINDOW=43690 RES=0x00 ACK SYN URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: INPUT SPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8000 DPT=51096 WINDOW=43690 RES=0x00 ACK SYN URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: OUTPUT DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=6164 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=342 RES=0x00 ACK URGP=0 
May  2 23:54:47 VM-32-4-centos kernel: INPUT DPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=6164 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=342 RES=0x00 ACK URGP=0 

申し訳ありません。ローカルアクセス時にSYNパケットがPOSTROUTINGを通過するのはなぜですか?

後続のACK + SYNパケットはPOSTROUTINGを通過しません。なぜですか?

なぜこれが起こるのか尋ねてもいいですか?関連情報がありますか?

ありがとうございます。

答え1

以下は、Linuxネットワークスタックを介してパケットがどのように移動するかを説明するNetfilterおよび一般的なネットワーキングのパケットフロー図です(ルーティングではなくブリッジングに使用される青いリンク層のフィールドは無視できます)。

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

パケットがシステムにローカルに保持されるようにするには、ルーティングスタックがlo(ループバック)インターフェイスを使用する前にパケットを評価する必要があります。

# ip route get 127.0.0.1
local 127.0.0.1 dev lo src 127.0.0.1 uid 0 
    cache <local> 

したがって、回路図に記載されているフローに従います。

  • ローカルプロセスによって発行された
  • ルーティング決定:出力インターフェースlo
  • さまざまなチェーンが出力にかかっています。
  • POSTROUTINGのさまざまなチェーンフック:これは常に転送または発信パケットで発生します。
  • lo最後に、回路も右側のインターフェースに送信されます。

これで、インターフェースloはループバックという目的を達成します。パケットはインターフェイスを介してlo回路図の左側に戻ります。loインターフェイスに戻ります。でも今回は出るのではなく入ってくるのです。

  • インターフェイス「から」lo着信パケット
  • PREROUTINGに接続されたさまざまなチェーン:これは常に受信パケットで発生します。
  • ルーティング決定:宛先はローカルプロセスになります。
  • INPUTの様々なチェーン
  • ローカルプロセスから受信

これで問題が発生しました。 NATです。 NATルールは、同じフロー内の他のすべてのパケットが同じ方法でどのように変換されるかを決定するために使用されます。特定のフローがNATされると、同じフロー(応答を含む)の他のすべてのパケットは、Netfilterおよびconntrack(NATの実行方法を含むこのフローに関する必須情報を記憶します)によって直接処理されます。合格しません。iptablesこれ以上ではありません。回路図にこれに関するメモがあります。

「新しい」接続についてのみ「nat」テーブルを参照してください。

その後、このストリームのNATに関する他のすべては、呼び出さないNetfilterによって短絡されます。iptablesNatはもはや抜けていません。


これにより、natテーブルを使用して結果を解釈できます。 2 つの nat/POSTROUTING ルールを使用します。

  • フローの最初のパケット:初期クエリ(SYNパケット)がNATルールを通過します。

    • 一致をフィルタリングし--dportてロギングをトリガーします。
    • 一致しない--sport(ログなし)
  • このフローに対するすべての後続のパケット(ポート8080のアプリケーションからの応答を含む)は、フローがすでに存在するため、もはやnatテーブルを通過しません(たとえば、パケットは「NEW」状態ではありません)。

    したがって、最終--sportルールは何も記録しません。

lo同様に、 nat/PREROUTING (またはほとんど使用されない nat/INPUT) に LOG ルールを追加すると、ローカルストリームの最初のパケットが常に送信されるため、インターフェイスからのコンテンツは表示されません。到着 lo受け取る前に~から lo:そのようなプロセスは常に存在します。

次のコマンドを使用して mangle/POSTROUTING にログインする場合:

iptables -t mangle -A POSTROUTING -p tcp --sport 8000 -j LOG --log-prefix "mangle POSTROUTING SPORT 8000 LOGS: "
iptables -t mangle -A POSTROUTING -p tcp --dport 8000 -j LOG --log-prefix "mangle POSTROUTING DPORT 8000 LOGS: "

フィルタ/入力、フィルタ/出力と同様に、ログ内のすべてのクエリとすべての応答パケットを表示できます。

上記以外の場合は、常に発生するように新しいステータスパケットのみを表示するフィルタを追加します。ナットテーブル:

iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -p tcp --sport 8000 -j LOG --log-prefix "mangle POSTROUTING SPORT 8000 LOGS: "
iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -p tcp --dport 8000 -j LOG --log-prefix "mangle POSTROUTING DPORT 8000 LOGS: "

その後、同じ初期動作が再び発生します。各ストリームの最初のパケットのログは1つだけです(したがって、--sportストリームの最初のパケットは応答であるため決して発生しません)。

関連情報