SSH远程管理

最后更新: 2026-01-11 作者: Linux Team
页面目录
目录

SSH基础

什么是SSH?

SSH(Secure Shell)是一种加密网络协议,用于安全地远程登录和传输数据。

┌─────────────────────────────────────────────────────────────┐
│                    SSH 工作原理                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Client ────────── SSH加密隧道 ────────── Server          │
│                                                             │
│   ├── 密钥交换 (Key Exchange)                               │
│   ├── 身份验证 (Password/Key)                               │
│   └── 数据加密传输 (AES, ChaCha20)                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

SSH配置文件

# 用户配置文件
~/.ssh/config

# 用户公钥
~/.ssh/id_rsa.pub           # RSA公钥
~/.ssh/id_ed25519.pub       # Ed25519公钥(推荐)
~/.ssh/id_ecdsa.pub         # ECDSA公钥

# 用户私钥
~/.ssh/id_rsa               # RSA私钥
~/.ssh/id_ed25519           # Ed25519私钥(推荐)
~/.ssh/id_ecdsa             # ECDSA私钥

# 系统配置
/etc/ssh/sshd_config        # SSH服务器配置
/etc/ssh/ssh_config         # SSH客户端默认配置
/etc/ssh/ssh_host_*         # 服务器主机密钥

基本连接

密码登录

# 基本语法
ssh username@hostname
ssh username@192.168.1.100
ssh -p 2222 username@hostname   # 指定端口

# 首次连接会显示指纹确认
The authenticity of host 'hostname' can't be established.
ECDSA key fingerprint is SHA256:xxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

SSH密钥登录

# 1. 生成密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 2. 选择存储位置(默认~/.ssh/)
Enter file in which to save the key (/home/user/.ssh/id_ed25519): 

# 3. 设置密码(可选但推荐)
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

# 4. 复制公钥到服务器
ssh-copy-id username@hostname
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@hostname

# 5. 登录测试
ssh username@hostname

SSH配置文件

# ~/.ssh/config
Host alias
    HostName hostname.example.com
    User username
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ForwardAgent yes

Host server1
    HostName 192.168.1.100
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_rsa

Host server2
    HostName 192.168.1.101
    User root
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentitiesOnly yes
# 使用别名连接
ssh alias
ssh server1
ssh server2

SSH密钥管理

密钥类型对比

类型 密钥大小 安全性 兼容性 推荐
RSA 2048-4096 最好 ⭐⭐
Ed25519 256 最高 良好 ⭐⭐⭐
ECDSA 256-521 良好 ⭐⭐

密钥操作

# 查看现有密钥
ls -la ~/.ssh/
cat ~/.ssh/id_ed25519.pub

# 添加密钥到ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l                    # 列出已加载的密钥

# macOS Keychain集成
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# 修改密钥密码
ssh-keygen -p -f ~/.ssh/id_ed25519

# 导出公钥
ssh-keygen -y -f ~/.ssh/id_ed25519

authorized_keys管理

# 查看服务器的authorized_keys
cat ~/.ssh/authorized_keys

# 允许多个密钥
ssh-rsa AAAAB3NzaC1... key1
ssh-rsa AAAAB3NzaC1... key2
ssh-ed25519 AAAAC3Nza... key3

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

SSH服务器配置

sshd_config详解

# /etc/ssh/sshd_config

# 基本设置
Port 22
ListenAddress 0.0.0.0
Protocol 2

# 认证设置
PermitRootLogin no              # 禁止root登录
PubkeyAuthentication yes        # 启用公钥认证
PasswordAuthentication yes      # 启用密码认证(建议关闭)
PermitEmptyPasswords no         # 禁止空密码
MaxAuthTries 3                  # 最大尝试次数
MaxSessions 10                  # 最大会话数

# 安全设置
ClientAliveInterval 300          # 客户端存活检测(秒)
ClientAliveCountMax 3           # 检测次数
LoginGraceTime 60               # 登录宽限期(秒)
StrictHostKeyChecking ask       # 主机密钥检查
X11Forwarding yes              # X11转发

# 日志
SyslogFacility AUTH
LogLevel INFO

# 子系统
Subsystem sftp /usr/lib/openssh/sftp-server

# 允许用户/组
AllowUsers user1 user2
AllowGroups sshusers

# 禁止用户/组
DenyUsers baduser
DenyGroups badgroup

安全加固配置

# 创建sshd配置备份
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 编辑配置
sudo vim /etc/ssh/sshd_config

# 推荐的安全配置
Port 2222
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowUsers username

# 重新加载配置
sudo systemctl restart sshd
sudo systemctl reload sshd

SSH密钥登录测试

# 1. 确保公钥已复制
ssh-copy-id -p 2222 username@hostname

# 2. 测试密钥登录
ssh -p 2222 username@hostname

# 3. 禁用密码登录后,确保密钥登录正常

SSH高级用法

文件传输

# scp - 安全复制
scp file.txt username@hostname:/path/        # 上传
scp username@hostname:/path/file.txt .     # 下载
scp -r folder/ username@hostname:/path/    # 递归复制

# 常用选项
scp -P 2222 file.txt username@hostname:/path/
scp -i ~/.ssh/key.pem file.txt username@hostname:/path/
scp -p file.txt username@hostname:/path/    # 保留属性
scp -v file.txt username@hostname:/path/    # 详细输出

# rsync - 增量同步
rsync -avz -e "ssh -p 2222" folder/ username@hostname:/path/
rsync -avz --delete folder/ username@hostname:/path/
rsync -avz --exclude='*.log' folder/ username@hostname:/path/

rsync高级选项

# 常用选项
rsync -a               # 归档模式(保留权限、时间等)
rsync -v               # 详细输出
rsync -z               # 压缩传输
rsync -n               # 预演(不实际传输)
rsync -P               # 显示进度,保留部分文件
rsync --delete        # 删除目标中多余的文件
rsync --exclude       # 排除文件
rsync --progress      # 显示进度

# 示例
rsync -avzP -e "ssh -p 2222" /local/path/ user@host:/remote/path/

sftp - SSH文件传输

# 启动sftp
sftp username@hostname
sftp -P 2222 username@hostname

# 交互命令
sftp> help
sftp> pwd                    # 远程当前目录
sftp> lpwd                   # 本地当前目录
sftp> ls                    # 列出远程文件
sftp> lls                   # 列出本地文件
sftp> cd /path              # 切换远程目录
sftp> lcd /path             # 切换本地目录

# 传输命令
sftp> get remote.txt        # 下载
sftp> get remote.txt local.txt  # 下载并重命名
sftp> put local.txt         # 上传
sftp> put *.txt /remote/    # 上传多个

# 批处理
sftp -b commands.txt username@hostname

端口转发

本地端口转发

# 语法:ssh -L local_port:destination:destination_port jump_host
ssh -L 8080:localhost:80 username@server

# 访问远程服务器的MySQL
ssh -L 3306:localhost:3306 username@remoteserver

# 本地访问内网服务
ssh -L 9000:internal_server:80 jump_server

远程端口转发

# 语法:ssh -R remote_port:destination:destination_port jump_host
ssh -R 8080:localhost:80 username@server

# 让远程访问本地服务
ssh -R 80:localhost:3000 username@server

# 反向代理
ssh -fNR 8080:localhost:80 username@gateway

动态端口转发(SOCKS代理)

# 创建SOCKS代理
ssh -D 1080 username@hostname

# 浏览器配置SOCKS代理
# localhost:1080

# 命令行使用代理
curl --socks5 localhost:1080 https://example.com

跳板机连接

# 直接跳板
ssh -J username@jump_server username@target_server

# 多级跳板
ssh -J user1@jump1,user2@jump2 target_server

# ProxyJump配置
Host target
    HostName target_server
    User username
    ProxyJump jump_server

# 通过配置文件
Host internal-server
    HostName 192.168.1.100
    ProxyJump user@gateway.com

SSH Agent

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

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

# 查看已加载密钥
ssh-add -l

# macOS添加到Keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# SSH Agent转发
ssh -A username@hostname

# 配置自动使用
# ~/.ssh/config
Host *
    ForwardAgent yes

SCP/SFTP命令速查

# SCP命令
scp file.txt user@host:/path/          # 上传
scp user@host:/path/file.txt .         # 下载
scp -r /local/dir/ user@host:/path/    # 目录
scp -P 2222                             # 端口

# SFTP命令
sftp user@host                          # 连接
get file.txt                           # 下载
put file.txt                           # 上传
mget *.txt                             # 多下载
mput *.txt                             # 多上传

SSH实战案例

远程执行命令

# 单命令
ssh username@hostname "ls -la /var/log"

# 多命令
ssh username@hostname "cd /var/log && tail -f syslog"

# 本地脚本在远程执行
cat script.sh | ssh username@hostname "bash -s"

# here-document方式
ssh username@hostname << 'ENDSSH'
cd /home/user
./deploy.sh
ENDSSH

保持连接活跃

# 客户端配置 - ~/.ssh/config
ServerAliveInterval 60
ServerAliveCountMax 3

# 服务器配置 - /etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 3

# SSH隧道保持
ssh -o ServerAliveInterval=60 -N -L 8080:localhost:80 hostname

远程备份脚本

#!/bin/bash
# backup.sh

REMOTE_USER="backup"
REMOTE_HOST="backup.server.com"
REMOTE_PATH="/backups"
LOCAL_PATH="/home/user/data"

# 创建tar包
BACKUP_FILE="backup_$(date +%Y%m%d_%H%M%S).tar.gz"
tar -czf "$BACKUP_FILE" "$LOCAL_PATH"

# 传输
scp -P 2222 "$BACKUP_FILE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH/"

# 清理本地
rm "$BACKUP_FILE"

# 远程清理(保留最近7天)
ssh -p 2222 "$REMOTE_USER@$REMOTE_HOST" "find $REMOTE_PATH -name 'backup_*.tar.gz' -mtime +7 -delete"

SSH故障排查

# 1. 检查服务状态
sudo systemctl status sshd

# 2. 检查端口监听
sudo ss -tlnp | grep ssh

# 3. 测试连接
ssh -v username@hostname          # 详细输出
ssh -vv username@hostname         # 更详细

# 4. 检查防火墙
sudo ufw status
sudo iptables -L -n | grep ssh

# 5. 检查日志
sudo journalctl -u sshd -f
sudo tail -f /var/log/auth.log

# 6. 检查SELinux(CentOS/RHEL)
sudo getsebool ssh_sysadm_login

# 7. 常见问题
# - 密钥权限错误
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub

# - 目录权限错误
chmod 700 ~/
chmod 700 ~/.ssh

课后练习

实践任务
  1. 生成SSH密钥对,配置无密码登录
  2. 配置SSH客户端配置文件,使用别名连接
  3. 加固SSH服务器配置
  4. 使用scp/rsync传输文件
  5. 配置SSH端口转发访问内网服务
  6. 编写自动化备份脚本

下一篇预告:我们将学习防火墙配置,掌握iptables、firewalld和ufw的使用。