dist-upgrade'd dual-stack wheezy to jessy, sshd don't listen ipv4 but ipv6
Last modified: Wed, Apr 29 14:52:07 JST 2015
Debian wheezy から jessie へ dist-upgrade したら sshd が IPv4 を listen してなくて IPv6 しかつながらなくなった。
ng: @from-wheezy:~$ ssh -X -4 upgraded-jessie.example.local
ok: @from-wheezy:~$ ssh -X -6 upgraded-jessie.example.local
確認してみる
@on-jessie:~$ ss -tlp | grep ":ssh"
LISTEN 0 128 2001:db8::15:ssh :::*
@on-jessie:~$ ip addr | grep inet
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 192.0.2.15/24 brd 192.0.2.255 scope global dynamic eth0
inet6 2001:db8::15/64 scope global
inet6 fe80::4ce2/64 scope link
インターフェイスは IPv4、IPv6 ともアドレスが振られており問題なさそう。設定変更してないのになんで sshd がIPv6しか上がってないのか..
jessie では起動システムがデフォルトでwheezyまでの sysvinit から systemd に変更されていて (いやなら今までどおりのsysvinit も使える)その影響を受けているのではないか。
試しに sshd を再起動してみる。
@on-jessie:~$ ls /lib/systemd/system | grep "ssh"
ssh.service
ssh@.service
@on-jessie:~$ sudo systemctl restart ssh.service*
@on-jessie:~$ ss -tlp | grep ssh
LISTEN 0 128 192.0.2.15:ssh *:*
LISTEN 0 128 2001:db8::15:ssh :::*
(* /etc/systemd/system/sshd.service がシンボリックリンクとして存在するので systemctl restart sshd でも ok)
マシンを起動するたびに systemctl restart ssh.service するのも嫌なので調べてみた。
疑問:
ブート直後の sshd は IPv4 を listen してないのに systemctl restart すると listen するのは何故?
推測:
ひょっとすると初回 sshd が起動する段階でネットワークインターフェイスに IPv4 アドレスがまだ振られていないのではないか。
調査と試行
手元の jessie のネットワーク起動はどうも systemd から旧来の /etc/init.d/networking を呼び出し /etc/network/interfaces を参照し ifup しているようだということがわかった。
wheezy で使っていた interfaces には v4 は dhcp でアドレス取得、v6は固定で指定していた。
/etc/netwok/interfaces
[...]
allow-hotplug eth0
iface eth0 inet dhcp
ethernet-wol g
# up ip -6 addr add 2001:db8::15/64 dev eth0
# up ip -6 route add ::/0 dev eth0 via fe80::?? mtu 1280
iface eth0 inet6 static
address 2001:db8::15
netmask 64
gateway 2001:db8::1
hwaddress ether 00:13::??
mtu 1280
ひょっとすると、dhcp での IPv4 取得に時間かかってるからか?(固定するとどうなるかは試してない..)
jessie の systemd では systemd-networkd というのがあって、こいつでネットワークの設定を代替できるので、これを使ってみる。(おそらく移行の手間とトラブルを避けるためだと思うのだがデフォルトではこいつは動いてない)
cf. systemd-networkd(8) , systemd.network(5)
設定は優先順位の高い
/etc/systemd/ に置く。
(ディストリビューションや systemd のバージョンによってはインターフェイス名が enm0p0 みたいになってるらしいのだが、jessie では旧来からの ethN %なんでかよくわかってない)
@on-jessie:~$ sudo -s
@on-jessie:# cd /etc/systemd
@on-jessie:# mkdir network
@on-jessie:# vi eth0.network
[Match]
Name=eth0
MACAddress=00::??
[Network]
DHCP=v4
Address=2001:db8::15/64
Gateway=192.0.2.1
Gateway=2001:db8::1
DNS=192.0.2.17
DNS=192.0.2.1
DNS=2001:db8::2
DNS=2001:db8::1
試しに呼んでみる。
@on-jessie:~$ systemctl status systemd-networkd
● systemd-networkd.service - Network Service
Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled)
Active: inactive (dead) since 水 2015-04-29 11:32:13 JST; 2s ago
Docs: man:systemd-networkd.service(8)
@on-jessie:~$ sudo systemd start systemd-networkd
@on-jessie:~$ systemctl status systemd-networkd
● systemd-networkd.service - Network Service
Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled)
Active: active (running) since 水 2015-04-29 11:33:54 JST; 6s ago
Docs: man:systemd-networkd.service(8)
Main PID: 8138 (systemd-network)
Status: "Processing requests..."
CGroup: /system.slice/systemd-networkd.service
└─8138 /lib/systemd/systemd-networkd
なんかエラーがでたら修正する..
(ちなみに、man 5 system.network すると、[NETWORK] SECTION OPTIONS とか見出しに書いてあるので、そのまま [NETWORK] って書いたらエラーになった。どうも [Network] と書かないと通らない(case sensitive)みたい)
よさそうなら起動時に有効になってるかどうか確認してみて..
@on-jessie:~$ systemctl is-enabled systemd-networkd
disabled
(is-enable"d" とちゃんと過去分詞になってるので注意)
次回起動時に有効になるように登録する。
@on-jessie:~$ sudo systemctl enable systemd-networkd
(通常の英語の文法でこっちは enable )
こうすることで、jessie の sshd は起動直後から IPv4, IPv6 の双方を listen してくれるようになった。
おそらく systemd の並列起動で旧来の ifup (dhcpで IPv4 取得)が完了しきらないうちに sshd が起動してしまっていたような症状に見えるが詳細は追っていないので不明.. すんません..
一部検証とばして記憶で書いてる部分があるので間違いあるかも.. すんません..