パケット生成を考慮しないIPルールを変更する方法は?

パケット生成を考慮しないIPルールを変更する方法は?

質問: 異なる送信元アドレスでパケットが生成されると、特定のインターフェイスでL4トラフィックをルーティングするために構築されたIPルールは遵守されません。

概要 ソースアドレスがホストアドレスと異なるパケットを生成したいと思います。これを達成するために、私はPythonパッケージScapyを使用します。注:私の目標はDNSトラフィックを送信することですが、DNS要求で送信元アドレスを偽装する簡単な解決策が見つからなかったため、ポート53でsrcとdstアドレスを使用してUDPパケットを生成しました。それでもこれだと思います。現時点では、実際のDNSプロトコルではなくL3とL4のみをテストしているので動作します。これは私のスクリプトです。

#!/usr/bin/python3

# The following is designed to generate a packet with a different source address

import sys 
from scapy.all import *

def main():
    S = "10.0.26.122" # spoofed source IP address
    D = "10.0.26.123" # destination IP address
    SP = 53 # source port
    DP = 53 # destination port
    payload = "This is a fake message" # packet payload

    spoofed_packet = IP(src=S, dst=D) / UDP(sport=53, dport=53) / payload
    send(spoofed_packet)

#Entry point
main()

スクリプトを実行する前のルーティングテーブルは次のようになりました。

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.26.0       0.0.0.0         255.255.255.0   U     0      0        0 ens224
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

これはIPインターフェースです

# ip -br a
lo               UNKNOWN        127.0.0.1/8
ens161           UP             10.0.29.122/24
ens192           UP             10.104.8.122/24
ens193           UP             10.0.27.122/24
ens224           UP             10.0.26.122/24
ens256           UP             10.0.21.122/24
virbr0           DOWN           192.168.122.1/24
virbr0-nic       DOWN
ip_vti0@NONE     DOWN

スクリプトを実行すると./packet-gen.py "10.0.26.122" "10.0.26.123"機能します。これは、IPルール/別々のルーティングテーブルを構築していないためです。ホスト(10.0.26.122)とリモートホスト(10.0.26.123)でtcpdumpを実行し、UDPパケットが送信されることを確認しました。また、dig www.google.com @10.0.26.123実際のDNS要求が実行され、応答を受信することをテストして確認しました。

これで問題が発生します。基本テーブルのルーティングエントリを削除してから、ポート番号のみに基づいてルーティングしたいと思います。これを行うには、次のコマンドを実行して最初に10.0.26.0/24のルーティングエントリを削除しました。

# ip route del 10.0.26.0/24 dev ens224
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

アイテムが削除されました。スクリプトを再実行すると動作しません。マイニング要求も失敗します。これは、デフォルトのカーネルルーティングテーブルにL3パスがないために予想される現象です。

L4でルーティングするために、まずens224を介してすべてのトラフィックを送信する新しいIPルーティングテーブルを作成しました。

# ip route add table 53 0.0.0.0/0 dev ens224

次に、ポート53を使用してすべてのトラフィックをキャプチャし、53を自分のカスタムテーブルに送信するIPルールを作成します。

# ip rule add ipproto udp dport 53 lookup 53

また、厳密なリバースパス転送ルールを過度に軽減するrp_filterの特別なsysctlルールを作成しました。

# sysctl -w "net.ipv4.conf.ens224.rp_filter=2"

私の仕事を確認するには、次のように表示されます。

# ip route list table 53
default dev ens224 scope link
# ip rule list
0:      from all lookup local
32765:  from all ipproto udp dport 53 lookup 53
32766:  from all lookup main
32767:  from all lookup default
# ip route get 10.0.26.123 ipproto udp dport 53
10.0.26.123 dev ens224 table 53 src 10.0.26.122 uid 0
    cache
# ip route get 10.0.26.123
10.0.26.123 via 10.104.8.1 dev ens192 src 10.104.8.122 uid 0
    cache

最後のコマンドは、通信がDNSでない場合、デフォルトでデフォルトパスが使用されることを示しています。

これをテストするために、まず10.0.26.123にpingを試みました。失敗すると予想されます。これでマイニング要求を実行しようとしましたが、うまくいきdig www.google.com @10.0.26.123ました。発掘要求はIPルールと一致し、ベーステーブルに入る前に適切にルーティングされます。 tcpdump(10.0.26.123)を介してサービスに到達し、自分のホスト(10.0.26.122)からの着信トラフィックが表示されます。

これでscapyスクリプトを再実行しようとしましたが、何も起こりません。私のホストまたはサーバーのソースアドレスがホストと同じであっても、tcpdumpには何もありません。ソースアドレスを変更してみましたが、変更はありませんでした。デフォルトのL3パスをベーステーブルの10.0.26.0/24に再度追加すると、scapyスクリプトが再実行されます。私がここで何を見逃しているのでしょうか?私が生成したトラフィックが私が作成したIPルールセットに準拠していないのはなぜですか?

ベストアンサー1

Scapyはオペレーティングシステムのルーティングメカニズムを使用しませんが、Scapyが起動したとき(またはメソッドが呼び出されるたびに)オペレーティングシステムのルーティングテーブルconf.routeから同期される独自のルーティングテーブル(オブジェクト)を使用します。conf.route.resync()

Scapyのルーティングメカニズムは、説明する動作を説明するソースルーティングをサポートしません。

おすすめ記事