scapy のルーティング

chestnut_eared_bunting02 linux

scapy は OS とは別に独自のルーティングテーブルを持ちます。scapy での送受信はこのルーティングテーブルの影響を受けます。

※ここでは実際に設定、動作したものを掲載していますが、内容について保証するものではありません。流用される場合は各自の責任でお願いします。

scapy の他の機能については「scapy について」からご参照ください。

以下は OS のルーティングテーブルです。

[root@rocky8-client scapy]# ip r
default via 10.0.2.1 dev enp0s3 proto static metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.44 metric 100
[root@rocky8-client scapy]#

以下は scapy のルーティングテーブルです。

>>> conf.route
Network          Netmask          Gateway   Iface   Output IP  Metric
0.0.0.0          0.0.0.0          10.0.2.1  enp0s3  0.0.0.0    100
10.0.2.0         255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.0         255.255.255.0    0.0.0.0   enp0s3  10.0.2.44  100
10.0.2.255       255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.44        255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
127.0.0.0        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.0.0.0        255.0.0.0        0.0.0.0   lo      127.0.0.1  0
127.0.0.1        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.255.255.255  255.255.255.255  0.0.0.0   lo      127.0.0.1  0
224.0.0.0        240.0.0.0        0.0.0.0   enp0s3  10.0.2.44  250
>>>

以降の検証で、scapy のデフォルトルートを削除し、scapy から外部への通信ができなくなることを確認します。

デフォルトルートの削除に先立ち、scapy でインターネット上のサーバに ping の送受信ができることを確認します。

>>> r, ur = sr(IP(dst="8.8.8.8/32")/ICMP(), timeout=1, verbose=False)
>>> r; r.nsummary()
<Results: TCP:0 UDP:0 ICMP:1 Other:0>
0000 IP / ICMP 10.0.2.44 > 8.8.8.8 echo-request 0 ==> IP / ICMP 8.8.8.8 > 10.0.2.44 echo-reply 0 / Padding
>>>

scapy のデフォルトルートを削除します。ただし、conf.route.delt() では削除できなかったため、ルーティングテーブルのデータが登録されているリストから直接削除します。

参考:デフォルトルートを削除できなかった件について

conf.route.delt() でデフォルトルートを削除しようとしましたが以下のとおりエラーとなりました。

>>> conf.route.delt(net="0.0.0.0/0", gw="10.0.2.1", metric=100)
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/scapy/route.py", line 126, in delt
    i = self.routes.index(route)
        ^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: (0, 0, '10.0.2.1', 'enp0s3', '10.0.2.44', 100) is not in list

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.11/site-packages/scapy/route.py", line 129, in delt
    raise ValueError("No matching route found!")
ValueError: No matching route found!
>>>

エラーメッセージによると、ルーティングテーブルのリストに削除対象である (0, 0, ‘10.0.2.1’, ‘enp0s3’, ‘10.0.2.44’, 100) のデータが無いとのことです。リストは以下のとおりです。

>>> conf.route.routes
[(167772672, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (167772716, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (167772927, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (2130706432, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (2130706432, 4278190080, '0.0.0.0', 'lo', '127.0.0.1', 0), (2130706433, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (2147483647, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (0, 0, '10.0.2.1', 'enp0s3', '0.0.0.0', 100), (167772672, 4294967040, '0.0.0.0', 'enp0s3', '10.0.2.44', 100), (3758096384, 4026531840, '0.0.0.0', 'enp0s3', '10.0.2.44', 250)]
>>>

リストに (0, 0, ‘10.0.2.1’, ‘enp0s3’, ‘0.0.0.0’, 100) はありますが、たしかにエラーで指摘されているデータは存在しません。(ルーティングテーブルで言うところのデフォルトルートの Output IP は ‘0.0.0.0’ であり、‘10.0.2.44’ とは一致していません。)
conf.route.delt() のオプションで Output IP を指定できれば対象のルーティングを削除できると思うのですが、やり方がわかりませんでした。

>>> # scapy のルーティングテーブルのリストを表示
>>> conf.route.routes
[(167772672, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (167772716, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (167772927, 4294967295, '0.0.0.0', 'enp0s3', '10.0.2.44', 0), (2130706432, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (2130706432, 4278190080, '0.0.0.0', 'lo', '127.0.0.1', 0), (2130706433, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (2147483647, 4294967295, '0.0.0.0', 'lo', '127.0.0.1', 0), (0, 0, '10.0.2.1', 'enp0s3', '0.0.0.0', 100), (167772672, 4294967040, '0.0.0.0', 'enp0s3', '10.0.2.44', 100), (3758096384, 4026531840, '0.0.0.0', 'enp0s3', '10.0.2.44', 250)]
>>>
>>> # 総当たりでデフォルトルートを示すルーティングデータのインデックスを確認(→7)
>>> conf.route.routes[7]
(0, 0, '10.0.2.1', 'enp0s3', '0.0.0.0', 100)
>>>
>>> # デフォルトルートのデータを削除
>>> del(conf.route.routes[7])
>>>

scapy のルーティングテーブルからデフォルトルート(10.0.2.1)が削除されていることを確認します。

>>> conf.route
Network          Netmask          Gateway  Iface   Output IP  Metric
10.0.2.0         255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
10.0.2.0         255.255.255.0    0.0.0.0  enp0s3  10.0.2.44  100
10.0.2.255       255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
10.0.2.44        255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
127.0.0.0        255.255.255.255  0.0.0.0  lo      127.0.0.1  0
127.0.0.0        255.0.0.0        0.0.0.0  lo      127.0.0.1  0
127.0.0.1        255.255.255.255  0.0.0.0  lo      127.0.0.1  0
127.255.255.255  255.255.255.255  0.0.0.0  lo      127.0.0.1  0
224.0.0.0        240.0.0.0        0.0.0.0  enp0s3  10.0.2.44  250
>>>

OS のルーティングテーブルに影響がないことを確認します。

[root@rocky8-client scapy]# ip r
default via 10.0.2.1 dev enp0s3 proto static metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.44 metric 100
[root@rocky8-client scapy]#

scapy からインターネット上のサーバに ping の送受信ができなくなったことを確認します。

>>> r, ur = sr(IP(dst="8.8.8.8/32")/ICMP(), timeout=1, verbose=False)
WARNING: No route found for IPv4 destination 8.8.8.8 (no default route?)
WARNING: No route found for IPv4 destination 8.8.8.8 (no default route?)
WARNING: more No route found for IPv4 destination 8.8.8.8 (no default route?)
>>>

OS レベルの ping では問題がないことを確認します。

[root@rocky8-client scapy]# ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=33.6 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 33.573/33.573/33.573/0.000 ms
[root@rocky8-client scapy]#

次に、scapy のデフォルトルートを手動で追加し、インターネット上のサーバとの通信を再開させます。

>>> # ルーティング追加
>>> conf.route.add(net="0.0.0.0/0",gw="10.0.2.1", metric=100)
>>>
>>> # ルーティングテーブルにデフォルトルート(10.0.2.1)が追加されていることを確認
>>> conf.route
Network          Netmask          Gateway   Iface   Output IP  Metric
0.0.0.0          0.0.0.0          10.0.2.1  enp0s3  10.0.2.44  100
10.0.2.0         255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.0         255.255.255.0    0.0.0.0   enp0s3  10.0.2.44  100
10.0.2.255       255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.44        255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
127.0.0.0        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.0.0.0        255.0.0.0        0.0.0.0   lo      127.0.0.1  0
127.0.0.1        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.255.255.255  255.255.255.255  0.0.0.0   lo      127.0.0.1  0
224.0.0.0        240.0.0.0        0.0.0.0   enp0s3  10.0.2.44  250
>>>

scapy でインターネット上のサーバに ping の送受信ができることを確認します。

>>> r, ur = sr(IP(dst="8.8.8.8/32")/ICMP(), timeout=1, verbose=False)
>>> r; r.nsummary()
<Results: TCP:0 UDP:0 ICMP:1 Other:0>
0000 IP / ICMP 10.0.2.44 > 8.8.8.8 echo-request 0 ==> IP / ICMP 8.8.8.8 > 10.0.2.44 echo-reply 0 / Padding
>>>

resync() でルーティングテーブルをリセットできます。

>>> # 以下はデフォルトルート(10.0.2.1)が削除された状態
>>> conf.route
Network          Netmask          Gateway  Iface   Output IP  Metric
10.0.2.0         255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
10.0.2.0         255.255.255.0    0.0.0.0  enp0s3  10.0.2.44  100
10.0.2.255       255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
10.0.2.44        255.255.255.255  0.0.0.0  enp0s3  10.0.2.44  0
127.0.0.0        255.255.255.255  0.0.0.0  lo      127.0.0.1  0
127.0.0.0        255.0.0.0        0.0.0.0  lo      127.0.0.1  0
127.0.0.1        255.255.255.255  0.0.0.0  lo      127.0.0.1  0
127.255.255.255  255.255.255.255  0.0.0.0  lo      127.0.0.1  0
224.0.0.0        240.0.0.0        0.0.0.0  enp0s3  10.0.2.44  250
>>>
>>> # リセット
>>> conf.route.resync()
>>>
>>> # リセット後のルーティングテーブル
>>> conf.route
Network          Netmask          Gateway   Iface   Output IP  Metric
0.0.0.0          0.0.0.0          10.0.2.1  enp0s3  0.0.0.0    100
10.0.2.0         255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.0         255.255.255.0    0.0.0.0   enp0s3  10.0.2.44  100
10.0.2.255       255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
10.0.2.44        255.255.255.255  0.0.0.0   enp0s3  10.0.2.44  0
127.0.0.0        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.0.0.0        255.0.0.0        0.0.0.0   lo      127.0.0.1  0
127.0.0.1        255.255.255.255  0.0.0.0   lo      127.0.0.1  0
127.255.255.255  255.255.255.255  0.0.0.0   lo      127.0.0.1  0
224.0.0.0        240.0.0.0        0.0.0.0   enp0s3  10.0.2.44  250
>>>
タイトルとURLをコピーしました