『体験しながら学ぶネットワーク技術入門』の検証環境をUbuntu上で構築

今週出版された新刊[『体験しながら学ぶ ネットワーク技術入門』](https://amazon.co.jp/dp/4815618593)を購入しました。仮想環境の中に13台のネットワーク機器・サーバからなる検証環境を構築して，パケットの動きを実際に観察して検証しようという興味深い本です。

# 書籍がサポートする検証環境の動作環境

この書籍の公式サポート環境は，**Ubuntu 20.04 on WSL2 on Windows 11 (x86_64)** という環境です。非公式サポートながら，**Ubuntu 20.04 on Multipass on Intel Mac** という環境も考慮されており，書籍の中で検証環境インストール法が1ページにわたり説明されているほか，[サポートページ](https://www.sbcr.jp/support/4815617794/)にもMac用セットアップスクリプトがダウンロードできます。

# Apple Silicon Mac で動かせないか？

**【2024/1/19追記】**[公式サポートページ](https://www.sbcr.jp/support/4815617794/)にて Apple Silicon 対応が発表されました。

<details><summary>古い情報</summary><div>

残念ながら，現状では **Apple Silicon 搭載 Mac では動作しません**。なぜ動作しないかを調べてみると，

* Ubuntu 20.04 (ARM版) on Multipass (ARM版) on Apple Silicon は動作する。
* その Ubuntu 上で動く Docker (ARM版) も動作する。
* [tinet](https://github.com/tinynetwork/tinet) は x86_64 版 Linux 用バイナリしか用意されていないが，自前で ARM 版バイナリをビルドすれば動作させることは可能。

```sh:ARM 版 Ubuntu 上で ARM 版 tinet バイナリを go でビルド
git clone https://github.com/tinynetwork/tinet tinet && cd $_
docker run --rm -i -t -v $PWD:/v -w /v golang:1.17 go build
mv tinet /usr/bin
```
* だが，セットアップスクリプトによって DockerHub からダウンロードされる Docker イメージが，x86_64 (amd64) 用イメージとなっており，それが動作しない。

という理由でした。これらの Docker イメージには ARM 版イメージが用意されておらず，Docker イメージが ARM 版 Ubuntu 上で動作しません。

## QEMU を使えば ARM 版 Docker で x86_64 用イメージを動作させられるのでは？

ARM 版 Ubuntu 上で

```sh
apt install -y qemu-user-static
```

として QEMU をインストールし，

```json:/etc/docker/daemon.json
{
	"experimental": true,
	"exec-opts": [
		"native.cgroupdriver=systemd"
	],
	"features": {
		"buildkit": true
	}
}
```

として QEMU によるエミュレーションを有効化させると，ARM 版 Docker 上で x86_64 用イメージを動作させることは可能になります。ただし，あくまでエミュレーションなので，全機能が使えるわけではありません。実際，今回使いたいネットワークインターフェースまわりのエミュレーションは，QEMU をかますとエラーが出て動作しないようでした。

というわけで，Apple Silicon Mac で動作させるには，今回動作させたい9個の Docker イメージ

* [sphalerite1313/dhclient](https://hub.docker.com/r/sphalerite1313/dhclient)
* [sphalerite1313/haproxy-bind](https://hub.docker.com/r/sphalerite1313/haproxy-bind)
* [sphalerite1313/frr-iptables-dnsmasq](https://hub.docker.com/r/sphalerite1313/frr-iptables-dnsmasq)
* [sphalerite1313/nginx](https://hub.docker.com/r/sphalerite1313/nginx)
* [sphalerite1313/frr-iptables](https://hub.docker.com/r/sphalerite1313/frr-iptables)
* [sphalerite1313/unbound](https://hub.docker.com/r/sphalerite1313/unbound)
* [sphalerite1313/frr](https://hub.docker.com/r/sphalerite1313/frr)
* [sphalerite1313/ovs](https://hub.docker.com/r/sphalerite1313/ovs)
* [sphalerite1313/base](https://hub.docker.com/r/sphalerite1313/base)

の ARM 版が用意されるのを待つ必要があります。

**※ 2024/1/16 12:00追記：これらの Docker イメージの[ ARM 版が用意され始めたようです](https://hub.docker.com/u/sphalerite1313)。Apple Silicon 対応が近いと期待しています！**

</div></details>

# x86_64 版 Ubuntu 上で検証環境を準備

そこで，Apple Silicon Mac への対応を待っている間に，**Intel Mac 用スクリプトを流用して，x86_64 版 Ubuntu 環境上に同じ検証環境を整えてみました**。

## 1. snap で Multipass をインストール

```sh
$ sudo snap install multipass
```

## 2. Intel Mac 用セットアップスクリプトをダウンロードしてホーム直下に展開

[サポートページ](https://www.sbcr.jp/support/4815617794/) から Intel Mac 用セットアップスクリプト `tinet_mac.zip` をダウンロードし，ホームディレクトリ直下に `tinet` ディレクトリとして配置します。


## 3. Multipass で Ubuntu 20.04 の仮想マシンを作成

```sh
$ multipass launch 20.04 --cpus 2 \
  --name UBUNTU \
  --mount $HOME/tinet:/mnt/c/tinet
```

## 4. Multipass のシェルに入る

```sh
$ multipass shell UBUNTU
```

## 5. 仮想マシン内の root ユーザのパスワードを設定して su する

```sh
ubuntu@UBUNTU:~$ sudo passwd root
New password:〈パスワード入力〉
Retype new password:〈パスワード再入力〉
passwd: password updated successfully
ubuntu@UBUNTU:~$ su
Password:〈パスワード入力〉
root@UBUNTU:/home/ubuntu#
```

## 6. 仮想マシン内でセットアップスクリプトを実行

```sh
root@UBUNTU:/home/ubuntu# bash /mnt/c/tinet/setup_mac.sh
```

## 7. チェックスクリプトで確認

```sh
root@UBUNTU:/home/ubuntu# bash /mnt/c/tinet/check_mac.sh
（中略）
========================================================
All checks passed successfully.
========================================================
```

`All checks passed successfully.` と出れば成功です。

## 8. 検証環境の構築

```sh
root@UBUNTU:/home/ubuntu# tinet up -c /mnt/c/tinet/spec_01.yaml | sh -x
root@UBUNTU:/home/ubuntu# tinet conf -c /mnt/c/tinet/spec_01.yaml | sh -x
```

これがエラーなく終了すれば検証環境構築成功です。

## 9. 検証環境の動作確認

```sh
root@UBUNTU:/home/ubuntu# docker exec -it cl1 /bin/bash
root@cl1:/#
```

ホスト名の表示が `@UBUNTU` から `@cl1` に変わります。

```sh
root@cl1:/# curl -k https://www.example.com/
sv1.example.com
```

`sv1.example.com` と返ってくれば，検証環境が正しく動作していることになります。

# 後編：Apple Silicon への対応成功

その後 Apple Silicon への対応に成功したので，続編記事を書きました。

https://qiita.com/doraTeX/items/613862b3172c0d0ebca5