SSH协议(SSH Protocol)

SSH(Secure Shell)是一种加密网络协议,用于在不安全的网络中安全地进行远程登录和其他网络服务


SSH概述

SSH是一种网络协议,用于在两个网络设备之间建立加密通道,提供安全的远程访问和文件传输功能。

SSH历史发展

1995: SSH-1.0由Tatu Ylönen开发
1995-1996: SSH-1.x系列发布
1998: SSH-2.0协议发布
2006: OpenSSH 4.3发布
2023: OpenSSH 9.2发布

SSH应用场景

  • 远程登录:安全地远程访问服务器
  • 文件传输:安全地传输文件(SFTP/SCP)
  • 端口转发:创建安全的隧道
  • 命令执行:远程执行命令
  • X11转发:安全地转发GUI应用

SSH协议结构

SSH协议层次

SSH协议栈
┌────────────────────┐
│   应用层协议       │ ← 用户认证、连接协议
├────────────────────┤
│   传输层协议       │ ← 密钥交换、加密、认证
├────────────────────┤
│   连接层协议       │ ← 通道管理
└────────────────────┘

SSH协议版本

SSH-1

  • 设计:相对简单
  • 安全性:存在已知漏洞
  • 状态:已弃用,不推荐使用

SSH-2

  • 设计:更安全、更灵活
  • 特点:分离认证和传输协议
  • 状态:当前标准,广泛使用

SSH传输层协议

密钥交换

SSH使用Diffie-Hellman密钥交换建立共享密钥。

DH密钥交换流程

客户端                                服务器
  │                                    │
  │ 1. 发送DH参数                      │
  ├──────────────────────────────────→│
  │                                    │
  │ 2. 发送DH公钥                      │
  ├──────────────────────────────────→│
  │                                    │
  │ 3. 发送DH公钥和签名                │
  ├←─────────────────────────────────┤
  │                                    │
  │ 4. 验证签名                        │
  ├──────────────────────────────────→│
  │                                    │
  │ 5. 计算共享密钥                    │
  ├↔────────────────────────────────↔│

密钥交换算法

加密与完整性

加密算法

算法类型推荐算法避免算法
对称加密aes128-ctr, aes192-ctr, aes256-ctraes128-cbc, aes256-cbc
流加密chacha20-poly1305@openssh.comarcfour, arcfour128
块加密aes256-gcm@openssh.com3des-cbc

完整性算法

  • hmac-sha2-256:HMAC-SHA256
  • hmac-sha2-512:HMAC-SHA512
  • umac-128-etm@openssh.com:UMAC-128
  • hmac-sha1:HMAC-SHA1(避免使用)

SSH认证机制

1. 主机认证

客户端验证服务器身份,防止中间人攻击。

主机密钥类型

  • RSA:传统RSA密钥
  • DSA:数字签名算法(不推荐)
  • ECDSA:椭圆曲线DSA
  • Ed25519:EdDSA曲线

主机密钥验证

首次连接:
The authenticity of host 'server.example.com (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:abc123...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'server.example.com' (ED25519) to the list of known hosts.

known_hosts文件

# known_hosts格式
hostname key-type key-data comment

# 示例
server.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGb...

2. 用户认证

用户向服务器证明自己的身份。

密码认证

# 最简单的认证方式
$ ssh user@server.example.com
user@server.example.com's password:

公钥认证

使用密钥对进行身份验证。

密钥生成

# 生成ED25519密钥对
ssh-keygen -t ed25519 -C "user@example.com"
 
# 生成RSA密钥对(更兼容)
ssh-keygen -t rsa -b 4096 -C "user@example.com"

公钥分发

# 复制公钥到服务器
ssh-copy-id user@server.example.com
 
# 或手动复制
cat ~/.ssh/id_ed25519.pub | ssh user@server.example.com "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

其他认证方式

  • 键盘交互:基于挑战-响应的认证
  • GSSAPI:Kerberos等认证
  • Hostbased:基于主机的认证

SSH连接协议

通道管理

SSH支持多种通道类型,满足不同需求。

会话通道

用于交互式会话和命令执行。

# 交互式会话
ssh user@server.example.com
 
# 执行单个命令
ssh user@server.example.com "ls -la /home"
 
# 执行多个命令
ssh user@server.example.com "cd /tmp && tar czf - . | cat > backup.tar.gz"

X11转发

安全地转发X11图形应用。

# 启用X11转发
ssh -X user@server.example.com
 
# 强制X11转发
ssh -Y user@server.example.com

端口转发

创建安全的TCP/IP隧道。

本地端口转发

# 将本地8080端口转发到远程服务器的80端口
ssh -L 8080:localhost:80 user@server.example.com

远程端口转发

# 将远程服务器的8080端口转发到本地机器的80端口
ssh -R 8080:localhost:80 user@server.example.com

动态端口转发(SOCKS代理):

# 创建本地SOCKS代理
ssh -D 1080 user@server.example.com

SSH配置

客户端配置

~/.ssh/config

# 全局配置
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    Compression yes

# 服务器特定配置
Host server1
    HostName server1.example.com
    User user1
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ForwardX11 yes
    LocalForward 8080 localhost:80

Host server2
    HostName server2.example.com
    User user2
    Port 2222
    IdentityFile ~/.ssh/id_rsa
    ProxyJump server1.example.com

SSH命令行选项

# 指定端口
ssh -p 2222 user@server.example.com
 
# 指定密钥文件
ssh -i ~/.ssh/custom_key user@server.example.com
 
# 调试模式
ssh -v user@server.example.com
ssh -vvv user@server.example.com
 
# 禁用主机密钥检查(不安全)
ssh -o StrictHostKeyChecking=no user@server.example.com

服务器配置

/etc/ssh/sshd_config

# 基本配置
Port 22
Protocol 2
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
 
# 安全配置
MaxAuthTries 3
LoginGraceTime 60
ClientAliveInterval 600
ClientAliveCountMax 0
MaxStartups 10:30:100
 
# 性能配置
UsePrivilegeSeparation yes
UsePAM yes
X11Forwarding yes
Compression delayed
 
# 日志配置
LogLevel INFO
SyslogFacility AUTH

密钥配置

# /etc/ssh/ssh_host_rsa_key
# /etc/ssh/ssh_host_rsa_key.pub
 
# /etc/ssh/ssh_host_ecdsa_key
# /etc/ssh/ssh_host_ecdsa_key.pub
 
# /etc/ssh/ssh_host_ed25519_key
# /etc/ssh/ssh_host_ed25519_key.pub

SSH应用

1. 文件传输

SCP(Secure Copy)

# 从本地复制到远程
scp local_file.txt user@server.example.com:/remote/path/
 
# 从远程复制到本地
scp user@server.example.com:/remote/file.txt /local/path/
 
# 递归复制目录
scp -r local_directory user@server.example.com:/remote/path/

SFTP(SSH File Transfer Protocol)

# 交互式SFTP
sftp user@server.example.com
 
# SFTP命令
sftp> ls
sftp> cd /remote/path
sftp> get remote_file.txt
sftp> put local_file.txt
sftp> exit

2. 自动化脚本

无密码登录

#!/bin/bash
# 使用密钥认证实现无密码登录
 
for server in server1 server2 server3; do
    ssh user@${server}.example.com "uptime"
done

并行执行

#!/bin/bash
# 使用pssh并行执行命令
 
pssh -h servers.txt -l user -i "uptime"

3. 隧道应用

数据库访问

# 安全访问远程数据库
ssh -L 3306:mysql.example.com:3306 user@bastion.example.com
# 然后在本地使用: mysql -h 127.0.0.1 -P 3306

Web服务访问

# 访问内部Web服务
ssh -L 8080:intranet.example.com:80 user@server.example.com
# 然后在浏览器访问: http://localhost:8080

SSH安全最佳实践

1. 服务器安全

禁用不安全的认证方式

# 禁用密码认证,强制使用密钥认证
PasswordAuthentication no
ChallengeResponseAuthentication no

限制用户访问

# 使用AllowUsers限制可登录用户
AllowUsers admin user1 user2
 
# 使用AllowGroups限制可登录组
AllowGroups sshusers admin
 
# 使用DenyUsers禁止特定用户
DenyUsers root guest

限制网络访问

# 使用TCP Wrappers限制访问
# /etc/hosts.allow
sshd: 192.168.1.0/24, 10.0.0.0/8
 
# /etc/hosts.deny
sshd: ALL

使用fail2ban防护

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

2. 客户端安全

密钥管理

# 使用强密钥类型
ssh-keygen -t ed25519 -a 100
 
# 使用强密码保护密钥
ssh-keygen -t ed25519 -a 100 -C "user@example.com"
 
# 使用ssh-agent管理密钥
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519

主机密钥验证

# 使用StrictHostKeyChecking防止中间人攻击
Host *
    StrictHostKeyChecking yes
    VerifyHostKeyDNS yes

3. 网络安全

使用跳板机

# 配置跳板机
Host internal-server
    HostName internal.example.com
    User user
    ProxyJump bastion.example.com

端口防护

# 使用非标准端口
Port 2222
 
# 使用防火墙限制访问
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

SSH高级应用

1. 多点认证

使用2FA

# 安装Google Authenticator
sudo apt-get install libpam-google-authenticator
 
# 配置SSH使用2FA
# /etc/pam.d/sshd
auth required pam_google_authenticator.so
 
# /etc/ssh/sshd_config
AuthenticationMethods "publickey,keyboard-interactive:pam"

2. 证书认证

SSH证书

# 签发证书
ssh-keygen -s ca_key -I user_id -V +52w user_key.pub
 
# 配置服务器信任CA
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca_keys.pub

3. 多通道复用

连接复用

# ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p
    ControlPersist 600

SSH故障排查

1. 连接问题

调试命令

# 详细调试
ssh -vvv user@server.example.com
 
# 检查配置
ssh -G user@server.example.com
 
# 测试认证
ssh -T user@server.example.com

2. 密钥问题

检查密钥权限

# 检查文件权限
ls -la ~/.ssh/
chmod 700 ~/.ssh/
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys

3. 服务器问题

检查服务器状态

# 检查SSH服务状态
sudo systemctl status sshd
 
# 检查SSH配置
sudo sshd -T
 
# 检查监听端口
sudo netstat -tlnp | grep :22

SSH未来发展趋势

1. 协议演进

  • SSH-2.0扩展:新功能扩展
  • 后量子加密:支持后量子密码算法
  • 多因素认证:更好的2FA支持

2. 工具发展

  • 图形化工具:更好的GUI客户端
  • 集成管理:集中化管理平台
  • 自动化:更好的自动化支持

3. 安全增强

  • 零信任:集成零信任模型
  • 行为分析:异常行为检测
  • 微分段:精细化访问控制

🔗 相关链接


最后更新:2025-01-26 维护规范:详见 笔记规范文档

SSH 远程访问 加密 密钥认证 隧道