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
>>>