DockerのコンテナでSamba ad dcとDHCPサーバーを動かすことができたので、これらを連携させてDynamic DNSができるようにする。
IPv4の方は書かれているとおりにほぼ動作したのだけれど、IPv6のDDNSはWikiで言及されておらず、DHCPサーバー側の情報も少なくて時間が掛かってしまった。
Samba Wiki / Configure DHCP to update DNS records
環境
ホームラボの環境は以下の通り。
今回は、example.net(HOGEDOMAIN)でDynamicDNSを動作させようとしている。
項目 | 値 | 備考 |
---|---|---|
サーバー | host name: mirror, addc device: ens33 IPv4: 192.168.110.4 IPv6: fdaa:aaaa:aaaa:aaaa::4 | Samba ad dcとDHCPサーバーが動いている。 |
ドメイン | example.net (HOGEDOMAIN) | Samba ad dcで構築したドメイン。 |
ドメインのDnsAdmins | ssoauth | 以前作ったユーザーを使用する。 専用のユーザーを新たに作るのも良い。 |
IPv4範囲 | 192.168.110.0/24 | |
IPv6範囲 | fdaa:aaaa:aaaa:aaaa::/64 | |
ルーター | [ens33] 192.168.110.10 fdaa:aaaa:aaaa:aaaa::10 [ens37] 192.168.nnn.10 fdnn:nnnn:nnnn:nnnn::110:10 24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn | マイホームとホームラボを繋ぐルーター。 今回の記事では、ルーターとして動作するのみ。 最終的にはSamba ad dcをDHCPサーバーを同居させる。 hogeserver.hogeddns.jp(HOGEDOMAIN)を管理予定。 |
ここまで整理できたので、Samba ad dcとDHCPを連携させたいと考えたのだった。
ファイル構成
前回の記事で用意したファイルに、Dynamic DNS関連のファイルを追加している。
IPv4とIPv6で共通のファイルがいくつかあるので、Dockerfileを個別ディレクトリから親ディレクトリに移動した。
リポジトリはこちら。
~/dhpc ├ docker-compose.yml ├ DockerfileIPv4 ├ DockerfileIPv6 ├ ssoauth.keytab ├ krb5.conf ├ dhcp-dyndns.sh* ├ v4 │ ├ entrypoint.sh* │ └ dhcpd.conf ├ v6 │ ├ entrypoint.sh* │ ├ dhcpd.conf │ └ radvd.conf └ setufw.sh*
*実行権限を付ける
もう一段整理して、1つのコンテナの中で実行することもできると思う。
でも、実際にはIPv6で色々と試すことがあって、分けておいた方がログが見やすい・デバッグしやすい環境だった。今後も手を入れることがあるかもしれないので、分けたままにしておくことにした。
キータブは、Samba ad dcでDnsAdminsに属するユーザーの名前にする。詳細は後述。
docker-compose.yml
最初に作ったDHCPとはディレクトリ構成を変えたので、buildのところで少し工夫している。
zukucode / Docker ComposeでDockerfileをビルドする際に親ディレクトリのファイルをコピーする
DNS更新スクリプトにSamba ad dcのホスト名と、ドメインのFQDN、DNS管理者ユーザー名を渡したかったので、環境変数を追加している。
~/docker-compose.yml
version: "3.9" services: dhcp4: build: context: ./ dockerfile: DockerfileIPv4 image: dhcp4:1.0.0 container_name: dhcp4 restart: "unless-stopped" environment: TZ: Asia/Tokyo DHCPIF: "ens33" DHCPSERVER: "addc" DHCPDOMAIN: "example.net" DHCPDNSADM: "ssoauth" DHCPDBGFLG: "false" hostname: dhcp4 network_mode: "host" volumes: - v4:/var/lib/dhcp dhcp6: build: context: ./ dockerfile: DockerfileIPv6 image: dhcp6:1.0.0 container_name: dhcp6 restart: "unless-stopped" environment: TZ: Asia/Tokyo DHCPIF: "ens33" DHCPSERVER: "addc" DHCPDOMAIN: "example.net" DHCPDNSADM: "ssoauth" DHCPDBGFLG: "false" hostname: dhcp6 network_mode: "host" volumes: - v6:/var/lib/dhcp volumes: v4: v6:
※IPv6を使わない場合は、dhcp6のコンテナのところをコメント化しておく。
DockerfileIPv4 and IPv6
Alpineに必要なパッケージを追加する。
IPv4とIPv6で必要なパッケージが違うため、分けてある。
キータブはこの後取り出しているので、それを設定する。
~/DockerfileIPv4
FROM alpine:latest
RUN apk add dhcp-server-vanilla samba-dc krb5 bash bind-tools tzdata && \
touch /var/lib/dhcp/dhcpd.leases
ADD v4/entrypoint.sh /
ADD v4/dhcpd.conf /etc/dhcp/
ADD dhcp-dyndns.sh /usr/local/bin/
ADD ssoauth.keytab /etc/
ADD krb5.conf /etc/
ENTRYPOINT ["/entrypoint.sh"]
~/DockerfileIPv6
FROM alpine:latest
RUN apk add dhcp-server-vanilla radvd samba-dc krb5 bash bind-tools tzdata && \
touch /var/lib/dhcp/dhcpd.leases && \
mkdir /run/radvd
ADD v6/entrypoint.sh /
ADD v6/dhcpd.conf /etc/dhcp/
ADD v6/radvd.conf /etc/
ADD dhcp-dyndns.sh /usr/local/bin/
ADD ssoauth.keytab /etc/
ADD krb5.conf /etc/
ENTRYPOINT ["/entrypoint.sh"]
ssoauth.keytab
DNS更新スクリプトは、キータブを使ってチケットを取得し、Samba ad dcを操作するようになっている。
以前、DnsAdminsのユーザーは作成していたので、これを利用する。
Samba ad dcのコンテナに入り、DnsAdminsであるssoauthアカウントのキータブを取り出す。
ファイル名は<username>.keytabとしている。
$ sudo docker exec -it samba bash --login
# samba-tool domain exportkeytab --principal=ssoauth@EXAMPLE.NET /ssoauth.keytab # exit
$ sudo docker cp samba:/ssoauth.keytab ~/dhcp/ $ sudo docker exec samba rm /ssoauth.keytab
取り出したファイルはrootにしか読めない状態だが、コンテナの操作にはsudoを付けるので、この方がいくらか安全だし、そのままにしておくことにする。
krb5.conf
DNS更新のためにチケットを取得するので、アクセス方法を設定しておく。
/krb5.conf
[libdefaults] default_realm = EXAMPLE.NET dns_lookup_realm = false dns_lookup_kdc = true [realms] EXAMPLE.NET = { kdc = addc.example.net # kdc = addc2.example.net default_domain = example.net } [domain_realm] addc = EXAMPLE.NET
dhcp-dyndns.sh
こちらからDNSを更新するスクリプト /usr/local/bin/dhcp-dyndns.sh をコピーしてくる。
Samba Wiki / Configure DHCP to update DNS records
このスクリプトを、今回構築するコンテナで動作させるために改造する。
少しのつもりだったけれども、当初想定より変更が大きくなったので変更のポイントだけメモして、ソース自体はリポジトリに置く。
- ログをstderrに出力するようにした。
- サーバー名とドメイン名、DNS管理者ユーザー名を環境変数で指定するようにした。
- ユーザーは作ってある前提なのでテストロジックを削除した。
- klistの-s指定をファイル名の前に移動した。
- 期限切れで削除になる時、対象IPアドレスからホスト名を取得するようにした。
- IPv6に対応する処理を追加した(ホームラボで使いたい範囲で動く程度)。
v4/entrypoint.sh
dhcpdを起動し、それが終了するのを待つ。
dhcpdを起動して放っておけばいけるかと思ったのだけれど、プロセス番号1として動作していると、終了のシグナルを受け取ってもうまく動作してくれないようだったので、スクリプトでシグナルを受けて、dhcpdに終了のシグナルを送ることにした。
#!/bin/bash echo "Start container with parameter : $@" trap sig_term SIGTERM sig_term() { echo "CATCH SIGTERM" pkill -SIGTERM dhcpd wait exit 0 } # Execute paramater. exec "$@" if [ ${DHCPDBGFLG^^} = "TRUE" ]; then DBG="-d" fi dhcpd -4 $DBG -f $DHCPIF & wait exit 1
実行権を付けておく。
$ chmod +x v6/entrypoint.sh
v4/dhcpd.conf
イベント発生時に情報を集めてDNS更新スクリプトを呼び出す。
Samba Wiki / Configure DHCP to update DNS records
#------------------------------- # Global options #------------------------------- authoritative; option domain-name "example.net"; option domain-name-servers 192.168.110.4; option ntp-servers 192.168.110.4; option routers 192.168.110.10; default-lease-time 86400; # 24 hours. max-lease-time 604800; # 7 days. lease-file-name "/var/lib/dhcp/dhcpd.leases"; #------------------------------- # Subnet #------------------------------- subnet 192.168.110.0 netmask 255.255.255.0 { range 192.168.110.100 192.168.110.199; } #------------------------------- # Fixed address #------------------------------- host party { hardware ethernet 00:0C:29:14:6E:24; fixed-address 192.168.110.12; } host work { hardware ethernet 00:0c:29:0a:83:af; fixed-address 192.168.110.3; } #------------------------------- # Dynamic DNS #------------------------------- on commit { set noname = concat("dhcp-", binary-to-ascii(10, 8, "-", leased-address)); set ClientIP = binary-to-ascii(10, 8, ".", leased-address); set ClientDHCID = concat ( suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2) ); set ClientName = pick-first-value(option host-name, config-option host-name, client-name, noname); #log(concat("Commit: IP: ", ClientIP, " DHCID: ", ClientDHCID, " Name: ", ClientName)); execute("/usr/local/bin/dhcp-dyndns.sh", "add", ClientIP, ClientDHCID, ClientName); } on release { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); set ClientDHCID = concat ( suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":", suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2) ); #log(concat("Release: IP: ", ClientIP)); execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, ClientDHCID); } on expiry { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); # cannot get a ClientMac here, apparently this only works when actually receiving a packet #log(concat("Expired: IP: ", ClientIP)); # cannot get a ClientName here, for some reason that always fails # however the dhcp update script will obtain the short hostname. execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "", "0"); }
v6/entrypoint.sh
dhcpdとradvdを起動し、それが終了するのを待つ。
#!/bin/bash echo "Start container with parameter : $@" trap sig_term SIGTERM sig_term() { echo "CATCH SIGTERM" pkill -SIGTERM dhcpd pkill -SIGTERM radvd wait exit 0 } # Execute paramater. exec "$@" if [ ${DHCPDBGFLG^^} = "TRUE" ]; then DBG=-d fi dhcpd -6 $DBG -f $DHCPIF & radvd -n & wait
実行権限を付けておく。
$ chmod +x v6/entrypoint.sh
v6/dhcpd.conf
イベント発生時にDNS更新スクリプトを呼び出す。
これがよく分からず、マニュアルを見ては試し、見ては試しの繰り返しになった。
ISC DHCP 4.4 Manual Pages - dhcpd
ISC DHCP 4.4 Manual Pages - dhcpd.conf
ISC DHCP 4.4 Manual Pages - dhcp-options
ISC DHCP 4.4 Manual Pages - dhcp-eval
IPv6の場合、コミット時にこのような情報をリースファイルに保管している。
… max-life 86400; ends 0 2022/10/30 22:07:52; set ClientIP = "fdaa:aaaa:aaaa:aaaa:0:0:1:199"; set ClientName = "temp"; on expiry { execute ("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "no", ClientName, "-IPv6-"); } on release { execute ("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "no", ClientName, "-IPv6-"); } …
これが、リリース・エクスパイアする時に実行されるようだった。
そのため、リリース・エクスパイアではClientIPとClientNameが設定されている前提でスクリプトを呼び出している。
きっとIPv6の仕様で、リリース・エクスパイアのときに情報を取り出すことができなくて、IPv4と同じような作りにすることができず、こうするより他なかったのではないかと想像している。
固定IPアドレスでは、グローバルに定義したイベント関数が呼び出されず、かつ、情報の取得ができなかったので、固定値でスクリプトを呼び出すようにしている。
#------------------------------- # Global options #------------------------------- authoritative; option dhcp6.domain-search "example.net"; option dhcp6.name-servers fdaa:aaaa:aaaa:aaaa::4; option dhcp6.sntp-servers fdaa:aaaa:aaaa:aaaa::4; default-lease-time 86400; # 24 hours. max-lease-time 604800; # 7 days. lease-file-name "/var/lib/dhcp/dhcpd.leases"; #log-facility syslog; #------------------------------- # Subnet #------------------------------- subnet6 fdaa:aaaa:aaaa:aaaa::/64 { range6 fdaa:aaaa:aaaa:aaaa::1:0100 fdaa:aaaa:aaaa:aaaa::1:0199; } #------------------------------- # Fixed address #------------------------------- host party { host-identifier option dhcp6.client-id 00:03:00:01:00:0c:29:14:6e:24; fixed-address6 fdaa:aaaa:aaaa:aaaa::12; on commit { execute("/usr/local/bin/dhcp-dyndns.sh", "add", "fdaa:aaaa:aaaa:aaaa::12", "no", "party", "-IPv6-"); } on release { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", "fdaa:aaaa:aaaa:aaaa::12", "no", "party", "-IPv6-"); } on expiry { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", "fdaa:aaaa:aaaa:aaaa::12", "no", "party", "-IPv6-"); } } host work { host-identifier option dhcp6.client-id 00:03:00:01:00:0c:29:0a:83:af; fixed-address6 fdaa:aaaa:aaaa:aaaa::3; on commit { execute("/usr/local/bin/dhcp-dyndns.sh", "add", "fdaa:aaaa:aaaa:aaaa::3", "no", "work", "-IPv6-"); } on release { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", "fdaa:aaaa:aaaa:aaaa::3", "no", "work", "-IPv6-"); } on expiry { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", "fdaa:aaaa:aaaa:aaaa::3", "no", "work", "-IPv6-"); } } #------------------------------- # Dynamic DNS #------------------------------- on commit { set ClientIP = binary-to-ascii(16, 16, ":", substring(option dhcp6.ia-na, 16, 16)); set ClientName = option fqdn.hostname; execute("/usr/local/bin/dhcp-dyndns.sh", "add", ClientIP, "no", ClientName, "-IPv6-"); } on release { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "no", ClientName, "-IPv6-"); } on expiry { execute("/usr/local/bin/dhcp-dyndns.sh", "delete", ClientIP, "no", ClientName, "-IPv6-"); }
v6/radvd.conf
ルーター広告は過去に調べていたので、それをベースに設定値を作成。
使用するネットワークインターフェースを指定している。
interface ens33 { AdvSendAdvert on; AdvManagedFlag on; AdvOtherConfigFlag on; AdvDefaultPreference low; prefix fdaa:aaaa:aaaa:aaaa::/64 { AdvAutonomous off; }; AdvCurHopLimit 0; };
setufw.sh
ファイアウォールの設定をするスクリプト。
IPv4について、理屈は確認していないが開放しなくても動作しているので、設定していない。
~/dhpc/setufw.sh
#!/bin/bash ufw $1 allow to any port 547 proto udp from any comment "DHCPv6"
実行権限を付けておく。
$ chmod +x ~/dhcp/setufw.sh
Samba ad dcの追加設定
Samba ad dcのコンテナを作成した頃には、IPv6のことは全然考慮に入れていなかった。
今回のことで、IPv6への対応が必要になる。
使用するIPアドレスを追加
Samba ad dcが使用するインターフェースにIPv6のIPアドレスを追加する。
$ sudo docker exec -it samba bash --login
コンテナの中ではvimが使えるので、以下を編集する。
/etc/samba/smb.conf
[global] bind interfaces only = Yes dns forwarder = 192.168.110.10 #dns update command = /usr/sbin/samba_dnsupdate --current-ip 192.168.110.10 interfaces = 192.168.110.4 fdaa:aaaa:aaaa:aaaa::4 127.0.0.1 netbios name = ADDC …
interfacesにIPv6のアドレスを追加。
samba_dnsupdateコマンドはinterfaces指定されているIPアドレスを使用するので、再定義の必要がなくなっているので、コメント化。
元々は、ネットワークモードをhostにしていなかったため、そのときには必要だった設定。いずれ、Samba ad dcコンテナの記事からも削除するつもり。
設定の変更を反映させるため、コンテナを再起動。
$ sudo docker compose restart
逆引きゾーン
コンテナの準備ができたのですぐに起動したいところだが、その前に逆引きゾーンを作っておく。
(作っておかなくても動作するようにスクリプトは作られているが、逆引きもできた方が良いのだろうなと)
IPv4
IPv4の管理範囲は、
192.168.110.0 ~
192.168.110.255
まで。
逆引きゾーンは 192.168.110 で管理することにした。
# samba-tool dns zonecreate localhost 110.168.192.in-addr.arpa -U administrator
IPv6
今回のDHCPv6でばらまくIPアドレスの範囲は
fdaa:aaaa:aaaa:aaaa:0000:0000:0001:0100 ~
fdaa:aaaa:aaaa:aaaa:0000:0000:0001:0199
までとした。
そして、固定で払い出すIPアドレスの範囲はIPv4ベースなので
fdaa:aaaa:aaaa:aaaa:0000:0000:0000:0000 ~
fdaa:aaaa:aaaa:aaaa:0000:0000:0000:0255
と決めた。
ということで、fdaa:aaaa:aaaa:aaaa:0000:0000:000で管理することにした。
# samba-tool dns zonecreate localhost 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa -U administrator PTR登録はこんな感じ。 # samba-tool dns add localhost 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 3.0.0.0.0 ptr work.example.net -U administrator ~~~~~~~~~ 4階層で管理
これでPTRレコードを追加すると、Samba ad dcでは4階層のデーターを作って管理してくれる。
# samba-tool dns query addc 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 0 PTR -U administrator Password for [MYGROUP\administrator]: Name=, Records=0, Children=0 Name=0, Records=0, Children=1 # samba-tool dns query addc 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 0.0 PTR -U administrator Password for [MYGROUP\administrator]: Name=, Records=0, Children=0 Name=0, Records=0, Children=1 # samba-tool dns query addc 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 0.0.0 PTR -U administrator Password for [MYGROUP\administrator]: Name=, Records=0, Children=0 Name=0, Records=0, Children=1 # samba-tool dns query addc 0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 0.0.0.0 PTR -U administrator Password for [MYGROUP\administrator]: Name=, Records=0, Children=0 Name=3, Records=1, Children=0 PTR: work.example.net (flags=f0, serial=6, ttl=900)
もちろん、気が変わってIPアドレスの範囲を変更することを考慮して fdaa:aaaa:aaaa:aaaa で管理することもできる。
ただ…管理はできるけれども、15階層はあまりに無駄が多いような気がしたので、4階層での管理を選択した。
# samba-tool dns zonecreate localhost a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa -U administrator この場合のPTR登録はこんな感じ。 # samba-tool dns add localhost a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa 3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 ptr work.example.net -U administrator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15階層で管理
固定IPアドレス
設定の中でさらっと固定IPアドレスと書いているけれども、特にUbuntuのIPv6では、systemd-networkdで少しやることがある。
前回そこに触れているので、必要時には参照のこと。
固定IPアドレス(IPv4)
MACアドレスで固定IPを割り振ることが可能。
固定IPアドレス(IPv6)
DUIDで固定IPアドレスを割り振ることが可能。
Windowsでは、ipconfig /all で分かる。
UbuntuのIPv6は、DUIDをMACアドレスを使ったものになるように設定できる。
/etc/systemd/networkd.conf
[DHCPv6] DUIDType=link-layer
※これで、00:03:00:01:<MAC ADDRESS>がDUIDになる。
起動
ここまでの操作で準備ができたので、コンテナを起動する。
起動
ファイアウォールを設定。
$ cd dhcp $ sudo ./setufw
コンテナを起動。
$ sudo docker compose up -d --build
適切な構成(docker-compose.yml, v4/dhcpd.conf, v6/dhcpd.conf, v6/radvd.conf)になっていれば、IPアドレスを払い出しはじめる。
設定変更
設定の変更はコンテナの外で行い、コンテナを削除してビルド・起動すれば反映できる。
$ sudo docker compose down $ sudo docker compose up -d --build
デバッグ
dhcpdの動作を細かく見たい時は、docker-compose.ymlのDHCPDBGFLGをtrueに設定して起動。
$ sudo docker compose up --build
スクリプトのデバッグをしたい時には、最初に -x を付けてビルド・起動する。
dhcp-dyndns.sh
#!/bin/bash -x
…
$ sudo docker compose up --build
どちらも、一時的にデバッグをするなら、コンテナの中に入って/entrypoint.shや/usr/local/bin/dhcp-dyndns.shを書き換えて…
$ sudo docker exec -it dhcp4 bash --login とか sudo docker exec -it dhcp6 bash --login でコンテナに入り…
# vi entrypoint.sh とか vi /usr/local/bin/dhcp-dyndns.sh で設定を修正して…
$ sudo docker compose stop $ sudo docker compose up
等を実行すればOK。
動作確認
Samba ad dcに登録状況を聞いてみる。
$ dig work.example.net -t any … ;; ANSWER SECTION: work.example.net. 900 IN A 192.168.110.3 work.example.net. 900 IN AAAA fdaa:aaaa:aaaa:aaaa::3 …
逆引きしてみる。
$ dig -x 192.168.110.3 … ;; ANSWER SECTION: 3.110.168.192.in-addr.arpa. 900 IN PTR work.example.net. … $ dig -x fdaa:aaaa:aaaa:aaaa::3 … ;; ANSWER SECTION: 3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.a.a.a.a.a.a.a.a.a.a.d.f.ip6.arpa. 900 IN PTR work.example.net. …
問題なく教えてくれるようになった。
ルーティングメモ
ホームラボから外に出るために、ルーティング設定を入れている。
[Internet] │ ┌──────────┐ [ My Home ]─<ens37> │ │ Samba ad dc & DHCP │ │ <ens33>─[ Homelab ] └──────────┘
ネットワーク設定
ネットワーク設定は以下のようになっている。
/etc/netplan/00-installer-config.yaml ※My Home側はマスクしている。
network: ethernets: ens33: addresses: - 192.168.110.10/24 - fdaa:aaaa:aaaa:aaaa::10/64 routes: - to: 192.168.110.0/24 via: 192.168.110.10 nameservers: addresses: - 192.168.110.4 - fdaa:aaaa:aaaa:aaaa::4 accept-ra: false dhcp6-overrides: use-dns: false dhcp6: false ens37: addresses: - 192.168.nnn.10/24 routes: - to: default via: 192.168.nnn.1 nameservers: addresses: - 192.168.nnn.1 version: 2
設定を変更したら、以下で反映する。
$ sudo netplan apply
ホームラボでは、ens37側(ネットワークMy Homeと接続している)がRAを受けており、2つのアドレスが追加される。
$ ip a show dev ens37
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:83:26:c3 brd ff:ff:ff:ff:ff:ff
altname enp2s5
inet 192.168.nnn.10/24 brd 192.168.nnn.255 scope global ens37
valid_lft forever preferred_lft forever
inet6 fdnn:nnnn:nnnn:nnnn::110:10/128 scope global dynamic noprefixroute
valid_lft 84386sec preferred_lft 51986sec
inet6 24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 14122sec preferred_lft 12322sec
inet6 fe80::nnnn:nnnn:nnnn:nnnn/64 scope link
valid_lft forever preferred_lft forever
ルーティング
ここにルーターとしての設定を入れていく(参照 IPv4, IPv6)。
/etc/ufw/sysctl.conf ※コメントアウトされているので有効に。
… # Uncomment this to allow this host to route packets between interfaces net/ipv4/ip_forward=1 net/ipv6/conf/default/forwarding=1 net/ipv6/conf/all/forwarding=1 …
/etc/ufw/before.rules ※最後に追加。
… COMMIT # NAT rules *nat :POSTROUTING ACCEPT [0:0] -F -A POSTROUTING -s 192.168.110.0/24 -o ens37 -j MASQUERADE COMMIT
/etc/ufw/before6.rules ※最後に追加。
… COMMIT # NAT rules *nat :POSTROUTING ACCEPT [0:0] -F -A POSTROUTING -s fdaa:aaaa:aaaa:aaaa::/64 -o ens37 -j MASQUERADE COMMIT
設定を反映。
$ sudo ufw reload
デフォルトポリシー(DROP)はそのままに、でも転送を許可する。
これだとACCEPTと変わらないけれど、将来、必要なものだけ開ける形にしたくなったら簡単に移行できる。
$ sudo iptables --list FORWARD Chain FORWARD (policy DROP) …
IPv4
$ sudo ufw route deny in on ens33 out on ens37 to 0.0.0.0/0 port 135,137:139,445 proto tcp $ sudo ufw route deny in on ens33 out on ens37 to 0.0.0.0/0 port 135,137:139,445 proto udp $ sudo ufw route allow in on ens33 out on ens37 to 0.0.0.0/0
IPv6
$ sudo ufw route deny in on ens33 out on ens37 to ::/0 port 135,137:139,445 proto tcp $ sudo ufw route deny in on ens33 out on ens37 to ::/0 port 135,137:139,445 proto udp $ sudo ufw route allow in on ens33 out on ens37 to ::/0
IPv4の方は、netplanでデフォルトゲートウェイを明確に指定しているのだけれど、IPv6の方は指定していない。
どうも、RAが送られてきたサーバーがそれにあたるらしく、RAを動かしておかないとルーティングしてくれないように見えた。
また、最初、IPv6はマスカレードせずともパケットを転送してくれるように見えていたけれど、それは設定中に起きていたオペミスのようだった。
サーバーを再起動したら動かない…
マスカレードの設定をいれて、正常動作となった。
起きたこと
IPv6で時刻サーバーをうまく使えない
IPv4はうまく動いているように見える。
/etc/netplan/00-installer-config.yaml
$ cat /etc/netplan/00-installer-config.yaml # This is the network config written by 'subiquity' network: ethernets: ens33: dhcp4: true dhcp6: false accept-ra: false version: 2
反映して確認。
$ sudo netplan apply
$ ip a show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:14:6e:24 brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.110.12/24 metric 100 brd 192.168.110.255 scope global dynamic ens33
valid_lft 86387sec preferred_lft 86387sec
inet6 fe80::20c:29ff:fe14:6e24/64 scope link
valid_lft forever preferred_lft forever
$ sudo systemctl restart systemd-timesyncd
$ timedatectl show-timesync
LinkNTPServers=192.168.110.10
FallbackNTPServers=ntp.ubuntu.com
ServerName=192.168.110.10
ServerAddress=192.168.110.10
RootDistanceMaxUSec=5s
同様にIPv6で試してみたところ、タイムサーバーが使われなかった。
/etc/netplan/00-installer-config.yaml
$ cat /etc/netplan/00-installer-config.yaml # This is the network config written by 'subiquity' network: ethernets: ens33: dhcp4: true dhcp6: false accept-ra: false version: 2
反映して確認。
$ sudo netplan apply $ ip a show ens33 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:0c:29:14:6e:24 brd ff:ff:ff:ff:ff:ff altname enp2s1 inet6 fdaa:aaaa:aaaa:aaaa::12/128 scope global dynamic noprefixroute valid_lft 86301sec preferred_lft 53901sec inet6 fe80::20c:29ff:fe14:6e24/64 scope link valid_lft forever preferred_lft forever $ sudo systemctl restart systemd-timesyncd $ timedatectl show-timesync FallbackNTPServers=ntp.ubuntu.com ServerName=ntp.ubuntu.com ServerAddress=2620:2d:4000:1::41 RootDistanceMaxUSec=5s …
最後の確認で、LinkNTPServersが表示されていない。
DHCPではちゃんと動いているのか。
RAをradvdumpで確認。
DHCPv6 Message type: Reply (7) Transaction ID: 0x5c7c56 … Simple Network Time Protocol Server Option: Simple Network Time Protocol Server (31) Length: 16 1 SNTP server address: fdaa:aaaa:aaaa:aaaa::4
ちゃんと配布しているように見える。
systemd-networkdで認識されているか。
$ networkctl --no-pager status ens33
● 2: ens33
Link File: /usr/lib/systemd/network/99-default.link
Network File: /run/systemd/network/10-netplan-ens33.network
Type: ether
State: routable (configured)
Online state: online
Alternative Names: enp2s1
Path: pci-0000:02:01.0
Driver: e1000
Vendor: Intel Corporation
Model: 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
HW Address: 00:0c:29:14:6e:24 (VMware, Inc.)
MTU: 1500 (min: 46, max: 16110)
QDisc: fq_codel
IPv6 Address Generation Mode: eui64
Queue Length (Tx/Rx): 1/1
Auto negotiation: yes
Speed: 1Gbps
Duplex: full
Port: tp
Address: fdaa:aaaa:aaaa:aaaa::12
fe80::20c:29ff:fe14:6e24
Gateway: fe80::20c:29ff:fe83:26b9 (VMware, Inc.) ← 192.168.110.10のLLA
fe80::20c:29ff:fe9f:50bd (VMware, Inc.) ← 192.168.110.4のLLA
DNS: fdaa:aaaa:aaaa:aaaa::4
NTP: fdaa:aaaa:aaaa:aaaa::4
Activation Policy: up
Required For Online: yes
DHCP6 Client IAID: 0x2b9434c1
DHCP6 Client DUID: DUID-LL:0001000c29146e240000
Connected To: n/a on port 00:50:56:c0:00:08
んー、ちゃんと認識しているようだ。
sytemd-timesyncdを再起動しても、Initial synchronizationのログが出ない。
そこで、デバッグログを出してみることにした。
$ sudo systemctl edit systemd-timesyncd
エディタが開くので、以下を追加。
### Editing /etc/systemd/system/systemd-timesyncd.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
### Lines below this comment will be discarded
保存して、サービスを再起動し、ログを見てみる。
$ sudo systemctl restart systemd-timesyncd
/var/log/syslog
Nov 3 19:22:44 party systemd[1]: Starting Network Time Synchronization...
Nov 3 19:22:44 party systemd-timesyncd[2445]: Bus bus-api-timesync: changing state UNSET → OPENING
Nov 3 19:22:44 party systemd-timesyncd[2445]: sd-bus: starting bus bus-api-timesync by connecting to /run/dbus/system_bus_socket...
Nov 3 19:22:44 party systemd-timesyncd[2445]: Bus bus-api-timesync: changing state OPENING → AUTHENTICATING
Nov 3 19:22:44 party systemd-timesyncd[2445]: Registering bus object implementation for path=/org/freedesktop/LogControl1 iface=org.freedesktop.LogControl1
Nov 3 19:22:44 party systemd-timesyncd[2445]: Added new server ntp.ubuntu.com.
Nov 3 19:22:44 party systemd-timesyncd[2445]: systemd-timesyncd running as pid 2445
Nov 3 19:22:44 party systemd[1]: Started Network Time Synchronization.
Nov 3 19:22:44 party systemd-timesyncd[2445]: Selected server ntp.ubuntu.com.
Nov 3 19:22:44 party systemd-timesyncd[2445]: Resolving ntp.ubuntu.com...
Nov 3 19:22:44 party systemd-timesyncd[2445]: Bus bus-api-timesync: changing state AUTHENTICATING → HELLO
SNTPで示されているサーバーを追加していない。
先程実行したステータス表示からすると、FallbackNTPServerとしてntp.ubuntu.comが登録されているのだろう。
デバッグログ出力をやめて…
$ sudo systemctl edit systemd-timesyncd
### Editing /etc/systemd/system/systemd-timesyncd.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file
[Service]
#Environment=SYSTEMD_LOG_LEVEL=debug
### Lines below this comment will be discarded
時刻サーバーがIPv6を受け付けられていないのかもしれないので、systemd-timesyncdが見に行くように設定してみよう。
/etc/systemd/timesyncd.conf
[Time] NTP=example.net #FallbackNTP=ntp.ubuntu.com #RootDistanceMaxSec=5 #PollIntervalMinSec=32 #PollIntervalMaxSec=2048
サービスを再起動し、時刻の同期を確認する。
$ sudo systemctl restart systemd-timesyncd $ timedatectl show-timesync SystemNTPServers=example.net FallbackNTPServers=ntp.ubuntu.com ServerName=example.net ServerAddress=fdaa:aaaa:aaaa:aaaa::4 RootDistanceMaxUSec=5s
ようやく動き出した。
でも、これって
- もしかして最新バージョンだと修正されているかもしれない。
- うちの中はデュアルスタックなのであり、IPv4が動かないことはないだろうから、当面は問題にならない。
と割り切って、当面は無視しておこうかと思う。
さいごに
現在稼働中の環境では、ホストの登録はできるものの、削除ができていなかった。
また、逆引きについては、Samba ad dcを導入してから管理できていなかった。
リプレイスしなきゃと夏から色々と調べ始めて、Samba ad dcとDHCPがようやくまともに使えそうな状態になってきた。長かった。
もうちょっとやることはあるけれど、年末にはOS更改できそうだ。
コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他