# 網路練習題 Part 2 ## 預備知識 ==Step2== 的部分是在其他都完成以後,才開始做的。 1. 關於 Container 與 Container Networking * Container 和 VM 的差別是? * 什麼是 Network Namespace? * 什麼是 cgroup? * Docker 和 Container 哪裡不同? 2. 關於 Bridge * Brctl * ovs-vsctl / ovs-ofctl ... (optional,有時間再看) 3. 關於 ip 指令 * ip netns * ip link * ip addr 4. IPTABLE 與 NetFilter 學習 ==Step 2== * iptables 中的 Packet Flow * 最常被使用到的 SNAT 與 DNAT ## CodeLab 使用 `docker` 指令與 `brctl` 指令,建立以下拓樸: ```graphviz graph G { a [shape=box, label="h1"] b [shape=box, label="h2"] c [shape=box, label="switch"] a -- c; b -- c; } ``` 建立拓樸之後,設定 h1 的 IP 為 `192.168.0.1/24`,h2 為 `192.168.0.2/24`,並且確定兩者可以 ping 通。 ```bash # Command Example docker create --net='none' --name='h1' --privilege -it ubuntu brctl addbr switch ip link add veth0 type veth peer name veth_net0 ``` 上述有一些可能能夠幫助你 "快速" 進入狀況的 command,例如:建立一個沒有任何網路的 Docker Container、建立一個 Bridge、建立一對 Veth Pair。 ```bash # 完整解法 sudo brctl addbr switch sudo ifconfig switch up sudo ip link set switch up docker run -i -t --rm --name='h1' --net='none' juamorous/ubuntu-ifconfig-ping /bin/bash docker run -i -t --rm --name='h2' --net='none' juamorous/ubuntu-ifconfig-ping /bin/bash pid=docker inspect -f '{{.State.Pid}}' container_name sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid # Below is an example for h1, h2 should not named duplicate veth pair sudo ip link add veth0 type veth peer name veth_net0 sudo brctl addif switch veth0 sudo ip link set veth0 up sudo ip link set veth_net0 netns $pid sudo ip netns exec $pid ip link set dev veth_net0 name eth0 sudo ip netns exec $pid ip link set eth0 up sudo ip netns exec $pid ip addr add 192.168.0.1/24 dev eth0 # Now you can try ping each host ``` ### Some hint for you 這邊有一些關於這個題目的提示,如果解不開來,就拿這些關鍵字去 Google 並弄懂他吧。 1. How to find Docker container's PID (Process ID) * 這又與 Container 的 Network Namespace 有什麼關係呢? 2. Attach veth to Docker ## CodeLab 2 ==Step 2== 使用 `docker` 指令與 `brctl` 指令,建立以下拓樸: ```graphviz graph G { a [shape=box, label="h1"] b [shape=box, label="h2"] c [shape=box, label="switch"] d [shape=box, label="gateway"] a -- c; b -- c; c -- d; } ``` 設定與 CodeLab 1 大致相同,但多出了一個特別的 Gateway ,Gateway 是一個 veth pair,一端連接在 Switch 上,另一端則放在 **Host Namespace** 當中,且 IP 為 `192.168.0.254/24`。 請設定 h1 及 h2 的 default gateway 為 `192.168.0.254`,並在 Host 上 config SNAT rules,使 h1 及 h2 能夠經由 gateway ping 到 Google DNS。 ```bash # 完整解法 sudo ip link add dev vmh1 type veth peer name vmh2 sudo brctl addif switch vmh1 sudo ip addr add 192.168.0.254/24 dev vmh2 sudo ip link set vmh1 up sudo ip link set vmh2 up # try ping 192.168.0.254 in host also ping 192.168.0.254 in h1 and h2 # delete default gateway and set 192.168.0.254 for gateway to h1 and h2 sudo ip netns exec $pid ip route del default sudo ip netns exec $pid ip route add default via 192.168.0.254 echo 1 > /proc/sys/net/ipv4/ip_forward # Replace wlp3s0 to the interface which you using for connecting to the internet sudo iptables -t nat -A POSTROUTING -s 192.168.0.254/24 -o wlp3s0 -j MASQUERADE ```