SSH接続が遅いのはなぜ?レイテンシ問題に対する5つの即効修正
Secure Shell(SSH)接続におけるイライラするレイテンシを診断し、解消します。このガイドでは、DNSルックアップやGSSAPI認証の無効化を含む5つの即効設定修正を紹介し、スムーズな端末応答時間を回復します。暗号化の最適化や接続多重化を活用してリモート生産性を向上させる実践的な手順を学びます。
SSH接続が遅いのはなぜ?レイテンシ問題に対する5つの即効修正
SSHの遅さは一つの問題ではありません。時にはプロンプトが表示される前から遅延が発生します。ログインは速いのに、キー入力のたびに引っかかる感じがすることもあります。SSHが、遅いシェル起動スクリプト、ブロックされたDNSルックアップ、またはラップトップと世界の反対側のクラウドリージョン間でパケットをドロップするネットワークパスのせいにされることもあります。
設定を変更する前に、簡単なテストを1つ実行してください:
time ssh -vvv [email protected] exit
timeの出力は、接続全体が遅いかどうかを示します。-vvvの出力は、クライアントがどこで時間を費やしているかを示します。繰り返されるキー試行、GSSAPIメッセージ、DNS関連の一時停止、または認証開始前の長いギャップを探してください。ssh user@host exitが速いのにインタラクティブログインが遅い場合、問題はおそらくSSH自体ではなくリモートシェルの起動ファイルにあります。
よくある3つのパターン:
- 認証前の遅さ: 通常はDNS、GSSAPI、ホストキールックアップ、または遅い認証バックエンド。
- 認証後、プロンプト前の遅さ: 通常は
.bashrc、.profile、.zshrc、ネットワークマウントされたホームディレクトリ、またはシェルプラグイン。 - タイピング中やフルスクリーンツール使用時の遅さ: 通常は実際のネットワークレイテンシ、パケットロス、過負荷のエンドポイント、圧縮オーバーヘッド、または端末レンダリング。
以下の修正は、実際のSSHレイテンシの苦情を解決する頻度順に並べられています。
1. サーバーでリバースDNSルックアップを無効にする
リバースDNSは、内部ネットワークでのSSHログインが遅くなる古典的な原因です。サーバーはTCP接続を受け入れ、接続元のクライアントIPアドレスをホスト名に解決しようとします。リバースDNSが存在しない、設定が間違っている、または遅いリゾルバで処理されている場合、ログインが数秒間停止することがあります。
これはサーバー側の設定です。/etc/ssh/sshd_configに次の行を追加または更新してください:
UseDNS no
次に、テストしてSSHをリロードします:
sudo sshd -t
sudo systemctl reload sshd
一部のディストリビューションでは、サービス名としてsshを使用します:
sudo systemctl reload ssh
新しいログインをテストしている間は、既存のセッションを開いたままにしておいてください。新しいログインが速ければ、遅延の原因が見つかりました。何も変わらなければ、環境に合っている場合は設定をそのままにしておきますが、トラブルシューティングを続けてください。
2. Kerberosを使用しない場合はGSSAPIを無効にする
GSSAPIはKerberosベースの環境では便利です。それ以外の環境では、不要な認証試行が追加される可能性があります。症状は通常、公開鍵認証が続行される前に接続設定中に一時停止が発生することです。
ローカルの~/.ssh/configにこれを設定します:
Host *
GSSAPIAuthentication no
遅延が1つのサーバーでのみ発生する場合は、そのホストに設定を限定します:
Host legacy-admin
HostName legacy-admin.example.com
User admin
GSSAPIAuthentication no
ssh -vvv legacy-adminを実行し、前後を比較してください。クライアントがGSSAPIをスキップし、直接公開鍵またはパスワード認証に進むのが確認できるはずです。
3. 間違ったキーを提供するのをやめる
SSHエージェントに多数のキーが保持されている場合、クライアントはサーバーが受け入れるキーに到達するまでに複数のIDを提供する可能性があります。これは必要以上に遅く、一部のサーバーは失敗した提供が多すぎるとログインを拒否します。
詳細出力でこれが明らかになります:
debug1: Offering public key: /Users/me/.ssh/id_personal
debug1: Authentications that can continue: publickey
debug1: Offering public key: /Users/me/.ssh/id_old_vendor
debug1: Authentications that can continue: publickey
debug1: Offering public key: /Users/me/.ssh/id_prod
正しいIDを固定します:
Host prod-api
HostName 203.0.113.20
User deploy
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes
IdentitiesOnly yesが重要です。これがないと、クライアントは設定されたファイルの前または一緒にエージェントキーを提供する可能性があります。
エージェントがロードしているものを確認することもできます:
ssh-add -l
リストが乱雑な場合は、エージェントから古いキーを削除し、現在の作業に必要なものだけを追加します:
ssh-add -D
ssh-add ~/.ssh/id_ed25519_prod
4. 圧縮は役立つ場合にのみ使用する
圧縮は万能の速度スイッチではありません。帯域幅が制約されていてデータが圧縮可能な場合、例えば遅いVPN経由の長いテキストログなどでは役立ちます。高速ネットワークでは、両側がデータを圧縮・解凍するためにCPUを消費し、本来ならすぐにワイヤを通過するはずのデータに悪影響を与える可能性があります。
狭い範囲で使用します:
Host distant-bastion
HostName bastion.example.net
User ops
Compression yes
日常の接続に役立つと測定しない限り、グローバルに有効にしないでください。通常のクラウドからラップトップへのSSHでは、デフォルトの方が良いことが多いです。
タイピングが遅い場合、圧縮が最初の修正になることはほとんどありません。ネットワークパスをテストします:
ping server.example.com
mtr server.example.com
高いレイテンシやパケットロスが見られる場合、SSH設定でできることは限られています。より近い踏み台を経由するか、VPNパスを修正するか、オペレーターに近いリージョンを使用してください。
5. 多重化で接続を再利用する
最初のSSH接続に数秒かかるが、新しい端末タブごとにそのコストが繰り返される場合、接続多重化がクリーンな修正です。SSHは1つの制御接続を開いたままにし、同じユーザー、ホスト、ポートへの後続のセッションでそれを再利用します。
~/.ssh/configにこれを追加します:
Host *
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%r@%h:%p
ControlPersist 10m
ソケットディレクトリを作成します:
mkdir -p ~/.ssh/controlmasters
chmod 700 ~/.ssh/controlmasters
最初の接続は通常のハンドシェイクと認証コストを支払います。次の接続はほぼ瞬時に感じられるはずです。
ネットワーク変更後に多重化された接続がスタックした場合は、マスターソケットを閉じます:
ssh -O exit [email protected]
または、~/.ssh/controlmastersから該当するソケットを削除します。
SSHを非難する前にシェル起動を確認する
これは見逃しがちです。SSHは素早く認証しても、シェルの起動ファイルがプロンプトが表示される前に数秒を消費することがあります。
これらを比較します:
time ssh [email protected] true
time ssh [email protected] 'bash --noprofile --norc -i -c exit'
次に、.bashrc、.bash_profile、.profile、.zshrc、およびそれらがソースするものを調べます。よくある遅延の原因には、大規模なディレクトリでGitコマンドを実行するプロンプトテーマ、リモートAPIに問い合わせるkubectlやクラウドCLIの補完、パッケージマネージャーの初期化、ブロックされたNFSホームディレクトリ、ログイン時に内部サービスを呼び出すスクリプトなどがあります。
最も速いSSH修正は、実際に確認できる一時停止に一致するものです。-vvvを使用し、一度に1つずつ変更し、現在のセッションを開いたままにして別の端末からテストしてください。