ネットワークエミュレータ「AGGRESSOR NETWORK」を作って試す 〜今回はRaspberry Pi 400で〜

ネットワークエミュレータ「AGGRESSOR NETWORK」を作って試す 〜今回はRaspberry Pi 400で〜
Page content

一度試してみたいツール

「AGGRESSOR NETWORK」というものを、Facebook上の投稿だったか広告を見て初めて知った。これはbitset社の製品で、ネットワークの有線接続の間に挟んで通信遅延やパケット損失をエミュレート、つまり意図的に発生させるツールとのこと。ネットワークの障害を再現する際に使うものらしい。

AGGRESSOR NETWORK

AGGRESSOR NETWORK

bitset

興味を持ったので情報を追いかけると、このツールの、MIT licenseなソースコードがGitHub上にあると分かった。

さらにREADMEには、「Raspberry Pi 4」を使って開発とテストを行ったと書かれている。ということは、私の手元のRaspberry Piを使ってこのツール作りに挑戦できるのか? そして実際に動作を試せるのか?

準備したもの

AGGRESSOR NETWORKを作るために下記の物を準備した。ラズパイ用のRTC (Real-Time Clock) のみ新規購入で、他は手元にある物を用いる。

RTCは、内蔵時計を持たないラズパイがNTPに頼らず時刻を保持するために必要となる。時刻情報は、AGGRESSOR NETWORKの画面上の表示だけでなく、パケットキャプチャを保存する場合にはそのタイムスタンプとしても必要になってくる。

種別商品名購入価格 (税込)購入店備考
RTCRaspberry Pi用RTC(DS1307)832円スイッチサイエンス送料200円
コンピュータRaspberry Pi 400-円-所有
有線LANアダプタTP-LINK UE300-円-所有
microSDカード16GBのもの-円-所有
TP-Link 有線LAN アダプター 10/100/1000 Mbps Giga USB3.0 ポータブル UE300

TP-Link 有線LAN アダプター 10/100/1000 Mbps Giga USB3.0 ポータブル UE300

TP-Link

構築手順

AGGRESSOR NETWORKの構築手順について。手順の確定は、最初に下記のaの組み合わせにて、多少のソース解析と何度かの試行錯誤を行った末に手順を見定めて、次にbの組み合わせでもその手順が通用することを確認する、という流れで行った。

  • a. Raspberry Pi 4 + Raspberry Pi OS (32-bit) Lite
  • b. Raspberry Pi 400 + Raspberry Pi OS (64-bit) Lite

なお、AGGRESSOR NETWORKのREADMEの記述内容にそのまま沿えばaの組み合わせになるのだが、なぜbも試したかというと、(ブログ記事としては) お手本通りではなく何らかの独自色を出したいなぁと思ったからである。

Step-1. Raspberry Pi OSを用意する

  1. 手元PCでRaspberry Pi Imagerを起動し、OS「Raspberry Pi OS Lite」をmicroSDカードにインストールする
    • 初期設定でユーザ名を「bitset」に設定しておくこと
  2. OSをインストールしたmicroSDカードを使ってラズパイを起動する (途中に自動で2回の再起動が行われる)
  3. RTCのドライバーのインストールとAGGRESSOR NETWORKの起動に必要となるパッケージを、次のコマンドでRaspberry Pi OSにインストールする
    sudo apt update
    sudo apt upgrade
    sudo apt install bridge-utils dstat fbcat git iftop tcpdump tmux toilet python3-yaml
    
  4. RTC (DS1307) の発売元Seeed-StudioのGitHubリポジトリ、pi-hats/RTC-HAT at master · Seeed-Studio/pi-hats · GitHubを参照して、次のようにしてRTCのドライバーをRaspberry Pi OSにインストールする
    bitset@aggressor-network:~ $ cd; git clone https://github.com/Seeed-Studio/pi-hats.git
    Cloning into 'pi-hats'...
    remote: Enumerating objects: 402, done.
    remote: Counting objects: 100% (25/25), done.
    remote: Compressing objects: 100% (16/16), done.
    remote: Total 402 (delta 10), reused 11 (delta 7), pack-reused 377 (from 1)
    Receiving objects: 100% (402/402), 10.24 MiB | 7.18 MiB/s, done.
    Resolving deltas: 100% (209/209), done.
    bitset@aggressor-network:~ $ cd ~/pi-hats/tools
    bitset@aggressor-network:~/pi-hats/tools $ sudo ./install.sh -u rtc_ds1307
    Uninstall rtc_ds3231 ...
    Uninstall rtc_ds1307 ...
    Uninstall adc_ads1115 ...
    Enable I2C interface ...
    Install rtc_ds1307 ...
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    The following packages will be REMOVED:
    fake-hwclock
    0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
    After this operation, 32.8 kB disk space will be freed.
    (Reading database ... 79795 files and directories currently installed.)
    Removing fake-hwclock (0.12+nmu1) ...
    Processing triggers for man-db (2.11.2-2) ...
    fake-hwclock.service is not a native service, redirecting to systemd-sysv-install.
    Executing: /lib/systemd/systemd-sysv-install disable fake-hwclock
    #######################################################
    Reboot the system to take a effect of Install/Uninstall
    #######################################################
    
  5. Raspberry Pi OSのNTPを無効化する
    sudo timedatectl set-ntp false
    
  6. Raspberry Pi OSをshutdownし、microSDカードを取り外す

Step-2. ソースコードを編集してmicroSDカードへ書き込む

  1. 手元PC (Ubuntuを想定) にStep-1のmicroSDカードをマウントして読み書きできるようにする
    • 以降、手元PCのユーザとしてhogeを想定している
    • microSDカードの領域はUbuntuの/media/hoge/以下にマウントされると想定している
  2. Step-1でのOSインストール時に自動生成された、microSDカードのPARTUUIDの値を調べる (この例ではbccf60c9-01bccf60c9-02)
    $ cat /media/hoge/rootfs/etc/fstab | grep PARTUUID
    PARTUUID=bccf60c9-01  /boot/firmware  vfat    defaults          0       2
    PARTUUID=bccf60c9-02  /               ext4    defaults,noatime  0       1
    
  3. 手元PCの任意のディレクトリにてAGGRESSOR NETWORKのソースコードを取得して、2つのファイルを編集する
    git clone https://github.com/bitset-jp/aggressor_network
    cd ./aggressor_network/src
    
    ## ↓2箇所ある「PARTUUID=###CHANGE-HERE###」部分の右辺を2で調べたPARTUUIDの値へ置換する
    vim ./etc/fstab
    
    ## ↓「PARTUUID=30bb3e2a-02」部分の右辺を同じく置換する
    vim ./boot/cmdline.txt
    
  4. 3にて一部編集したAGGRESSOR NETWORKのソースコードをmicroSDカードへ書き込む (下記の手順ではrsync時に念のため事前確認として -n (--dry-run) を行っている)
    ## boot領域
    rsync -n -av ./boot/ /media/hoge/bootfs/
    rsync    -av ./boot/ /media/hoge/bootfs/
    
    ## ホーム領域
    sudo rsync -n -av ./home/bitset/ /media/hoge/rootfs/home/bitset/
    sudo rsync    -av ./home/bitset/ /media/hoge/rootfs/home/bitset/
    sudo mkdir /media/hoge/rootfs/home/bitset/.config/
    sudo chown -R 1000:1000 /media/hoge/rootfs/home/bitset/
    
    ## /etc領域
    sudo rsync -n -av ./etc/ /media/hoge/rootfs/etc/
    sudo rsync    -av ./etc/ /media/hoge/rootfs/etc/
    sudo chown -R root:root /media/hoge/rootfs/etc/
    
    ## /opt領域
    sudo rsync -n -av ./opt/ /media/hoge/rootfs/opt/
    sudo rsync    -av ./opt/ /media/hoge/rootfs/opt/
    sudo chown    root:root /media/hoge/rootfs/opt/
    sudo chown -R 1000:1000 /media/hoge/rootfs/opt/bitset/
    
  5. microSDカードのマウントを解除して取り出す

Step-3. ラズパイにRTCを接続してAGGRESSOR NETWORKを起動する

  1. ボタン型電池を装填したRTCを、RTC上の「1」のPINがRaspbery Pi 400の「PIN1」に刺さるような位置で、Raspberry Pi 400に接続する。
  2. Step-2で用意したmicroSDカードを用いてRaspberry Piを起動する
  3. Interface eth1 does not exist! がCUI画面に繰り返し表示されるが、USB接続の有線LANアダプタを挿し直せば収まるようだ
  4. (Enterキーを押せば) login:プロンプトが表示されるので、ユーザ「bitset」でログインする
  5. CUIでの分割画面が表示されれば、AGGRESSOR NETWORKの起動は成功である
  6. 時刻設定とRTCへの保存はrtcコマンドで行える

Step-4. 通信障害を発生させる

ここからはAGGRESSOR NETWORK自体の操作方法となるので、詳細については下記リンクの本家ドキュメントを参照するのがよいと思う。

今回の実験では、自宅PCにて行うfast.comの速度測定に、AGGRESSOR NETWORKでエミュレーションする通信障害によってどのような変化が現れるかを観測する。

  1. 自宅にて、PCとルータの間のLAN配線を変更して、AGGRESSOR NETWORKを介在させるようにした。下記のような構成になる。
flowchart LR;
	Hub --> Router[自宅ルータ]
	Hub --> Server[(自宅サーバ)]
	RPi -->|USB接続| eth1([eth1])
	eth1 --> Hub{Hub}
	PC[PC] --> RPi[Raspberry Pi w/eth0]
	Router --> Internet(((the Internet)))

subgraph AGGRESSOR NETWORK
	RPi
	eth1
end
subgraph 基幹系
	Hub
	Router
	Server
end
subgraph 部屋
	PC
end
  1. PCと自宅サーバ間の通信速度をLinuxのiperf3コマンドで計測し、AGGRESSOR NETWORKを介在させても940Mbits/sec前後で、介在前と変化がないことを確認した。
  2. AGGRESSOR NETWORKに何も設定しない状態で https://fast.com/ での速度測定を行った。これが今回の基準値となる。
    コマンドDownloadUploadLatency
    なし310Mbps420Mbpsアンロード済み4ms, ロード済み5ms
  3. 各種コマンドを使って障害 (通信速度の制限、パケットロス、遅延) を発生させた。fast.comの結果は次の表の通り。
    コマンドDownloadUploadLatency
    rate 1Mbit890Kbps2.7Mbps14ms/776ms
    loss 1%190Mbps140Mbps4ms/6ms
    loss 5%94Mbps21Mbps5ms/5ms
    loss 10%24Mbps3.0Mbps4ms/14ms
    loss 20%2.5Mbps410Kbps5ms/42ms
    delay 100ms 20ms 10%2.2Mbps200Mbps180ms/207ms
    delay 300ms2.9Mbps28Mbps604ms/605ms
    loss 5% and delay 100ms410Kbps1.6Mbps205ms/206ms

AGGRESSOR NETWORK自体とは関係のない考察だが、以上の実験により、パケットロスや長い遅延が発生する場合、実効速度に大きく影響することが一目瞭然となった。これらはネットワークの品質を下げてしまう大敵だなと再認識。ちなみに、上記よりも遅いrate 64Kbitも試してはみたものの、あまりにも通信速度が遅いと今度は名前解決にも時間がかかるために (PCの他の通信が帯域を使い切っていた可能性もあり)、timeoutでfast.comを開くことさえままならなくなった。

まとめ

AGGRESSOR NETWORKは、ネットワークエミュレーションにtcコマンド (私は今回初めて知った)、画面構成にはtmuxコマンドを用いつつ、Raspberry Pi OSをベースに使いやすく、電源ぶち抜きも行えるように大変巧くパッケージングされていることが分かった。

今後もしネットワークエミュレーションが必要な場面に私が遭遇したらば、このAGGRESSOR NETWORKをぜひ活用してみようと思う。また、ラズパイを用いる「電源ONしたらすぐ使える」システムのパッケージングの一例として、諸々参考にできそうな気がしている。