つらみの分解:「たまに失敗」が難しい理由
つらみ1:間欠タイムアウトを認証のせいにする。デュアルスタックでは同一ホスト名に対しIPv6を先に試し、失敗したらIPv4へ戻る、あるいはその逆が起きます。経路の片側が黒穴化するとTCP握手で止まるように見えますが、authorized_keysとは無関係です。
つらみ2:DNSのsplit horizon。社内と社外でA/AAAAの答えが変わると、VPNの内外で「同じ名前」が別の待受へ向きます。リモートMacのsshdログでは送信元のスタックが切り替わり、known_hostsの期待とズレます。
つらみ3:FWが半分だけ。22/tcpと書いてもIPv4とIPv6は別扱いです。セキュリティグループがIPv4だけだとIPv6は静かに落ち、「たまに転送できる」症状になります。
つらみ4:CGNATとキュー。IPv4がCGNATでIPv6が直結のとき、並列とkeepaliveを見ないままだと、遅延が鍵問題に見えます。
脅威モデルと観測指標:ネット層とセッション層を分ける
観測は次の4点に分けるのが扱いやすいです。DNSのA/AAAA、TCPのRTT、SSHの鍵交換時間、SFTPサブシステムの最初の遅延です。リモートMac側のログ抽出条件は、FWカウンタと同じセッションで突き合わせます。Tailscale/Headscaleがあるなら、まず「プライベートIPだけ到達可能」へ寄せ、ListenAddressを単純化します。
数値で終わらせる:感覚ではなく分布で語る
大陸間ではv4とv6でRTTが20〜80ms違うことは珍しくありません。Happy Eyeballsの並列試行は数百ms〜数秒の待ちを足します。ConnectTimeoutとServerAliveIntervalを基線化し、異常はDNS変更や経路と先に照合します。CI側でIPv4 NAT出口が揺れるなら、TCP到達を先に固め、MaxAuthTries議論はその後に回します。
判断表:IPv4のみ、IPv6のみ、デュアルスタック
| 状況 | 優先策 | 得るもの | 注意 |
|---|---|---|---|
| AAAAのみ公開 | クライアントAddressFamily inet6、サーバはv6待受+v6FW | 経路が単純 | 古いクライアントは踏み台が必要 |
| デュアルだがv6が不安定 | 対象ホストだけinet固定や別名分割 | 成熟経路へ固定 | 将来のAAAA移行と衝突し得る |
| 公網と私網の両方がある | 本番は私網やmesh、公網は運用のみ | 攻撃面が小さい | DNSと経路設計が増える |
| CIと人間が同居 | アカウントやポート、方針を分ける | デバッグがCI制限を踏まない | 監視が増える |
手順:解決から待受、FWまで(How-to)
# 1) DNS:AとAAAAが同時に返るか(例の名前に置換)
# dig +short A your.remote.mac.example
# dig +short AAAA your.remote.mac.example
# 2) クライアント:IPv4固定の例
# Host rm-prod
# HostName your.remote.mac.example
# AddressFamily inet
# ServerAliveInterval 30
# ServerAliveCountMax 6
# 3) クライアント:IPv6のみ
# Host rm-prod-v6
# HostName your.remote.mac.example
# AddressFamily inet6
# 4) サーバ:sshdの待受確認
# sudo sshd -T | egrep 'listenaddress|addressfamily|port'
# 5) ポート到達の素早い確認(v4とv6で別マシンから)
# nc -vz <host> 22
# nc -6vz <host-v6> 22
手順1:変更窓でDNSを凍結し、TTLと権威を記録します。
手順2:人間用とCI用でHost別名を分け、CIはUserKnownHostsFile方針を固定します。known_hosts固定の型を流用します。
手順3:ListenAddressが::を含むか、IPv4だけになっていないか確認します。
手順4:IPv4とIPv6でFWルールを分け、ヒットが片側ゼロならネットを先に疑います。
手順5:並列SFTPとMaxSessions、ClientAliveIntervalを同じ負荷試験に載せます。
読む順番・FAQ・SFTPMACのホスト型リモートMacへ
順番の例:本文→known_hosts→並列→試行回数→ProxyJump→トップ。
社内でAAAAを消してよいですか
恒久対策としては非推奨です。Hostを分け、AddressFamilyを文書化し、各自のhosts改変で分岐させない方が安全です。
macOSとLinux CIで挙動が違う
OpenSSHの版と設定の読み込み順を揃え、CIではssh -G出力を基線化します。差は多くの場合、解決と既定スタックにあります。
rsyncにも効きますか
-e sshなら同じです。Runbookを共有します。
まとめ:「pingできる」と「安定転送」は別で、DNS・スタック・待受・FWを揃えると認証の迷子が減ります。
限界:事業者DNSや社内DNSのAAAA変更は静かに症状を戻します。
対比:SFTPMACのホスト型リモートMacは、待受と転送運用を製品として揃えやすく、半端なデュアルスタック調査に時間を取られにくい進め方になります。
スタックとknown_hostsを同じRunbookに置き、回帰を短く保ちます。
