余白

SSH 用法速查

基本连接

密码登录

# 基本用法
ssh user@hostname

# 指定端口
ssh -p 2222 user@hostname

# 指定密钥
ssh -i ~/.ssh/my_key user@hostname

密钥登录配置

# 1. 生成密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
# 或 RSA(兼容性好)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 2. 查看公钥
cat ~/.ssh/id_ed25519.pub

# 3. 复制公钥到服务器
ssh-copy-id user@hostname
# 或手动添加
ssh user@hostname "mkdir -p ~/.ssh && echo '公钥内容' >> ~/.ssh/authorized_keys"

# 4. 设置权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

SSH Config 配置

编辑 ~/.ssh/config:

# 全局配置
Host alias                    # 简写别名
    HostName example.com       # 实际地址
    User username              # 用户名
    Port 22                    # 端口
    IdentityFile ~/.ssh/key    # 密钥文件
    ForwardAgent yes           # 转发认证代理

Host *
    ServerAliveInterval 60     # 保活
    ServerAliveCountMax 3      # 超时次数
    AddKeysToAgent yes         # 自动添加密钥
    IdentitiesOnly yes         # 只用指定密钥

使用:

ssh alias    # 直接用别名连接

密钥生成与管理

使用 ssh-keygen 生成密钥

# 生成 RSA 密钥(兼容性最好)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 生成 Ed25519 密钥(更安全、更短,推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 交互式生成(会提示输入文件名和密码)
ssh-keygen

# 指定文件路径和密码
ssh-keygen -t ed25519 -f ~/.ssh/my_key -C "my key"

# 常用选项
# -t type     密钥类型:rsa, ed25519, ecdsa
# -b bits     密钥位数:4096(RSA)
# -C comment  注释,通常用邮箱
# -f file     指定密钥文件路径
# -p          修改密码
# -y          从私钥导出公钥

密钥类型选择:

类型长度兼容性安全性推荐场景
Ed25519256位现代系统最强✅ 推荐
RSA4096位最好强兼容老系统
ECDSA256/384/521位现代系统强可选

上传密钥到服务器

方法一:ssh-copy-id(推荐,最简单)

# 基本用法
ssh-copy-id user@hostname

# 指定端口
ssh-copy-id -p 2222 user@hostname

# 指定密钥文件
ssh-copy-id -i ~/.ssh/my_key.pub user@hostname

# 一次性配置多个服务器
ssh-copy-id -p 2222 -i ~/.ssh/id_ed25519.pub user1@host1
ssh-copy-id -p 2222 -i ~/.ssh/id_ed25519.pub user2@host2

方法二:手动上传(适合没有 ssh-copy-id 的情况)

Step 1: 在本地查看公钥

# 查看公钥内容
cat ~/.ssh/id_ed25519.pub
# 或
cat ~/.ssh/id_rsa.pub

# 复制输出内容(以 ssh-ed25519 AAAAB3... 或 ssh-rsa AAAAB3... 开头)

Step 2: 在服务器创建目录和文件

# SSH 登录到服务器
ssh user@hostname

# 创建 .ssh 目录(如不存在)
mkdir -p ~/.ssh

# 创建 authorized_keys 文件
touch ~/.ssh/authorized_keys

# 添加公钥(粘贴刚才复制的公钥内容)
echo "ssh-ed25519 AAAAB3... your_email@example.com" >> ~/.ssh/authorized_keys

# 或使用 cat 多行输入
cat >> ~/.ssh/authorized_keys << 'EOF'
ssh-ed25519 AAAAB3... your_email@example.com
ssh-rsa AAAAB3... another_key
EOF

Step 3: 设置权限

# 必须设置正确的权限,否则 SSH 会拒绝
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

方法三:一条命令远程执行(无需先登录)

# 通过 SSH 直接在远程创建目录和添加密钥
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 更安全的方式(指定端口)
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 user@hostname "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys"

验证密钥登录

# 测试密钥登录(不会提示输入密码)
ssh -i ~/.ssh/my_key user@hostname

# 详细调试模式(查看连接过程)
ssh -vvv -i ~/.ssh/my_key user@hostname

管理多个密钥

# 查看已添加的密钥
ssh-add -l

# 添加密钥到 agent
ssh-add ~/.ssh/my_key

# 添加密钥并设置超时(3600秒 = 1小时)
ssh-add -t 3600 ~/.ssh/my_key

# 删除所有密钥
ssh-add -D

# 删除特定密钥
ssh-add -d ~/.ssh/my_key

# 查看密钥指纹
ssh-keygen -lf ~/.ssh/my_key.pub

最佳实践

# 1. 为不同服务器使用不同密钥
# 公司服务器
ssh-keygen -t ed25519 -f ~/.ssh/company_key -C "work@company.com"

# 个人服务器
ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "me@home.com"

# 2. 在 ~/.ssh/config 中指定密钥
Host company
    HostName company-server.com
    User admin
    IdentityFile ~/.ssh/company_key

Host personal
    HostName my-server.com
    User root
    IdentityFile ~/.ssh/personal_key

# 3. 设置密钥密码(可选,但更安全)
# 首次使用时会提示输入密码
# 可以用 ssh-agent 记住密码,避免每次输入
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/my_key

端口转发

本地端口转发

本地端口映射到远程:

# 将本地 8080 转发到远程内网服务
ssh -L 8080:localhost:80 user@server

# 格式
ssh -L 本地端口:目标地址:目标端口 跳板服务器

# 示例:访问远程内网 MySQL
ssh -L 3306:localhost:3306 user@remote_server

# 示例:访问内网其他服务器
ssh -L 8080:192.168.1.100:80 user@jump_server

远程端口转发

远程端口映射到本地(反向隧道):

# 将远程 8080 转发到本地
ssh -R 8080:localhost:80 user@server

# 格式
ssh -R 远程端口:目标地址:目标端口 远程服务器

# 示例:让远程访问本地开发服务
ssh -R 80:localhost:3000 user@remote_server

动态端口转发(SOCKS 代理)

# 创建 SOCKS5 代理
ssh -D 1080 -q -C -N user@server

# 参数说明
# -D 1080    本地监听端口
# -q         静默模式
# -C         压缩数据
# -N         不执行远程命令

# 保持后台运行
nohup ssh -D 1080 -q -C -N user@server > /dev/null 2>&1 &

# 配合浏览器代理使用
# SOCKS5 代理:127.0.0.1:1080

本地动态转发(透明代理)

# 透明代理,代理所有流量
ssh -D 1080 -f -C -q -N user@server

# -f 后台运行

SCP 文件传输

基本用法

# 本地到远程
scp file.txt user@host:/path/
scp file1.txt file2.txt user@host:/path/

# 远程到本地
scp user@host:/path/file.txt ./

# 目录传输
scp -r /local/dir user@host:/remote/dir

# 常用选项
scp -P port        # 指定端口(大写P)
scp -p              # 保留文件属性
scp -r              # 递归复制
scp -C              # 压缩传输
scp -v              # 详细输出

保持后台运行

# 传输大文件
nohup scp -r large_dir user@host:/path/ > transfer.log 2>&1 &

Rsync 远程同步

# 基本同步
rsync -av /local/ user@host:/remote/

# 同步到远程
rsync -avz --delete /local/ user@host:/remote/

# 从远程同步
rsync -av user@host:/remote/ /local/

# 常用选项
# -a      归档模式
# -v      详细
# -z      压缩
# -P      显示进度
# --delete  删除目标多余文件
# --exclude 排除文件

SSH 隧道应用

1. 内网数据库访问

# MySQL
ssh -L 3306:localhost:3306 user@db_server

# PostgreSQL
ssh -L 5432:localhost:5432 user@db_server

# Redis
ssh -L 6379:localhost:6379 user@redis_server

2. 跳板机访问内网

# 通过跳板机访问内网服务器
ssh -J user@jump_server user@internal_server

# 或配置 ~/.ssh/config
Host internal
    HostName 192.168.1.100
    ProxyJump user@jump_server

3. 远程开发

# 转发远程端口到本地
ssh -L 8000:localhost:8000 user@dev_server

# VSCode Remote SSH
ssh user@host

Git SSH 代理

配置 Git SSH

编辑 ~/.ssh/config:

# 全局代理(所有 Git 操作)
Host github.com gitlab.com
    ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p

# 或使用 Connect 工具
Host github.com
    ProxyCommand connect -S 127.0.0.1:1080 %h %p

安装 connect-proxy

# Ubuntu
sudo apt install connect-proxy

# macOS
brew install connect

X-Window 转发

# 开启 X11 转发
ssh -X user@host

# 加速模式(不检查)
ssh -Y user@host

# 运行图形程序
firefox &
gedit file.txt

SSH 连接管理

SSH Agent

# 启动 agent
eval "$(ssh-agent -s)"

# 添加密钥
ssh-add ~/.ssh/id_ed25519
ssh-add ~/.ssh/id_rsa

# 列出已添加密钥
ssh-add -l

# 删除所有密钥
ssh-add -D

# 设置超时(缓存时间)
ssh-add -t 3600 ~/.ssh/key

连接复用

编辑 ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

创建 socket 目录:

mkdir -p ~/.ssh/sockets

安全建议

1. 禁用密码登录

编辑 /etc/ssh/sshd_config(服务器端):

PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
MaxAuthTries 3

2. 更改默认端口

Port 2222

3. 限制用户登录

AllowUsers user1 user2
AllowGroups sudo

4. 使用 fail2ban

sudo apt install fail2ban
sudo systemctl enable fail2ban

常用场景

场景1:临时代理访问外网

ssh -D 1080 -q -C -N user@overseas_server

场景2:同步代码到服务器

rsync -avz --exclude='.git' --exclude='node_modules' ./ user@server:/var/www/

场景3:保持连接活跃

# 客户端配置
ServerAliveInterval 60
ServerAliveCountMax 3

场景4:SFTP 传输

sftp user@host
# 或图形化
filezilla

命令速查

命令说明
ssh user@host基本连接
ssh -p port user@host指定端口
ssh -i key user@host密钥登录
ssh -L port:host:port本地端口转发
ssh -R port:host:port远程端口转发
ssh -D portSOCKS 代理
ssh -J user@jump user@dest跳板连接
scp file user@host:/path复制到远程
scp -r dir user@host:/path复制目录
rsync -av /local/ user@host:/remote/同步目录

参考链接