介绍
这是我们的SSH故障排除文章系列的延续 。
第一篇文章将帮助您确定何时解决问题,而不是迁移或重新部署问题,并为您需要有效地进行故障排除的信息提供资源。 本系列的其他部分包括如何识别和解决特定的SSH错误,并分解您需要调试成功的SSH连接的哪个阶段 :
- SSH连接故障排除 ,这是本教程。 这会处理诸如连接被拒绝或超时的错误。
- 这包括客户端突然被丢弃或关闭,客户端抱怨密码协商,或与未知或更改的远程主机的问题。
- SSH 验证故障排除 这包括密码认证或SSH密钥认证拒绝的问题。
- 解决SSH Shell环境 。 这包括无法分割进程,系统报告它不是有效的shell或到达主目录的问题。
将SSH客户端连接到SSH服务器时,必须正确建立基本的网络连接。 本教程将介绍如何确定一些常见情况,这些情况将会导致此过程中的这一点出现问题,如何解决这些情况以及额外的资源以防止将来
先决条件
要解决SSH连接问题,您需要确保您的Droplet正常从Web控制台正常响应,并使用正常的网络配置。 您可以通过遵循如何和什么时候解决SSH问题教程来执行此操作 。
在对SSH进行故障排除之前,您应该始终检查云计算面板,以了解影响您的Droplet的区域,管理程序状态以及通过Web控制台的Droplet状态的持续问题 。
错误
以下是您可能遇到的常见SSH连接错误。
主机名解析
当对SSH主机的引用无法映射到网络地址时,会出现大多数解决方案错误。 虽然这几乎与DNS相关,但根本原因并不总是DNS问题。
在OpenSSH客户端中,像ssh user@example.com
这样的命令可能会导致类似于
Error outputssh: Could not resolve hostname example.com: Name or service not known
在PuTTY中,您可能会看到与文本类似的错误对话框:
PuTTY error outputUnable to open connection to example.com Host does not exist
以下是您可以采取的一些步骤来解决此错误。
- 验证主机名是否正确拼写。 印刷错误可随时发生。
- 验证您可以使用系统
ping
命令来解析客户端计算机上的主机名。 使用第三方网站(如WhatsMyDns.net)检查超出您自己的DNS缓存也可以帮助确认结果。
如果您在任何级别遇到DNS解决问题,也可以使用Droplet IP地址作为临时解决方案,如ssh user@111.111.111.111
而不是ssh user@example.com
。
以下教程是开始制定DNS配置错误的好资源:
连接超时
连接超时表示客户端尝试向SSH服务器建立网络套接字,但服务器在超时时间内无法响应。
在OpenSSH客户端中,像ssh user@111.111.111.111
这样的命令可能会导致类似于
Error outputssh: connect to host 111.111.111.111 port 22: Connection timed out
在PuTTY中,您可能会看到与文本类似的错误对话框:
PuTTY error output Network error: Connection timed out
以下是您可以采取的一些步骤来解决此错误。
- 验证主机IP地址对于Droplet是否正确。
- 验证您的网络是否支持通过正在使用的SSH端口的连接。 某些公共网络可能会阻塞端口
22
或自定义SSH端口。 您可以通过例如使用与已知工作的SSH服务器相同的端口测试其他主机来实现。 这可以帮助您确定问题不是特定于您的Droplet。 - 验证Droplet防火墙规则 。 检查它们是否未设置为DROP的默认策略, 并且未添加端口以允许连接。
拒绝连接
被拒绝的连接与超时有一些微妙的区别。 这意味着请求被路由到SSH主机,但是主机没有成功接受该请求。
在OpenSSH客户端中,像ssh user@111.111.111.111
这样的命令可能会导致类似于
Error outputssh: connect to host 111.111.111.111 port 22: Connection refused
在PuTTY中,您可能会看到与文本类似的错误对话框:
PuTTY error outputNetwork error: Connection refused
在这种情况下,您可能会遇到与连接超时错误相同的根问题,但还有一些额外的事情您可能要检查。
- 验证主机IP地址对于Droplet是否正确。
- 验证您的网络是否支持通过正在使用的SSH端口的连接。 某些公共网络可能会阻塞端口
22
或自定义SSH端口。 您可以通过例如使用与已知工作的SSH服务器相同的端口测试其他主机来实现。 这可以帮助您确定问题不是特定于您的Droplet。 - 验证Droplet防火墙规则 。 检查它们是否未设置为DROP的默认策略, 并且未添加端口以允许连接。
- 验证该服务当前正在运行并绑定到预期端口 。
解决方案
以下是常见SSH连接错误的一些故障排除方法和解决方案。
检查你的防火墙
一些连接问题可能由防火墙配置引起。 如果您的防火墙设置为阻止某些端口或服务,则可能会禁止您连接。 你可以在这里了解防火墙什么是防火墙,它是如何工作的? 教程。
对于您的系统的任何防火墙,您需要熟悉如何修改其规则。 Ubuntu服务器通常运行UFW ; CentOS服务器经常使用FirewallD 。 如果你还没有使用,那就像你使用iptables一样 。 您还需要知道您的SSH服务正在使用哪个端口。 默认情况下,它是22
,但您可以按照下面的检查SSH服务端口部分找出。
对于不运行UFW或FirewallD的Linux系统,请使用带有sudo
或root用户的iptables
命令列出防火墙规则。
iptables -nL
以下输出将指示没有阻止SSH流量的规则:
OutputChain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
如果您看到规则或默认策略为REJECT
或DROP
,则应确保INPUT
链允许您的SSH服务正在运行的端口,默认值为22
。
对于FirewallD用户,请使用firewall-cmd
命令列出服务:
firewall-cmd --list-services
输出应显示服务列表,包括SSH(默认端口22
),以指示防火墙支持SSH流量:
Outputdhcpv6-client http ssh
如果您使用自定义端口进行SSH,则可以使用--list-ports
选项进行检查。 如果创建了自定义服务定义,则应该仍然通过--list-services
看到SSH。
最后,使用UFW的用户应该使用ufw status
来检查防火墙:
ufw status
输出类似地显示可用的端口:
OutputStatus: active
To Action From
-- ------ ----
22 LIMIT Anywhere
443 ALLOW Anywhere
80 ALLOW Anywhere
Anywhere ALLOW 192.168.0.0
22 (v6) LIMIT Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
确保您的SSH端口在列表中。
检查SSH服务状态
如果您不能SSH到您的Droplet,您应该检查SSH服务是否正在运行。 如何做到这一点取决于您的Dropet正在运行的操作系统。 在较旧的操作系统版本(如Ubuntu 14.04,CentOS 6或Debian 8)上,这将使用service
命令。 在使用Systemd的更现代化的分发版上,将使用systemctl
命令。
验证服务实际运行可能因系统而异。 在较旧的操作系统版本(Ubuntu 14及更低版本,CentOS 6,Debian 6)上,可能会使用Upstart支持的service
命令,而在使用systemd的更现代发行版上,您将使用systemctl
命令来管理该服务。
注意:基于Red Hat的发行版(例如CentOS和Fedora)在Debian和Ubuntu称之为ssh
时调用服务sshd
。
对于在Ubuntu 14.04上使用service
命令的系统,您可以使用此命令检查SSH进程的状态(以root身份运行或以sudo
运行):
service ssh status
如果进程按预期运行,您将看到包含PID(进程ID)的输出:
Output (running)ssh start/running, process 1262
如果没有运行,您会看到输出指示进程停止:
Output (not running)ssh stop/waiting
同样,在使用SystemD(如CentOS 7)的服务器上,使用systemctl
命令查看状态:
systemctl status sshd
正在运行的服务会显示这样的输出。 请注意主动线。
Output (running)sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: active (running) since Mon 2017-03-20 11:00:22 EDT; 1 months 1 days ago
Process: 899 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
Main PID: 906 (sshd)
CGroup: /system.slice/sshd.service
├─ 906 /usr/sbin/sshd -D
├─26941 sshd: [accepted]
└─26942 sshd: [net]
如果服务没有运行,您将看到该行上的“ 不活动 ”,然后是该服务的最近日记帐分录。
Output (not running)sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: inactive (dead) since Fri 2017-04-21 08:36:13 EDT; 2s ago
Process: 906 ExecStart=/usr/sbin/sshd -D $OPTIONS (code=exited, status=0/SUCCESS)
Process: 899 ExecStartPre=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
Main PID: 906 (code=exited, status=0/SUCCESS)
如果在两种情况下都不运行该服务,则可以使用service ssh start
或systemctl start sshd
来重新启动它。
检查SSH服务端口
检查SSH服务正在运行的端口有两种一般方法。 一个是检查SSH配置文件,另一个是检查正在运行的进程。
在大多数系统上,SSH配置文件是/etc/ssh/sshd_config
。 默认端口为22
,但可以通过此文件中的任何配置行覆盖,指定具有数字的Port
指令。
您可以使用grep搜索这样的行:
grep Port /etc/ssh/sshd_config
你会看到这样的输出端口号:
OutputPort 22
如果您知道服务正在运行 ,您可以使用ss
(使用sudo
运行或以root用户身份)确认服务正在预期端口上运行。 netstat -plnt
命令也提供类似的输出,但ss
是查询内核套接字信息的首选命令。
ss -plnt
您要查找的输出应引用在配置端口上监听的程序名。 例如,该输出显示SSH服务正在监听端口22`上的所有接口*
。
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:* users:(("sshd",pid=1493,fd=3))
LISTEN 0 128 :::22 :::* users:(("sshd",pid=1493,fd=4))
接口引用*
和0.0.0.0
表示Droplet上的所有接口。 127.0.0.1
表示该服务不可公开访问。 相关的sshd_config
指令是ListenAddress
,应该注释掉所有接口的默认值,或设置为Droplet的公网IP地址。
结论
如果您需要进一步帮助建立与您的Droplet上运行的SSH服务的连接,您可以向我们的支持小组打开一张机票 。 确保包括:
- 用于连接的用户名,主机和端口
- 您希望使用的身份验证机制
- 全部输出的错误链接到错误阶段,包括SSH客户端的详细输出
- 目前为止您从故障排除收集的所有信息
- 在引用这篇文章时,你不清楚什么
包括所有上述诊断信息,并澄清您在尝试连接时遇到问题的位置,可以帮助我们快速加快您在需要时遇到问题的速度。