SSH 免密登录配置完整指南
本文档详细说明 SSH 免密登录的配置方法(含本地→远程、多服务器互信),同时补充Windows(Git Bash/WSL)连Linux免密、禁用密码登录强化安全、多密钥管理等实用场景,步骤适配所有主流Linux发行版(CentOS/Ubuntu/Debian/AlmaLinux),核心原理为SSH公钥认证,配置后无需重复输入密码即可登录/执行远程命令。
一、核心原理
SSH免密登录基于非对称加密实现,核心分3个环节:
本地机器生成密钥对(私钥id_xxx + 公钥id_xxx.pub),私钥本地严格保管,公钥可公开传输;
将本地公钥上传至目标远程机器,并添加到远程机器的~/.ssh/authorized_keys文件(SSH认证白名单);
本地发起SSH连接时,远程机器验证本地私钥与已保存的公钥是否匹配,匹配则直接放行,无需密码。
加密算法推荐:优先用ED25519(更安全、密钥体积小),兼容旧系统可使用RSA(推荐2048位及以上)。
二、前置条件
本地和远程机器均安装openssh-client和openssh-server(Linux默认自带,未安装可按下方命令补装);
网络互通:本地能ping通远程机器的IP/主机名,远程机器开放22端口(SSH默认端口,防火墙/安全组需放行);
双方均有可登录的用户账号(推荐非root用户,root免密需额外配置);
禁止修改本地/远程的~/.ssh目录权限为过宽(如777),Linux对SSH认证目录的权限有严格限制(核心避坑点)。
补装OpenSSH组件(若未安装)
# CentOS/RHEL/AlmaLinux 7/8/9
yum install -y openssh-clients openssh-server
systemctl enable –now sshd # 启动并开机自启SSH服务
# Ubuntu/Debian
apt update && apt install -y openssh-client openssh-server
systemctl enable –now ssh # Ubuntu中服务名是ssh,不是sshd
三、基础配置:本地Linux → 远程Linux 免密登录(最常用)
步骤1:本地机器生成SSH密钥对
登录本地Linux,执行密钥生成命令(二选一,优先ED25519),全程回车默认即可(无需设置密钥密码,设置则为「双因素认证」,需输入密钥密码才能免密登录)。
推荐:ED25519算法(高安全)
ssh-keygen -t ed25519
兼容旧系统:RSA算法(2048位及以上)
ssh-keygen -t rsa -b 4096 # -b 指定密钥长度,4096位比默认2048位更安全
执行结果说明
密钥对会默认生成在本地机器的~/.ssh/目录下,生成后目录下会出现2个核心文件:
# 查看生成的密钥文件
ls -l ~/.ssh/
# 输出(ED25519为例,RSA则为id_rsa/id_rsa.pub)
-rw——- 1 user user 411 月 日 时:分 id_ed25519 # 私钥,权限必须为600,严禁公开/修改
-rw-r–r– 1 user user 102 月 日 时:分 id_ed25519.pub # 公钥,可自由传输到目标机器
关键:本地私钥默认权限为600(仅所有者可读可写),若被修改会导致SSH认证失败,无需手动调整。
步骤2:将本地公钥上传至远程Linux机器
提供2种上传方法,方法1(ssh-copy-id) 最快捷(推荐),方法2(手动复制) 适配无ssh-copy-id的极简系统(如嵌入式Linux)。
方法1:ssh-copy-id 一键上传(推荐)
核心命令格式:ssh-copy-id [远程用户]@[远程机器IP/主机名],执行后输入远程机器的用户密码即可完成上传(仅最后一次输入密码)。
# 示例:远程用户为root,远程IP为192.168.1.100(替换为实际信息)
ssh-copy-id root@192.168.1.100
# 若远程SSH端口非默认22(如改为2222),加-p参数
ssh-copy-id -p 2222 root@192.168.1.100
作用:该命令会自动完成3件事:
远程机器若无~/.ssh目录,自动创建(权限700);
将本地公钥追加到远程机器的~/.ssh/authorized_keys文件(权限600);
自动校验目录/文件权限,避免手动配置的权限错误。
方法2:手动复制公钥(适配无ssh-copy-id场景)
若本地/远程机器无ssh-copy-id命令,通过cat+ssh手动传输公钥,步骤如下:
# 核心命令:将本地公钥追加到远程authorized_keys(ED25519为例,RSA替换为id_rsa.pub)
cat ~/.ssh/id_ed25519.pub | ssh root@192.168.1.100 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys'
# 端口非22则加-p:
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 root@192.168.1.100 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys'
命令说明:
-
mkdir -p ~/.ssh:远程无.ssh目录则创建,有则不报错;
-
cat >> ~/.ssh/authorized_keys:将本地公钥追加到远程认证文件(避免覆盖已有公钥);
-
chmod 700/600:强制设置远程.ssh目录和认证文件的合规权限。
步骤3:验证免密登录是否生效
本地机器执行SSH登录命令,无需输入密码即成功登录,说明配置完成:
# 基础登录(默认22端口)
ssh root@192.168.1.100
# 非22端口
ssh -p 2222 root@192.168.1.100
# 免密执行远程命令(无需登录)
ssh root@192.168.1.100 'ls -l /root' # 远程执行ls命令,本地输出结果
四、反向配置:远程Linux → 本地Linux 免密登录
若需要远程机器免密登录本地,仅需在远程机器重复上述步骤1-3:
远程机器执行ssh-keygen生成密钥对;
远程机器执行ssh-copy-id 本地用户@本地IP,输入本地机器密码;
远程机器执行ssh 本地用户@本地IP验证免密。
五、特殊场景配置
场景1:Windows(Git Bash/WSL/CMD)→ Linux 免密登录
Windows下常用的SSH工具(Git Bash、WSL、PowerShell7+、OpenSSH)均支持该配置,步骤与Linux完全一致:
打开Git Bash/WSL(推荐),执行ssh-keygen -t ed25519生成密钥对(密钥保存在C:\\Users\\你的Windows用户名.ssh\\);
执行ssh-copy-id 远程用户@远程IP上传公钥;
执行ssh 远程用户@远程IP验证免密。
场景2:配置root用户免密登录(部分系统默认禁用)
CentOS/RHEL 7+、Ubuntu 20.04+ 部分版本默认禁止root用户SSH密码登录,但公钥免密需确认远程机器的SSH配置,若root免密登录失败,按以下步骤开启:
登录远程机器,编辑SSH配置文件:
vi /etc/ssh/sshd_config
找到以下配置项,修改为对应值(无则新增):
PermitRootLogin yes # 允许rootSSH登录(公钥认证)
PubkeyAuthentication yes # 开启公钥认证(默认开启,确保未被注释)
PasswordAuthentication yes # 暂时保留密码登录,验证免密后再禁用
ChallengeResponseAuthentication no
重启SSH服务使配置生效:
# CentOS/RHEL/AlmaLinux
systemctl restart sshd
# Ubuntu/Debian
systemctl restart ssh
重新执行公钥上传和验证步骤即可。
场景3:多SSH密钥管理(本地连接多个远程服务器,不同密钥)
若本地需要用不同密钥连接不同远程服务器(如公司服务器用密钥A,个人服务器用密钥B),需创建SSH配置文件~/.ssh/config,实现「按主机名自动匹配密钥」:
本地创建并编辑配置文件:
vi ~/.ssh/config
写入以下内容(按实际信息修改,可新增多个Host):
# 公司服务器(自定义主机名:company-server,可任意命名)
Host company-server
HostName 192.168.1.100 # 远程服务器IP
Port 22 # SSH端口
User root # 远程登录用户
IdentityFile ~/.ssh/id_ed25519_company # 该服务器对应的私钥路径
# 个人服务器(自定义主机名:personal-server)
Host personal-server
HostName 10.0.0.5 # 远程服务器IP
Port 2222 # 非默认端口
User ubuntu # 远程登录用户
IdentityFile ~/.ssh/id_rsa_personal # 该服务器对应的私钥路径
设置配置文件权限(必须为600,否则SSH忽略):
chmod 600 ~/.ssh/config
免密登录简化命令(直接用自定义主机名):
ssh company-server # 连接公司服务器
ssh personal-server # 连接个人服务器
场景4:禁用密码登录,仅保留公钥认证(强化服务器安全)
免密登录验证成功后,强烈建议禁用远程机器的密码登录,避免暴力破解,步骤如下:
登录远程机器,编辑SSH配置文件:
vi /etc/ssh/sshd_config
修改核心配置项:
PasswordAuthentication no # 禁用密码登录(仅保留公钥认证)
PermitEmptyPasswords no # 禁止空密码登录
重启SSH服务:
# CentOS/RHEL/AlmaLinux
systemctl restart sshd
# Ubuntu/Debian
systemctl restart ssh
关键:禁用密码前务必确保公钥免密登录正常,否则会导致无法远程登录服务器!
六、核心避坑点:权限配置(90%的免密失败源于此)
Linux SSH对本地/远程的.ssh目录和相关文件权限有严格限制,非合规权限会直接导致公钥认证失败,以下是必须遵守的权限规则,配置后若免密失败,优先检查权限:
本地机器(发起登录方)权限要求
# 检查本地权限,执行后按以下标准核对
ls -ld ~/.ssh && ls -l ~/.ssh/
| ~/.ssh | 700(drwx——) | 仅所有者可访问 |
| ~/.ssh/id_ed25519/id_rsa(私钥) | 600(-rw——-) | 仅所有者可读可写,严禁其他用户访问 |
| ~/.ssh/id_ed25519.pub/id_rsa.pub(公钥) | 644(-rw-r–r–) | 公钥可公开,权限无严格限制 |
| ~/.ssh/config(若有) | 600(-rw——-) | 仅所有者可访问 |
远程机器(被登录方)权限要求
# 登录远程机器,检查权限
ls -ld ~/.ssh && ls -l ~/.ssh/authorized_keys
| ~/.ssh | 700(drwx——) | 仅所有者可访问 |
| ~/.ssh/authorized_keys(公钥白名单) | 600(-rw——-) | 仅所有者可读写,禁止其他用户修改 |
| 远程用户家目录~ | 不可为777 | 若家目录权限为777,SSH会拒绝认证 |
权限修复命令(直接执行,一键修复远程机器权限)
# 远程机器执行
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys && chown -R 用户名:用户名 ~/.ssh
# 示例:远程用户为root
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys && chown -R root:root ~/.ssh
七、免密登录失败:常见问题排查
若按步骤配置后仍需输入密码,按以下顺序排查(从易到难):
检查网络和端口:本地ping远程IP,执行telnet 远程IP 22检查22端口是否开放;
检查权限:按「第六节」修复本地/远程的.ssh目录和文件权限;
检查SSH配置:远程机器确认sshd_config中PubkeyAuthentication yes未被注释;
检查公钥是否匹配:本地公钥内容与远程authorized_keys中的内容完全一致(无换行/空格错误);
# 本地查看公钥
cat ~/.ssh/id_ed25519.pub
# 远程查看公钥白名单
cat ~/.ssh/authorized_keys
检查SELinux/防火墙:远程机器关闭SELinux(临时)或放行SSH端口,关闭防火墙测试:
# 临时关闭SELinux(CentOS/RHEL)
setenforce 0
# 临时关闭防火墙
systemctl stop firewalld # CentOS/RHEL
ufw disable # Ubuntu/Debian
查看SSH调试日志:本地执行带-v的SSH命令,查看认证失败原因(关键):
ssh -v root@192.168.1.100 # -v 显示调试信息,-vvv 显示更详细信息
八、常用扩展命令
| 查看本地SSH密钥指纹 | ssh-keygen -lf ~/.ssh/id_ed25519.pub |
| 远程机器查看已授权公钥 | cat ~/.ssh/authorized_keys |
| 远程机器删除某条公钥 | 编辑~/.ssh/authorized_keys,删除对应行 |
| 本地测试SSH连接(不登录) | ssh -T root@192.168.1.100 |
| 重启SSH服务(CentOS) | systemctl restart sshd |
| 重启SSH服务(Ubuntu) | systemctl restart ssh |
| 查看SSH服务状态 | systemctl status sshd/ssh |
九、总结
核心步骤:本地生成密钥对 → 上传公钥到远程 → 验证权限 → 测试免密,全程仅需3个核心命令;
避坑核心:严格遵守本地/远程的.ssh目录和文件权限,700(目录)/600(私钥/认证文件) 是关键;
安全最佳实践:免密验证成功后,禁用远程机器的密码登录,仅保留公钥认证;避免用root用户日常登录,创建普通用户并赋予sudo权限;
多场景适配:Windows连Linux、多密钥管理、root免密均基于基础步骤扩展,重点修改配置文件和权限;
排查思路:免密失败先查权限,再查SSH配置,最后查网络/防火墙,用ssh -v查看调试日志是终极方法。




