SSH 远程连接
服务器在机房或云端,你不可能搬个显示器接上去。SSH(Secure Shell)就是远程登录和管理 Linux 服务器的标准协议——加密、安全、功能强大。这一篇讲从基础连接到密钥免密、文件传输、端口转发的完整技能。
1. ssh:基本连接
最简单的用法:ssh 用户名@主机。第一次连会问你是否信任对方,输入 yes 即可。
# 基本连接
ssh user@host # 用户名@主机(IP 或域名)
ssh root@192.168.1.100
ssh aden@example.com
# 指定端口(默认 22,有些服务器改了端口)
ssh -p 2222 user@host
ssh -p 22022 aden@example.com
# 首次连接会问你是否信任这个主机
# The authenticity of host '192.168.1.100' can't be established.
# ED25519 key fingerprint is SHA256:xxxxx.
# Are you sure you want to continue connecting (yes/no)?
# 输入 yes,主机的指纹会存进 ~/.ssh/known_hosts
# 执行单条命令不进入交互 shell
ssh user@host "uname -a"
ssh user@host "df -h"
# 执行完自动断开退出 SSH 会话用 exit 或 Ctrl+D。如果连接卡住了,按回车后输入 ~.(波浪号加点)可以强制断开。
2. SSH 密钥:免密登录
每次输密码既麻烦又不安全。SSH 密钥让你一次配置,永久免密——而且比密码安全得多。这是运维和开发的必备技能。
# SSH 密钥:免密登录的基础
# 1. 生成密钥对(本地操作,一次生成永久用)
ssh-keygen -t ed25519 -C "your_email@example.com"
# -t 算法(ed25519 推荐;老式 rsa 也行,但建议 -b 4096)
# -C 注释(标识这个密钥是谁的)
# 回车后会问:
# 保存路径(默认 ~/.ssh/id_ed25519,直接回车)
# passphrase(密钥密码,可以留空,但加一层更安全)
# 生成两个文件:
# ~/.ssh/id_ed25519 私钥(绝对不能泄露!)
# ~/.ssh/id_ed25519.pub 公钥(可以告诉别人)
# 2. 把公钥传到服务器(用 ssh-copy-id 一键搞定)
ssh-copy-id user@host
ssh-copy-id -i ~/.ssh/mykey.pub user@host # 指定密钥
# 3. 之后 ssh user@host 不用再输密码
# scp/rsync/git push 都自动免密3. 密钥登录的原理
理解原理有助于排查问题。SSH 密钥用的是非对称加密:
# SSH 密钥登录原理(非对称加密)
# 你的本地有两个文件:
# 私钥 id_ed25519 --- 必须保密,留在本地
# 公钥 id_ed25519.pub --- 可以公开
# 服务器的 ~/.ssh/authorized_keys 里存了你的公钥
# 连接时:
# 1. 客户端发起连接
# 2. 服务器用你存的公钥发起一个数学挑战
# 3. 客户端用私钥响应(证明"我有私钥"但不传输私钥)
# 4. 服务器验证响应,通过则登录成功
# 关键:私钥从不离开你的电脑,所以即使网络被监听也安全
# 密钥权限要求(SSH 极严格,权限不对就拒绝)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 # 私钥
chmod 644 ~/.ssh/id_ed25519.pub # 公钥
chmod 600 ~/.ssh/authorized_keys # 服务器端关键特性:私钥从不离开你的电脑,所以即使网络被监听也安全。这也是为什么 GitHub、GitLab 都推荐用 SSH 密钥 push 代码。
4. 常见问题排查
配了密钥还是要密码?按这个顺序查:
- 权限不对(最常见):
~/.ssh必须 700,私钥必须 600,服务器authorized_keys必须 600。 - 服务器配置:检查
/etc/ssh/sshd_config里PubkeyAuthentication yes。 - 详细日志:客户端用
ssh -v user@host看详细握手过程(-vv更详细)。 - 服务器日志:(在服务器上)
sudo tail -f /var/log/auth.log。
5. scp 与 rsync:传文件
在本地和远程之间传文件,有两个工具:
# scp:secure copy,在本地和远程之间复制文件
# 从本地传到远程
scp file.txt user@host:/path/
scp file.txt user@host:/path/newname.txt
scp -r mydir user@host:/tmp/ # -r 传目录
# 从远程拉到本地
scp user@host:/var/log/app.log ./
scp -r user@host:/backup ~/local-backup/
# 指定端口
scp -P 2222 file.txt user@host:/tmp/ # 注意是大写 P(ssh 是小写 -p)
# rsync:更强大的同步工具(增量传输、断点续传)
rsync -avz mydir/ user@host:/backup/
# -a 归档模式(保留权限、递归)
# -v 显示过程
# -z 压缩传输
# 源路径末尾的 / 很关键:
# mydir/ 同步目录里的内容
# mydir 把 mydir 目录本身传过去
# 带进度条
rsync -avz --progress mydir/ user@host:/backup/
rsync -avz --delete src/ user@host:dst/ # --delete 删目标多余的文件scp 简单直接,适合偶尔传几个文件;rsync 增量同步、断点续传、压缩传输,适合大量文件或定期备份。注意 rsync 源路径末尾的 /——加了同步内容,不加传整个目录,这个差别让无数人踩坑。
6. ssh config:管理多台服务器
如果你管多台服务器(开发、测试、生产、客户机),每次敲 ssh -i xxx -p xxx user@ip 太烦。~/.ssh/config 把这些信息存下来,起个短名字:
# ~/.ssh/config:管理多台服务器(强烈推荐)
# 编辑 vim ~/.ssh/config,加入:
Host myserver
HostName 192.168.1.100
User aden
Port 22
IdentityFile ~/.ssh/id_ed25519
Host gpu
HostName gpu.lab.univ.edu
User researcher
Port 22022
IdentityFile ~/.ssh/lab_key
Host aws-prod
HostName ec2-1-2-3-4.compute.amazonaws.com
User ubuntu
IdentityFile ~/.ssh/aws.pem
# 之后直接 ssh myserver,不用敲一长串
ssh myserver
scp file.txt myserver:/tmp/
rsync -avz dir/ gpu:~/data/
# 通配符:给一组主机设共同配置
Host *.lab.univ.edu
User researcher
Port 22022配置好后,直接 ssh myserver 就能连接,scp/rsync 也都能用这个别名(scp f myserver:/tmp/)。这是提升幸福感的小技巧。
7. 端口转发:SSH 隧道
SSH 不只能登录,还能做端口转发——通过 SSH 隧道访问本来访问不到的服务。三个方向:
# 端口转发:通过 SSH 隧道访问内网服务
# 本地转发(-L):把远程服务映射到本地端口
# 场景:数据库在内网(只允许 localhost 连),你想本机访问
ssh -L 5432:localhost:5432 user@jumpserver
# 本机的 5432 端口 = 通过 jumpserver 转发到内网的 5432
# 然后本机连 localhost:5432 就是连远程数据库
# psql -h localhost -p 5432 即可
# 远程转发(-R):把本地服务暴露给远程
# 场景:本机起了个开发服务,想让公网服务器临时访问
ssh -R 8080:localhost:3000 user@public-server
# public-server 的 8080 = 转发到你本机的 3000
# 动态转发(-D):SOCKS 代理
ssh -D 1080 user@server
# 本机 1080 是个 SOCKS5 代理,流量经 server 出去
# 后台跑 + 不分配 tty(端口转发常用)
ssh -fNL 5432:localhost:5432 user@host
# -f 后台 -N 不执行命令 -L 本地转发最常用的是本地转发 -L:数据库只允许从服务器本机连(安全考虑),你本机想连,就通过 SSH 隧道转发:ssh -L 5432:localhost:5432 user@server 后,本机连 localhost:5432 就是连远程数据库。
8. 安全建议(生产环境必读)
- 禁用 root 远程登录:编辑
/etc/ssh/sshd_config设PermitRootLogin no。 - 禁用密码登录(只允许密钥):
PasswordAuthentication no。攻击者暴力破解密码就无效了。 - 改默认端口:把 22 改成其他端口(如 22022),避开大量自动扫描。注意防火墙要放行新端口。
- 用 fail2ban:多次失败登录自动封 IP。
- 密钥加 passphrase:私钥即使被盗,没有 passphrase 也用不了。
- 不要把私钥提交到 Git:
~/.ssh/里的私钥绝对不能上传到任何仓库或网盘。
改完 sshd_config 后用 sudo systemctl restart sshd 重启服务生效。改之前保持一个已登录的会话不要断开,以防配置出错把自己锁在外面。
9. 实战:从零配置一台新服务器
拿到一台云服务器,完整流程:
- 本地
ssh-keygen生成密钥(如果还没有)。 - 首次用密码登录服务器,创建普通用户(不用 root 干活)。
- 本地
ssh-copy-id user@server上传公钥。 - 测试密钥登录成功后,关闭密码登录和 root 登录。
- 本地
~/.ssh/config加个别名。 - 之后
ssh myserver一键连接。
小结
这一篇你掌握了 SSH 的全套技能:基本连接、密钥免密登录、scp/rsync 传文件、ssh config 管理多主机、端口转发访问内网服务、生产环境安全加固。下一篇讲服务管理——systemd。
← 上一篇 Vim 编辑器
下一篇 systemd 服务管理 →