解决 OpenSSH - “ Error: Connection closed by server with exitcode 128 ” 错误

昨晚,使用 FileZilla 的 SFTP 连接 Ubuntu Server 10.10 时碰到一个诡异错误:

状态:	正在连接 10.1.13.69...
响应:	fzSftp started
命令:	keyfile "E:\key\Bert_id_rsa.ppk"
命令:	open "[email protected]" 22
状态:	Connected to 10.1.13.69
错误:	Connection closed by server with exitcode 128
错误:	无法连接到服务器
 

而使用 Putty 连接就没有问题,使用相同的 key 文件。这说明问题不是出现公钥密码及主机验证上,即 SSH 连接没有问题。


根据错误提示:Connection closed by server with exitcode 128 。其中 128 表示传入了无效参数,参考自 ”Exit Codes With Special Meanings “。在 OpenSSH FAQ 上没有找到答案,然后在其 FileZilla Forums 上找到一篇相关文章 ”Connection closed by server with exitcode 128 “。该文章提示使用”调试“模式运行,以便输出更多有价值错误信息。于是根据 “Logging in FileZilla ” 提示设置 Filezilla Client,日志输出如下:

 

状态:	正在连接 10.1.13.69...
追踪:	Going to execute "F:\FileZilla FTP Client\fzsftp.exe"
响应:	fzSftp started
追踪:	CSftpControlSocket::ConnectParseResponse(fzSftp started)
追踪:	CSftpControlSocket::SendNextCommand()
追踪:	CSftpControlSocket::ConnectSend()
命令:	keyfile "E:\key\Bert_id_rsa.ppk"
追踪:	CSftpControlSocket::ConnectParseResponse()
追踪:	CSftpControlSocket::SendNextCommand()
追踪:	CSftpControlSocket::ConnectSend()
命令:	open "[email protected]" 22
追踪:	Looking up host "10.1.13.69"
追踪:	Connecting to 10.1.13.69 port 22
追踪:	Server version: SSH-2.0-OpenSSH_5.5p1 Debian-4ubuntu4
追踪:	Using SSH protocol version 2
追踪:	We claim version: SSH-2.0-PuTTY_Local:_May_22_2011_19:21:03
追踪:	Doing Diffie-Hellman group exchange
追踪:	Doing Diffie-Hellman key exchange with hash SHA-256
追踪:	Host key fingerprint is:
追踪:	ssh-rsa 2048 6c:df:ef:0b:98:1b:7f:cb:77:23:3d:c0:ac:29:9d:fd
追踪:	Initialised AES-256 SDCTR client->server encryption
追踪:	Initialised HMAC-SHA1 client->server MAC algorithm
追踪:	Initialised AES-256 SDCTR server->client encryption
追踪:	Initialised HMAC-SHA1 server->client MAC algorithm
追踪:	Pageant is running. Requesting keys.
追踪:	Pageant has 1 SSH-2 keys
追踪:	Successfully loaded 1 key pair from file
追踪:	Trying Pageant key #0
追踪:	Key matched loaded keyfile, remove duplicate
追踪:	Sending Pageant's response
追踪:	Access granted
追踪:	Opened channel for session
追踪:	Started a shell/command
状态:	Connected to 10.1.13.69
追踪:	Server exited on signal "PIPE"
错误:	Connection closed by server with exitcode 128
追踪:	CControlSocket::DoClose(64)
追踪:	CSftpControlSocket::ResetOperation(66)
追踪:	CControlSocket::ResetOperation(66)
错误:	无法连接到服务器
 

上面日志信息的关键部分:

追踪:    Server exited on signal "PIPE"
错误:    Connection closed by server with exitcode 128

 

遗憾的是,由于自己对 Linux 系统不太熟悉,还是没有解决问题。只能接着该文继续顺藤摸瓜了。


接下来,查看服务器那边的日志记录,看能否找到些关键线索。通过在 Ubuntu Documentation 上搜索 OpenSSH Server log file 找到 "OpenSSH Configuring ",知道其日志记录文件为 /var/log/auth.log 。该问题的相关日志信息如下:

Jul 24 10:39:22 tdmaster sshd[2096]: Accepted publickey for tdhadoop from 10.1.13.102 port 2740 ssh2
Jul 24 10:39:22 tdmaster sshd[2096]: pam_unix(sshd:session): session opened for user tdhadoop by (uid=0)
Jul 24 10:39:22 tdmaster sshd[2109]: subsystem request for sftp
Jul 24 10:39:22 tdmaster sshd[2096]: pam_unix(sshd:session): session closed for user tdhadoop

 

从权限认证日志中,发现 问题根源是由于子系统请求 sftp 请求导致 session 关闭。 同时,上述日志信息也验证了先前的推断:publickey 确实是正确的。再在 Google 通过上面的错误信息:“ subsystem request for sftp session closed ” 搜索,找到” Debian User Forums - OpenSSH SFTP cannot connect “,同时通过查看 Ubuntu 的启动配置脚本文件 $HOME/.bashrc 也证明 Ubuntu Server 是基于 Debian 系统实现的。 这样, 经过大约 2.5 个小时的奋斗终于把问题给解决了。 (解决问题的时间还是太长了,不是很满意,希望以后有更大的提高。该时间很大程度上取决于找资料的时间:如果我能在最短时间内找到最有用的资料,时间自然而然地缩短了。 这也反映了我的搜索能力还差远了,需要提高很多)解决方法如下:

 

# 注意:SSH 还允许客户端传递系统 Locale 相关的环境变量给服务器
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

# 将
# Subsystem sftp /usr/lib/openssh/sftp-server
# 替换为
Subsystem sftp internal-sftp

 

但我觉得这种解决方案不是很好,修改该配置信息可能会导致系统服务器那边不能使用 sftp 传输功能(经验证,修改前后的 sftp 功能都运行正常。参考自 sftp - OpenSSH Manualsftp manual )。况且,其它服务器的同样设置都 OK。所以,我断定根源不是由此引起的。通过观察发现,每次登录这台服务器都会输出下面信息,而其它服务器则不会:

-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

 

并且从 sshd_config 配置文件可知,SSH 会接受 LC_* 环境变量,见上文。这让我猜测问题的 真正 根源 可能是 LC_ALL 设置不正确而引起的 。通过在 Ubuntu Documentation 上搜索 locale LC_ALL 找到“Environment Variables - Locale setting variables ”、“Locale - Ubuntu Documentation ”。如果设置了 LC_ALL 环境变量,它会覆盖所有 LC_* 的环境变量值。/etc/default/locale 文件内容如下:

 

LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"  # 引起该问题的根源
LANGUAGE="en_US:en"

 

而其它服务器的 locale 文件则没有设置 LC_ALL 。

接下来就是去掉该行,重启 ssh 服务。退出重新登录后,上面的 -bash 警告信息也没了。 教训:以后得注意了,警告也可能引起一些很难解决的问题,并且这些问题很难追踪。 再通过 FileZilla Client ,看能否访问该服务器?Ok,问题终于完美解决了。 这也验证了我上述的猜测。


重点参考资料

  1. FileZilla Forums - Connection closed by server with exitcode 128
  2. Debian User Forums - OpenSSH SFTP cannot connect
  3. Wiki - SSH File Transfer Protocol

 

你可能感兴趣的:(ssh,sftp,openssh,FileZilla)