Raspberry Pi(Debian)でdhclientを使う

# 概要
Raspberry Pi(DebianというかRaspbian/RaspberryPi OS)では、デフォルトだと[dhcpcd](https://roy.marples.name/projects/dhcpcd/)が動いている。
普通に使うには問題ないのだが、DHCPオプションを取る方法が分からなかったので、dhclient([ISC DHCP](https://www.isc.org/dhcp/))を使うことにした。
[前回](https://qiita.com/kmorimoto/items/77ea0370ee46f7b3e006)同様、技術的には難しいことが何もないのだが、後々書きたい投稿の周辺情報/下準備として必要なので書いておく。

# ポイント/狙い
- 今dhcpcdで問題ないのに、わざわざdhclientを動かす背景を共有(言い訳)する。
- ついでにsystemdで動かす方法も残しておく。

### 背景
後々別の投稿で書くつもりだが、NTTのフレッツ網(NGN)からひかり電話の情報(SIPサーバのアドレスや電話番号)を取得するには、DHCPオプション([RFC3361](https://tools.ietf.org/html/rfc3361)で定義されているもの)を使わねばならないようだ。
なのでまずデフォルトで動いているdhcpcdでDHCPオプションを扱おうと思ったのだが、[公式ページ](https://roy.marples.name/projects/dhcpcd/configuration/)曰く、
>**MAN PAGE IS CURRENTLY OFFLINE. AN AUTOMATED ONE IS BEING WORKED.**

とのことで、コンソール上の簡素なman dhcpcdを見るしかない。が、一通り読んでみても、それらしい記述を見つけることが出来なかった。
ここでdhcpcdを諦め、他のDHCPクライアントを使おうと考えたとき、昨今の状況/トレンドを考えて[NetworkManager](https://wiki.gnome.org/Projects/NetworkManager)を使おうかと考えた。そして同じくDHCPオプションが扱えるかどうかを確認したところ、[公式ページ](https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html)にて
>dhcp
>	
This key sets up what DHCP client NetworkManager will use. Allowed values are dhclient, dhcpcd, and internal. The dhclient and dhcpcd options require the indicated clients to be installed. The internal option uses a built-in DHCP client **which is not currently as featureful as the external clients.**

と書かれており、出だしからあまり期待できない....。
が、試しにaptでNetworkManagerを入れて動作(`dhcp=internal`)を確認してみたら、`/etc/dhcp/dhclient.conf`で詳細設定することで各種DHCPオプションを扱うことが出来た。（`/etc/dhcp/dhclient.conf`で設定すると、`/etc/NetworkManager/conf.d/`に設定が反映される）
ただしよく考えてみると、わざわざNetworkManagerを入れたのに、`dhclient.conf`で設定するのであれば、最初から入っているdhclientを動かせば良い気がした。
以上の試行や判断により、dhcpcdの代わりにdhclientを使うこととなった。

# 作戦
- デフォルトで動いているdhcpcdは止めて、dhclientが動くようにする。
- dhclientをsystemdで動かすため、ユニット定義ファイルを作成する。

# 手順
### dhcpcdを止める
普通に`systemctl`で止めるだけ。

```
systemctl stop dhcpcd.service
systemctl disable dhcpcd.service
```
なお固定IPの設定を[公式ドキュメント](https://www.raspberrypi.org/documentation/configuration/tcpip/)に従っている場合は、その設定を`/etc/dhcpcd.conf`から`/etc/network/interfaces.d/`に転記してやる必要がある。

### dhclientのユニット定義ファイルを作成する
DHCPクライアントはリース更新のために動かし続けないといけないので、systemdで動かすユニット定義ファイルを作成する。
これも技術的には何も難しい/工夫したところは何もなく、適当に検索して見つけた以下のサイト

- https://gist.github.com/corvax19/6230283

を丸ごとコピペした。

```/etc/systemd/system/dhclient.service
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
 
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient
 
[Install]
WantedBy=multi-user.target
```

もしIFの関係でタイミング調整が必要な場合は、`Before`とか`After`で調整する。
私の環境ではその必要がなかったので、以下のように有効化してそのまま使っている。

```
systemctl daemon-reload
systemctl enable dhclient.service
systemctl start dhclient.service
```

これでDHCPの各種情報が取得できると、`/var/lib/dhcp/dhclient.leases`に取得内容が書き出される。

```/var/lib/dhcp/dhclient.leases
lease {
  interface "eth0";
  fixed-address xxx.xxx.xxx.xxx;
  option subnet-mask 255.255.255.xxx;
  option dhcp-lease-time 14400;
  option routers xxx.xxx.xxx.xxx;
  option dhcp-message-type 5;
  option dhcp-server-identifier xxx.xxx.xxx.xxx;
  option dhcp-renewal-time 7200;
  option dhcp-rebinding-time 10800;
  (略)
  renew 3 2021/02/17 05:11:02;
  rebind 3 2021/02/17 06:14:29;
  expire 3 2021/02/17 07:14:29;
}
```

### その他
環境によるのかもしれないが、私はRaspberry Pi 2Bで上記作業を進めると、ログイン時に以下のメッセージが出るようになった。

```
rfkill: cannot open /dev/rfkill: 許可がありません
rfkill: cannot read /dev/rfkill: 不正なファイル記述子です
```

調べてみると、[公式フォーラム](https://www.raspberrypi.org/forums/viewtopic.php?t=274816)でも同じような話が出ていた。
一通り調べた上で、私(2B)の場合はこの状態で実害がないし面倒なので、無理やりメッセージを押さえ込んで終わった。

```
mv /etc/profile.d/wifi-check.sh /etc/profile.d/wifi-check.sh.bak
```

# あとがき
冒頭で書いたとおり、[背景](https://qiita.com/kmorimoto/items/e76047be70dd64c08a1e#%E8%83%8C%E6%99%AF)を共有して何かコメントをもらうことが目的なので、技術的なことが知りたい人は他の投稿を読む方がいいと思います。