# 網路模擬與分析(5/3): Containernet
###### tags: `Mininet`、`Containernet`
---
**--------------目前為純 code 及 result,詳解部分之後更新--------------**
---
## Containernet 介紹
編譯 containernet 環境
`cd containernet`
`python ./setup.py install`
編譯環境成功會長這樣
```
(以上省略)
Using /usr/local/lib/python2.7/dist-packages
Searching for pyparsing==2.4.6
Best match: pyparsing 2.4.6
Removing pyparsing 2.0.3 from easy-install.pth file
Adding pyparsing 2.4.6 to easy-install.pth file
Using /usr/local/lib/python2.7/dist-packages
Searching for idna==2.8
Best match: idna 2.8
Removing idna 2.0 from easy-install.pth file
Adding idna 2.8 to easy-install.pth file
Using /usr/local/lib/python2.7/dist-packages
Searching for chardet==3.0.4
Best match: chardet 3.0.4
Adding chardet 3.0.4 to easy-install.pth file
Installing chardetect script to /usr/local/bin
Using /usr/local/lib/python2.7/dist-packages
Searching for certifi==2019.11.28
Best match: certifi 2019.11.28
Adding certifi 2019.11.28 to easy-install.pth file
Using /usr/local/lib/python2.7/dist-packages
Finished processing dependencies for containernet==3.0
```
測試環境是否成功
```
python examples/dockerhosts.py
exit
```
docker 安裝 `ubuntu:trusty`
```
root@vm2:/home/user/containernet# docker images | grep ubuntu
ubuntu trusty 13b66b487594 2 months ago 197MB
```
執行 docker 並開啟 ssh 服務,其中建立 user, tom 的使用者
```
docker run -it ubuntu:trusty bash
useradd user
passwd user
ifconfig
apt update
apt install openssh-server -y
/etc/init.d/ssh start
/etc/init.d/ssh status
```
```
docker run -it ubuntu:trusty bash
useradd tom
passwd tom
ifconfig
apt update
apt install openssh-server -y
/etc/init.d/ssh start
/etc/init.d/ssh status
```
另一台終端機使用 ssh 連線
```
ssh user@172.17.0.2
ssh tom@172.17.0.2
```


```
root@vm2:/home/user# docker commit 345 ubuntu:sshd2
sha256:d17b859f891e7aa85dc5db10c224807615ccf62192d34692f5bd30758c34078f
root@vm2:/home/user# docker images | grep ubuntu
ubuntu sshd2 d17b859f891e 10 seconds ago 249MB
ubuntu sshd1 d655dae46b73 8 minutes ago 249MB
ubuntu trusty 13b66b487594 2 months ago 197MB
nitincypher/docker-ubuntu-python-pip latest a6659c7f1508 3 years ago 922MB
root@vm2:/home/user#
```
topology:

```
python3 1.py
xterm h1 d1 d2
```
[h1]
```
ping 10.0.0.251
ping 10.0.0.252
ssh user@10.0.0.251
ssh tom@10.0.0.252
```

---
### 利用字典攻擊法破解 ssh
```
apt install hydra
```
[h1]
```
vim user.txt
vim password.txt
```

h1 使用`hydra -L user.txt -P password.txt 10.0.0.252 ssh- t 4`去破解 d2 的使用者密碼

---
### 實現動態路由
安裝 quagga: `apt install quagga -y`
docker image 下載鏡像: `docker pull kathara/quagga:latest`

dropbox 下載2個檔案, 路徑: `/server-test/test-quagga-ospf`
```
#!/usr/bin/env python
from mininet.net import Containernet
from mininet.cli import CLI
from mininet.link import TCLink, Link
from mininet.log import info, setLogLevel
if '__main__' == __name__:
setLogLevel('info')
net = Containernet()
h1 = net.addHost('h1')
h2 = net.addHost('h2')
r1 = net.addDocker('r1', dimage="kathara/quagga:latest", volumes=["/home/user/Downloads/dynamic_routing/r1/quagga:/etc/quagga"])
r2 = net.addDocker('r2', dimage="kathara/quagga:latest", volumes=["/home/user/Downloads/dynamic_routing/r2/quagga:/etc/quagga"])
r3 = net.addDocker('r3', dimage="kathara/quagga:latest", volumes=["/home/user/Downloads/dynamic_routing/r3/quagga:/etc/quagga"])
net.addLink(h1, r1)
net.addLink(h2, r2)
net.addLink(r1, r2)
net.addLink(r1, r3)
net.addLink(r2, r3)
net.build()
r1.cmd("ifconfig r1-eth0 0")
r1.cmd("ifconfig r1-eth1 0")
r1.cmd("ifconfig r1-eth2 0")
r2.cmd("ifconfig r2-eth0 0")
r2.cmd("ifconfig r2-eth1 0")
r2.cmd("ifconfig r2-eth2 0")
r3.cmd("ifconfig r3-eth0 0")
r3.cmd("ifconfig r3-eth1 0")
r1.cmd("ip addr add 192.168.1.254/24 brd + dev r1-eth0")
r1.cmd("ip addr add 12.1.1.1/24 brd + dev r1-eth1")
r1.cmd("ip addr add 13.1.1.1/24 brd + dev r1-eth2")
r2.cmd("ip addr add 192.168.2.254/24 brd + dev r2-eth0")
r2.cmd("ip addr add 12.1.1.2/24 brd + dev r2-eth1")
r2.cmd("ip addr add 23.1.1.2/24 brd + dev r2-eth2")
r3.cmd("ip addr add 13.1.1.3/24 brd + dev r3-eth0")
r3.cmd("ip addr add 23.1.1.3/24 brd + dev r3-eth1")
r1.cmd("/etc/init.d/quagga restart")
r2.cmd("/etc/init.d/quagga restart")
r3.cmd("/etc/init.d/quagga restart")
h1.cmd("ifconfig h1-eth0 0")
h1.cmd("ip address add 192.168.1.1/24 dev h1-eth0")
h1.cmd("ip route add default via 192.168.1.254 dev h1-eth0")
h2.cmd("ifconfig h2-eth0 0")
h2.cmd("ip address add 192.168.2.1/24 dev h2-eth0")
h2.cmd("ip route add default via 192.168.2.254 dev h2-eth0")
CLI(net)
net.stop()
```
下載完使用
```
chmod 777 -R dynamic_routing
python dynamic_routing.py
```

> 一開始還在建立路由表規則,所以 ping 不通是正常的
開啟新的終端機使用:


> password: zebra
```
en
show ip ospf
show ip ospf route
```
當登入進去後,使用`show ip osfp route`
```
R1# show ip ospf route
============ OSPF network routing table ============
N 12.1.1.0/24 [10] area: 0.0.0.0
directly attached to r1-eth1
N 13.1.1.0/24 [10] area: 0.0.0.0
directly attached to r1-eth2
N 23.1.1.0/24 [20] area: 0.0.0.0
via 12.1.1.2, r1-eth1
via 13.1.1.3, r1-eth2
N 192.168.1.0/24 [10] area: 0.0.0.0
directly attached to r1-eth0
N 192.168.2.0/24 [20] area: 0.0.0.0
via 12.1.1.2, r1-eth1
============ OSPF router routing table =============
============ OSPF external routing table ===========
```
開啟另一台終端機,使用`docker exec -it mn.r1 bash`
並且中斷 r1-eth1

可以看到,因為當 link 斷掉時,動態路由會自動幫你連另一條 link,因此連線是正常的。
---
### Mininet-wifi
```
cd /home/user/mininet-wifi
util/install.sh -n
```

```
#!/usr/bin/python
from mininet.log import setLogLevel, info
from mn_wifi.net import Mininet_wifi
from mn_wifi.node import Station, OVSKernelAP
from mn_wifi.cli import CLI
from mn_wifi.link import wmediumd
from mn_wifi.wmediumdConnector import interference
from subprocess import call
def myNetwork():
net = Mininet_wifi(topo=None,
build=False,
link=wmediumd,
wmediumd_mode=interference,
ipBase='10.0.0.0/8')
info( '*** Adding controller\n' )
info( '*** Add switches/APs\n')
ap1 = net.addAccessPoint('ap1', cls=OVSKernelAP, ssid='ap1-ssid',
channel='1', mode='g', position='331.0,232.0,0')
ap2 = net.addAccessPoint('ap2', cls=OVSKernelAP, ssid='ap2-ssid',
channel='1', mode='g', position='446.0,198.0,0')
info( '*** Add hosts/stations\n')
sta1 = net.addStation('sta1', ip='10.0.0.1',
position='266.0,359.0,0')
sta2 = net.addStation('sta2', ip='10.0.0.2',
position='402.0,360.0,0')
info("*** Configuring Propagation Model\n")
net.setPropagationModel(model="logDistance", exp=3)
info("*** Configuring wifi nodes\n")
net.configureWifiNodes()
info( '*** Add links\n')
net.addLink(sta1, ap1)
net.addLink(sta2, ap1)
net.plotGraph(max_x=1000, max_y=1000)
info( '*** Starting network\n')
net.build()
info( '*** Starting controllers\n')
for controller in net.controllers:
controller.start()
info( '*** Starting switches/APs\n')
net.get('ap1').start([])
net.get('ap2').start([])
info( '*** Post configure nodes\n')
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
myNetwork()
```
先關閉網路服務`systemctl stop NetworkManager`
`python mininet-wifi.py`


> `iwconfig`: 列出 station 資訊
> `iw dev sta1-vlan0 scan`: 掃描附近基地台數量,並列出資訊。
---
## Reference
1. http://csie.nqu.edu.tw/smallko/sdn/routing.htm
2. https://www.youtube.com/watch?v=RpgX07v7DiY
3. https://www.youtube.com/watch?v=lVRxycBe1RE
4. https://www.youtube.com/watch?v=wpw2KRdeaUo
5. https://www.youtube.com/watch?v=N-afnAxcK7g