Linux 下 OpenSSH 基础应用指南:从配置到安全最佳实践
概述
OpenSSH 是 SSH(Secure Shell)协议 的免费开源实现,核心功能是为远程服务器控制、跨主机文件传输提供加密通信通道。在 Linux 服务器运维中,OpenSSH 是不可或缺的工具 —— 它彻底替代了 Telnet、FTP、rsh 等明文传输协议(这些协议会暴露密码和数据,存在严重安全风险),通过非对称加密、身份认证等机制,确保远程操作的安全性。
关于 OpenSSH,有几个常见认知误区需要澄清:
- 与 OpenSSL 无关联:两者虽名称相似,但分属不同项目 ——OpenSSH 专注于 “安全远程通信”,OpenSSL 专注于 “加密算法库与证书管理”,仅目标(提供开源加密工具)相近;
- 属于 OpenBSD 子项目:OpenSSH 最初源于 OpenBSD 系统,目前已成为所有主流 Linux 发行版(Ubuntu、CentOS、Debian 等)的默认远程管理工具;
- 支持多场景功能:除了远程登录(ssh 命令),还包含密钥生成(ssh-keygen)、公钥分发(ssh-copy-id)、加密文件传输(scp)等工具集,形成完整的远程运维生态。
本文将从 “核心配置文件解析”“安全最佳实践”“常用命令实操” 三个维度,系统梳理 OpenSSH 的基础应用,帮你掌握远程服务器的安全管理技巧。
一、核心配置文件:sshd_config 详解
OpenSSH 服务端(sshd)的所有行为由 /etc/ssh/sshd_config 配置文件控制,包括端口、认证方式、日志策略等。以下是最关键配置项的说明(按 “安全优先级” 排序,默认值基于主流 Linux 发行版):
配置项 | 默认值 | 核心说明 | 安全建议 |
---|---|---|---|
Protocol | 2 | 指定 SSH 协议版本,2 是安全版本(支持 AES 加密、公钥认证),1 为老旧版本(仅支持 DES 加密,已淘汰) | 强制设为 2,禁止 Protocol 1(避免兼容性漏洞) |
Port | 22 | SSH 服务监听的端口号(默认 22,是黑客扫描的高频目标) | 修改为非默认端口(如 2022、50022),减少暴力破解尝试 |
ListenAddress | 0.0.0.0(IPv4)、::(IPv6) | 指定服务监听的 IP 地址(0.0.0.0 表示监听所有 IPv4 地址) | 若服务器仅对内网提供服务,设为内网 IP(如 192.168.0.100),禁止公网访问 |
PermitRootLogin | prohibit-password(部分系统为 yes) | 是否允许 root 用户远程登录:- yes:允许 root 登录(风险高)- no:禁止 root 登录(推荐)- prohibit-password:允许 root 但禁止密码认证 | 设为 no,禁止 root 直接登录(通过普通用户 sudo 提权,降低风险) |
PasswordAuthentication | yes | 是否允许 “密码认证”(输入用户名 + 密码登录) | 设为 no,强制使用 “公钥认证”(密码易被暴力破解,公钥更安全) |
PubkeyAuthentication | yes | 是否允许 “公钥认证”(通过密钥对登录,无需输入密码) | 保持 yes,这是最安全的认证方式(需配合 AuthorizedKeysFile 配置) |
AuthorizedKeysFile | .ssh/authorized_keys .ssh/authorized_keys2 | 存放用户公钥的路径(默认在用户家目录下的 .ssh 文件夹中) | 保持默认即可,需确保 .ssh 目录权限为 700、公钥文件权限为 600(避免其他人修改) |
PermitEmptyPasswords | no | 是否允许 “空密码用户” 登录 | 保持 no(空密码无任何安全防护,绝对禁止) |
MaxAuthTries | 6 | 单个连接的最大认证失败次数(如密码输错次数) | 设为 3(减少暴力破解的尝试机会,失败即断开连接) |
MaxSessions | 10 | 单个连接允许的并行会话数 | 按实际需求调整(如运维人员常用 2-3 个会话,设为 5 足够) |
LoginGraceTime | 2m(120 秒) | 用户需在指定时间内完成认证,超时则断开连接 | 设为 30s(缩短黑客的尝试窗口,避免资源占用) |
ClientAliveInterval | 0 | 若客户端无数据传输,服务端每隔多久发送 “存活检测” 消息(0 表示不发送) | 设为 300(5 分钟),避免空闲会话长期占用资源 |
ClientAliveCountMax | 3 | 存活检测无响应时,最多重试次数(超过则断开连接) | 保持默认 3(15 分钟无响应则断开,兼顾稳定性与安全性) |
UseDNS | no(部分系统为 yes) | 是否对客户端 IP 进行反向 DNS 解析(验证主机名与 IP 一致性) | 设为 no(DNS 解析可能延迟连接,且对内网环境无意义) |
AllowUsers / AllowGroups | 未配置(允许所有用户) | 仅允许指定用户 / 组登录(如 AllowUsers admin@192.168.0.0/24) | 强烈配置,限制仅运维用户(如 admin)从内网登录,拒绝其他用户 |
DenyUsers / DenyGroups | 未配置(允许所有用户) | 禁止指定用户 / 组登录(如 DenyUsers guest) | 配合 AllowUsers 使用,双重限制风险用户 |
Subsystem sftp | /usr/lib/openssh/sftp-server | SFTP 服务的后端程序路径(用于加密文件传输) | 保持默认即可,若需限制 SFTP 目录,可配置 ChrootDirectory |
配置生效方法
修改 /etc/ssh/sshd_config 后,需重启 sshd 服务使配置生效(不同发行版命令略有差异):
# Ubuntu/Debian 系统
sudo systemctl restart sshd
# CentOS/RHEL 系统
sudo systemctl restart sshd
# 验证服务状态(确保重启成功)
sudo systemctl status sshd
二、OpenSSH 安全最佳实践:规避 90% 风险
远程服务器被攻击的主要途径是 SSH 暴力破解、弱密码登录,遵循以下最佳实践可大幅提升安全性:
1. 禁用密码认证,强制公钥登录
密码认证易被暴力破解(黑客用字典批量尝试),公钥认证基于非对称加密(私钥仅存于客户端,公钥存于服务器),安全性极高:
- 配置步骤:在 sshd_config 中设 PasswordAuthentication no,重启 sshd;
- 前提:已为用户配置公钥(见下文 “ssh-keygen 与 ssh-copy-id 命令”)。
2. 修改默认端口,减少扫描暴露
默认端口 22 是黑客扫描的重点目标,修改为非知名端口(如 2022、50022)可避免大部分无差别攻击:
- 配置步骤:在 sshd_config 中设 Port 2022,重启 sshd;
- 注意:需同步更新防火墙规则(如 ufw、firewalld),开放新端口(否则无法连接)。
3. 禁止 root 直接登录,通过普通用户提权
root 是系统最高权限用户,一旦被破解后果严重,建议:
- 配置步骤:在 sshd_config 中设 PermitRootLogin no,重启 sshd;
- 替代方案:用普通用户(如 admin)登录,执行 sudo 命令提权(需确保该用户在 sudoers 列表中)。
4. 限制登录用户与来源 IP
通过 AllowUsers / AllowGroups 限制仅指定用户从内网登录,拒绝公网或无关用户:
# 示例:仅允许 admin 用户从 192.168.0.0/24 内网登录
AllowUsers admin@192.168.0.*
# 示例:仅允许 ssh-users 组的成员登录
AllowGroups ssh-users
5. 配置防火墙,仅开放必要端口
结合 Linux 防火墙(ufw 或 firewalld),仅允许信任 IP 访问 SSH 端口:
# Ubuntu 示例(ufw 防火墙):仅允许 192.168.0.0/24 访问 2022 端口
sudo ufw allow from 192.168.0.0/24 to any port 2022 proto tcp
sudo ufw enable # 启用防火墙
# CentOS 示例(firewalld 防火墙):仅允许 192.168.0.0/24 访问 2022 端口
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.0.0/24" port port="2022" protocol="tcp" accept' --permanent
sudo firewall-cmd --reload # 重载防火墙规则
6. 生成强密码(若仍需密码认证)
若因特殊需求保留密码认证,务必使用 “大小写 + 数字 + 特殊字符” 的强密码,可通过以下命令生成随机强密码:
# 生成 30 位包含大小写、数字、下划线的强密码
tr -dc A-Za-z0-9\_ < /dev/urandom | head -c 30 | xargs
7. 限制 SSH 并发连接与认证次数
避免黑客通过大量并发连接耗尽服务器资源:
- 在 sshd_config 中设 MaxAuthTries 3(最多 3 次认证失败);
- 设 MaxSessions 5(单个连接最多 5 个会话);
- 设 MaxStartups 5:50:10(连接数达 5 时开始拒绝 50%,达 10 时全部拒绝)。
三、OpenSSH 常用命令:从登录到文件传输
OpenSSH 提供了一套完整的客户端工具,以下是日常运维最常用的命令实操:
1. ssh:远程登录服务器
ssh 是核心命令,用于连接远程 SSH 服务端,基本语法:
# 基本用法:ssh 用户名@服务器IP/域名 -p 端口号
ssh admin@192.168.0.100 -p 2022
# 选项说明:
# -p <port>:指定 SSH 服务端监听的端口(默认 22,若修改过端口必须指定)
# -X:启用 X11 转发(允许在远程服务器运行图形化程序,如 gedit)
# -Y:启用“信任的 X11 转发”(比 -X 权限更高,适合需要图形化的场景)
# -t:强制分配伪终端(用于在远程执行 sudo 等需要交互的命令)
# 示例 1:连接默认端口 22 的服务器
ssh admin@192.168.0.100
# 示例 2:连接端口 2022 的服务器,并启用 X11 转发
ssh admin@192.168.0.100 -p 2022 -X
# 示例 3:直接在远程服务器执行命令(执行后断开连接)
ssh admin@192.168.0.100 "df -h" # 查看远程服务器磁盘使用情况
2. ssh-keygen:生成密钥对(公钥 + 私钥)
用于生成公钥认证所需的密钥对(私钥存于客户端,公钥上传到服务器):
# 基本用法:生成 RSA 算法的密钥对(最常用,兼容性好)
ssh-keygen -t rsa
# 选项说明:
# -t <type>:指定密钥算法,可选 rsa(经典)、ed25519(更安全、密钥更小)
# -b <bits>:指定密钥长度(RSA 推荐 2048 或 4096 位,ed25519 无需指定)
# -C <comment>:添加注释(如邮箱,便于区分不同密钥)
# 示例 1:生成 4096 位 RSA 密钥,添加注释 "admin@local"
ssh-keygen -t rsa -b 4096 -C "admin@local"
# 示例 2:生成 ed25519 密钥(更安全,适合现代系统)
ssh-keygen -t ed25519 -C "admin@local"
生成过程说明:
- 执行命令后,会提示 “密钥保存路径”(默认 ~/.ssh/id_rsa,私钥;公钥为 ~/.ssh/id_rsa.pub);
- 提示 “输入密码”(可选,为私钥设置密码,防止私钥泄露后被滥用);
- 生成完成后,~/.ssh 目录下会新增两个文件:
- id_rsa:私钥(绝对不能泄露给他人,权限需设为 600);
- id_rsa.pub:公钥(可公开,需上传到远程服务器)。
3. ssh-copy-id:将公钥上传到远程服务器
ssh-copy-id 是简化公钥上传的工具,无需手动复制公钥内容,直接将本地公钥添加到远程服务器的 authorized_keys 文件中:
# 基本用法:ssh-copy-id 用户名@服务器IP/域名 -p 端口号
ssh-copy-id admin@192.168.0.100 -p 2022
# 选项说明:
# -i <key_file>:指定要上传的公钥文件(默认上传 ~/.ssh/id_rsa.pub)
# 示例:上传 ed25519 公钥(非默认路径)
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@192.168.0.100 -p 2022
验证公钥登录:
上传公钥后,执行 ssh admin@192.168.0.100 -p 2022,若无需输入密码直接登录,说明公钥认证配置成功。
4. scp:加密传输文件 / 目录
scp 基于 SSH 协议实现加密文件传输,替代传统的 FTP(明文传输),基本语法:
# 语法 1:从远程服务器下载文件到本地
scp -P <端口号> 用户名@服务器IP:远程文件路径 本地保存路径
# 语法 2:从本地上传文件到远程服务器
scp -P <端口号> 本地文件路径 用户名@服务器IP:远程保存路径
# 选项说明:
# -P <port>:指定 SSH 端口(注意是大写 P,与 ssh 命令的小写 p 区分)
# -r:递归传输目录(传输文件夹时必须加此选项)
# -p:保持源文件的属性(修改时间、权限等)
# -q:静默模式(不显示传输进度,适合脚本中使用)
# 示例 1:从远程服务器下载 /home/admin/logs 目录到本地 ~/downloads
scp -P 2022 -r admin@192.168.0.100:/home/admin/logs ~/downloads
# 示例 2:将本地 ~/docs/report.pdf 上传到远程服务器 /home/admin/docs
scp -P 2022 -p ~/docs/report.pdf admin@192.168.0.100:/home/admin/docs
# 示例 3:静默模式上传多个文件到远程服务器
scp -P 2022 -q ~/files/*.txt admin@192.168.0.100:/home/admin/files
5. 密钥认证测试(以 GitHub 为例)
若需验证本地密钥是否能正常用于远程服务(如 GitHub、GitLab),可通过 ssh -T 测试(-T 表示 “不分配终端”,仅测试连接):
# 测试与 GitHub 的 SSH 连接(验证公钥是否已添加到 GitHub 账户)
ssh -T git@github.com
# 成功提示:Hi username! You've