2014年6月15日日曜日

ssh できなかったので MTU を調整

サーバーに ssh しようとしたらうまく接続できなかったので調べてみました。

環境

Server/Client Ubuntu Version
ssh サーバー側 Ubuntu 14.04 Server
ssh クライアント側 Ubuntu 14.04 日本語 Remix

ssh できない事象

ssh クライアントから ssh サーバーに接続できません。

v オプションを付けて ssh しようとすると、以下のように 「 debug1: expecting SSH2_MSG_KEX_ECDH_REPLY 」で止まっています。

$ ssh -v SshServer
... snip ...
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5-etm@openssh.com none
debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY

いろいろググると MTU が関係している場合もあるようです。今回の環境ではサーバー側にファイヤーウォールがあったり、クライアント側は (多分) PPPoE の光回線だったりするので MTU が原因であることは十分に考えられます。

クライアント側 MTU の調整

MTU の値を確認してみます。
$ ifconfig wlan0 | grep MTU
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1

クライアント側は無線 LAN なのでインタフェースは wlan0 です。MTU は通常の 1500 でした。

試しに MTU をずっと小さな値 (1000) にしてみました。
$ sudo ifconfig wlan0 mtu 1000

$ ifconfig wlan0 | grep MTU
          UP BROADCAST RUNNING MULTICAST  MTU:1000  メトリック:1

この MTU だと ssh できました。

MTU が原因だとわかったので、最適な MTU 値を探ります。

まず、MTU を 1500 に戻します。
$ sudo ifconfig wlan0 mtu 1500

$ ifconfig wlan0 | grep MTU
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
データサイズを MTU と同じ 1500 バイトにしてフラグメント禁止の ping を google.com に打ってみます。
$ ping -c 1 -M do -s 1500 google.com
PING google.com (173.194.38.36) 1500(1528) bytes of data.
ping: local error: Message too long, mtu=1500

--- google.com ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

ping は失敗しました。

PING google.com (173.194.38.36) 1500(1528) bytes of data. 」のメッセージより、ping データサイズを 1500 バイトにすると IP パケットサイズが 1528 バイトとなり、オーバーヘッドは 1528 - 1500 = 28 バイトだとわかりました。

ping: local error: Message too long, mtu=1500 」のメッセージより、クライアント PC のインターフェースからパケットを出せていないことがわかります。

これは MTU が 1500 なのに、それ以上の 1528 バイトのフラグメント禁止 IP パケットを送出しようとしたことが原因です。

パケットサイズが 1500 バイトになるようにフラグメント禁止の ping を打ってみます。

オーバーヘッドが 28バイトなので、ping のデータサイズは 1500 - 28 = 1472 バイトです。

$ ping -c 1 -M do -s 1472 google.com
PING google.com (173.194.38.40) 1472(1500) bytes of data.
From XXX.XXX.XXX.XXX icmp_seq=1 Frag needed and DF set (mtu = 1454)

--- google.com ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

これも ping は失敗しました。

From XXX.XXX.XXX.XXX icmp_seq=1 Frag needed and DF set (mtu = 1454) 」のメッセージより XXX.XXX.XXX.XXX (クライアント側の光回線のブロードバンドルーターの IP アドレスです。) での MTU が 1454 で、この箇所でひっかかっていることがわかりました。

パケットサイズが 1454 バイトになるようにフラグメント禁止の ping を打ってみます。

ping のデータサイズは 1454 - 28 = 1426 バイトです。

$ ping -c 1 -M do -s 1426 google.com
PING google.com (173.194.38.46) 1426(1454) bytes of data.
1434 bytes from kix01s04-in-f14.1e100.net (173.194.38.46): icmp_seq=1 ttl=55 time=5.31 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.319/5.319/5.319/0.000 ms

ping は成功しました。クライアント PC の wlan0 の MTU 最適値は 1454 であることがわかりました。

クライアント PC の wlan0 の MTU 値を 1454 に設定します。

これまでは ifconfig コマンドで MTU 値を設定していましたが、PC を再起動すると 初期値の 1500 に戻ってしまいます。

PC を再起動しても MTU の値が 1454 となるように以下の内容の /etc/network/if-up.d/mtu を設置します。

#!/bin/sh

/sbin/ifconfig wlan0 mtu 1454

このファイルに実行権を付けます。

$ sudo chmod +x /etc/network/if-up.d/mtu

PC を再起動して、wlan0 の MTU が 1454 になったことを確認します。

しかし、まだサーバーに ssh できません。最初と同様に「 debug1: expecting SSH2_MSG_KEX_ECDH_REPLY 」の部分で止まったままです。

サーバー側 MTU の調整

クライアント側と同様に MTU の値を調査すると最適値は 1318 でしたのでこの値に変更しました。

これで無事、クライアント PC からサーバーに ssh できるようになりました。

今回のケースではサーバー側の MTU を変更するだけで ssh できるようになったのかもしれませんが、一応クライアント側の MTU も最適な値のままにしておきました。


0 件のコメント:

コメントを投稿