2
1

ろうとるがPythonを扱う、、(その17:Scapyでルーティングおよびブリッジ)

Posted at

Scapyでルーティングおよびブリッジを実現

Scapy(Pythonにてネットワークパケットを生成などするライブラリ)の2回目(前回は「tracerouteを考察」でとりあげた)。今回は、ルーティングおよびブリッジを実現してみる。

ルーティング

ネットワーク的には下記のようなもの。
image.png
VirtualBoxの3つのVMを利用。両側の異なるネットワークを中央のVM(Lubuntu)でルーティングする。

ソースコード

from scapy.all import *

s0 = conf.L3socket(iface='enp0s3')
s1 = conf.L3socket(iface='enp0s8')

while True:
    p0 = s0.recv()
    if p0:
        #print(p0)
        send(p0, iface='enp0s8')
    p1 = s1.recv()
    if p1:
        #print(p1)
        send(p1, iface='enp0s3')

L3ソケットを定義。あるネットワークI/Fにてパケットを受信したら、別のネットワークI/Fに送信(send())するのみ。

検証

末端PC間のpingの結果。

$ ping -c 5 -w 10000 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=3046 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=2034 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=1036 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=1009 ms
64 bytes from 192.168.10.1: icmp_seq=5 ttl=64 time=988 ms

VM上にもかかわらず、とても遅い。無駄なことをしているのであろう。ブリッジでの結果に続く。

ブリッジ

ネットワーク的には下記のようなもの。
image.png
中央のVM(Lubuntu)ネットワークブリッジ、両端は同一ネットワークセグメントに属する。

ソースコード

調べると、”bridge_and_sniff()”として、scapy内に用意されていることがわかった。ソースコード的には、こちらにある。

from scapy.all import *

def callback(p):
    if p.haslayer(Raw):
        #p.show()
        wrpcap('test.pcap', p, append=True)
    return True
    # If it returns True, the packet is forwarded as it.

# All works        
bridge_and_sniff('enp0s3', 'enp0s8', xfrm12=callback, xfrm21=callback)
#bridge_and_sniff('enp0s3', 'enp0s8')
#bridge_and_sniff('enp0s3', 'enp0s8', prn= lambda x: x.summary())
#bridge_and_sniff('enp0s3', 'enp0s8', prn=callback)

単に、ネットワークI/Fを指定するだけである。さらに、Callback関数を定義し、付加的な動作をすることができる(転送するには、Callback関数の最後に”return”が必要)。ここでは、TCPなどのデータ(Raw)が存在するパケットを、'test.pcap'としてキャプチャファイル化(追加)している。なお、コメント”# All works”以下のものはすべて動作する。

検証

「bridge_and_sniff('enp0s3', 'enp0s8')」を利用した時の末端PC間のpingの結果。

$ ping -c 5 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=4.75 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=2.92 ms
64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=3.77 ms
64 bytes from 10.1.1.2: icmp_seq=4 ttl=64 time=2.13 ms
64 bytes from 10.1.1.2: icmp_seq=5 ttl=64 time=2.71 ms

ルーティング時の結果と比べて、格段に速い。ユーザーランドのL3処理(ソケット)に負荷がかかっていることがわかる。

おまけ(Linuxカーネルにてルーティング)

ルーティング時のネットワーク構成で、Linuxカーネルレベル(net.ipv4.ip_forward = 1)でルーティングした時の結果は下記となる。

$ ping -c 5 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=63 time=2.17 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=63 time=1.10 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=63 time=0.693 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=63 time=0.827 ms
64 bytes from 192.168.10.1: icmp_seq=5 ttl=63 time=0.785 ms

やはり、これが最も速い。

EOF

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1