Linux-Ubantu-贴士-SSH 免密登录与端口修改

SSH 免密配置零散写过几次,这次收成一篇:生成密钥、装公钥、关密码登录、改端口。最容易翻车的是改完端口连不上,排查放在倒数第二节,按命中率排序。

本地生成密钥对

arduino 复制代码
ssh-keygen -t ed25519 -C "你的邮箱或备注"

ed25519 密钥短,安全性不比 RSA 差,现在默认选它。碰上很老的服务器不认,再换 -t rsa -b 4096

它会问你两件事:

  1. 存哪里。直接回车,默认 ~/.ssh/id_ed25519
  2. 要不要设密码短语(passphrase)。留空,以后用密钥不再输任何密码;电脑可能被别人碰的话就设一个。嫌每次输麻烦可以配 ssh-agent,这里不展开。

生成完 ~/.ssh/ 下多两个文件:id_ed25519 是私钥,留在本机,谁都不给;id_ed25519.pub 是公钥,往服务器上装。

把公钥装到服务器

ssh-copy-id 就用它,一条命令:

javascript 复制代码
ssh-copy-id -i ~/.ssh/id_ed25519.pub 用户名@服务器IP

端口不是 22 就加 -p

css 复制代码
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 用户名@服务器IP

Windows 上没有这个命令,手动来。先看公钥内容:

bash 复制代码
cat ~/.ssh/id_ed25519.pub

复制整行输出,登录服务器:

bash 复制代码
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "刚才复制的公钥" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

测试免密登录

javascript 复制代码
ssh -i ~/.ssh/id_ed25519 用户名@服务器IP

没问密码直接进去,就成了。还在问密码,多半是权限问题,看后面的权限那节。

关掉密码登录

密钥确认能用了,再把密码登录关掉,暴力破解的路就断了。编辑 /etc/ssh/sshd_config

bash 复制代码
sudo nano /etc/ssh/sshd_config

找到或加上:

yaml 复制代码
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
PermitEmptyPasswords no

新一点的 OpenSSH 把第三项改名为 KbdInteractiveAuthentication,旧名字作为别名仍然有效,不用改。

PermitRootLogin 建议设 prohibit-password,root 只认密钥。用不上 root 远程登录的话,直接写 no

重启服务:

bash 复制代码
# Ubuntu / Debian
sudo systemctl restart ssh

# CentOS / RHEL
sudo systemctl restart sshd

改之前先确认密钥能登录。重启前多开一个终端保持现有连接别退,新配置验证没问题再关。这是改 sshd 配置的保命习惯。

改端口

同一个文件,找到 #Port 22,改成:

yaml 复制代码
Port 2222

过渡期可以新旧两行同时留着,新端口能连上之后再删 22。

重启服务,然后放行防火墙:

  • Ubuntu:sudo ufw allow 2222/tcp
  • CentOS:sudo firewall-cmd --permanent --add-port=2222/tcp && sudo firewall-cmd --reload
  • 云服务器另外要去控制台安全组放行,系统防火墙管不到那一层。

改完端口连不上,按命中率排查

九成出在下面几处。

1. 服务没重启

改完 sshd_config 必须重启。Ubuntu/Debian 服务名是 ssh,CentOS/RHEL 是 sshd,别写反。

2. Ubuntu 22.10+ 的 socket 激活

这些版本默认由 ssh.socket 监听端口,改了 sshd_config 之后要走这一套才生效:

复制代码
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket

daemon-reload 不能省,systemd 靠它重新按配置生成监听参数。要是执行完新端口还是不监听,说明这版系统的 socket 不会自己读 sshd_config,退回传统方式最省事:

bash 复制代码
sudo systemctl disable --now ssh.socket
sudo systemctl enable --now ssh.service

3. 防火墙没放行

系统防火墙要单独开新端口。Ubuntu 用 sudo ufw allow 2222/tcp;CentOS 用:

css 复制代码
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload

4. SELinux 没加标签

CentOS/RHEL 开着 SELinux 的话,sshd 不能随便绑新端口:

arduino 复制代码
sudo semanage port -l | grep ssh_port_t
sudo semanage port -a -t ssh_port_t -p tcp 2222

提示端口已存在就改用 -m。最小安装的系统没有 semanage 命令,先装:CentOS 7 装 policycoreutils-python,8 代之后的系统装 policycoreutils-python-utils

5. 云安全组没放行

安全组和系统防火墙是两层。控制台里实例的入方向规则放行新端口 TCP,注意规则优先级,一条优先级更高的拒绝规则会把你加的允许规则盖掉。

6. macOS 是另一套

macOS 的 sshd 由 launchd 托管,端口写在 /etc/services,改 sshd_config 里的 Port 不生效:

bash 复制代码
sudo vim /etc/services

ssh 22/tcpssh 22/udp 两行的 22 改掉,然后重启服务:

bash 复制代码
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load /System/Library/LaunchDaemons/ssh.plist

7. 还不行就看日志

复制代码
sudo journalctl -u ssh -n 50

绑定失败、权限问题、配置语法错,日志里都会写。

权限问题

SSH 对权限很挑,太宽直接拒绝用你的密钥,标准权限是:

bash 复制代码
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519          # 私钥
chmod 644 ~/.ssh/id_ed25519.pub      # 公钥
chmod 600 ~/.ssh/authorized_keys     # 服务器上的授权文件

在 WSL 里操作 Windows 分区(比如 /mnt/c/...)上的密钥会报权限错,那是文件系统不支持 Linux 权限位,把密钥挪进 WSL 自己的家目录再设权限就行。

常见报错速查

报错 大概率原因 处理
一直提示输密码 ~/.ssh/config 指错了密钥,或 authorized_keys 内容不完整 ssh -v 用户名@服务器IP 看详细日志
Permission denied (publickey) 公钥没装上,或服务器端权限不对 检查 authorized_keys 存在、内容完整、权限 600
UNPROTECTED PRIVATE KEY FILE 私钥权限太宽 chmod 600 私钥
Connection refused sshd 没跑,或端口不对 systemctl status ssh 看状态

最后配个别名

以上都通了,在本地 ~/.ssh/config 里写一段:

javascript 复制代码
Host myserver
    HostName 服务器IP
    User 用户名
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

chmod 600 ~/.ssh/config。以后连服务器就是 ssh myserver 一条命令,scprsync、走 SSH 的 Git 操作也全部跟着免密。

相关推荐
团子股股东峥哥1 小时前
day34-RHEL-管理SELinux的安全性
linux·运维·服务器
‎ദ്ദിᵔ.˛.ᵔ₎1 小时前
Linux 重定向
linux·运维·服务器
LRL_1 小时前
离线/纯内网环境下,Linux 服务器时间不准如何强制修改?(以 Oracle Linux 9 / RHEL 9 为例)
linux·服务器·oracle
wuminyu1 小时前
Kafka利用sendfile与Page Cache实现高性能传输剖析
java·linux·c语言·jvm·c++
dingdingfish2 小时前
TLPI 第36章 读书笔记:Process Resource
linux·resource·getrusage·tlpi·setrlimit·getrlimit
阿钱真强道2 小时前
04 嵌入式操作系统 | 常用命令Ⅱ:用户权限、进程与网络
linux·ubuntu·进程管理·用户权限·网络排查
阿钱真强道2 小时前
03 嵌入式操作系统 | 常用命令Ⅰ:文件、查找与压缩
linux·ubuntu·文件管理·命令行·压缩解压
fengyehongWorld2 小时前
Linux 配置Syncthing的中继服务器
linux·运维·服务器
深念Y2 小时前
黑苹果P400-卡顿排查与优化记录
linux·macos·ios·pve·黑苹果·英伟达·n卡