UbuntuでUSBテザリング時のIP・MACアドレスを固定する

自分のための覚書です。
なお、OSはUbuntu22.04、ハードは[AK1Plus CPU:N95 RAM:8GB](https://www.amazon.co.jp/dp/B0C1YY8GSB)です。

# 1. NIC名を固定にする
USBで接続しなおすたびにNIC名(デバイス名)が変わってしまうので、固定化する。
[Linuxのudevルールを使ってUSBデバイスを挿入する順番の制約を無くそう](https://zenn.dev/karaage0703/articles/d6759ea297dbf8) を参考にした。

## 1.1 USBテザリング機器のIDを確認する。

`lsusb`でUSBテザリング機器のIDを確認する。
[PIX-MT100](https://www.pixela.co.jp/products/network/pix_mt100/)の場合は

```bash:接続無し
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 1c4f:0034 SiGma Micro XM102K Optical Wheel Mouse
Bus 001 Device 005: ID 0573:1573 Zoran Co. Personal Media Division (Nogatech) USB Audio and HID
Bus 001 Device 007: ID 0bda:c821 Realtek Semiconductor Corp. Bluetooth Radio 
Bus 001 Device 008: ID 1c4f:0002 SiGma Micro Keyboard TRACER Gamma Ivory
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
```

```bash:接続あり
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 1c4f:0034 SiGma Micro XM102K Optical Wheel Mouse
Bus 001 Device 005: ID 0573:1573 Zoran Co. Personal Media Division (Nogatech) USB Audio and HID
Bus 001 Device 007: ID 0bda:c821 Realtek Semiconductor Corp. Bluetooth Radio 
Bus 001 Device 008: ID 1c4f:0002 SiGma Micro Keyboard TRACER Gamma Ivory
Bus 001 Device 011: ID 15a9:002d Gemtek WLTUBA-107 [Yota 4G LTE]
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
```
なので、差分からベンダーIDが`15a9`、プロダクトIDが`002d`と分かる。


## 1.2 USBテザリング機器のNIC名を固定する。

USB Ethernetの設定画面から現時点のUSBテザリング機器のIPアドレスは`192.168.0.12`、MACアドレスは`1E:49:7B:81:0B:E3`とわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360166/8e7628d0-cc75-4af6-ad5a-8881036e4d22.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360166/37b85074-1233-4ba7-96b7-a8e1de5c8534.png)

また、ターミナルで `sudo ip link show` を実行するとNIC名とMACアドレスがわかる。
MACアドレスに紐づくNIC名から、現在のNIC名は`enx1e497b810be3`とわかる。
```bash:設定前
$ sudo ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 68:1d:ef:42:d6:46 brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether c8:8a:d8:93:21:75 brd ff:ff:ff:ff:ff:ff
4: br-4a7baf2cdcc2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:78:33:33:fc brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:96:36:0d:3c brd ff:ff:ff:ff:ff:ff
6: enx1e497b810be3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 1e:49:7b:81:0b:e3 brd ff:ff:ff:ff:ff:ff
```

NIC名を固定するために、以下の内容で `/etc/udev/rules.d/99-nic-name.rules` を作成する。
ここではNIC名を`usbeth0`に設定する。

```txt:/etc/udev/rules.d/99-nic-name.rules
SUBSYSTEM=="net", ACTION=="add", ATTRS{idVendor}=="15a9", ATTRS{idProduct}=="002d", NAME="usbeth0"
```

作成できたら `sudo udevadm control --reload-rules` で設定を反映する。
 
問題なければ一度デバイスを脱着し `sudo ip link show` コマンドをもう一度実行すると、デバイス名が`usbeth0`になっているはず。

```bash:設定後
$ sudo ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 68:1d:ef:42:d6:46 brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether c8:8a:d8:93:21:75 brd ff:ff:ff:ff:ff:ff
4: br-4a7baf2cdcc2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:78:33:33:fc brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 02:42:96:36:0d:3c brd ff:ff:ff:ff:ff:ff
7: usbeth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 1e:49:7b:81:0b:e3 brd ff:ff:ff:ff:ff:ff
```

# 2. usbeth0 のMACアドレスを固定化
[Ubuntu 22.04 LTSで固定IPアドレスの設定](https://qiita.com/zen3/items/757f96cbe522a9ad397d)と[Ubuntu 22.04でNICのMACアドレスを変更する](https://qiita.com/ak-sakatoku/items/bbf952f1861fa331b110)を参考に、`usbeth0` のIPアドレスとMACアドレスを固定化する。

`/etc/netplan/99_usbeth0.yaml` を新規に作成し、下記のフォーマットで記載する。

```yaml:/etc/netplan/99_usbeth0.yaml
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    usbeth0:                            # NIC名を指定する
      dhcp4: false
      dhcp6: false
      addresses: [192.168.0.100/24]     # IPアドレスを指定する
      routes:
        - to: default
          via: 192.168.0.1              # USBテザリング機器(ルータ)のIPアドレスを指定
      nameservers:
        addresses: [192.168.0.1, 8.8.8.8, 8.8.4.4]
      macaddress: 12:34:56:78:90:ab     # MACアドレスを指定する
      optional: true
```

設定できたら `sudo chmod 600 /etc/netplan/99_usbeth0.yaml`でパーミッションを変更したうえで、 `sudo netplan apply` で設定を反映する。
※一時的に設定を反映し、不具合があった時に備えて自動で戻したい場合は `sudo netplan try` で一時的に設定を反映する。
 
デバイスを一度脱着し、`sudo ip link usbeth0` で固定化したMACアドレスになっていたら成功！

```bash:bash
$ sudo chmod 600 /etc/netplan/99_usbeth0.yaml
$ sudo netplan apply
$ sudo ip link usbeth0
8: usbeth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 12:34:56:78:90:ab brd ff:ff:ff:ff:ff:ff permaddr 1e:49:7b:81:0b:e3
```

# 3. 【最終手段】systemd の起動スクリプトで変更
MACアドレスが書き換わらない場合、`Netplan` ではなく `systemd` の起動スクリプトを使って MACアドレスを強制的に変更する方法もある。
この方法では、システム起動時に `ip link set` コマンドを使って強制的に MAC アドレスを変更する。

## 3.1. systemd サービスを作成
```bash:bash
$ sudo nano /etc/systemd/system/set-mac.service
```
以下の内容を追加
```ini:/etc/systemd/system/set-mac.service
[Unit]
Description=Set MAC address for usbeth0
After=network-pre.target
Wants=network-pre.target
Before=networking.service

[Service]
Type=oneshot
ExecStart=/sbin/ip link set dev usbeth0 address 12:34:56:78:90:ab
ExecStart=/sbin/ip link set dev usbeth0 up
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

## 3.2. サービスを有効化
```bash:bash
$ sudo systemctl daemon-reload
$ sudo systemctl enable set-mac.service
$ sudo systemctl start set-mac.service
```

## 3.3 確認
```bash:bash
$ ip link show usbeth0
```