2015年7月9日木曜日

IPv6 TempAddr - jessie - kde - network-manager

手元に Win7pro のインストールされたノートブック Toshiba R730 が、お下がりでやってきたので Debian jessie をインストールしてみた。

先日、d-u.jp で、IPv6 の tempaddr について話があったのでちょっと確認してみた。

今までの手元のマシン4台はサーバー系用途のために IPv6 も固定で設定してあり、network-manager も使っていなかったため検証不能だった(後日 2015-08-23 検証してみた)ので..

なお、kernel レベルでの制御は sysctl (/etc/sysctl.conf, /etc/sysctl.d/*.conf, sysctl(8)コマンド) で可能であり、GUI ツールからの設定も最終的にはここの net.ipv6.conf.IFname.use_tempaddr の値を設定する。

Gnome は好みでないのと、Win7pro を残しデュアルブートにしたため、残り半分のディスクスペースしかなく、Gnome導入する余裕がなかったので KDE 環境のみで検証した。

おそらく、Gnome 環境でもほぼ同様に設定、利用できると思う。(未確認)

 

network-manager

KDE環境では network-manager (nm) はタスクバーに表示されるアイコン(あるいは追加ウィジェット)からアクセスするようになっている。(デフォルトではタスクバーは画面下に横たわっている..)


ここでは wireless 環境なので wifi アイコンになってる。wired 環境だと RJ-45コネクタのアイコンになったと思う。

初期では MAC から生成された EUI-64 な IPv6 アドレスが使われる設定になっていたので、これを変更してみる。

タスクバーの電波アイコン(1.)をクリックすると network-manager によるネットワークの概要が表示され、さらにその右上のスパナアイコン(2.)をクリックすると次のスクリーンショットのような Connection editor というタイトルのウィンドウが表示される。


ここで、1. 目的のネットワークを選択し、2. 編集をクリック すると、さらに次の Edit Connection [connection name] の画面が表示される。


この画面のタブの中から右端にある IPv6 のタブを選択すると、Privacy という項目があり、プルダウンタブをクリックすると Enabled (prefer temporary address) という選択肢が現れるので、これを選択する。

タスクバーのアイコンから一度コネクションを 切断(disconnect)-> 接続(connect) すると、次のスクリーンショットのように ip addr コマンドの出力には、 wlan0 の IPv6 アドレス (inet6 で始まる行) が3つ現れる。(ここでは無線LAN環境なので wlan0 になってる)


一番下のアドレス先頭が fe80 で始まるものは scope link であり、いわゆる link-local と呼ばれるもので、グローバルに使用されるものではない。

残りの2つの上の方、(末尾が :f39e/64 の方)は、scope global temporary となっており、これが 上の設定によって追加された temporary address である。

もう一つは MAC を元にした EUI-64 なアドレス(mngtmpaddrの方)である。

IPv6 は1つのインターフェイスに複数割りあてられるのでこういう状態でも両方のアドレスで通信は可能である。



モバイル機器やクライアント機においては、固定アドレス、EUI-64 なアドレスでは、個人が特定されプライバシーが侵害されるおそれがあるので、IPv6 tempaddr (temporary address) の利用が推奨される。

あちこちのネットワークを渡り歩くような機器の場合は tempaddr を使うように設定しておこう。

sysctl - 後日の検証

上記のように NetworkManager から wlan0 に対して tempaddr を利用するように設定した場合、
sysctl -a | grep "tempaddr"
の結果は、 
net.ipv6.conf.wlan0.use_tempaddr = 2 
のように "2" がセットされている。 

この値については、kernel 付属のドキュメントの networking/ip-sysctl.txt.gz (jessie の標準では linux-doc-3.16) につぎのような記述がある。


use_tempaddr - INTEGER
   Preference for Privacy Extensions (RFC3041).         
   <= 0 : disable Privacy Extensions
   == 1 : enable Privacy Extensions, but prefer
          public addresses over temporary addresses.
   >  1 : enable Privacy Extensions and prefer
          temporary addresses over public addresses.
  
Default:  0 (for most devices)                
         -1 (for point-to-point devices and loopback
             devices)

訳すと..


use_tempaddr (一時アドレスを使用)  整数値
       プライバシー拡張(RFC3041)の設定 
                      <= 0 (0以下) : プライバシー拡張 無効
                      == 1 (1)    : プライバシー拡張 有効、ただし
                                    一時アドレスよりパブリックアドレスを
                                    優先
                      >  1 (1より大) : プライバシー拡張 有効、
                                      パブリックアドレスより一時アドレス
                                      を優先使用する
       デフォルト  : 0 (ほとんどのデバイス用途)
               -1 (point-to-point デバイスと
                           ループバックデバイス用途)

となる。

  • tempaddr : 一時アドレス。ブートごとにカーネルにより自動生成されるランダムな IPv6 アドレス

  • public address : 管理者により設定された固定 IPv6 アドレスか、それがない場合はには、EUI-64 という方式によりネットワークインターフェイスの MAC アドレスより自動的に算出される固定 IPv6 アドレス。

なお、文中では RFC3041 と書かれているが、これはすでに古くなっており現時点(2015-08-23)では、より新しい RFC4941 によって置き換えられている。

ちょっと事情があり、jessie 環境をクリーンインストールしたデスクトップ機でも検証してみた。こちらは wireless 環境がないため、インターフェイスは eth0 になる。

また、固定 IPv6 を利用するにあたって network-manager や avahi-daemon をアンインストールし、インターフェイスのブリングアップを従来の ifupdown から systemd の systemd-networkd を利用する方式に変更してある。

クリーンインストール直後は net.ipv6.conf.eth0.use_tempaddr = 2 の状態であったが、network-manager の削除により、net.ipv6.conf.eth0.use_tempaddr は "0" に変化した。

これを /etc/sysctl.d/use_tempaddr.conf ファイルを作成し、次のように記述、net.ipv6.conf.eth0.use_tempaddr=1
再起動すると、eth0 に tempaddr が割り振られた。

しかし、ssh やブラウザで確認すると、tempaddr では接続していないことが確認された。

さらに、net.ipv6.conf.eth0.use_tempaddr=2 として再起動してみた。

すると、ip addr の結果は次の通り。

ブラウザのプロキシ設定を外して ipv6-test.com へ接続すると..

 
ssh で別マシンへ接続してみると..



 と、このように、eth0 に割り振られた 3つ(linklocal も含めると 4つ)の IPv6 アドレスのうち、ランダムに生成された tempaddr を使用して接続していることが確認された。

付記

さらに、MAC アドレスをランダムに生成するという方法もあり、windows10 で対応されたようで一部で話題になっているが、linux でも systemd-networkd を使用すると可能なようだ。

cf. man(5) systemd.link の [LINK] SECTION OPTION 参照。

[LINK] SECTION OPTIONS
       The "[Link]" section accepts the following keys:

       Description=
           A description of the device.

       Alias=
           The "ifalias" is set to this value.

       MACAddressPolicy=
           The policy by which the MAC address
           should be set.
           The available policies are:

           "persistent"
               If the hardware has a persistent MAC
               address, as most hardware should, and
               if it is used by the kernel, nothing
               is done.
               Otherwise, a new MAC address is
               generated which is guaranteed to be
               the same on every boot for the given
               machine and the given device, but
               which is otherwise random.

           "random"
               If the kernel is using a random MAC
               address, nothing is done.
               Otherwise, a new address is randomly
               generated each time the device appears,
               typically at boot.


この "random" の部分を見てみると、つぎの意味だと思われる。

"random"
  カーネルがランダムMACアドレスを使用する場合はなにもしない。そうでなければ一般的にはブート時に新しいアドレスがランダムに生成される。

ちなみに、kernel が random MAC を使うようにする設定方法についてはまだ調べていない..


2015年6月1日月曜日

## jessie - systemd - poweroff - acpid ##

Debian jessie では systemd の導入によって shutdown の動作は systemd の
コマンド systemctl が管理するようになった。

 $ ls -l /sbin | grep systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 halt -> /bin/systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 poweroff -> /bin/systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 reboot -> /bin/systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 runlevel -> /bin/systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 shutdown -> /bin/systemctl
 lrwxrwxrwx 1 root root  14  4月 17 00:53 telinit -> /bin/systemctl


うっかりマシンの電源ボタンに触れてしまい、
/sbin/poweroff が呼ばれて runlevel 0 に入って電源が切れた。

wheezy までの 'sudo shutdown -h now' では、BIOS でセットした キーボー
ドにより wake や ethernet インターフェイスによる wake (いわゆる
wakeonlan=wol) が有効な状態、つまりマザーボードへの電源が部分的に供給され
ている状態へ遷移していたのだが、jessie の poweroff ではマザーボードへ
の電源供給が完全に断たれた状態 hardoff へと遷移してしまう。

こうなると、ケースの電源ボタンを押しても起動しない。ケース裏の電源の
on/off スイッチを一度OFFにして再度ONにしてから電源ボタン押すという操作
が必要になってしまった。

なんでや..

キーボードでの wake や wol は便利で良く利用していて、jessie の
poweroff の状態はとても不便なので調べてみた。

マシンの電源管理は旧来、 BIOS の APM で制御していたのが、現在では ACPI
という OS から制御可能な仕組みになっている。(すでに BIOS 自体が EFI
(UEFI) と置き換えられている)

jessie の systemctl [halt, poweroff, reboot] では ACPI の制御はまだな
いようなので、acpid を動かすようにした。

もともと wheezy の前から acpid 入れてた 'はず' なんだけど..
dist-upgrade で消えたのかな? dist-upgrade 時のスクリプトを見てみたら
置き換える場面が記録されているが、先日 sudo apt-get install acpid して
るので.. たぶん、apt-get autoremove したかなんかの拍子に引きずられて消
えたの可能性が... why???


もうちょっと追いかけて正確に書くべきと思うのだが.. すんません..

ときになんか変なことが起こっていたら必要なパッケージが remove されてないかどうか確認してみるのがよい。

dpkg-query -l acpid
sudo apt-get install acpid

2015年5月28日木曜日

wanderlust: use gnutls insted of starttls

wanderlust: use gnutls insted of starttls

Created: Thu, May 28 10:55:42 JST 2015
Last modified: Thu, May 28 17:31:49 JST 2015

もしも F1 v starttls-use-gnutls あるいは M-x customize-valiable starttls-use-gnutls して、すでに "nil" ではなく "t" になっているならここから先はまったく必要ない。


手元では emacs24.5, wl, starttls についてはソースからインストール、gnutls-bin は deb パッケージをインストールしてある。

最近、TLS まわりにインシデントが出てきていろいろと調整していた。いろいろとログを見ていたら手元の wanderlust が LAN 内にある cyrus-imapd に接続に行くときに
 starttls: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits new) no authentication
で接続していることに気づいた。

これ、そろそろ TLSv1.2 にしたほうが良いだろう、ということでうろうろしてみた。

starttls.el 自体は Gnus の一部として Emacs 本体に含まれている(emacs-*/lisp/gnus/starttls.el)。そこから先、実際にサーバーとコネクトする部分についてはカスタマイズ可能な変数として starttls.el で定義されている。

starttls.c (ftp://ftp.opaopa.org/elisp/starttls-0.10.tar.gz) を読んでみると TLSv1 の記述は見つかるが TLSv1.2 の記述は見つからない。

そこで starttls.el から starttls.c(のコンパイルされたもの) を呼ぶのではなく gnutls-cli を使って TLS 接続してみる。

 ;; wl だけで有効にしたいなら~/.wl に記述。
 (setq starttls-use-gnutls t)
 (setq starttls-gnutls-program "gnutls-cli")
 (setq starttls-extra-arguments '("--insecure"))


(M-x customize-variable でもいいかも)
自己署名証明書を使っている場合に検証 (validate) で弾かれるような場合は "--insecure" オプションを有効にする。これ、本来は MITHM があるので良くない。サーバーによって "--insecure" つけるかどうかフラッグで切り替えた方がよさそう..

詳細は man gnutls-cli して確認。

wl + gnutls-cli で cyrus-imapd へ接続した場合の cyrus-imapd のログは、
 starttls: TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits new) no authentication
のようになった。

ひょっとすると deb パッケージなどで emacs + wl な環境とかだと、すでにこのあたり有効になってる可能性高いので、必ず
 M-x describe-valiable starttls-use-gnutls
とかして t か nil かをまず確認してみること。

2015年5月18日月曜日

jessie - systemd - journalctl - ANSI escape

jessie - systemd - journalctl - ANSI escape

wheezy から jessie に dist-upgrade したマシンで、sudo journalctl -l とかすると、systemd は bold 表示する目的で ANSI エスケープシーケンス使っているのがうまく解釈されずに生で見えてしまう。


これ、読みづらいので何とかすべく調べてみた。

$ sudo journalctl -l
だと上記画像の状態。調べてみると SYSTEMD_PAGER という環境変数に "less -j4aR" 設定するとかあったので、ためしに設定してみる

$ sudo -s
# env SYSTEMD_PAGER='less -j4aR' journalctl -l


じゃぁ、"lv -c" でもいけるよね.. ということで試したら問題ない。

そこで、一般ユーザーの.bachrc に export SYSTEMD_PAGER='lv -c' と書いて(ターミナル起動しなおして)みて、sudo journalctl -l すると、だめ..

なぜだかしばらく悩んで.. この SYSTEMD_PAGER 環境変数が引き継がれてないことに気づいた..

これ.. sudo だ..

sudo, sudoers

/etc/sudoers を読んでみると、冒頭に、

Defaults env_reset

という記述がある。そこで、man sudoers してみると、env_keep オプションが見つかる。現状の sudo の状況を確認するには、root ユーザで sudo -V してみろという記述も見つかったので、やってみる。

$ sudo -s
# sudo -V
[...]

状況確認ができたので、SYSTEMD_PAGER 環境変数を保護するようにしてみる。ちなみに、まずい環境変数設定されてぼこぼこにされるのはみんな嫌だと思うので、冒頭の Defaults env_reset を無効にするようなことはやってはいけない。

visudo

/etc/sudoers ファイルは visudo というコマンドで編集する。これはロックがかかったり、万一、記述ミスがあったりすると、sudo できなくなってしまうので、こういう状況を避けるためにチェッカーが動いてくれる優れものだ。

$ sudo visudo

してみると、vi じゃなくて nano が起動してしまった..





nano を使い慣れている方はそのまま編集されるといいと思うのだが、僕はなれてないので、これを vim に替えたい。

そのまま nano を終了するには、末尾の案内にしたがって  Ctrl - X をタイプする。



変更保存するか聞かれるので "N" で保存しないを選択..

以前の Debian だと、環境変数 EDITOR とかで切り替えられたのだが、jessie だと、EDITOR 読んでもらえないみたいなので、update-alternatives で /usr/bin/editor を切り替えないとだめみたい。

まず状況確認..


$ update-alternatives --display editor
editor - 自動モード
  リンクは現在 /bin/nano を指しています
/bin/ed - 優先度 -100
  スレーブ editor.1.gz: /usr/share/man/man1/ed.1.gz
/bin/nano - 優先度 40
  スレーブ editor.1.gz: /usr/share/man/man1/nano.1.gz
/usr/bin/vim.basic - 優先度 30
  スレーブ editor.1.gz: /usr/share/man/man1/vim.1.gz



$ sudo update-alternatives --config editor
alternative editor (/usr/bin/editor を提供) には 4 個の選択肢があります。

  選択肢    パス              優先度  状態
------------------------------------------------------------
* 0            /bin/nano            40        自動モード
  1            /bin/ed             -100       手動モード
  2            /bin/nano            40        手動モード
  3            /usr/bin/vim.basic   30        手動モード
  4            /usr/bin/vim.tiny    10        手動モード

現在の選択 [*] を保持するには Enter、さもなければ選択肢の番号のキーを押してください: 3
 
update-alternatives: /usr/bin/editor (editor) を提供するためにマニュアルモードで /usr/bin/vim.basic を使います


これで visudo を呼ぶと vim で編集できるようになる。

$ sudo visudo





OK.
man sudoers して、env_keep を使って SYSTEMD_PAGER をリセット対象から外すように指定してみる。





$ env SYSTEMD_PAGER='lv -c' sudo journalctl -l



OK.

これで一般ユーザ の(rootじゃないよ) ~/.bashrc に

exports SYSTEMD_PAGER='lv -c'

と 書いておくと次からはなにも考えずに sudo journalctl -l しても ANSIエスケープシーケンス見えてしまうことはない && bold (フォントの関係などで bold できないばあいは一段明るい色で強調表示される)表示される。はず。

------

PS.


vim をカラフルにするには、(ここの画像のは jellybeans.vim)カラー設定を書くかいただいてきて、~/.vim/colors に *.vim ファイルを保存するか ln -s しておく。

jellybeans の場合、
https://github.com/nanotech/jellybeans.vim から git clone するか http で zip をもらってきて unzip する。

で、 ~/.vimrc に
set background=dark
colorscheme jellybeans
syntax on
filetype on

みたいにかいておくとできる。

2015年5月14日木曜日

nfsv4 + krb5 on jessie

 

ここが参考になる。

https://www.debian-administration.org/article/570/MIT_Kerberos_installation_on_Debian

あと、krb5-doc パッケージを入れておいて w3m file:///usr/share/doc/krb5-doc/index.html すると krb5 関連のドキュメントを読める。

実は以前も DNS で SRV レコードを作成してサービスの検出に使う方法 (http://web.mit.edu/Kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-install/Hostnames-for-the-Master-and-Slave-KDCs.html) を取っていたのだが、nfs-kernel-server, krb5-{kdc, admin-server} のマシンの HDD とばしてしまって環境つぶしちゃってから、復活させずに放置していたのを jessie に dist-upgrade したのを期に復活させてみた。

以前の nfsv4+krb5 では今となっては脆弱な暗号化通信(すでに weak_crypto とされてる des-cbc-crc:normal)しかサポートされてなかったのだが、古い nfsv4 がいない(後方互換すてられる)なら aes などが使えるので、des-cbc-crc とか使ってるマシンは早めに dist-upgrade したほうが良いと思う。

いろいろ忘れてて苦戦した記録...

DNS での krb5 関連の SRV レコード設定


bind9 での例

/etc/bind/db.example.org


[...]
$ORIGIN example.org.
[...]
server1               A      192.0.2.1
                      AAAA   2001:db8::1
ntp1                  CNAME  server1
kerberos              CNAME  server1
_kerberos             TXT    "EXAMPLE.ORG kerberos service"
_kerberos._udp        SRV 0 0 88  server1
_kerberos-adm._tcp    SRV 0 0 749 server1
_kerberos-master._udp SRV 0 0 751 server1
_kerberos-master._tcp SRV 0 0 751 server1
_kpasswd._udp         SRV 0 0 464 server1

これで TTL を小さくして serial をあげて systemctl restart bind9 する。スレーブがあるならそっちで rndc retransfer example.org して更新しておく。設定終わったら TTL 元に戻しておいた方がいいと思う。(いじるレコード毎に小さなTTL書くほうがいいかもしれない)

こうすると server1.example.org は ntp1.example.org や kerberos.example.org という fqdn でもアクセスできるようになる。

dig @ns.example.org kerberos.example.org 
dig @ns.example.org _kerberos._udp.example.org SRV
とかで期待したとおりに動いているか確認する。


/etc/nsswitch.conf

しばらく /etc/krb5.conf で kerberos.example.org を指定しても kdc へつながらずに悩んだ(kadmin.local はつながるけど kadmin や kinit が接続できない症状がでてた)のだが、/etc/nsswitch.conf を修正するとうまくうごいた。

デフォルトでは
hosts:   files mdns4_minimal [NOTFOUND=return] dns mdns4
こうなっているのを、dns を files の直後に持ってきて mdns4_minimal よりも優先する。
hosts:   files dns mdns4_minimal [NOTFOUND=return] mdns4

mdns4 って avahi-daemon のだけど、使おうと思ったことないのでなにをどうするものなのかよく知らない...

/etc/krb5.conf 

[libdefaults]
default_realm = STAINED-G.LOCAL
dns_lookup_kdc = true
scan_interfaces = true
dns_lookup_realm = true

srv_lookup = true
[...]
[realms] 
[...]
EXAMPLE.ORG {
default_domain = example.org
kdc = kerberos.example.org 
admin_server = kerberos.example.org  
}

みたいに指定しておいて

kinit や kadmin でうまく kdc や admin_server につながればOK。

その他調整が必要な設定ファイル

  • /etc/idmapd.conf
 環境に応じて /etc/krb5.conf などと整合性とれるように設定する。

[General]

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs #<-- ここ
#Domain = localdomain
Domain = example.org               #<-- ここ
Local-Realm = EXAMPLE.ORG          #<-- ここ

[Mapping]

Nobody-User = nobody
Nobody-Group = nogroup

[Translation]
Method = nsswitch,static          #<-- ここ
GSS-Methods = nsswitch,static     #<-- ここ

[Static]
whoami@EXAMPLE.ORG = iamjon
              #<-- ここ

  • /etc/default/nfs-common
NEED_IDMAPD="yes" 
NEED_GSSD="yes"

  • /etc/default/nfs-kernel-server
NEED_SVCGSSD=yes

krb5kdc の起動時 (sudo systemctl start krb5-kdc) に Couldn't open logfile [...] というようなエラーが表示されることがある。これ、/etc/krb5.conf と /etc/krb5kdc/kdc.conf の [logging] セクションで kdc = FILE:/var/log/krb5kdc/kdc.log のような指定していて、krb5.conf と kdc.conf で指定違ってたりすると起こる模様..

jessie の krb5.conf(5) を読むとそもそも [logging] セクションの記述がないので、/etc/krb5.conf には [logging]セクションは 記述しない = 削除する のが正解だと思う。

おそらく、以前のバージョンから引き継いで使ってる場合に残っちゃったのではないだろうか。(以前導入した時に私が kdc.conf と混乱して記述しちゃった可能性もないではないが、検索すると結構あちこちで見かけるので..)




2015年4月29日水曜日

jessie: wakeonlan

jessie - systemd and wakeonlan

wheezy では /etc/network/interfaces  に ethernet-wol g とか書いておけばよかったのだが、jessie ではどうもこれがうまく効いてない。

sysvinit から systemd-networkd へ変更したのもあって、wakeonlan の設定も systemd から呼び出すことにした。

 (他に udev の方で設定することも出来るらしいが udev 設定するのは見通しわるくなるしあまり気乗りしない)

具体的には /etc/systemd/system/wol@.service というファイルを用意する


@on-jessie:~$ sudo vi /etc/systemd/system/wol@.service

/etc/systemd/system/wol@.service

[Unit]
Description=Wake-on-LAN for %i
Requires=network.target
After=network.target

[Service]
ExecStart=/sbin/ethtool -s %i wol g
Type=oneshot

[Install]
WantedBy=multi-user.target



wheezy から jessie へ dist-upgrade した環境の場合、テストするには

@on-jessie:~$ sudo systemctl restart networking.service

して
@on-jessie:~$ sudo ethtool eth0
してみる。



/sbin/ethtool コマンドがないならインストールする。
@on-jessie:~$ sudo apt-get install ethtool
使ってるネットワークインターフェイスがどのタイプのWakeOnLanをサポートしているのかは、ethtool コマンドで調べられる。

wakeonlan のタイプには p(phy),u(unicast),m(multicast),b(broadcast),a(arp),g(MagickPacket&#x2122;),s(SecureOn&tm; MagickPacket&#x2122;),d がある。

@on-jessie:~$ man ethtool

@on-jessie:~$ sudo ethtool eth0
    [...]
    Supports Wake-on: umbg
    Wake-on: g

wakaonlan パッケージや etherwake を使うと g とか s で LAN 内の特定のマシンを起動できるので便利。

また /etc/ethers に MAC とマシン名の対応、コメントを書いておくとMACではなくマシン名で呼び出せるので便利。

 追記 2015-08-24


jessie を dist-upgrade ではなく、クリーンインストールした環境では上記では不十分で、以下が必要。

テストするには、(eth0 は該当インターフェイス名、wol@.service ファイルの %i に置き換えられる)

sudo systemctl start wol@eth0.service

うまく行ったなら、

sudo systemctl enable wol@eth0.service

cf. ethers(5), https://wiki.archlinux.org/index.php/Wake-on-LAN





jessie systemd sshd ipv4 ipv6

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 が起動してしまっていたような症状に見えるが詳細は追っていないので不明.. すんません..

一部検証とばして記憶で書いてる部分があるので間違いあるかも.. すんません..