1Password CLI のタイムアウトを切り分けた経緯(IPv6 の MTU 問題だった)

(最終更新: )

あるときから、1Password のコマンドラインインターフェイスである op コマンドの反応が明らかに悪くなりました。失敗する回数も増え、挙動としてはタイムアウトに近い状態です。デスクトップ版の 1Password アプリもオフラインになりがちでした。

最初に疑ったのは、1Password 側の一時的な不調や、アプリと CLI の連携問題です。しかし切り分けていくと、原因は手元の IPv6 経路、より具体的には MTU/PMTUD 周辺にありました。

環境

自宅回線は IPoE 接続で、ルーターは ASUS RT-BE18000 を使っています。

少し前に GitHub への接続が不安定だったため、ルーター側の MTU を 1460 に変更したところ、アクセスは劇的に改善しました。ただし、このとき合わせたのはルーター側だけです。Mac の Wi-Fi MTU は 1500 のままでした。

networksetup -getMTU "Wi-Fi"
Active MTU: 1500 (Current Setting: 1500)

症状

IPv4 では 1Password に問題なく接続できました。

curl -4 -sS -o /dev/null -w 'ipv4 total=%{time_total} code=%{http_code}\n' https://my.1password.com
ipv4 total=0.863744 code=200

一方で IPv6 は様子が違います。

curl -6 -sS -o /dev/null -w 'ipv6 total=%{time_total} code=%{http_code}\n' https://my.1password.com
curl: (28) SSL connection timeout
ipv6 total=300.565966 code=000

DNS の AAAA レコードは引けています。

dig AAAA my.1password.com
;; ANSWER SECTION:
my.1password.com. IN AAAA 2600:...
my.1password.com. IN AAAA 2600:...
my.1password.com. IN AAAA 2600:...

つまり、名前解決ができていないわけではありません。

さらに curl -6 -v で見ると、TCP 接続自体は成立していました。

curl -6 --connect-timeout 10 -v https://my.1password.com

抜粋するとこうです。

* Connected to my.1password.com (...) port 443
* TLS handshake, Client hello
* TLS handshake, Server hello
* TLS handshake, Client hello
* SSL connection timeout

IPv6 で完全に到達不能なのではなく、TCP 443 まではつながります。しかし TLS ハンドシェイクの途中で止まります。これは MTU や Path MTU Discovery の問題を疑う典型的なパターンです。

なぜ MTU/PMTUD を疑ったか

IPv6 では、途中のルーターがパケットを分割してくれません。送信元が経路上で通る最大サイズを学習し、そのサイズに合わせて送る必要があります。

この仕組みが Path MTU Discovery、PMTUD です。

経路上でパケットサイズが大きすぎる場合、本来は ICMPv6 の Packet Too Big によって「そのサイズでは通らない」と送信元に通知されます。ところが、この ICMPv6 がルーター、ファイアウォール、ISP 経路などで落ちると、送信元は適切なサイズを学習できません。

結果として、通信の一部だけが詰まります。今回のように、TCP 接続はできるが TLS の証明書チェーンなど大きめの応答でタイムアウトする、という見え方になります。

Mac の Wi-Fi MTU 1500 とルーターの MTU 1460 が食い違うと、小さいパケットは通って TCP 443 は確立する一方、1460 を超える応答は通れず、ICMPv6 の Packet Too Big も届かないため TLS ハンドシェイクがタイムアウトする流れを示した図
MTU の不一致で IPv6 の TLS が詰まる仕組み

Mac 側の MTU をルーターに合わせる

そこで Mac の Wi-Fi MTU も、ルーターと同じ 1460 に合わせます。

sudo networksetup -setMTU "Wi-Fi" 1460
networksetup -getMTU "Wi-Fi"

期待する表示はこうです。

Active MTU: 1460 (Current Setting: 1460)

この状態で改めて IPv6 接続を確認します。

curl -6 --connect-timeout 10 --max-time 20 -sS -o /dev/null -w 'ipv6 total=%{time_total} code=%{http_code}\n' https://my.1password.com

結果は正常でした。

ipv6 total=0.869733 code=200

curl -6 -v でも TLS ハンドシェイクが完了し、HTTP/2 のリクエストまで進みます。

* SSL connection using TLSv1.3
* ALPN: server accepted h2
* SSL certificate verify ok.
* using HTTP/2

遅くなっていた op コマンドも、ひとまず応答するようになりました。

今回の結論

今回の原因は、1Password 側の障害ではなく、手元の IPv6 経路における MTU/PMTUD 問題でした。

整理するとこうです。

ルーター MTU: 1460
Mac Wi-Fi MTU: 1500
=> 1Password の IPv6 TLS が timeout

ルーター MTU: 1460
Mac Wi-Fi MTU: 1460
=> curl -6 https://my.1password.com が 0.87s / 200
=> op も応答復帰

ルーターだけ MTU を変更しても、クライアント側が 1500 のままだと、IPv6 では中途半端な壊れ方をします。特に PMTUD がうまく働かない環境では、TLS の途中で詰まる症状として表面化します。

ここまでの切り分けは、IPv4 と IPv6 を分けた比較、TLS ハンドシェイクが止まる位置の確認、MTU を揃える前後での再現確認という手順を踏んでいます。その範囲では、症状は一貫して MTU の不一致と対応していました。

ただし、経路上のどの機器で ICMPv6 が落ちていたかまでは特定していません。そのため、MTU/PMTUD が原因だと断定できたというより、手元で確認できた範囲では MTU を揃えたことで再現しなくなった、という言い方が実態に近いと考えています。同じ症状でも、別の要因が重なっている環境はあり得ます。

使った確認コマンド

IPv4 と IPv6 の差を見るには、まずこれが分かりやすいです。

curl -4 -sS -o /dev/null -w 'ipv4 total=%{time_total} code=%{http_code}\n' https://my.1password.com
curl -6 -sS -o /dev/null -w 'ipv6 total=%{time_total} code=%{http_code}\n' https://my.1password.com

IPv6 の TLS ハンドシェイクがどこで止まるかを見るには:

curl -6 --connect-timeout 10 --max-time 20 -v https://my.1password.com

Mac のネットワークサービス名を確認するには:

networksetup -listallnetworkservices

Wi-Fi の MTU を確認するには:

networksetup -getMTU "Wi-Fi"

Wi-Fi の MTU を変更するには:

sudo networksetup -setMTU "Wi-Fi" 1460

元が 1500 だった場合に戻すには:

sudo networksetup -setMTU "Wi-Fi" 1500

補足: automatic は使えなかった

macOS の networksetup では、環境によって MTU の automatic 指定が使えることがあります。しかし今回の環境では使えませんでした。

sudo networksetup -setMTU "Wi-Fi" automatic
Error - 0 is not in the valid MTU range of 1280-1500
** Error: The parameters were not valid.

この場合は 1460 や 1500 のように明示値で管理する必要があります。

学び

CLI ツールのタイムアウトは、ツールそのものや認証連携の問題に見えがちです。しかし今回のように、原因が IPv6 の経路にあることもあります。

特に次のような状況では、IPv4 と IPv6 を分けて確認すると切り分けが早くなります。

  • アプリが「オフライン」になりがち
  • CLI がタイムアウトする
  • ブラウザや別サービスでは一見問題がない
  • 最近 MTU を変更した
  • IPoE / IPv4 over IPv6 / VPN / 独自ルーター設定を使っている

curl -4 は通るが curl -6 が TLS の途中で止まるなら、DNS ではなく IPv6 経路、MTU、PMTUD、ICMPv6 周辺を見る価値があります。