SSH(Secure Shell,安全外壳)是一种加密的网络协议,用于安全地远程登录和管理服务器。它由Tatu Ylönen于1995年开发,现已成为远程管理的事实标准。
SSH能够取代不安全的Telnet和rlogin,得益于以下特点:
SSH使用多层加密保护通信安全:
SSH支持多种认证方式:
SSH 公钥认证时序图
sequenceDiagram
participant U as 用户
participant C as 客户端
participant S as 服务器
C->>S: TCP 连接到端口22
S->>C: TCP ACK
C->>S: SSH版本协商
S->>C: 版本确认
C->>S: KEX_INIT (密钥交换初始化)
S->>C: KEX_INIT
Note over C,S: 协商加密算法
C->>S: DH_KEX_INIT (迪菲-赫尔曼)
S->>C: DH_REPLY (公钥+签名+服务器nonce)
Note over C: 验证服务器公钥
C->>S: NEWKEYS (切换到会话密钥)
S->>C: NEWKEYS
Note over C,S: 加密通道建立
C->>S: 用户公钥
S->>C: 请求认证质询
C->>S: 用私钥签名质询
S->>C: 认证成功 (多个因素可叠加)
**设置公钥认证**:
1. 生成密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
2. 复制公钥到服务器
ssh-copy-id user@server
3. 禁用密码认证(可选但推荐)
编辑 /etc/ssh/sshd_config
PasswordAuthentication no
SSH 端口转发示意图
flowchart LR
subgraph 本地["本地主机"]
A[应用] -->|本地端口| L[SSH Client]
end
subgraph 远程["远程服务器"]
S[SSH Server] -->|目标端口| B[目标服务]
end
L -->|加密隧道| S
style L fill:#3498db,color:#fff
style S fill:#3498db,color:#fff
style B fill:#e74c3c,color:#fff
基本连接
ssh user@host
指定端口
ssh -p 2222 user@host
指定私钥文件
ssh -i ~/.ssh/mykey user@host
执行单个命令
ssh user@host "ls -la"
执行多个命令
ssh user@host "cd /var/www && ls -la"
执行本地脚本
ssh user@host 'bash -s' < local_script.sh
本地→远程
scp local_file user@host:/remote/path/
远程→本地
scp user@host:/remote/file /local/path/
递归复制目录
scp -r local_dir user@host:/remote/path/
指定端口
scp -P 2222 local_file user@host:/remote/path/
连接
sftp user@host
常用命令
ls # 列出远程文件
lls # 列出本地文件
cd path # 切换远程目录
lcd path # 切换本地目录
get file # 下载文件
put file # 上传文件
exit # 退出
服务器别名
Host myserver
HostName 192.168.1.100
User admin
Port 2222
IdentityFile ~/.ssh/myserver_key
ServerAliveInterval 60
通用配置
Host *
Compression yes
ForwardAgent yes
使用配置后,可以简化连接:
ssh myserver # 不需要再输入IP、用户、端口
端口
Port 2222
禁止root登录
PermitRootLogin no
禁用密码认证
PasswordAuthentication no
允许公钥认证
PubkeyAuthentication yes
限制用户
AllowUsers alice bob
空闲超时
ClientAliveInterval 300
ClientAliveCountMax 2
修改后重启SSH服务:
systemctl restart sshd
SSH端口转发可以创建安全隧道:
TCP连接状态转换(SSH场景)
stateDiagram-v2
[*] --> CLOSED
CLOSED --> LISTEN : 服务器监听22端口
LISTEN --> SYN_SENT : 客户端发起连接
SYN_SENT --> SYN_RECEIVED : 收到SYN+ACK
SYN_RECEIVED --> ESTABLISHED : 发送ACK
ESTABLISHED --> CLOSE_WAIT : 收到FIN(主动关闭)
ESTABLISHED --> FIN_WAIT_1 : 发送FIN(主动关闭)
FIN_WAIT_1 --> FIN_WAIT_2 : 收到ACK
FIN_WAIT_2 --> TIME_WAIT : 收到对方FIN
TIME_WAIT --> CLOSED : 2MSL后
CLOSE_WAIT --> LAST_ACK : 发送FIN
LAST_ACK --> CLOSED : 收到ACK
将本地端口转发到远程服务器
格式:-L 本地端口:目标主机:目标端口
ssh -L 8080:internal-server:80 user@gateway
访问本地8080端口 → 相当于访问internal-server:80
将远程端口转发到本地
格式:-R 远程端口:本地主机:本地端口
ssh -R 9000:localhost:3000 user@server
访问server:9000 → 相当于访问本地3000
创建SOCKS5代理
格式:-D 本地端口
ssh -D 1080 user@server
浏览器配置SOCKS代理127.0.0.1:1080,所有流量通过SSH加密
---
**延伸阅读**:
**相关工具**: