🔍搜索⌘K

Linux 下 OpenSSH 基础应用指南:从配置到安全最佳实践

概述

OpenSSH 是 SSH(Secure Shell)协议 的一个免费开源实现,核心就一件事:给远程服务器管控、跨主机传文件提供一条加密的通信通道。在 Linux 服务器运维里,OpenSSH 是离不开的工具——它彻底顶替了 Telnet、FTP、rsh 这些明文传输协议(那些协议会把密码和数据裸奔出去,安全风险很大),靠非对称加密、身份认证这些机制,保证你远程操作是安全的。

关于 OpenSSH,有几个常见的误会得先掰扯清楚:

  1. 跟 OpenSSL 不是一回事:俩名字像,但其实是不同的项目——OpenSSH 只管”安全远程通信”,OpenSSL 管的是”加密算法库和证书管理”,顶多目标(都提供开源加密工具)有点接近;
  2. 它源自 OpenBSD 项目:OpenSSH 最早是从 OpenBSD 系统里出来的,现在已经是所有主流 Linux 发行版(Ubuntu、CentOS、Debian 等)默认的远程管理工具了;
  3. 功能不止登录:除了远程登录(ssh 命令),它还带着密钥生成(ssh-keygen)、公钥分发(ssh-copy-id)、加密传文件(scp)这一整套工具,组成了完整的远程运维生态。

这篇文章打算从”核心配置文件怎么看""安全上怎么最好地实践""常用命令怎么实操”三个角度,把 OpenSSH 的基础用法理一遍,帮你把远程服务器的安全管理弄明白。

一、核心配置文件:sshd_config 详解

OpenSSH 服务端(sshd)的一举一动都由 /etc/ssh/sshd_config 这个配置文件管着,端口、认证方式、日志策略全在里面。下面把最关键的配置项按”安全优先级”排了序说明(默认值以主流发行版为准):

配置项默认值核心说明安全建议
Protocol2指定 SSH 协议版本,2 是安全版本(支持 AES 加密、公钥认证),1 为老旧版本(仅支持 DES 加密,已淘汰)强制设为 2,禁止 Protocol 1(避免兼容性漏洞)
Port22SSH 服务监听的端口号(默认 22,是黑客扫描的高频目标)修改为非默认端口(如 2022、50022),减少暴力破解尝试
ListenAddress0.0.0.0(IPv4)、::(IPv6)指定服务监听的 IP 地址(0.0.0.0 表示监听所有 IPv4 地址)若服务器仅对内网提供服务,设为内网 IP(如 192.168.0.100),禁止公网访问
PermitRootLoginprohibit-password(部分系统为 yes)是否允许 root 用户远程登录:- yes:允许 root 登录(风险高)- no:禁止 root 登录(推荐)- prohibit-password:允许 root 但禁止密码认证设为 no,禁止 root 直接登录(通过普通用户 sudo 提权,降低风险)
PasswordAuthenticationyes是否允许 “密码认证”(输入用户名 + 密码登录)设为 no,强制使用 “公钥认证”(密码易被暴力破解,公钥更安全)
PubkeyAuthenticationyes是否允许 “公钥认证”(通过密钥对登录,无需输入密码)保持 yes,这是最安全的认证方式(需配合 AuthorizedKeysFile 配置)
AuthorizedKeysFile.ssh/authorized_keys .ssh/authorized_keys2存放用户公钥的路径(默认在用户家目录下的 .ssh 文件夹中)保持默认即可,需确保 .ssh 目录权限为 700、公钥文件权限为 600(避免其他人修改)
PermitEmptyPasswordsno是否允许 “空密码用户” 登录保持 no(空密码无任何安全防护,绝对禁止)
MaxAuthTries6单个连接的最大认证失败次数(如密码输错次数)设为 3(减少暴力破解的尝试机会,失败即断开连接)
MaxSessions10单个连接允许的并行会话数按实际需求调整(如运维人员常用 2-3 个会话,设为 5 足够)
LoginGraceTime2m(120 秒)用户需在指定时间内完成认证,超时则断开连接设为 30s(缩短黑客的尝试窗口,避免资源占用)
ClientAliveInterval0若客户端无数据传输,服务端每隔多久发送 “存活检测” 消息(0 表示不发送)设为 300(5 分钟),避免空闲会话长期占用资源
ClientAliveCountMax3存活检测无响应时,最多重试次数(超过则断开连接)保持默认 3(15 分钟无响应则断开,兼顾稳定性与安全性)
UseDNSno(部分系统为 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-serverSFTP 服务的后端程序路径(用于加密文件传输)保持默认即可,若需限制 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"

生成过程说明:

  1. 跑完命令,它会问你”密钥存哪儿”(默认 ~/.ssh/id_rsa,这是私钥;公钥是 ~/.ssh/id_rsa.pub);
  2. 再问你”设个密码不”(可选项,给私钥加个密码,万一私钥泄露也不至于被人直接拿去用);
  3. 生成完之后,~/.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