Mininet作業記録

Mininet本家にあるMininet Walkthroughをやってみた記録。
[インフラ勉強会で行われていたサーバーネットワーキング講座](https://wp.infra-workshop.tech/event/5472/)で知ったのがきっかけ。
[視聴方法](https://wp.infra-workshop.tech/how-to-join-a-session/)のdiscordのチャンネルにあるリンクから辿れる場所に、録画されたものが一週間だけ残っているらしい。
なお、私個人はアプリケーションプログラマであり、ネットワークエンジニアではないことを付記しておく。
専門外を興味のまま調べてるだけ。

# Mininetとは
[Mininetのインストールと使用方法 - Qiita](https://qiita.com/28tomono/items/e8cf97a4b38b30f6c0cb)参照。

# インストール
上記のリンク先ではソースから入れているし、本家では配られてるVMがUbuntu 14.04ベースだったので、ここでは18.10にパッケージインストールする形で実施。

## 本体インストール
```console
$ sudo apt install mininet
```

## GUI準備
これだけでも作業は出来るが、python/TKを使ったGUIがあるようなので、これを使って作業する(上記講座でも使用されていた)。

```console
$ sudo apt install python-tk
```

GUIの起動は、以下のように実施。

```console
$ zcat /usr/share/doc/mininet/examples/miniedit.py.gz | sudo python
```

↓起動画面
![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/0e12e4a6-8f84-ff9f-a7b7-7d2175253da8.png)

## パケットキャプチャGUIの準備
wiresharkのインストール

```console
$ sudo apt install wireshark
```
途中で↓な画面が出るので、「はい」を選択した(wiresharkを一般ユーザで動かしたいので)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/7fab1602-fa6b-809e-6f1d-48318ba2ab85.png)

インストール後、wiresharkグループに普段使いのユーザーを追加。

```console
$ sudo vigr
```

```console
wireshark:x:グループID:
```
みたいな行があるのでユーザーIDを追加する

```console
wireshark:x:グループID:ユーザーID
```
shadow側も自分で追加

```console
sudo vigr -s
```
同じ感じでユーザーIDを追加する。
一旦ログアウトしてログインし直す。
メニューから起動するとこんな感じ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/c7dbeb8e-75ba-2352-6fa1-8d65c7ee1a11.png)

# [Mininet Walkthrough](http://mininet.org/walkthrough/)の実施

GUI(miniedit.py)とwiresharkを起動した状態でスタート。

## ホストやスイッチと対話する

### (1) 最小構成のネットワークを描く

![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/7ee8af1a-d794-6508-da51-e112cb3cb7dd.png)

ホスト2つが(レガシー)スイッチで繋がってる構成。

### (2) Run

Runボタン押下で、実際にこの構成の仮想ネットが稼働する。

h1のIPは10.0.0.1が自動で振られている。
h2のIPは10.0.0.2が自動で振られている。

### (3) h1からh2へ疎通確認

1. h1で右クリックしてTerminal選択した状態で離す→xterm起動
2. ip a→IPなどを確認(ifconfigの代わり)
3. ping 10.0.0.2→パケットが届く

開いたxtermは仮想ホストh1で開いたような操作感。

例)

```console
root@lubuntu:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: h1-eth0@if56: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 22:7e:cf:71:61:8b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.1/8 brd 10.255.255.255 scope global h1-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::207e:cfff:fe71:618b/64 scope link 
       valid_lft forever preferred_lft forever
root@lubuntu:~# ping -c 4 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.156 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.041 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.070 ms

--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 76ms
rtt min/avg/max/mdev = 0.041/0.077/0.156/0.047 ms
root@lubuntu:~# 
```
ここではpingに-c 4をオプション指定して、4回パケットを送出するようにしている(未指定はCtrl-Cするまで繰り返し)。
見れば分かるとおり、0.2ms以下で応答が返ってきている→OK。

### (4) h2からh1へ疎通確認

1. h2で右クリックしてTerminal選択した状態で離す→xterm起動
2. ip a→IPなどを確認(ifconfigの代わり)
3. ping 10.0.0.1→パケットが届く

開いたxtermは仮想ホストh2で開いたような操作感。
同様に確認する。

```console
root@lubuntu:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: h2-eth0@if57: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 12:51:85:b2:42:5a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.2/8 brd 10.255.255.255 scope global h2-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::1051:85ff:feb2:425a/64 scope link 
       valid_lft forever preferred_lft forever
root@lubuntu:~# ping -c 4 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.165 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.070 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.070 ms

--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 74ms
rtt min/avg/max/mdev = 0.067/0.093/0.165/0.041 ms
root@lubuntu:~#
```

### (5) 仮想ホストのプロセス共有確認

1. h1のxtermでps -a
2. h2のxtermでps -a
3. ツールのメニューからRun>Root Terminalでxterm起動
4. 起動したxtermでps -a

全て同じプロセスであることを確認

例)

```console
root@lubuntu:~# ps -a
  PID TTY          TIME CMD
14360 pts/0    00:00:00 sudo
14371 pts/0    00:00:02 python
14865 pts/0    00:00:00 xterm
14881 pts/4    00:00:00 ps
root@lubuntu:~#
```

### (6) 仮想ホストでウェブサーバを起動し、疎通確認

`ホスト1`でウェブサーバをバックグラウンドジョブとして起動

```console
# python -m SimpleHTTPServer 80 &
```
`ホスト2`でそのWebの/を取ってくる

```console
# wget http://10.0.0.1/
```
index.htmlを取得できればOK

`ホスト1`でウェブサーバを止める

```console
# kill %1
```

### (7) wiresharkでキャプチャ(追記)

上記で、ホスト1<->ホスト2のHTTP通信をキャプチャする。

#### 1. wget実行前に、wiresharkの画面で、「キャプチャ」をクリック
すると↓のような一覧が出る
![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/b455297b-15fd-5609-f2a5-7cb33f1bc80b.png)
#### 2. 一番下を選択/開始する。
一番下のインターフェースs1-eth2:s1-eth2は仮想スイッチS1のホスト2に繋がるインターフェース。
つまりホスト2のeth0と直結しているインターフェース。
本当はホスト2のeth0をキャプチャしたいが、できないので、これをキャプチャする。
#### 3. ホスト2のxtermからwget→キャプチャされる
#### 4. wiresharkの画面でメニューからキャプチャ＞停止
キャプチャ直後の画面はこんな感じ↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/ad90ae69-08b8-d95e-5496-a9ddcbca155b.png)
#### 5. 解析
先頭のSYNパケットを選んで、メニューから分析＞追跡＞TCPストリーム
![image.png](https://qiita-image-store.s3.amazonaws.com/0/374336/7722eb1a-cb01-97a2-61cb-0a0ad402c708.png)
これで、パケットの中身の詳細まで知らずとも(知ってた方が良いけど)、生ソケットレベルのTCPのストリームを追うことができる。

## 高度な起動オプション

以降はGUIを使用しない、mininet自体の機能の紹介だったので割愛。
多分必要なときに読めばいい。

# 今後の予定
次はOpenFlowのチュートリアルをやってみたい。