Skip to content

Instantly share code, notes, and snippets.

@buzztaiki
Last active May 26, 2026 10:58
Show Gist options
  • Select an option

  • Save buzztaiki/eeccc781e96b88d011fb414ace86902d to your computer and use it in GitHub Desktop.

Select an option

Save buzztaiki/eeccc781e96b88d011fb414ace86902d to your computer and use it in GitHub Desktop.
f5vpn 接続中に az-cli が固まる問題

f5vpn 接続中に az-cli が固まる問題

f5vpn で会社の VPN つないでる時に az login (というか az 全般) が無言で固まる問題を Claude と切り分けしたメモ。

先に結論

  • f5vpn は tun0 で IPv6 default route (::/1 + 8000::/1) を吸い込む。が、tun0 自体は IPv6 GUA を持たない (link-local のみ) ので IPv6 が black hole になる。
  • curl は happy-eyeballs で IPv4 にフォールバックするから動く。az-cli (中身は Python の urllib3) は happy-eyeballs を持たないので AAAA を引いた瞬間ハングする。
  • 対策は /etc/gai.confprecedence ::ffff:0:0/96 100 のコメントアウトを外して IPv4 優先にすること。

遭遇した問題

f5vpn で VPN 接続している状態で az を叩くと固まる。

❯❯ az login --debug
...
cli.azure.cli.core.auth.binary_cache: load: /home/taiki/.azure/msal_http_cache.bin
urllib3.util.retry: Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
urllib3.connectionpool: Starting new HTTPS connection (1): login.microsoftonline.com:443

(ここで止まる)

^C
cli.__main__: Command ran in 7.562 seconds (init: 0.035, invoke: 7.527)

色々調べたやつ

最初 strace az login を取ったけど、これは間違い。/usr/bin/az はただのシェルスクリプトで、本体は /opt/azure-cli/bin/python。つまり、strace の出力は bash が wait4(-1 で子プロセスを待ってるところで止まっていて、Python 側のシステムコールが見えない。子も追うなら strace -f、もしくは az --debug をするべきだった。

DNS まわりが怪しいかなと思って resolvectl status を見た。

❯❯ resolvectl status
Global
           Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
    resolv.conf mode: stub
  Current DNS Server: 172.16.31.254
         DNS Servers: 172.16.31.254
          DNS Domain: ~.

社内 DNS が ~. で刺さってるので、全部の名前解決が VPN 経由で社内 DNS に行く構成。これは正しい。

名前解決自体は通る。

❯❯ resolvectl query login.microsoftonline.com
login.microsoftonline.com: 2603:1047:1:a0::c   -- link: tun0
                           2603:1047:1:a0::11  -- link: tun0
                           ...
                           40.126.13.9         -- link: tun0
                           20.190.141.37       -- link: tun0
                           ...

AAAA も A も両方返ってくる。

curl もそのまま叩くと普通に通る。

❯❯ curl -v --max-time 10 https://login.microsoftonline.com/
*   Trying [2603:1047:1:a0::8]:443...
*   Trying 40.126.13.9:443...
* ALPN: curl offers h2,http/1.1
...
< HTTP/2 302

ここで curl は IPv6 を試した直後に IPv4 に切り替えている事に気付く。これは happy-eyeballs

ということは、curl は気付かないだけで IPv6 は壊れているのでは? と思って -6 / -4 で確かめると、

❯❯ curl -6 -v --max-time 5 https://login.microsoftonline.com/
*   Trying [2603:1047:1:150::1]:443...
*   Trying [2603:1046:2000:148::3]:443...
...
* Connection timed out after 5001 milliseconds

❯❯ curl -4 -v --max-time 5 https://login.microsoftonline.com/
*   Trying 20.190.141.34:443...
...
< HTTP/2 302

IPv6 だけ詰む。

ip -6 routeip -6 addr show tun0 を見ると理由がわかる。

❯❯ ip -6 route
::/1 dev tun0 metric 1024 pref medium
fe80::/64 dev tun0 proto kernel metric 256 pref medium
8000::/1 dev tun0 metric 1024 pref medium

❯❯ ip -6 addr show tun0
25: tun0: <POINTOPOINT,UP,LOWER_UP> mtu 1371 ...
    inet6 fe80::8c4c:4c93:7f05:db78/64 scope link stable-privacy proto kernel_ll

::/1 + 8000::/1 の二本で IPv6 default route を全部 tun0 に吸い込んでいる (full tunnel)。なのに tun0 には link-local の IPv6 しかない。つまり f5vpn は IPv4 only な tunnel なのに IPv6 の default route まで奪っている。AAAA で返ってきた 2603:... 宛てのパケットは tun0 に入って消える → TCP timeout までハング。

curl は happy-eyeballs で見限って IPv4 に切り替えるので問題が起こらない。Python の urllib3 / requests は happy-eyeballs を持たず、getaddrinfo が返した最初のアドレス (AAAA) に直列で繋ぎに行くから、ハングしているように見える。az-cli, Azure SDK for Python に限らず Python 系の HTTP クライアントは基本的に全てこの罠を踏むはず。

解決方法

/etc/gai.conf の以下の行をコメントアウト解除する。

precedence ::ffff:0:0/96  100

これで glibc の getaddrinfo が IPv4-mapped アドレス (= IPv4) を IPv6 GUA より優先するようになって、Python が AAAA を選ばなくなる。VPN を切ってる時にも IPv6 native が使えるサイトでは IPv4 が選ばれるだけなので副作用はほぼ無い。

glibc は /etc/gai.conf.d/ はサポートしていない (man 5 gai.conf 参照)。ので、ファイル本体を直接編集する。

参考

  • man 5 gai.conf
  • man systemd-resolved.service

おわり。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment