ルータ設定を極力いじらずに IPv4 + IPv6 の DNS & DHCP サーバを構築する方法
はじめに
本記事では、ルータの設定を極力いじらずに、Raspberry Pi で DNS & DHCP サーバを構築する方法について紹介する。なお、IPv4 だけでなく IPv6 にも対応する方法も取り扱っている。
なぜ「ルータの設定を極力いじらずに」構築する必要があるのか。筆者の自宅では SoftBank 光を契約しているのだが、SoftBank 光から提供されるルータは、うんざりするほどルータの設定が制限されている。
- DHCPv4 をオフにできない
- IPv6 を有効にすると DHCPv6 をオフにできない
- IPv6 を有効にすると Router Advertisement をオフにできない
おまけに、IPv6 を有効にするためには、SoftBank 光から提供されたルータを使用することが必須となる。そのため、このルータを取り外し、市販のルータを代わりに使うと IPv6 が使えなくなってしまう。とにかくよそ者を許さない仕様なのだ。
それでも、今のところは他のプロバイダに切り替えるつもりはない。なぜなら、SoftBank 光は爆速だからだ。
今回は、ルータの設定が制限されている状況でも、別の DNS & DHCP サーバを運用できるように設定する方法について紹介する。DNS & DHCP サーバとして機能させる機器として Raspberry Pi を使用する。
環境
Ubuntu 20.04.3 LTS
使用するパッケージのインストール
Dnsmasq と radvd を使用する。なお、radvd は IPv6 の設定でのみ使用するため、IPv6 の設定が不要な場合はインストールしなくて良い。
sudo apt -y install dnsmasq radvd radvdump
既存の IP アドレスをチェック
Raspberry Pi の IP アドレス
現時点で Raspberry Pi に割り当てられている IPv6 アドレスを調べる。
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether dc:a6:32:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.3.2/24 brd 192.168.3.255 scope global dynamic eth0
valid_lft 82426sec preferred_lft 82426sec
inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 82428sec preferred_lft 10428sec
inet6 fe80::dea6:32ff:fec5:ed06/64 scope link
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether dc:a6:32:xx:xx:xx brd ff:ff:ff:ff:ff:ff
以下の 3 つの IP アドレスを控えておく。
- IPv4 プライベートアドレス
- 上記の例でいう
192.168.3.2
の部分
- 上記の例でいう
- IPv6 リンクローカルユニキャストアドレス
- 上記の例でいう
fe80::dea6:32ff:fec5:ed06
の部分 -
fe80::
から始まるのが特徴
- 上記の例でいう
- IPv6 グローバルユニキャストアドレス
- これはグローバルユニキャストアドレスのため、上記の例では
xxxx
のように伏せ字になっている -
2
または3
から始まるのが特徴 (たいていは2
から始まる)
- これはグローバルユニキャストアドレスのため、上記の例では
ルータの IPv4 プライベートアドレス
ルータの IPv4 プライベートアドレスを調べる。
ip route show
default via 192.168.3.1 dev eth0 proto static
default via 192.168.3.1 dev eth0 proto dhcp src 192.168.3.2 metric 100
192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.3.2
192.168.3.1 dev eth0 proto dhcp scope link src 192.168.3.2 metric 100
default via
に続く IPv4 プライベートアドレス (上記の例でいう 192.168.3.1
) を控えておく。
ルータの IPv6 リンクローカルユニキャストアドレス
ルータの IPv6 リンクローカルユニキャストアドレスを調べる。
ip -6 route show
::1 dev lo proto kernel metric 256 pref medium
xxxx:xxxx:xxxx:xxxx::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via fe80::da0f:99ff:fedb:2bad dev eth0 proto static metric 1024 pref medium
default via
に続く IPv6 リンクローカルユニキャストアドレス (上記の例でいう fe80::da0f:99ff:fedb:2bad
) を控えておく。
IP アドレスの固定
Raspberry Pi 自身の IP アドレスを固定する。/etc/netplan/99_config.yaml
というファイルがなければ新規作成する。
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 192.168.3.2/24
- xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64
gateway4: 192.168.3.1
gateway6: fe80::da0f:99ff:fedb:2bad
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
-
network.ethernets.eth0
- ネットワークインターフェースが
eth0
でない場合は変更すること
- ネットワークインターフェースが
-
network.ethernets.eth0.addresses
- 以下の 2 つを設定する
- Raspberry Pi の IPv4 プライベートアドレス
- Raspberry Pi の IPv6 グローバルユニキャストアドレス
- 以下の 2 つを設定する
-
network.ethernets.eth0.gateway4
- ルータの IPv4 プライベートアドレス
-
network.ethernets.eth0.gateway6
- ルータの IPv6 リンクローカルユニキャストアドレス
-
network.ethernets.eth0.nameservers.addresses
- 上流の DNS を配列形式で指定 (複数可)
- 特にこだわりがなければ上記と同じ IP アドレスで問題ない
- 上流の DNS を配列形式で指定 (複数可)
設定ができたら、反映させる。
sudo netplan apply
ルータの設定
ルータの設定は極力いじらずに構築する、と言ったので、本当はいじりたくないのだが、DHCPv4 の割当範囲だけ変更する。
自宅にあるルータは DHCPv4 をオフにできないが、幸い、DHCPv4 の割り当て IP アドレスの範囲を変更することはできる。
ルータの設定ページを開き、割り当てる IP アドレスの範囲を極限まで減らす。
上記の例では、192.168.3.2
のみしか割り当てられないようにしている。そしてこのアドレスは Raspberry Pi に割り当てているプライベートアドレスのため、それ以外の一切のクライアントに、このルータが IPv4 アドレスを割り振ることはなくなる。
これで、後に設定する Raspberry Pi 側の DHCPv4 の設定が確実に適用されるようになる。
なお、Raspberry Pi 側で IP アドレスを固定したが、ルータ側でも固定する必要がある。ルータから見れば、Raspberry Pi 側での IP アドレスの固定は、あくまで勝手にやっているという扱いになる。そのため、ルータ側でも設定しておかないと、他のネットワーク機器に 192.168.3.2
を割り振った結果、IP アドレスが重複してしまう問題が発生するので注意すること。
DNSv4 & DHCPv4 の設定
まずは IPv4 用の DNS & DHCP サーバを構築する。/etc/dnsmasq.conf
に以下の設定を追加する。
domain-needed
bogus-priv
no-hosts
no-resolv
no-poll
strict-order
expand-hosts
bind-interfaces
no-hosts
dhcp-authoritative
dhcp-rapid-commit
no-negcache
port=53
server=1.1.1.1
server=8.8.8.8
listen-address=127.0.0.1,192.168.3.2
dhcp-range=192.168.3.200,192.168.3.254,12h
dhcp-option=option:netmask,255.255.255.0
dhcp-option=option:router,192.168.3.1
dhcp-option=option:dns-server,192.168.3.2
-
port
-
53
を設定する - ファイアウォールで 53 番をブロックしている場合は許可を忘れずに
-
-
server
- 上流の DNSv4 サーバを指定する
- 特にこだわりがなければ上記と同じで良い
- 上流の DNSv4 サーバを指定する
-
listen-address
- 以下の 2 つをカンマ区切りで設定する
127.0.0.1
- Raspberry Pi の IPv4 プライベートアドレス
- 以下の 2 つをカンマ区切りで設定する
-
dhcp-range
- 以下の 3 つをカンマ区切りで指定する
- DHCP で割り当てる IP アドレスの範囲の開始アドレス
- DHCP で割り当てる IP アドレスの範囲の終了アドレス
- リース時間
- 特にこだわりがなければ上記と同じで良い
- 以下の 3 つをカンマ区切りで指定する
-
dhcp-option=option:netmask
- サブネットマスクを指定する
- 筆者の環境では
192.168.3.0/24
だったので255.255.255.0
を指定している
- 筆者の環境では
- サブネットマスクを指定する
-
dhcp-option=option:router
- ルータの IPv4 プライベートアドレスを指定する
-
dhcp-option=option:dns-server
- Raspberry Pi の IPv4 プライベートアドレスを指定する
設定が完了したら Dnsmasq を起動または再起動する。
sudo systemctl restart dnsmasq.service
PC やスマートフォンなどのクライアントの DHCP リース更新を行うか再起動すると、Raspberry Pi (Dnsmasq) 側で設定した内容が反映されるはずだ。
DNSv6 & DHCPv6 の設定
次に IPv6 用の DNS & DHCP サーバを構築する。先ほどと同じく /etc/dnsmasq.conf
に以下の設定を追加する。
server=2606:4700:4700::1001
server=2001:4860:4860::8844
ra-param=eth0,high,0,0
quiet-ra
dhcp-range=::fec5:0,::fec5:7fff,constructor:eth0,ra-names,slaac,12h
dhcp-option=option6:dns-server,[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
dhcp-option=option6:information-refresh-time,6h
-
server
- 上流の DNSv6 サーバを指定する
- 特にこだわりがなければ上記と同じで良い
- 上流の DNSv6 サーバを指定する
-
ra-param
-
eth0,high,0,0
を指定する- ただし、ネットワークインターフェースが
eth0
でない場合は変更すること
- ただし、ネットワークインターフェースが
-
-
dhcp-range
-
::fec5:0,::fec5:7fff
のfec5
部分は以下に置き換える- Raspberry Pi のリンクローカルユニキャストアドレスの 7 セクション目 (コロン区切りの左から 7 個目)
- 先頭の
::
や:0
,:7fff
の部分はそのままで良い
-
constructor:eth0,ra-names,slaac,12h
の部分はそのままで良い- ただし、ネットワークインターフェースが
eth0
でない場合は変更すること
- ただし、ネットワークインターフェースが
-
-
dhcp-option=option6:dns-server
- Raspberry Pi の IPv6 グローバルユニキャストアドレスを指定する
-
dhcp-option=option6:information-refresh-time
- リフレッシュタイムを指定する
- 特にこだわりがなければ上記と同じで良い
- リフレッシュタイムを指定する
設定が完了したら Dnsmasq を再起動する。
sudo systemctl restart dnsmasq.service
これで各クライアントに IPv6 アドレスも設定されてほしい、のだが、筆者の環境では設定されなかった。
その場合は、radvd を利用する。
/etc/radvd.conf
というファイルを新規作成し、以下の設定を追加する。
interface eth0 {
AdvSendAdvert on;
AdvDefaultPreference high;
prefix xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:8000/113 {
AdvOnLink on;
AdvRouterAddr on;
AdvPreferredLifetime 120;
AdvValidLifetime 300;
};
route fe80::da0f:99ff:fedb:2bad/128 {
AdvRoutePreference high;
AdvRouteLifetime 3600;
};
RDNSS xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx {
AdvRDNSSLifetime 3600;
};
};
-
interface eth0
- ネットワークインターフェースが
eth0
でない場合は変更すること
- ネットワークインターフェースが
-
prefix
- Raspberry Pi の IPv6 グローバルユニキャストアドレスの最後の 8 セクション目を
8000
に置き換え、その後ろに/113
を追加したものを指定する
- Raspberry Pi の IPv6 グローバルユニキャストアドレスの最後の 8 セクション目を
-
route
- ルータの IPv6 リンクローカルユニキャストアドレスを指定する
- 後ろに
/128
をつけることを忘れずに
-
RDNSS
- Raspberry Pi の IPv6 グローバルユニキャストアドレスを指定する
末尾に Lifetime
とつく設定は文字通りその設定のライフタイムを表しているが、あまり短くしすぎると設定が反映されたり消えたりする。筆者の環境では 60
だとうまくいかなかったので 3600
にしておくことをおすすめする。
設定が完了したら radvd を起動または再起動する。
sudo systemctl restart radvd.service
これで各クライアントに IPv6 アドレスが設定されれば完了だ。
灰色の部分が、Raspberry Pi の IPv6 グローバルユニキャストアドレスになっていれば正しく DNSv6 アドレスが設定されている。
radvd の自動起動を有効化
radvd はデフォルトでは自動起動が有効になっていないので、有効にする。
sudo systemctl enable radvd.service
IPv6 テスト
本当に IPv6 でのインターネット接続ができているのかをテストする。以下の 3 つのサイトにアクセスして、IPv6 が有効になっていることを確認する。
参考サイト
- RPi4 - IPv4 and IPv6 network with custom DNS
- How to configure IPv6 with Netplan on Ubuntu 18.04
- 1. Displaying existing IPv6 routes
- インターネット10分講座:IPv6アドレス~技術解説~
- 16.12.1 RAによるアドレス情報配布
- Router Advertisement (RA)
- 第5回 IPv6アドレスをDHCPで割り当てる
- Brief note on IPv6 flags and Dnsmasq modes
- man pages section 8: System Administration Commands
- Linux の Network Namespace と radvd / dnsmasq で IPv6 SLAAC (+RDNSS) を試す
- [Dnsmasq-discuss] Unable to send custom RDNSS value in RA
- DNSMASQ
- Dnsmasq – A simple DHCPv6 server for Embedded devices
- IPv6 change radvd advertised Default Gateway
Discussion