Dockerネットワークで遊ぶ_その1_同セグPING編

## はじめに

[ルーター自作でわかるパケットの流れ](https://gihyo.jp/book/2011/978-4-7741-4745-1)を**Dockerネットワーク**で試す
ゆくゆくは**実際のマシン**を使って何かしてみたい。
たとえば先駆者がすでにやっているような、[HTTP上の画像をすり替える悪いルーターの制作](https://iciclize.net/posts/my-bad-router-that-replaces-images-on-http/)とか。

### 「ルーター自作でわかるパケットの流れ」

ハッシュタグ[#router_jisaku](https://twitter.com/hashtag/router_jisaku?src=hashtag_click)で検索すると、同じ本を読んだ人のツイートが確認できる
（本書の巻末に#router_jisakuでつぶやいてシェアしてください、と筆者コメント有り）

https://gihyo.jp/book/2011/978-4-7741-4745-1

### 本記事は

1. Dockerで１つネットワーク作成する
1. その中に２つLinuxマシンを作る
1. ２つマシン間でPING疎通確認をする

### 連載情報

連載|内容
---|---
[その１](https://qiita.com/t13801206/items/0fd95e85377098f996b3)|〈実践〉同じセグメント内のPING疎通確認
[その2](https://qiita.com/t13801206/items/0858f2af9c57a9db65aa)|〈コード〉イーサネットヘッダの中身をみてみる
[その3](https://qiita.com/t13801206/items/81459f9374bffcd293ec)|〈コード〉ARP,IP,ICMPの中身をみてみる
[その4](https://qiita.com/t13801206/items/478493c1527cbcf0511c)|〈実践〉IP,TCPをキャプチャする
[その5](https://qiita.com/t13801206/items/7fa2f7bf75021899e05e)|〈実践）ルーターを準備する
[その6](https://qiita.com/t13801206/items/0aa1d0f2b762d013e9f8)|〈実践〉別セグメントのWEBへアクセスをする

### 検証環境と前提

- Dockerはすでにインストール済み
- Windows 11のPowerShellから`docker ***`コマンドを打つ
- DockerコンテナはUbuntuを使う

## Dockerネットワークを新規で作る

`testnw`を新規作成する

```powershell
docker network create --driver bridge testnw
docker network ls
```

:::note info 
各コマンドを実行したあとに`ls`をするのは確認のため。省略可能。
:::

デフォルトでは`bridge`という名前のネットワークが採用される
環境の汚染や、問題切り分けの観点から、今回の検証はすべて`testnw`を使う。（あとでネットワークを追加する予定もある）

[Docker コンテナ・ネットワークの理解](https://docs.docker.jp/engine/userguide/networking/dockernetworks.html)

## Dockerイメージを取得する

本書では**CentOS**を使っているが、本記事では**Ubuntu**を使う

```powershell
docker image pull ubuntu:latest
docker image ls
```

Ubuntuを採用した理由は
今後、実機（ラズパイ）を使った遊びもしてみたいので、`apt`で書き残したいというのと
CentOSのサポート問題があるため（下記）

:::note warn
本書が書かれたのは2011年であるが、2023年現在ではCentOSはサポート終了が予定されている
:::

https://business.ntt-east.co.jp/content/cloudsolution/ih_column-16.html

### Ubuntuバージョン確認

今回使用するイメージは、Ubuntuの **22.04.2**

```bash:cat /etc/issue
Ubuntu 22.04.2 LTS \n \l
```

## Dockerコンテナを立ち上げる

サーバとクライアントを１台ずつ立ち上げる

```powershell
docker container run -itd --privileged --mount type=bind,source=/d/200_Study/2304_Router_Jisaku,target=/app --net testnw --hostname Server1 --name myserver ubuntu:latest
docker container run -itd --privileged --mount type=bind,source=/d/200_Study/2304_Router_Jisaku,target=/app --net testnw --hostname Client1 --name myclient ubuntu:latest
docker container ls
```

- 静的ルーティングを変更するために、特権`--privileged`を付けている
- `/d/200_Study/2304_Router_Jisaku`には本書が配布しているソースコードを入れている。そのコードをコンテナ内で`make`して実行する。


## 必要なパッケージをインストールする

PowerShellのウィンドウを２つ立ち上げて、サーバとクライアントの各コンテナの中に入る

```powershell
docker container exec -it myserver /bin/bash
docker container exec -it myclient /bin/bash
```

**ネットワーク系**のパッケージはサーバ・クライアントの両方に入れておく

```powershell
apt update
apt install -y iputils-ping traceroute ncat nmap iproute2 net-tools curl dnsutils
```

:::note warn
今回はどちらもインストールしたが、本来は[net-toolsではなくiproute2が推奨されている模様](https://ubuntu.perlzemi.com/blog/20200324174004.html)
:::

`make`,`gcc`など**プログラミング系**のパッケージは、ひとまずクライアントだけに入れておく

```powershell
apt install -y vim make build-essential
```

何かしようとしてコマンドが見つからないと怒られたら、その都度`apt install xxx`すればよい

## pingで疎通確認する

クライアントからサーバ（`Server1`）に向けて`ping`を打つ

```Powershell:ping Server1
PING Server1 (172.18.0.2) 56(84) bytes of data.
64 bytes from myserver.testnw (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
```

## ARPでネットワーク内の機器を確認する

`arp`でテーブルを見ると、ゲートウェイとサーバの２つが見えている

```powershell:arp -a
Address                  HWtype  HWaddress           Flags Mask            Iface
myserver.testnw          ether   02:42:ac:12:00:02   C                     eth0
172.18.0.1               ether   02:42:3a:07:58:80   C                     eth0
```

ネットワークのゲートウェイや所属するコンテナは`inspect`で調べられる　※一部抜粋

```powershell:docker network inspect testnw
[
    {
        "Name": "testnw",
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
            "Containers": {
                "Name": "myserver",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
            },
                "Name": "myclient",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
            }
        },
```

## 糸冬了！！