kex_exchange_identification: read: Connection reset by peer エラーの解決方法
問題の概要
SSHまたはSCP接続時に以下のエラーが発生する場合があります:
kex_exchange_identification: read: Connection reset by peer
Connection reset by x.x.x.x port 22
lost connection
このエラーは、SSHクライアントがサーバーとの暗号化鍵交換プロトコル(KEX)の初期段階で、接続がリセットされたことを示しています。
主な原因
このエラーには様々な原因が考えられます:
- ファイアウォールまたはネットワークの問題
- SSHサーバー設定の誤り
- サーバー側のリソース問題
- クライアント側の設定問題
- ネットワークルーティングの問題
解決策
1. サーバー側の確認
SSHサービスとプロセスの確認
サーバーにアクセス可能な場合、SSHサービスを再起動します:
# SSHサービスのステータス確認
sudo systemctl status sshd
# SSHサービスの再起動
sudo systemctl restart sshd
リスニングポートの確認
サーバーでSSHポートが正しくリッスンされているか確認します:
# ポート22のリスニング状態を確認
sudo netstat -tlnp | grep :22
# または ss コマンドを使用
sudo ss -tlnp | grep :22
ファイアウォール設定の確認
# UFW (Ubuntu)
sudo ufw status
sudo ufw allow ssh
# firewalld (CentOS/RHEL)
sudo firewall-cmd --list-all
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
# iptables
sudo iptables -L
2. クライアント側の確認
詳細デバッグモードでの接続試行
ssh -vvv user@server_ip
-vvv
オプションで詳細なデバッグ情報が表示され、問題の特定に役立ちます。
3. 一般的な解決方法
ルーティングテーブルの確認
クライアント側でルーティングテーブルに問題がある場合があります:
# ルーティングテーブルの確認
route -n
# 問題のあるルートを削除(例)
sudo route del 192.168.50.0/24 via 192.168.50.1
hosts.allow/hosts.deny の確認
サーバー側でホストベースのアクセス制限が原因の場合:
# 設定ファイルの確認
cat /etc/hosts.allow
cat /etc/hosts.deny
# 必要に応じて編集(すべてのホストを許可する例)
echo "sshd: ALL" | sudo tee -a /etc/hosts.allow
DNS設定の確認
DNS解決の問題が原因の場合、DNSサーバーを変更してみます:
# 一時的なDNS変更(Google Public DNS)
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 8.8.4.4" | sudo tee -a /etc/resolv.conf
4. 特定の環境での対応
GitLab CI/CD パイプラインでの問題
元の質問のようにGitLabパイプラインで問題が発生する場合:
# .gitlab-ci.yml の例
deploy:
before_script:
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_rsa
- ssh-keyscan -H $SERVER_IP >> ~/.ssh/known_hosts
script:
- scp -o ConnectTimeout=30 -o StrictHostKeyChecking=no api.yml user@$SERVER_IP:/path/
WARNING
SSH鍵のパーミッションは必ず600に設定してください。777などの広いパーミッションだとSSHが鍵を無視することがあります。
特定のOSバージョン間の互換性問題
クライアントとサーバーでSSHバージョンに互換性問題がある場合:
# クライアント側で古い暗号化方式を試す
ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 user@server_ip
サーバーログの確認
サーバーにアクセス可能な場合、認証ログを確認します:
# Ubuntu/Debian
tail -f /var/log/auth.log
# CentOS/RHEL
tail -f /var/log/secure
# 特定のIPからの接続試行をフィルタリング
grep "123.456.789.0" /var/log/auth.log
ネットワーク診断
接続の問題を診断するためのコマンド:
# ポートが開放されているか確認
telnet server_ip 22
# または nc コマンド
nc -zv server_ip 22
# パケットキャプチャ(サーバー側)
sudo tcpdump -i any port 22 -n
まとめ
kex_exchange_identification: read: Connection reset by peer
エラーは多岐にわたる原因が考えられます。系統立った診断アプローチが重要です:
- サーバー側のSSHサービス状態を確認
- ファイアウォールとネットワーク設定を確認
- クライアント側の設定とネットワーク接続を確認
- サーバーログを詳細に調査
どの解決策も効果がない場合は、サーバーの再起動やSSHの再インストールを検討してください。
INFO
このエラーはSSH接続のごく初期段階で発生するため、通常はサーバー側の問題であることが多いですが、クライアント側のネットワーク設定やファイアウォールが原因の場合もあります。