SSH远程管理服务

10 阅读10分钟

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

参数常见值说明
Port22监听端口
ListenAddress0.0.0.0监听的 IP
HostKey/etc/ssh/ssh_host_ed25519_key服务端主机私钥位置
LogLevelINFO日志等级
SyslogFacilityAUTH日志记录 SSH 登录情况
GSSAPIAuthenticationyesGSSAPI(Kerberos)认证
PermitRootLoginyes / no是否允许 root 直接登录
PubkeyAuthenticationyes是否启用公钥认证
AuthorizedKeysFile.ssh/authorized_keys公钥保存位置(相对用户家目录)
PasswordAuthenticationyes / no是否允许密码认证
PermitEmptyPasswordsno是否允许空密码
UsePAMyes是否使用 PAM 做认证/会话管理
MaxAuthTries6最大认证尝试次数

关于 GSSAPIAuthentication(常见坑)

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

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

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

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

关于已过时的参数

旧参数说明
Protocol 2OpenSSH 7.6+ 已删除,不用再写
ServerKeyBits 1024已移除,且 1024 位过弱
ssh_host_dsa_keyDSA 在 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
路径要求权限
~/.ssh700
~/.ssh/authorized_keys600
~/.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 refusedsshd 没起 / 端口不对 / 防火墙 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 210 分钟无操作断开
改端口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 连接工具

工具平台说明
PuTTYWindows老牌免费工具,支持 SSH、Telnet、串口
SecureCRTWindows / macOS商业软件,多标签、会话管理强
XshellWindows商业软件,国内使用广泛
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