🦖

DHCPサーバーを設定する(LinuC202学習)

2024/07/07に公開

DHCPの基本情報

DHCP(Dynamic Host Configuration Protocol)はネットワーク内のIPアドレスを自動で取得、割り当てを行えるプロトコル。
ネットワーク内にコンピューターが参加したときにDHCP要求を行い、DHCPがそれに応答して利用可能なIPアドレスを提供する。

RFC2131にて定義。(日本語訳)
わかりやすい解説:https://milestone-of-se.nesuke.com/nw-basic/grasp-nw/dhcp/

プロトコルの特徴は、クライアントがIPアドレスの割り当てを求める「DHCP要求」は リミテッドブロードキャストアドレス(255.255.255.255 固定) 宛に行われること。
ネットワーク内の全コンピューターに広報するには ブロードキャストアドレス(ネットワークアドレスが192.168.0.0/16の場合、192.168.255.255) を用いれる。
しかし、参加したてのコンピューターは、そもそもネットワークアドレスがわからないのでブロードキャストアドレスも特定できない。
そのために固定の255.255.255.255 が使われるというわけだ。

構築

環境

マシンはVagrantにて動作させる。

Vagrant.configure("2") do |config|
  # Ubuntuサーバー
  config.vm.define "dhcp-server" do |dhcp_server|
    dhcp_server.vm.box = "bento/ubuntu-24.04"
    dhcp_server.vm.hostname = "dhcp-server"
    dhcp_server.vm.network "private_network", ip: "192.168.1.10"
    dhcp_server.vm.network "private_network", ip: "192.168.1.11"
    dhcp_server.vm.provider "virtualbox" do |vb|
      vb.name = "dhcp-server"
      vb.memory = 1024
      vb.cpus = 1
    end
  end

  # Ubuntuクライアント 1号機
  config.vm.define "dhcp-client-1" do |dhcp_client_1|
    dhcp_client_1.vm.box = "bento/ubuntu-24.04"
    dhcp_client_1.vm.hostname = "dhcp-client-1"
    dhcp_client_1.vm.network "private_network", ip: "192.168.1.100"
    dhcp_client_1.vm.network "private_network", ip: "192.168.1.101"
    dhcp_client_1.vm.provider "virtualbox" do |vb|
      vb.name = "dhcp-client-1"
      vb.memory = 1024
      vb.cpus = 1
    end
  end

  # Ubuntuクライアント 2号機
  config.vm.define "dhcp-client-2" do |dhcp_client_2|
    dhcp_client_2.vm.box = "bento/ubuntu-24.04"
    dhcp_client_2.vm.hostname = "dhcp-client-2"
    dhcp_client_2.vm.network "private_network", ip: "192.168.1.110"
    dhcp_client_2.vm.network "private_network", ip: "192.168.1.111"
    dhcp_client_2.vm.provider "virtualbox" do |vb|
      vb.name = "dhcp-client-2"
      vb.memory = 1024
      vb.cpus = 1
    end
  end
end

以降はrootユーザーにて実行

cat /etc/os-release 
PRETTY_NAME="Ubuntu 24.04 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
ip addr show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000       
    link/ether 08:00:27:18:62:91 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe18:6291/64 scope link
       valid_lft forever preferred_lft forever

構築

apt install isc-dhcp-server

dhcpd.confを作成する。インストール時に存在するdhcpd.confは一旦dhcpd.conf.exampleにリネームする。

mv dhcpd.conf dhcpd.conf.example
nano dhcpd.conf

以下を記載する

dhcpd.conf
option domain-name-servers 8.8.8.8, 8.8.4.4;
option subnet-mask 255.255.255.0;
option routers 192.168.1.10; # eth1のアドレス
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.200 192.168.1.250;
}
chown root:root  /var/lib/dhcp/dhcpd.leases

フォアグラウンドで起動する。この時点でコンソールにリアルタイムでログが出力される。

dhcpd --version
isc-dhcpd-4.4.3-P1
dhcpd -f -d

クライアント側で操作してみる。
クライアント側インターフェースでは固定IPが設定されているので、一旦インターフェースeth1 をDOWNし、NetplanでDHCPを有効にする。
自身の環境では50-vagrant.yamlというNetplanのyamlファイルだが、ここは環境によって異なる。

root@dhcp-client-1:~# ip addr show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:0b:40:94 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.1.100/24 brd 192.168.1.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe0b:4094/64 scope link
       valid_lft forever preferred_lft forever

ip link set dev eth1 down

nano /etc/netplan/50-vagrant.yaml

以下のように設定する。2つあるインターフェースのうち、eth1のみdhcpを有効にしている。

50-vagrant.yaml
---
network:
  version: 2
  renderer: networkd
  ethernets:
    eth1:
      dhcp4: true
    eth2:
      dhcp4: false
      addresses:
      - 192.168.1.101/24

保存してnanoを閉じ、、yaml設定内容を適用、DOWNしていたインターフェースをUPする。

netplan apply
ip link set dev eth1 up

この時点でサーバー側のログにDHCPのリクエストとリースが発生しているのが見える。
想定外だが、DHCPの探索やリクエストはeth1ではなくeth2から行われている。

DHCPDISCOVER from 08:00:27:0b:40:94 via eth2 ← DHCPの探索(eth2)
DHCPOFFER on 192.168.1.200 to 08:00:27:0b:40:94 (dhcp-client-1) via eth2 ← DHCPサーバーからクライアントへ使用可能IPアドレスの提示
DHCPREQUEST for 192.168.1.200 (192.168.1.11) from 08:00:27:0b:40:94 (dhcp-client-1) via eth2 ← クライアントがIPアドレスのリクエスト
DHCPACK on 192.168.1.200 to 08:00:27:0b:40:94 (dhcp-client-1) via eth2 ← DHCPサーバーがIPアドレスの割当を承認するメッセージを送信

これらのログは/var/log/syslogに入っている。

確認

dhcpd.conf

改めて元のdhcpd.conf.exampleを確認してみる。

cat /etc/dhcp/dhcpd.conf.example # たくさん出力される
# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#
# Attention: If /etc/ltsp/dhcpd.conf exists, that will be used as        
# configuration file instead of this file.
#
...

アンコメントされている行をピックアップ

dhcpd.conf.example
option domain-name "example.org"; # ドメイン名を指定。
option domain-name-servers ns1.example.org, ns2.example.org; # ネームサーバーを指定。
default-lease-time 600; # アドレスのデフォルト貸出時間(秒)。クライアントが時間を指定しなかったらこの時間貸し出す。
max-lease-time 7200; # アドレスの最大貸出時間。クライアントが時間を指定した場合に応えることができる最大時間。
ddns-update-style none; # 貸し出しを行ったときにDNSの更新を試みるかの制御について。 ad-hoc/interim/none である必要がある。v2はDDNSをサポートしていないため、none

host [デバイス名] によって特定のデバイスに固定IPアドレスを割り当てることができるので、既存のdhcpd.confに設定してみる。
vagrant ssh dhcp-client-2のネットワークインターフェースを固定する。

ip addr show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:af:23:48 brd ff:ff:ff:ff:ff:ff ← MACアドレスが08:00:27:af:23:48であることを確認。
    altname enp0s8
    inet 192.168.1.110/24 brd 192.168.1.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:feaf:2348/64 scope link
       valid_lft forever preferred_lft forever
nano /etc/netplan/50-vagrant.yaml

以下のように更新。

dhcpd.conf
option domain-name-servers 8.8.8.8, 8.8.4.4;
option subnet-mask 255.255.255.0;
option routers 192.168.1.10; # eth1のアドレス
subnet 192.168.1.0 netmask 255.255.255.0 {
+  range 192.168.1.200 192.168.1.250;
+  host dhcp-client-2-eth1 {
+    hardware ethernet 08:00:27:af:23:48; # 先ほど特定したMACアドレスを入力
+    fixed-address 192.168.1.251; # 指定したMACアドレスのデバイスについては固定のIPアドレスを割り当てるようにする。
+  }
}

dhcpdを起動。

dhcpd -f -d

もう一度dhcp-client-2で操作。50-vagrant.yamlを以下のように更新

nano /etc/dhcp/dhcpd.conf

以下のように更新する。

50-vagrant.yaml
---
network:
  version: 2
  renderer: networkd
  ethernets:
    eth1:
      dhcp4: true # dhcpを有効化
    eth2:
      addresses:
      - 192.168.1.111/24

更新を適用。

netplan apply

サーバー側の出力を確認。DHCPOFFERにてDHCPが固定で192.168.1.251を提供しているのがわかる。

DHCPDISCOVER from 08:00:27:af:23:48 via eth1
DHCPOFFER on 192.168.1.251 to 08:00:27:af:23:48 via eth1
DHCPREQUEST for 192.168.1.251 (192.168.1.11) from 08:00:27:af:23:48 via eth2
DHCPACK on 192.168.1.251 to 08:00:27:af:23:48 via eth2
DHCPREQUEST for 192.168.1.251 (192.168.1.11) from 08:00:27:af:23:48 via eth1
DHCPACK on 192.168.1.251 to 08:00:27:af:23:48 via eth1

dhcpd.leases

サーバー側で/var/lib/dhcp/dhcpd.leasesを確認する。

lease 192.168.1.200 {
  starts 0 2024/07/07 07:38:46;
  ends 0 2024/07/07 19:38:46;
  cltt 0 2024/07/07 07:38:46;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet 08:00:27:0b:40:94;
  uid "\377\257\201\217}\000\002\000\000\253\021\363\022x\020\303\227\213\327";
  client-hostname "dhcp-client-1";
}

各項目を見てみる。

項目 説明
starts リースの開始日時
ends リースの終了日時
cltt クライアントが最後にリースの更新または取得を行った日時
binding state 現在のリース状態(activeは貸出中)
ext binding state リースが終了したときの次の状態(freeは開放されて再び使えるようになること)
rewind binding state リースの巻き戻し状態(エラーが起きたときに巻き戻しを行ったあと、どのような状態にするか)
hardware ethernet ネットワークインターフェースのMACアドレス
uid このクライアントのUID。
client-hostname クライアントホスト名

dhcpd.leases~ について

同時に /var/lib/dhcp/dhcpd.leases~ というものも存在が確認できる。dhcpd.leasesの紛失時に手動復旧ができるようにした予備ファイルである。
dhcpdプロセスの予期せぬ終了時にdhcpd.leases紛失する可能性がある。その際にdhcpd.leases~をコピーして復元できる。
dhcpd.leasesは定期的に更新され、古いものはdhcpd.leases~となり、ローテーションされるが、それを利用したものである。

おわりに

dhcpdの構築から設定を行い、以下のことが確認できた。

  • dhcpdによってIPアドレスの動的割り当てが行える
  • dhcpd.confによって特定のサブネットでアドレス範囲を指定した貸出が行える。
    • 特段の設定によって特定のネットワークインターフェースに対してはIPを固定化できる。
  • dhcpd.leasesを確認することで、リース時期、リース状態、リース先などの情報が確認できる。

参考

Discussion