Ubuntu 系统系列 | 第 15 天:SSH 远程管理与安全加固——密钥认证、SSH 配置、fail2ban

第 15/30 天

引言

“SSH 是通往服务器的第一道门,也是黑客最想撬开的锁。”

在 Linux 服务器管理中,SSH(Secure Shell)是最核心的远程管理工具。无论是管理一台云服务器,还是运维上百台集群,SSH 都是你与服务器之间的生命线。然而,这条生命线同时也是攻击者的首要目标——根据各大安全机构的统计,一台暴露在公网的 SSH 服务器,每天平均会遭受数百次暴力破解攻击。

今天,我们将深入 Ubuntu 的 SSH 远程管理世界,从基础安装配置到密钥认证,再到 fail2ban 入侵防御,帮你构建一套既高效又安全的远程管理方案。

一、SSH 基础:安装与首次配置

1.1 安装 OpenSSH

Ubuntu 桌面版默认不安装 SSH 服务端,但客户端通常已预装。检查并安装:

# 检查是否已安装
dpkg -l | grep openssh-server

# 安装 OpenSSH 服务端
sudo apt update
sudo apt install openssh-server -y

# 检查服务状态
sudo systemctl status ssh

输出示例:

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-07-22 08:00:00 CST
       Docs: man:sshd(8)
           man:sshd_config(5)
     Main PID: 1234 (sshd)
       Tasks: 1 (limit: 2234)
      Memory: 5.2M

1.2 SSH 配置文件结构

SSH 的核心配置文件有两个:

文件 用途 说明
/etc/ssh/sshd_config SSH 服务端配置 控制服务器端的认证、端口、权限等
/etc/ssh/ssh_config SSH 客户端配置 控制客户端的连接参数、主机别名等
~/.ssh/config 用户级客户端配置 每个用户可自定义,优先级高于全局配置

1.3 基本连接测试

# 从客户端连接服务器
ssh username@server_ip

# 指定端口(默认22)
ssh -p 2222 username@server_ip

# 启用详细输出来排查连接问题
ssh -vvv username@server_ip

二、密钥认证:告别密码登录

密码认证存在两大隐患:一是容易被暴力破解工具猜解,二是密码本身可能被中间人窃听。SSH 密钥认证使用非对称加密,从根本上解决了这些问题。

2.1 生成密钥对

# 生成 ED25519 密钥对(推荐,更安全且性能更好)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 或者使用 RSA(兼容性更好,但密钥更长)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

执行过程:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

关于密钥类型的选择:

密钥类型 位数 安全性 性能 兼容性
ED25519 256 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 良好(OpenSSH 6.5+)
RSA 4096 ⭐⭐⭐⭐ ⭐⭐⭐ 最佳(所有版本)
ECDSA 256/384/521 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 一般(需依赖椭圆曲线)

实操要点: 建议使用 ED25519,它在相同安全强度下密钥更短、生成和签名更快。如果兼容老旧的 SSH 客户端(比如某些嵌入式设备),则选择 RSA 4096。

2.2 部署公钥到服务器

# 方法一:使用 ssh-copy-id(推荐,自动处理权限)
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@server_ip

# 方法二:手动追加(当 ssh-copy-id 不可用时)
# 在客户端查看公钥
cat ~/.ssh/id_ed25519.pub

# 在服务器上追加到 authorized_keys
echo "ssh-ed25519 AAAAC3... your_email@example.com" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

2.3 使用 SSH Agent 管理密钥

当你设置了密钥的 passphrase 后,每次 SSH 连接都需要输入密码。SSH Agent 可以解决这个问题:

# 启动 SSH Agent 并添加密钥
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# 查看已添加的密钥
ssh-add -l

# 删除所有密钥
ssh-add -D

进阶技巧: 在桌面环境中,可以配置 ssh-agent 随系统自动启动。在 ~/.bashrc~/.zshrc 中添加:

# 自动启动 ssh-agent 并添加密钥
SSH_ENV="$HOME/.ssh/agent-environment"
if [ -f "$SSH_ENV" ]; then
    . "$SSH_ENV" > /dev/null
    ps -ef | grep $SSH_AGENT_PID | grep ssh-agent$ > /dev/null || {
        start_agent
    }
else
    start_agent
fi

三、SSH 服务端安全加固

这是整个 SSH 配置中最关键的部分。以下配置全部在 /etc/ssh/sshd_config 中修改,修改后执行 sudo systemctl restart ssh 生效。

3.1 禁用密码认证(关键步骤)

# 禁止密码认证,仅允许密钥登录
# 找到并修改或添加:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no

⚠️ 注意: 在执行此操作前,务必确认密钥认证已经正常工作。建议先保留一个备用 SSH 会话,防止被锁在服务器外。

3.2 更改默认端口

# 将默认的 22 端口改为自定义端口(如 2222)
Port 2222

更改端口后,客户端连接时需指定端口:

ssh -p 2222 username@server_ip

3.3 限制登录用户

# 只允许特定用户登录
AllowUsers alice bob

# 或只允许特定组登录
AllowGroups ssh-users

# 禁止 root 直接登录
PermitRootLogin no

3.4 其他安全选项

# 限制最大认证尝试次数(防止暴力破解)
MaxAuthTries 3

# 登录超时(秒)
LoginGraceTime 60

# 空闲连接超时(断开空闲连接)
ClientAliveInterval 300
ClientAliveCountMax 2

# 使用更安全的密钥交换算法
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512

# 禁用不安全的 SSH 协议版本
Protocol 2

3.5 完整的安全配置示例

将以下内容整合到一个安全的 sshd_config 中:

# 网络配置
Port 2222
ListenAddress 0.0.0.0

# 认证配置
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AuthenticationMethods publickey
MaxAuthTries 3
LoginGraceTime 60

# 会话配置
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive yes

# 用户限制
AllowUsers alice bob

# 日志配置
SyslogFacility AUTH
LogLevel VERBOSE

四、客户端配置优化

4.1 使用 ~/.ssh/config 简化连接

为常用服务器配置主机别名,让 SSH 连接像命令一样简单:

# ~/.ssh/config
Host myserver
    HostName 192.168.1.100
    Port 2222
    User alice
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

配置后,只需 ssh myserver 即可连接,不需要再输入 IP、端口、用户名等信息。

4.2 SSH 跳板机(Jump Host)

在企业环境中,通常只有跳板机(堡垒机)能直接访问生产服务器:

# 通过跳板机连接目标服务器
ssh -J jump_user@jump_host target_user@target_host

# 或在 ~/.ssh/config 中配置
Host bastion
    HostName bastion.example.com
    User jump_user

Host internal-server
    HostName 10.0.1.50
    User admin
    ProxyJump bastion

4.3 SSH 隧道和端口转发

SSH 隧道是远程运维的利器,可以安全地转发本地端口到远程服务器:

# 本地端口转发:将远程的 3306(MySQL)映射到本地 3306
ssh -L 3306:localhost:3306 user@server

# 远程端口转发:将本地的 8080 暴露到远程服务器
ssh -R 8080:localhost:8080 user@server

# 动态端口转发(SOCKS5 代理)
ssh -D 1080 user@server

五、fail2ban:暴力破解的终极防御

即使启用了密钥认证,SSH 服务端仍然会记录大量认证失败日志。fail2ban 通过分析日志文件,自动将恶意 IP 加入防火墙黑名单。

5.1 安装 fail2ban

sudo apt update
sudo apt install fail2ban -y

5.2 配置 SSH 保护规则

创建一个本地配置文件,它会覆盖默认配置:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

编辑 /etc/fail2ban/jail.local,找到 [sshd] 部分并配置:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600

参数说明:
maxretry = 5:在 findtime 时间内最多允许 5 次失败
findtime = 600:检测时间窗口(秒),即 10 分钟内
bantime = 3600:封禁时长(秒),即 1 小时

5.3 启动并验证

# 启动 fail2ban 服务
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 查看 SSH 监狱状态
sudo fail2ban-client status sshd

# 手动解除 IP 封禁(误封时使用)
sudo fail2ban-client set sshd unbanip 192.168.1.100

# 查看 fail2ban 日志
sudo tail -f /var/log/fail2ban.log

输出示例:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     156
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 7
   |- Total banned:     42
   `- Banned IP list:   185.220.101.42 103.235.46.93 ...

5.4 高级配置:永久封禁惯犯

# 对反复攻击的 IP 逐步增加封禁时间
[sshd]
enabled = true
maxretry = 5
findtime = 600
bantime = 3600
# 使用 recidive 监狱处理惯犯
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 86400
bantime = 604800  # 一周

六、实战:完整的 SSH 安全加固流程

以下是一个完整的、可落地的一键加固脚本:

#!/bin/bash
# SSH 安全加固脚本
# 使用前:确保已部署密钥认证并保留备用会话

set -euo pipefail

SSHD_CONFIG="/etc/ssh/sshd_config"
BACKUP="${SSHD_CONFIG}.backup.$(date +%Y%m%d%H%M%S)"

# 1. 备份原始配置
cp "$SSHD_CONFIG" "$BACKUP"
echo "✅ 已备份原配置到 $BACKUP"

# 2. 应用安全配置
cat > "$SSHD_CONFIG" << 'EOF'
Port 2222
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AuthenticationMethods publickey
MaxAuthTries 3
LoginGraceTime 60

AllowUsers alice
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive yes

SyslogFacility AUTH
LogLevel VERBOSE
EOF

# 3. 检查配置语法
if sshd -t; then
    systemctl restart ssh
    echo "✅ SSH 配置已更新并重启"
else
    echo "❌ SSH 配置语法错误,正在恢复备份"
    cp "$BACKUP" "$SSHD_CONFIG"
    systemctl restart ssh
    exit 1
fi

# 4. 安装并启动 fail2ban
apt install -y fail2ban
systemctl enable --now fail2ban

echo "🎉 SSH 安全加固完成!"
echo "⚠️ 重要:请保持当前 SSH 会话不要关闭,"
echo "   在新终端中测试连接 http://localhost:2222 确认正常后再退出"

七、常见问题与故障排查

7.1 连接被拒绝

ssh: connect to host server_ip port 22: Connection refused

可能原因及解决方案:
1. SSH 服务未运行:sudo systemctl start ssh
2. 端口被防火墙阻止:sudo ufw allow 2222/tcp
3. SSH 配置语法错误:sudo sshd -t 检查配置

7.2 密钥认证失败

Permission denied (publickey)

排查步骤:

# 1. 检查服务端日志
sudo tail -50 /var/log/auth.log | grep sshd

# 2. 确认 authorized_keys 权限正确
ls -la ~/.ssh/
# 正确权限:authorized_keys 应为 600,.ssh 目录应为 700

# 3. 修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

# 4. 检查客户端使用的密钥
ssh -i ~/.ssh/id_ed25519 -vvv user@server

7.3 被 fail2ban 误封

# 查看自己被封的 IP
sudo fail2ban-client status sshd

# 解除封禁
sudo fail2ban-client set sshd unbanip YOUR_IP

# 如果要永久白名单某个 IP
echo "ignoreip = 127.0.0.1/8 YOUR_IP" >> /etc/fail2ban/jail.local
sudo systemctl restart fail2ban

八、总结

今天我们从基础到进阶,全面覆盖了 SSH 远程管理的核心技能:

层次 内容 安全等级
基础 SSH 安装、基本连接、配置文件结构
提升 密钥认证(ED25519)、ssh-agent 管理 ⭐⭐⭐
强化 禁用密码、更改端口、用户限制、超时设置 ⭐⭐⭐⭐⭐
防御 fail2ban 暴力破解防御、IP 封禁 ⭐⭐⭐⭐⭐
网络 跳板机、端口转发、SOCKS5 代理 ⭐⭐⭐⭐

核心原则: 密钥认证 + 禁用密码 + fail2ban = 三重防护,这是每个 Linux 运维工程师的黄金配置。

下期预告

明天我们将进入 Ubuntu 服务器实战的第二站——第 16 天:Web 服务器搭建:Nginx/Apache 安装配置与反向代理。我们将从零搭建一个生产级的 Web 服务器,涵盖虚拟主机配置、SSL 证书、反向代理、负载均衡等实战内容。

系列目录

天数 文章 链接
第 1 天 Ubuntu 简介与版本选择 阅读
第 2 天 手把手安装 Ubuntu 阅读
第 3 天 Ubuntu 桌面环境初探 阅读
第 4 天 Ubuntu 终端基础 阅读
第 5 天 用户与权限管理 阅读
第 6 天 软件包管理全面对比 阅读
第 7 天 文件与文本操作实战 阅读
第 8 天 系统服务管理指南 阅读
第 9 天 磁盘与文件系统管理 阅读
第 10 天 网络配置与管理 阅读
第 11 天 进程管理与监控 阅读
第 12 天 计划任务与自动化 阅读
第 13 天 备份与恢复策略 阅读
第 14 天 系统更新与升级管理 阅读
第 15 天 SSH 远程管理与安全加固 本文
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容