前言
在 Linux 系统中,SSH 密钥登录是替代传统密码登录的更安全方式,能有效避免密码被暴力破解的风险。(可能等到哪天你的服务器受到不明攻击时,你就会明白这么做的重要性)
注意:这里推荐所有操作不要在root用户下进行,而是新增自己的专有用户,当然你用root也可以,只是安全性没那么高
bash
# 添加用户 adduser 自定义用户名
sudo adduser xiangyu
# 切换用户 su 自定义的用户名
su xiangyu
# 创建 .ssh 目录
mkdir -p ~/.ssh
一、修改 SSH 配置文件
首先需要登录 Linux 服务器,通过修改 sshd_config 文件开启公钥验证功能。
1. 登录服务器并编辑配置文件
使用密码登录服务器后,执行以下命令打开 SSH 配置文件:
bash
# 先切换root下操作
su root
# 编辑SSH配置文件
vim /etc/ssh/sshd_config
2. 调整关键配置项
在配置文件中找到以下 4 个配置项,取消注释(若有 # 前缀)并修改为指定值:
| 配置项 | 推荐值 | 配置说明 |
|---|---|---|
| RSAAuthentication | yes | 开启基于 RSA 算法的安全验证(兼容传统 RSA 密钥) |
| PubkeyAuthentication | yes | 开启公钥登录验证(核心配置,必须设为 yes) |
| AuthorizedKeyFiles | .ssh/authorized_keys | 指定存储客户端公钥的文件路径(默认路径,无需修改) |
| StrictModes | no | 关闭 SSH 登录前对用户家目录、rhosts 文件的权限检查(避免权限问题导致登录失败) |
| PermitRootLogin | no或者prohibit-password | 默认为yes,意思是:允许 root 用户通过 SSH 直接登录服务器。不建议设为 yes,因为root 是黑客第一个尝试的用户名,容易被暴力破解。设为 no:禁止 root 登录,必须先登录普通用户,再 su - 或 sudo 切换。如果必须用 root,建议用设置成prohibit-password,这样只允许密钥登录,不允许密码登录 |
3.重启 SSH 服务使配置生效
修改完成后,保存并退出 vim(按 Esc 后输入 :wq),执行以下命令重启 SSH 服务:
bash
systemctl restart sshd.service
linux的各个发行版本,SSH服务命令略有差异, 关键区别:Ubuntu/Debian 的 SSH 服务名是
ssh,其他多数版本是sshd,centos7是sshd.service
二、客户端(本地电脑)配置:生成公钥与私钥
以 macOS 客户端为例(Windows 可通过 Git Bash、PowerShell 操作,步骤一致),生成用于登录的密钥对(公钥 + 私钥)。
1. 进入客户端 .ssh 目录
打开终端,执行命令进入用户目录下的 .ssh 文件夹(若不存在会自动创建):
bash
cd ~/.ssh
2. 生成 ed25519 密钥对
执行以下命令生成密钥,支持自定义密钥名称和关联邮箱(便于区分多台服务器密钥):
bash
# 基础生成命令(默认密钥名为 id_ed25519)
ssh-keygen -t ed25519 # 推荐 ed25519 算法(比 RSA 更安全高效)
# 自定义密钥名称 + 关联邮箱(推荐,例如区分服务器用途)
ssh-keygen -t ed25519 -C "server_linux@example.com" -f "id_ed25519"
3. 完成密钥生成
执行命令后按提示操作:
- 若不需要为密钥设置密码(简化登录,适合个人使用),直接按 3 次回车;
- 若需要更高安全性(防止私钥泄露后被滥用),可输入密码并确认。
生成成功后,.ssh 目录下会出现两个文件:
- 私钥文件(如
id_ed25519):保存在客户端,严禁泄露给他人; - 公钥文件(如
id_ed25519.pub):需上传到 Linux 服务器。
三、服务器端:添加客户端公钥并设置权限
将客户端生成的公钥上传到服务器,并配置正确的文件权限(权限错误会导致公钥登录失败,是常见坑点)。
1. 上传客户端公钥到服务器
方法一 scp 命令
- 通过 scp 命令将客户端公钥文件上传到服务器的 ~/.ssh/ 目录(以默认密钥名 id_ed25519.pub 为例):
bash
# 格式:scp 客户端公钥路径 服务器用户名@服务器IP:服务器目标路径
scp ~/.ssh/id_ed25519.pub root@xxx.xxx.xxx.xxx:~/.ssh/
执行后输入服务器密码,完成公钥上传。
- 合并公钥到 authorized_keys
登录服务器,进入 ~/.ssh/ 目录,将上传的公钥追加到 authorized_keys 文件(若文件不存在会自动创建):
bash
# 进入 .ssh 目录
cd ~/.ssh/
# 追加公钥到 authorized_keys(避免覆盖已有公钥)
cat id_ed25519.pub >> authorized_keys
# 删除上传的原始公钥文件(清理冗余文件)
rm -f id_ed25519.pub
方法二 ssh-copy-id命令
运行下面命令(替换 user 和 服务器IP):
bash
ssh-copy-id user@服务器IP
输入一次服务器密码,搞定。
方法三 手动粘贴复制
复制id_rsa.pub的内容,然后登录服务器,粘贴到 ~/.ssh/authorized_keys 文件里。
方法四 通过指令给文件追加文本
bash
echo "公钥内容(也就是xxx.pub里的内容)" >> ~/.ssh/authorized_keys
authorized_keys文件不存在的话会直接新增
3. 配置正确的权限(关键步骤)
SSH 对目录和文件权限有严格要求,权限过宽会导致登录失败,需执行以下命令设置权限:
bash
# 设置 .ssh 目录权限(仅所有者可读写执行,其他用户无权限)
chmod 700 ~/.ssh/
# 设置 authorized_keys 文件权限(仅所有者可读写,其他用户无权限)
chmod 644 ~/.ssh/authorized_keys
我自己配置也经常遗忘这一步,导致连接不上
四、修改SSH连接端口和检查 SSH 服务状态
1. 修改SSH连接端口
默认SSH连接端口是22,这很不安全,我们可以前面配置修改端口
bash
vim /etc/ssh/sshd_config
这里我改成16222

重启 SSH 服务使配置生效
bash
systemctl restart sshd.service
2. 检查 SSH 服务状态和是否放行了新端口
bash
# 1. 检查 SSH 服务状态
systemctl status sshd

bash
# 2. 查看 SSH 实际监听的端口
netstat -tlnp | grep sshd

服务器安全组添加规则,放通16222端口

bash
# 3. 检查防火墙是否放行了新端口
# CentOS 7 用 firewalld
firewall-cmd --list-all
# 或用 iptables
iptables -L -n | grep 16222

bash
# 4. 如果没有放行,添加规则
firewall-cmd --permanent --add-port=16222/tcp
# 重新加载防火墙
firewall-cmd --reload
# 或者用 iptables
iptables -I INPUT -p tcp --dport 16222 -j ACCEPT
service iptables save
五、关闭密码登录
为了安全性,启用密钥登录之后,最好关闭服务器的密码登录。
对于 OpenSSH,具体方法就是打开服务器 sshd 的配置文件/etc/ssh/sshd_config,将PasswordAuthentication这一项设为no。
bash
vim /etc/ssh/sshd_config

修改配置文件以后,不要忘了重新启动 sshd,否则不会生效。
bash
systemctl restart sshd.service
六、其他
1. 连接报错Too many authentication failures
说明您本地SSH客户端尝试了太多错误的认证方式,触发了服务器的保护机制。触发了 MaxAuthTries 限制(默认6次)
- 方案1:等待自动解锁(最简单)
等待约1分钟,服务器的认证失败计数会自动重置,然后使用正确的方式连接。` - 方案2:在服务器端临时增加最大认证次数(不推荐长期)
bash
# 编辑配置
vi /etc/ssh/sshd_config
# 找到或添加这一行
MaxAuthTries 10
# 重启SSH
systemctl restart sshd
2. 公钥连接服务器
我这里使用的是FinalShell连接演示,注意如果你的公钥不是配置在root里,则用户名改成你对应的用户

3. 如果服务器的SSH 密码登录已经被关了,连不上服务器没办法输入指令怎么办?
可以通过控制台vnc登入服务器:https://cloud.tencent.com/document/product/213/35701
参考
https://juejin.cn/post/7564241609501294627