SSH远程管理服务

文章来源声明: 原文作者:帷幕落秋; 来源站点:掘金; 原文链接:https://juejin.cn/post/7699753031052050466; 本文基于上述来源整理/加工,觅优补充点评,仅供技术学习交流。版权归原作者所有。
觅优短评

这篇内容从底层原理到配置、排障与安全加固,覆盖运维日常最高频的 SSH 场景。易错点与加固清单尤其实用,适合 Linux 运维入门者和面试复习对照查阅。

SSH 远程管理 --------

第一节 SSH 简介

1.1 什么是 SSH

SSH 为 Secure Shell 的缩写,是一种用于远程登录和文件传输的加密协议。它工作在应用层,基于传输层 TCP(默认 22 端口)。

只要记住一句:SSH 把"明文传输的 telnet"变成了"加密传输"。

1.2 基础信息

项目内容
默认端口**22**
Linux 守护进程**`sshd`**
安装服务**OpenSSH**
服务端主程序`/usr/sbin/sshd`
客户端主程序`/usr/bin/ssh`
服务端配置`/etc/ssh/sshd_config`
客户端配置`/etc/ssh/ssh_config`
# 确认是否安装
rpm -qa | grep openssh
dnf install -y openssh-server openssh-clients

# 确认服务状态
systemctl status sshd
ss -lntp | grep :22

第二节 SSH 原理

2.1 对称加密

采用单钥密码系统,同一个密钥既用于加密也用于解密。

  • 优点:快,适合加密大量数据
  • 缺点:密钥怎么安全地交给对方?这就是"密钥分发问题"
  • 代表算法:AES、ChaCha20

2.2 非对称加密

又名"公开密钥加密算法",需要一对密钥:

  • 公钥(public key):可以公开
  • 私钥(private key):只有自己持有

核心特性:

公钥加密 → 只有私钥能解
私钥签名 → 只有公钥能验

  • 优点:解决了密钥分发问题
  • 缺点:慢,比对称加密慢几个数量级
  • 代表算法:RSA、ECDSA、Ed25519

2.3 SSH 为什么两种都用(★ 核心)

很多人背了两种算法,却说不清 SSH 到底用哪种。答案是:两种都用,各管一段。

阶段用什么为什么
**建立连接时**非对称加密安全地协商出会话密钥,不需要提前共享密码
**传输数据时****对称加密**速度快,适合大流量

一句话:

非对称负责"安全地把钥匙交给你",对称负责"拿到钥匙后高效地传数据"。

2.4 完整的连接建立过程

① TCP 三次握手,连上 22 端口

② 协议版本协商
   客户端:SSH-2.0-OpenSSH_8.0
   服务端:SSH-2.0-OpenSSH_8.7

③ 算法协商
   双方各自列出支持的加密算法,选出一个都支持的

④ 密钥交换(KEX)
   通过 Diffie-Hellman 算法,双方各自算出【同一个会话密钥】
   ★ 注意:这个密钥从来没有在网络上传输过

⑤ 服务端出示主机公钥
   客户端校验:这个公钥和我记过的一致吗?(known_hosts)
   ★ 这一步防的是"中间人攻击"

⑥ 用户身份认证(二选一)
   · 密码认证:在【已加密的通道】里传密码
   · 公钥认证:客户端用私钥签名,服务端用公钥验签

⑦ 认证通过,建立会话
   之后所有数据都用【对称加密】传输

2.5 两种用户认证方式

**密码认证****公钥认证**
原理把密码放进加密通道里传客户端用私钥签名,服务端用公钥验签
私钥会传输吗—**不会**,只传签名
安全性中(可能被暴力破解)高
便利性要输密码免密登录
生产推荐关掉**推荐**

第三节 SSH 配置文件

3.1 服务端配置:/etc/ssh/sshd_config

参数常见值说明
`Port``22`监听端口
`ListenAddress``0.0.0.0`监听的 IP
`HostKey``/etc/ssh/ssh_host_ed25519_key`服务端主机私钥位置
`LogLevel``INFO`日志等级
`SyslogFacility``AUTH`日志记录 SSH 登录情况
`GSSAPIAuthentication``yes`GSSAPI(Kerberos)认证
`PermitRootLogin``yes` / `no`是否允许 root 直接登录
`PubkeyAuthentication``yes`是否启用公钥认证
`AuthorizedKeysFile``.ssh/authorized_keys`公钥保存位置(相对用户家目录)
`PasswordAuthentication``yes` / `no`是否允许密码认证
`PermitEmptyPasswords``no`是否允许空密码
`UsePAM``yes`是否使用 PAM 做认证/会话管理
`MaxAuthTries``6`最大认证尝试次数

关于 GSSAPIAuthentication(常见坑)

在没有 Kerberos/DNS 的实验环境里,这个选项会让登录卡好几秒。

# 服务端
GSSAPIAuthentication no      # /etc/ssh/sshd_config

# 客户端
GSSAPIAuthentication no      # /etc/ssh/ssh_config

两个文件里都有这一项,两边都关掉才彻底不卡。

关于已过时的参数

旧参数说明
`Protocol 2`OpenSSH 7.6+ 已删除,不用再写
`ServerKeyBits 1024`已移除,且 1024 位过弱
`ssh_host_dsa_key`DSA 在 7.0+ 默认禁用,用 ed25519 或 rsa

改完配置必须重启服务:

sshd -t                      # ★ 先检查语法,避免把自己锁在外面
systemctl restart sshd

3.2 客户端配置:/etc/ssh/ssh_config

客户端配置管的是"我怎么连别人",常见内容:

Host myserver
    HostName 192.168.44.2
    User root
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

配好之后,直接 ssh myserver 就能连。

参数作用
`Host`别名,供 `ssh 别名` 使用
`HostName`真实 IP 或域名
`User`默认登录用户名
`Port`默认端口
`IdentityFile`指定私钥文件
`StrictHostKeyChecking`是否严格校验主机公钥(实验环境可设 `no`,生产**不要**)
`ServerAliveInterval`多少秒发一次心跳,防断线
`TCPKeepAlive`是否用 TCP 层保活

生产建议:加 ServerAliveInterval 60,避免长时间不操作被防火墙断开。

3.3 认证相关文件一览

文件位置作用
私钥`~/.ssh/id_ed25519`自己的私钥,**权限必须 600**
公钥`~/.ssh/id_ed25519.pub`自己的公钥,可以公开
授权公钥`~/.ssh/authorized_keys`允许登录这台机器的公钥列表
已知主机`~/.ssh/known_hosts`记录连过的主机公钥
服务端主机密钥`/etc/ssh/ssh_host_*`服务端身份,**重装后会变**

第四节 常用 SSH 命令

4.1 ssh 远程登录

ssh 用户名@IP
ssh root@192.168.44.2
ssh -p 2222 root@192.168.44.2      # 指定端口
ssh -i ~/.ssh/id_ed25519 root@IP   # 指定私钥

客户端是通用的:Windows(PowerShell/termius)、macOS 终端、Linux 都能用同样的命令连 Linux 服务器。

4.2 常用参数

参数作用
`-p`指定端口
`-i`指定私钥文件
`-v` / `-vv` / `-vvv`调试模式,**卡在哪一步一目了然**
`-o`临时指定配置项,如 `-o StrictHostKeyChecking=no`
`-N`不执行远程命令(只做转发)
`-f`后台运行
`-T`不分配伪终端
`-L` / `-R` / `-D`端口转发

4.3 scp 文件传输

# 下载:远程 → 本地
scp root@192.168.44.2:/root/test.txt .
scp -r root@192.168.44.2:/root/logs ./logs

# 上传:本地 → 远程
scp /root/123 root@192.168.44.2:/root/
scp -r /root/123 root@192.168.44.2:/root/

例子逐项拆解:

scp -r localfile.txt username@192.168.0.1:/home/username/

部分含义
`scp`命令
`-r`递归(传目录)
`localfile.txt`本地文件路径
`username`服务器账号
`192.168.0.1`服务器 IP
`/home/username/`目标目录

版本提醒:OpenSSH 9.0 起,scp 默认改用 SFTP 协议传输。连很老的服务器如果报错,可以加 -O 强制用旧协议。

大文件建议用 rsync:支持断点续传和增量同步,比 scp 更适合重复同步场景。

4.4 sftp 交互式传输

sftp root@192.168.4.2

命令作用
`ls`查看**服务器端**文件
`cd`切换**服务器端**目录
`pwd`显示服务器端当前目录
`lls`查看**本地**文件
`lcd`切换**本地**目录
`get`下载
`put`上传
`mkdir` / `rm`在服务器端建目录 / 删文件
`bye` / `exit`退出

记忆法:带 l 前缀的是本地(local),不带的是远端。

4.5 免密登录(公钥认证)

第一步:生成密钥对

ssh-keygen -t ed25519 -C "your_email@example.com"
# 一路回车即可,默认保存到 ~/.ssh/

第二步:把公钥传到目标机器

ssh-copy-id root@192.168.44.2
# 或者手动:ssh root@IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_ed25519.pub

第三步:验证

ssh root@192.168.44.2      # 不再提示输入密码

★ 权限必须正确,否则免密一定失败

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519

路径要求权限
`~/.ssh``700`
`~/.ssh/authorized_keys``600`
`~/.ssh/id_*`(私钥)`600`
用户家目录**不能对组或其他用户可写**

报错 Authentication refused: bad ownership or modes 就是这个原因。

4.6 known_hosts 与首次连接

第一次连接某台主机时,会看到:

The authenticity of host '192.168.44.2' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxx...
Are you sure you want to continue connecting (yes/no)?

输入 yes 后,对方的主机公钥会被写入 ~/.ssh/known_hosts。

重装系统或换机器后,会报这个错:

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

不是被攻击,而是主机密钥变了。清除旧记录:

ssh-keygen -R 192.168.44.2

4.7 端口转发(运维高频)

类型命令场景
**本地转发**`ssh -L 8080:127.0.0.1:80 user@跳板机`通过跳板访问内网服务
**远程转发**`ssh -R 8080:127.0.0.1:80 user@公网机`把内网服务暴露到公网
**动态转发**`ssh -D 1080 user@跳板机`建一个 SOCKS 代理
# 本地转发:访问本机 8080,等于访问跳板机能看到的 127.0.0.1:80
ssh -N -f -L 8080:127.0.0.1:80 root@192.168.44.2

  • -N:不执行远程命令
  • -f:后台运行

第五节 运维必备

5.1 服务管理

systemctl status sshd
systemctl restart sshd
ss -lntp | grep :22
journalctl -u sshd -f
tail -f /var/log/secure        # Rocky/CentOS 的 SSH 日志

5.2 修改端口的完整步骤(★ 最容易漏 SELinux)

# 1) 改配置
vim /etc/ssh/sshd_config
Port 2222

# 2) 防火墙放行
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload

# 3) SELinux 放行(Rocky/CentOS 必做!)
semanage port -a -t ssh_port_t -p tcp 2222

# 4) 检查语法再重启
sshd -t
systemctl restart sshd

# 5) 新开一个窗口验证,确认能连再关掉旧连接
ssh -p 2222 root@IP

semanage 不是默认安装的:dnf install -y policycoreutils-python-utils

漏了这步的表现是:端口在监听、防火墙也放行了,就是连不上。

5.3 连接不上怎么排查

# 客户端:看卡在哪一步
ssh -vvv root@192.168.44.2

# 服务端:服务在跑吗
systemctl status sshd
ss -lntp | grep sshd

# 服务端:日志说了什么
journalctl -u sshd --since "10 minutes ago"
tail -50 /var/log/secure

# 网络层排查
ping 192.168.44.2
nc -vz 192.168.44.2 22

现象大概率原因
`Connection refused`sshd 没起 / 端口不对 / 防火墙 REJECT
`Connection timed out`防火墙 DROP / 网络不通
`Permission denied (publickey)`公钥没传对 / 权限不对
卡在 `pledge` 或几秒无响应GSSAPI 没关 / DNS 反解慢
`REMOTE HOST IDENTIFICATION HAS CHANGED`主机密钥变了,`ssh-keygen -R`

5.4 安全加固清单

加固项配置说明
禁用 root 直接登录`PermitRootLogin no`用普通用户登录后 `sudo`
禁用密码认证`PasswordAuthentication no`只留公钥登录
限制尝试次数`MaxAuthTries 3`降低暴力破解空间
限制可登录用户`AllowUsers ops`白名单
空闲超时`ClientAliveInterval 300` + `ClientAliveCountMax 2`10 分钟无操作断开
改端口`Port 2222`只减少扫描噪音,**不是真正的安全措施**
防暴力破解fail2ban多次失败自动封 IP

面试点:"改端口能提升安全性吗?" → 只能减少自动化扫描的噪音,扫描器照样能全端口扫出来。真正的安全靠密钥认证 + 禁用 root + 最小权限。

第六节 易错点

  • 客户端配置和服务端配置不是一回事:PermitRootLogin、PasswordAuthentication 这些只能写在 sshd_config。
  • 改完 sshd_config 一定要 systemctl restart sshd,而且要先 sshd -t 检查语法,否则可能把自己锁在外面。
  • 改端口必须同时处理防火墙和 SELinux,漏一个就连不上。
  • 公钥免密登录失败,九成是权限问题(.ssh 700、authorized_keys 600)。
  • known_hosts 里记录的是主机公钥,不是你的公钥;重装系统后必然变化。
  • scp -r 的 -r 是递归,传目录必须加。
  • 私钥绝对不能外传,authorized_keys 里放的永远是 .pub 文件。
  • GSSAPI 没关会导致登录慢,服务端和客户端都要检查。

第七节 SSH 连接工具

工具平台说明
**PuTTY**Windows老牌免费工具,支持 SSH、Telnet、串口
**SecureCRT**Windows / macOS商业软件,多标签、会话管理强
**Xshell**Windows商业软件,国内使用广泛
**Mac 自带终端**macOS系统自带,直接用 `ssh` 命令

第八节 密钥对登录

本节和 4.5 是同一件事。 4.5 用 ssh-keygen -t ed25519 + ssh-copy-id,更短更稳;本节是传统的手工步骤,对照着看即可。

密钥对验证:既安全又方便。

步骤 1:生成并上传公钥

Client 客户端:

ssh-keygen -t rsa

Server 服务端:把公钥上传到服务器

cat id_rsa.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

步骤 2:修改服务端 SSH 配置文件

vim /etc/ssh/sshd_config

PubkeyAuthentication yes                    # 是否使用公钥验证
AuthorizedKeysFile .ssh/authorized_keys     # 公钥保存位置
PasswordAuthentication no                   # 禁止使用密码验证登录

步骤 3:重启 SSH 服务

systemctl restart sshd