SSH连接Linux服务器遭遇”Connection refused”:逐层解剖网络连接故障

【摘要】

“Connection refused”是Linux运维中最令人头疼的SSH连接错误之一。本文通过真实的故障排查场景,从服务状态、防火墙配置、端口监听到网络策略,提供一套完整的诊断流程和解决方案,帮助系统管理员快速恢复服务器连接。

图片[1]-SSH连接Linux服务器遭遇”Connection refused”:逐层解剖网络连接故障-Vc博客

一、故障现场:无法连接的服务器

凌晨2点,紧急告警显示应用服务器无法通过SSH连接:

# 尝试连接时的错误信息
ssh admin@192.168.1.100
# 输出:ssh: connect to host 192.168.1.100 port 22: Connection refused

这种错误意味着TCP连接到达了目标服务器,但被明确拒绝。我们需要从内到外逐层排查。

二、第一层诊断:SSH服务状态检查

1. 服务状态与进程检查

# 检查SSH服务是否运行(在目标服务器上执行)
sudo systemctl status sshd
# 或者使用旧版本命令
sudo service sshd status

# 检查SSH进程是否存在
ps aux | grep sshd
# 应该有类似输出:/usr/sbin/sshd -D

# 如果服务未运行,启动服务
sudo systemctl start sshd
sudo systemctl enable sshd  # 设置开机自启

2. 服务配置检查

# 检查SSH配置文件语法
sudo sshd -t
# 无输出表示配置正确

# 查看SSH服务监听的端口
sudo netstat -tlnp | grep ssh
# 或使用ss命令
sudo ss -tlnp | grep :22

# 期望输出:
# tcp   0   0 0.0.0.0:22   0.0.0.0:*   LISTEN   1234/sshd
# tcp6  0   0 :::22        :::*        LISTEN   1234/sshd

三、第二层诊断:防火墙与安全组策略

1. 防火墙规则检查

# 检查iptables规则(CentOS 6/7)
sudo iptables -L -n | grep :22
# 或者查看具体规则
sudo iptables -S | grep 22

# 检查firewalld(CentOS 7/8, RHEL, Fedora)
sudo firewall-cmd --list-all
# 查看ssh服务是否在允许列表中

# 检查UFW(Ubuntu/Debian)
sudo ufw status
sudo ufw app list | grep ssh

2. 防火墙规则修复

# 临时开放SSH端口(重启后失效)
# iptables版本
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# firewalld版本
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload

# UFW版本
sudo ufw allow ssh
sudo ufw reload

# 对于非标准端口(如2222):
sudo firewall-cmd --add-port=2222/tcp --permanent
sudo firewall-cmd --reload

四、第三层诊断:网络配置与端口监听

1. 监听地址检查

# 检查SSH服务监听的地址
sudo netstat -tlnp | grep sshd
# 重点关注监听地址:
# 0.0.0.0:22 - 监听所有地址 ✓
# 127.0.0.1:22 - 仅监听本地 ✗

# 如果只监听127.0.0.1,需要修改配置
sudo grep "ListenAddress" /etc/ssh/sshd_config
# 应该注释掉或设置为0.0.0.0

2. 端口冲突检测

# 检查22端口是否被其他进程占用
sudo lsof -i :22
# 或者使用
sudo netstat -tlnp | grep :22

# 如果有其他进程占用,考虑:
# 1. 停止冲突进程
# 2. 修改SSH监听端口

五、第四层诊断:SELinux与AppArmor

1. SELinux问题排查

# 检查SELinux状态
sudo sestatus
# 或者
getenforce

# 如果SELinux启用,检查相关策略
sudo sealert -a /var/log/audit/audit.log | grep ssh

# 临时禁用SELinux进行测试
sudo setenforce 0
# 永久修改需要编辑/etc/selinux/config

2. SSH端口SELinux策略

# 如果使用非标准端口,需要添加SELinux策略
# 检查当前SSH端口标签
sudo semanage port -l | grep ssh

# 添加自定义端口到SSH
sudo semanage port -a -t ssh_port_t -p tcp 2222

# 验证添加结果
sudo semanage port -l | grep ssh

六、高级诊断:网络层深度排查

1. 完整连接测试脚本

<strong>#!/bin/bash</strong>
# ssh_connection_diagnosis.sh

TARGET_HOST="$1"
SSH_PORT="${2:-22}"

echo "开始SSH连接诊断: $TARGET_HOST:$SSH_PORT"
echo "======================================"

# 1. 基础网络连通性
echo "1. 网络连通性测试:"
ping -c 3 -W 2 "$TARGET_HOST" > /dev/null <strong>2</strong>><strong>&1</strong>
if [ $? -eq 0 ]; then
    echo "   ✓ 目标主机可达"
else
    echo "   ✗ 目标主机不可达"
    exit 1
fi

# 2. 端口连通性
echo "2. 端口连通性测试:"
nc -z -w 3 "$TARGET_HOST" "$SSH_PORT"
if [ $? -eq 0 ]; then
    echo "   ✓ 端口 $SSH_PORT 可达"
else
    echo "   ✗ 端口 $SSH_PORT 不可达"
fi

# 3. 详细端口扫描
echo "3. 详细端口信息:"
nmap -p "$SSH_PORT" "$TARGET_HOST"

# 4. 路由跟踪
echo "4. 网络路径跟踪:"
traceroute -w 1 -m 15 "$TARGET_HOST" <strong>2</strong>>/dev/null || tracepath "$TARGET_HOST"

echo "======================================"
echo "诊断完成"

2. SSH客户端调试模式

# 使用详细输出模式连接
ssh -vvv user@hostname
# 这将显示详细的调试信息,包括:
# - 连接的建立过程
# - 认证方法尝试
# - 具体的错误原因

# 或者指定特定端口
ssh -p 2222 -v user@hostname

# 调试信息示例:
# debug1: Connecting to host [192.168.1.100] port 22.
# debug1: connect to address 192.168.1.100 port 22: Connection refused
# debug1: Connecting to host [192.168.1.100] port 22.

七、配置文件修复与优化

1. 关键配置项检查

# 检查SSH服务端配置
sudo grep -E "^Port|^ListenAddress|^PermitRootLogin|^PasswordAuthentication" /etc/ssh/sshd_config

# 常见问题配置:
# Port 2222                    # 使用了非标准端口
# ListenAddress 127.0.0.1      # 只监听本地
# PermitRootLogin no           # 禁止root登录
# PasswordAuthentication no    # 禁止密码认证

# 修复配置后重启服务
sudo systemctl restart sshd

2. 安全加固配置模板

# /etc/ssh/sshd_config 安全配置示例

# 基本连接设置
Port 22
ListenAddress 0.0.0.0
Protocol 2

# 认证安全
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
PermitEmptyPasswords no

# 会话设置
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3

# 重启服务应用配置
sudo systemctl restart sshd
sudo systemctl status sshd  # 验证服务状态

八、自动化修复脚本

1. 一键修复常见问题

<strong>#!/bin/bash</strong>
# ssh_fix_common_issues.sh

echo "开始修复SSH连接常见问题..."

# 1. 确保服务运行
sudo systemctl start sshd
sudo systemctl enable sshd

# 2. 检查防火墙
if command -v firewall-cmd &> /dev/null; then
    sudo firewall-cmd --add-service=ssh --permanent
    sudo firewall-cmd --reload
    echo "firewalld配置已更新"
elif command -v ufw &> /dev/null; then
    sudo ufw allow ssh
    echo "UFW配置已更新"
fi

# 3. 检查SELinux
if [ "$(getenforce <strong>2</strong>>/dev/null)" = "Enforcing" ]; then
    sudo setenforce 0
    echo "SELinux已临时禁用"
fi

# 4. 验证服务状态
echo "SSH服务状态:"
sudo systemctl status sshd --no-pager -l

# 5. 测试本地连接
echo "本地连接测试:"
ssh -o ConnectTimeout=5 -o BatchMode=yes localhost echo "本地SSH连接成功" || echo "本地SSH连接失败"

echo "修复完成"

九、预防措施与监控

1. SSH服务监控脚本

<strong>#!/bin/bash</strong>
# ssh_service_monitor.sh

HOST="localhost"
PORT="22"
ALERT_EMAIL="admin@company.com"

# 测试SSH连接
nc -z -w 3 "$HOST" "$PORT"

if [ $? -ne 0 ]; then
    # 连接失败,发送告警并尝试重启
    echo "警告: SSH服务在 $HOST:$PORT 不可用" | mail -s "SSH服务告警" "$ALERT_EMAIL"
    
    # 尝试自动恢复
    sudo systemctl restart sshd
    sleep 5
    
    # 再次检查
    nc -z -w 3 "$HOST" "$PORT"
    if [ $? -eq 0 ]; then
        echo "SSH服务已自动恢复" | mail -s "SSH服务恢复" "$ALERT_EMAIL"
    fi
fi

2. 定期健康检查

# 添加到crontab,每分钟检查一次
* * * * * /opt/scripts/ssh_service_monitor.sh > /dev/null <strong>2</strong>><strong>&1</strong>

# 每周检查配置文件和密钥
0 2 * * 0 /opt/scripts/ssh_security_audit.sh

【总结】

SSH “Connection refused”错误通常由服务未运行、防火墙阻止、配置错误或端口冲突引起。通过系统化的排查流程:检查服务状态→验证防火墙规则→确认端口监听→排查SELinux策略,可以快速定位并解决问题。建立SSH服务监控和定期健康检查机制,能够有效预防连接故障的发生。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容