📖 导读:这篇文章面向第一次接触 SSH 的新手。正文保留原技术内容,对出现的专业名词和概念用
💡 注的形式补充通俗解释,帮你扫清理解障碍。命令部分可以直接照抄使用。
SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络上安全地运行网络服务。它最常用于远程登录到计算机系统,执行命令,也支持文件传输、端口转发等功能。SSH 是系统管理员、开发人员和运维工程师的必备工具。
💡 注(网络协议):协议就是两台计算机约定好"怎么互相说话"的规则–数据以什么格式发送、对方怎么回应。SSH 是其中一种专门用于"安全远程操作"的协议。
💡 注(加密):加密就是把原本明文的数据用数学方法打乱成一串乱码,只有持有"钥匙"的人才能还原。这样即使数据在网络传输途中被别人截获,看到的也是乱码,无法读懂内容。
💡 注(远程登录):就是你在自己的电脑上,通过网络操作另一台电脑,效果就像坐在那台电脑前敲键盘一样。常用于管理服务器–服务器通常放在机房或云端,你没法物理接触。
1. 什么是 SSH?
SSH 是 Secure Shell 的缩写,它替代了早期的 Telnet、rlogin 等不安全的远程登录协议。SSH 通过对所有通信数据进行加密和认证,防止了中间人攻击、窃听、连接劫持等风险。
💡 注(三种攻击通俗解释):
- 窃听:别人在网络上"偷听"你发的数据。早期 Telnet 明文传输,密码都能被直接读出来。
- 中间人攻击:攻击者冒充服务器(或客户端)插在你们中间,转发并窃取信息。
- 连接劫持:攻击者在你已经连上之后,强行接管你的连接。
SSH 的加密和认证机制能防住这三种。
SSH 的主要组件
- SSH 客户端:用于发起连接的软件,如 OpenSSH 客户端(
ssh命令)、PuTTY、Termius 等。 - SSH 服务器:运行在远程主机上的守护进程(
sshd),接受客户端的连接请求。 - 加密技术:SSH 使用公钥密码学进行身份认证,并使用对称加密(如 AES)保护会话数据。
- 协议版本:目前主流的是 SSH-2,修复了 SSH-1 中的安全漏洞。
💡 注(守护进程 daemon):守护进程就是一直在后台运行、默默等待任务的服务程序。
sshd里的d就代表 daemon。它开机就启动,一直监听"有没有人来连接",有人连就处理。💡 注(公钥密码学 / 对称加密):这是两种加密方式,后文"密钥认证"会详细讲公钥密码学。这里先知道:对称加密 = 加密和解密用同一把钥匙(速度快,用来加密会话内容);公钥密码学 = 一对钥匙,一把公开一把保密(用来做身份认证)。
SSH 工作原理简述
- 连接建立:客户端向服务器发起 TCP 连接(默认端口 22)。
- 版本协商:双方交换协议版本。
- 密钥交换:通过 Diffie-Hellman 算法生成共享密钥,用于后续对称加密。
- 服务器认证:客户端验证服务器的主机密钥(通常存储在
~/.ssh/known_hosts中)。 - 用户认证:客户端通过密码、公钥等方式向服务器证明身份。
- 会话交互:认证成功后,双方建立加密通道,用户即可执行命令或传输文件。
💡 注(端口 port):端口可以理解为一台电脑上"信箱的编号"。一台电脑同时跑很多网络服务,IP 地址只定位到电脑,端口号定位到电脑上的具体服务。SSH 默认用 22 号端口。后面会看到很多
-p 端口号的用法就是指定端口。💡 注(主机密钥):服务器自带的"身份证",用于让客户端确认"我连的确实是这台服务器,没被冒充"。第一次连接时客户端会把这个身份证记下来(存在
known_hosts文件里),下次再连如果身份证变了就会警告。
2. 如何安装 SSH
💡 注(OpenSSH):OpenSSH 是 SSH 协议最主流的免费开源实现,绝大多数系统里的
ssh命令都来自它。
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install openssh-client # 仅客户端
sudo apt install openssh-server # 仅服务器(如需作为服务端)
💡 注(sudo):
sudo表示"以管理员权限运行",安装软件需要权限所以前面要加它。会让你输密码,输入时不显示字符是正常的。
macOS
macOS 默认已安装 OpenSSH 客户端。如需启动服务器(远程登录),在 系统设置 -> 通用 -> 共享 中开启"远程登录"。
Windows
Windows 10 版本 1809 及更高版本内置了 OpenSSH 客户端,可通过 PowerShell 安装:
# 安装客户端
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
# 安装服务器(可选)
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
也可使用第三方工具如 PuTTY、Git Bash 中的 SSH。
3. SSH 的基本用法
3.1 连接远程主机
ssh user@hostname
user:远程主机上的用户名hostname:远程主机的 IP 地址或域名
例如:
ssh alice@192.168.1.100
首次连接时,会提示确认主机密钥,输入 yes 后即可输入密码登录。
💡 注(首次连接提示):第一次连一台新服务器时,SSH 会说"我不认识这台机器,它的指纹是 xxx,要继续吗?“这是在让你确认服务器身份。输
yes就会把它记到known_hosts,以后不再问(除非它变了–那可能是被冒充,会警告)。
3.2 指定端口
如果 SSH 服务器运行在非默认端口(如 2222),使用 -p 选项:
ssh -p 2222 user@hostname
3.3 执行远程命令
直接在 ssh 命令后加上要执行的命令,命令将在远程主机上运行,然后退出:
ssh user@hostname "ls -la /var/log"
3.4 启用调试输出
遇到连接问题时,可使用 -v(详细)模式,或 -vvv 获取更详细的调试信息:
ssh -v user@hostname
4. 密钥认证(免密登录)
使用 SSH 密钥对替代密码登录,更安全且方便自动化。
💡 注(密钥对–重要概念):密钥认证的核心是一对钥匙–公钥和私钥。
- 可以这样理解:公钥相当于一把"锁”(可以给别人),私钥相当于"开这把锁的钥匙"(只自己保留)。
- 你把公钥放到服务器上(相当于给服务器装了把锁),自己保留私钥。
- 连接时,服务器用公钥出一道题考你,只有持有私钥的人才能答对,答对就放行–全程不传密码。
- 私钥文件绝不能给别人,公钥可以随便公开。
4.1 生成密钥对
使用 ssh-keygen 生成 RSA(或 Ed25519)密钥对:
ssh-keygen -t ed25519 -C "your_email@example.com"
-t ed25519:指定密钥类型(推荐 Ed25519,性能好且安全)-C:添加注释,通常填写邮箱 按提示选择保存路径(默认~/.ssh/id_ed25519)和设置密码短语(可选)。
💡 注(
~符号):~在类 Unix 系统(Linux/macOS)里代表"当前用户的家目录",相当于/home/你的用户名(macOS 是/Users/你的用户名)。所以~/.ssh就是家目录下的.ssh文件夹。Windows 上~通常对应C:\Users\你的用户名。💡 注(密码短语 passphrase):这是给私钥文件再加一层密码保护。即使别人偷到你的私钥文件,没有这个短语也用不了。可以留空(图省事),但填了更安全。
4.2 复制公钥到远程主机
使用 ssh-copy-id 命令自动将公钥添加到远程主机的 ~/.ssh/authorized_keys 中:
ssh-copy-id user@hostname
若系统无此命令,可手动复制公钥内容并追加到远程 ~/.ssh/authorized_keys:
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
💡 注:
authorized_keys就是服务器上"登记哪些公钥可以登录我"的名单文件。你的公钥加进去后,服务器就认得你了。
4.3 配置权限
确保远程主机的 ~/.ssh 目录权限为 700,authorized_keys 文件权限为 600:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
💡 注(权限数字):Linux 文件权限用三位数字表示,分别对应"文件主人 / 同组用户 / 其他人"能做什么。每个数字由 读(4)+写(2)+执行(1) 组合而成:
700= 主人能读能写能执行(7=4+2+1),其他人啥也不能干(0)。600= 主人能读能写(6=4+2),其他人啥也不能干(0)。- SSH 对权限很敏感:如果权限太松(别人能读你的密钥文件),它会拒绝工作。这是安全保护。
完成上述步骤后,再次连接将不再提示输入密码。
5. SSH 客户端配置文件
通过 ~/.ssh/config 文件可以为不同的主机设置别名、端口、密钥等,简化连接命令。
示例配置文件:
Host myserver
HostName 192.168.1.100
User alice
Port 2222
IdentityFile ~/.ssh/mykey_ed25519
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_ed25519
配置后,可直接使用 ssh myserver 连接,无需输入冗长的参数。
💡 注:这个配置文件是纯文本,没有也照样能用 SSH,只是有了它更省事–给常连的服务器起个短别名,记不住的 IP、端口、密钥路径都写进去,以后
ssh myserver一条命令搞定。
6. 文件传输
6.1 scp(基于 SSH 的远程复制)
# 从本地复制到远程
scp /local/file.txt user@hostname:/remote/path/
# 从远程复制到本地
scp user@hostname:/remote/file.txt /local/path/
# 复制整个目录(加 -r 选项)
scp -r /local/dir user@hostname:/remote/dir
6.2 sftp(交互式文件传输)
sftp user@hostname
进入 SFTP 提示符后,可使用 get、put、ls、cd 等命令操作文件。
💡 注(scp vs sftp):
scp是"一次性传文件"–一条命令传完就结束;sftp是"交互式"–进去后可以反复下命令传多个文件,像用 FTP 一样。日常传一两个文件用 scp 更快。
7. SSH 代理(ssh-agent)
ssh-agent 是一个缓存私钥的程序,避免每次使用密钥都输入密码短语。
启动 ssh-agent 并添加密钥
eval "$(ssh-agent -s)" # 启动代理
ssh-add ~/.ssh/id_ed25519 # 添加私钥(会提示输入密码短语)
之后在同一会话中连接远程主机时,将自动使用已添加的密钥。
💡 注(eval 是干嘛的):
ssh-agent -s会输出几行"设置环境变量"的命令,但只是打印出来不会执行。eval "$(...)"的作用是"把括号里命令的输出当成命令再执行一遍",从而真正把环境变量设好,让后续的ssh-add和ssh能找到这个代理。照抄即可,不用深究。💡 注(会话):这里说的"会话"指一个终端窗口开着期间。关掉终端,代理就结束了,下次还得重新启动–所以才有下面的"永久配置"。
永久配置(macOS/Linux)
可将上述命令添加到 shell 配置文件(如 .bashrc、.zshrc)中。
💡 注(shell 配置文件):
.bashrc/.zshrc是终端每次启动时自动执行的脚本。把启动代理的命令写进去,就不用每次手动运行了。macOS 默认用 zsh(对应.zshrc),多数 Linux 用 bash(对应.bashrc)。
8. SSH 端口转发(隧道)
💡 注(端口转发 / 隧道–重要概念):端口转发(也叫"隧道")就是把"本来要发到 A 端口的流量,通过 SSH 加密管道转交给 B"。打个比方:SSH 是一条加密的地下管道,你把本来要走地上(不安全)的流量改走这条地下管道,既安全又能"绕路"到达原本到不了的地方。下面三种是不同方向的转发。
SSH 端口转发允许将本地端口流量通过 SSH 加密隧道转发到远程主机,或反向转发。
8.1 本地转发(将远程端口映射到本地)
访问远程主机上的服务(如数据库)就像访问本地服务一样。
ssh -L 本地端口:目标主机:目标端口 用户@跳板机
例如,通过跳板机访问内部网络的 MySQL(3306):
ssh -L 3306:internal-db:3306 user@jumpbox
然后在本地用 127.0.0.1:3306 连接即可。
💡 注(跳板机 / 堡垒机):内部网络里的数据库通常不对外开放,只能从一台"中间机器"访问,这台中间机器就叫跳板机(jumpbox)或堡垒机。你先 SSH 到跳板机,再通过它转到内部数据库。本地转发就是让"本地端口"的流量经跳板机送到数据库。
8.2 远程转发(将本地端口暴露到远程)
让远程主机可以访问我们本地的服务。
ssh -R 远程端口:本地主机:本地端口 用户@远程主机
例如,让远程主机能访问本地运行的 web 服务(8080):
ssh -R 8080:localhost:3000 user@remote
在远程主机上访问 localhost:8080 即可。
💡 注(
-Lvs-R怎么记):-L(Local)= 在本地开端口,把远程服务拉到本地;-R(Remote)= 在远程开端口,把本地服务推到远程。两者方向相反。
8.3 动态转发(SOCKS 代理)
创建一个 SOCKS 代理,通过 SSH 服务器转发所有流量。
ssh -D 本地端口 用户@远程主机
例如,在本地创建 SOCKS5 代理端口 1080:
ssh -D 1080 user@remote
然后在浏览器或系统设置中配置 SOCKS 代理为 127.0.0.1:1080,即可通过远程主机上网。
💡 注(SOCKS 代理):SOCKS 是一种通用的代理协议。开了动态转发后,你的浏览器把所有流量交给本地 1080 端口,SSH 把这些流量加密送到远程主机,再由远程主机替你访问互联网–相当于"借远程主机的网络上网"。常用于在不信任的网络里安全上网,或访问只有远程主机那边才能访问的资源。
9. 安全最佳实践
- 禁用 root 密码登录:在
/etc/ssh/sshd_config中设置PermitRootLogin prohibit-password(仅允许密钥登录)。 - 使用密钥认证,禁用密码:设置
PasswordAuthentication no。 - 更改默认端口:降低被自动扫描的概率(但并非真正安全)。
- 限制用户访问:使用
AllowUsers或DenyUsers指令。 - 使用防火墙:如
ufw限制 SSH 端口访问来源 IP。 - 定期更新 OpenSSH:确保修复已知漏洞。
💡 注:
/etc/ssh/sshd_config是 SSH 服务器端的主配置文件,改完要让配置生效需重启 sshd 服务(如sudo systemctl restart sshd)。改之前建议备份原文件–改错了可能把自己锁在外面连不上服务器。
10. 故障排查
常见问题及解决
- 连接超时:检查远程主机是否可达(ping),防火墙是否开放端口。
- 认证失败:检查用户名、密码/密钥是否正确;查看服务器日志
/var/log/auth.log。 - 主机密钥变更:如果重装系统后连接,会出现"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!",需移除旧的 known_hosts 条目:
ssh-keygen -R 主机名 - 权限错误:确保本地
~/.ssh和私钥文件权限正确(私钥应为 600)。
💡 注(主机密钥变更警告):这行警告意思是"这台服务器的身份证和上次记的不一样了"。常见原因:服务器重装系统、IP 对应的机器换了。但也可能是真的被冒充了。确认安全后用
ssh-keygen -R 主机名删掉旧记录,重新连接即可。
11. 总结
SSH 是远程管理和安全通信的核心工具。掌握 SSH 的基本用法、密钥认证、配置管理和端口转发,能极大提高工作效率和系统安全性。建议日常工作中尽量使用密钥认证,并熟悉客户端配置文件以简化操作。
本文档适用于个人知识库构建,涵盖了 SSH 的主要概念和实践用法。如有更深入的需求,可参考 OpenSSH 官方文档或 man ssh。
💡 注(
man命令):man ssh就是打开 ssh 命令的内置说明书(manual),按方向键滚动,按q退出。Linux/macOS 下几乎所有命令都有 man 手册。