客户端 服务端
│── 版本协商 ──────────────────→│
│←── 版本协商 ──────────────────│
│── 算法协商 ──────────────────→│
│←── 算法协商 ──────────────────│
│←── 服务端主机密钥 ───────────│
│── DH密钥交换 ───────────────→│
│←── DH密钥交换 ───────────────│
│ (会话密钥建立) │
│── 认证请求 ─────────────────→│
│←── 认证结果 ─────────────────│
│── 加密数据传输 ─────────────→│
| 版本 | 状态 | 说明 |
|---|---|---|
| SSH-1 | 已弃用 | 存在安全漏洞 |
| SSH-2 | 当前标准 | DH密钥交换,强加密 |
$ grep -v '^#' /etc/ssh/sshd_config | grep -v '^$' | head -20
Include /etc/ssh/sshd_config.d/*.conf AddressFamily any PermitRootLogin yes KbdInteractiveAuthentication no UsePAM yes X11Forwarding yes PrintMotd no UseDNS no AcceptEnv LANG LC_* Subsystem sftp /usr/lib/openssh/sftp-server PasswordAuthentication no PermitEmptyPasswords no
$ systemctl status sshd 2>/dev/null | head -10 || systemctl status ssh | head -10
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-05-19 02:15:58 CST; 19h ago
TriggeredBy: ● ssh.socket
Docs: man:sshd(8)
man:sshd_config(5)
Process: 972 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 1000 (sshd)
Tasks: 3 (limit: 9127)
Memory: 5.2M (peak: 15.5M swap: 516.0K swap peak: 516.0K)# /etc/ssh/sshd_config 安全加固
Port 2222 # 修改默认端口
PermitRootLogin no # 禁止root登录
PasswordAuthentication no # 禁用密码认证
PubkeyAuthentication yes # 启用密钥认证
MaxAuthTries 3 # 最多尝试3次
LoginGraceTime 30 # 30秒内必须认证
AllowUsers deploy admin@10.0.0.* # 限制用户和来源IP
X11Forwarding no # 禁用X转发
PermitEmptyPasswords no # 禁止空密码
ClientAliveInterval 300 # 5分钟空闲检测
ClientAliveCountMax 2 # 2次无响应断开
# 重启SSH服务
sudo systemctl restart sshd
$ ls -la ~/.ssh/
total 8 drwx------ 2 root root 4096 Apr 26 2024 . drwx------ 17 root root 4096 May 19 21:32 .. -rw------- 1 root root 0 May 14 12:15 authorized_keys
# 生成密钥对
ssh-keygen -t ed25519 -C "user@host" # 推荐(Ed25519)
ssh-keygen -t rsa -b 4096 -C "user@host" # RSA备选
# 复制公钥到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# 或手动复制
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 密钥权限(必须!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
# 启动ssh-agent
eval $(ssh-agent -s)
# 添加密钥
ssh-add ~/.ssh/id_ed25519
# 查看已添加的密钥
ssh-add -l
# 使用Agent转发(在~/.ssh/config中)
Host server
ForwardAgent yes
# ~/.ssh/config 客户端配置
Host myserver
HostName 192.168.1.100
Port 2222
User deploy
IdentityFile ~/.ssh/id_ed25519
ForwardAgent yes
Host jump
HostName jump.example.com
User admin
Host internal
HostName 10.0.0.50
ProxyJump jump # 通过跳板机连接
User deploy
# 使用
ssh myserver # 自动使用配置
ssh internal # 通过跳板机连接
# 将本地8080端口转发到远程的localhost:80
ssh -L 8080:localhost:80 user@server
# 访问内网数据库
ssh -L 3306:db.internal:3306 user@bastion
# 然后本地连接 localhost:3306 即可访问内网数据库
# 将远程的9090端口转发到本地的3000
ssh -R 9090:localhost:3000 user@server
# 他人访问server:9090 即可访问你本地的3000端口
# 创建SOCKS5代理
ssh -D 1080 user@server
# 浏览器配置SOCKS5代理为 localhost:1080
# 详细输出
ssh -vvv user@server
# 检查服务端
sudo systemctl status sshd
sudo journalctl -u sshd -n 20
# 检查端口
ss -tlnp | grep 22
# 检查防火墙
sudo ufw status
sudo iptables -L -n | grep 22
# 检查hosts.deny
cat /etc/hosts.deny
# 检查fail2ban
sudo fail2ban-client status sshd# 安装fail2ban
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
# 1. 生成Ed25519密钥对
ssh-keygen -t ed25519 -C "$(whoami)@$(hostname)"
# 2. 查看当前SSH配置
grep -v '^#' /etc/ssh/sshd_config | grep -v '^$'
# 3. 检查密钥权限
ls -la ~/.ssh/
# 4. 查看SSH登录日志
sudo journalctl -u sshd | tail -10
sudo last | head -5✅ 理解SSH协议与认证流程
✅ 掌握SSH服务端安全加固
✅ 学会密钥认证配置
✅ 掌握SSH隧道与端口转发
✅ 了解fail2ban防暴力破解
# ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600 # 10分钟后关闭
# 创建socket目录
mkdir -p ~/.ssh/sockets
# 效果:第一个SSH连接建立后,后续连接复用同一通道
# 大幅减少连接建立时间
#!/bin/bash
# ssh-audit.sh - SSH安全审计
echo "===== SSH安全审计 ====="
# 检查SSH版本
echo "--- SSH版本 ---"
ssh -V 2>&1
# 检查关键配置
echo "\n--- 安全配置检查 ---"
for key in PermitRootLogin PasswordAuthentication PubkeyAuthentication MaxAuthTries Port; do
val=$(grep "^$key" /etc/ssh/sshd_config 2>/dev/null | awk '{print $2}')
echo "$key: ${val:-未设置(使用默认值)}"
done
# 检查密钥类型
echo "\n--- 主机密钥 ---"
ls -la /etc/ssh/ssh_host_*_key 2>/dev/null
# 检查授权密钥
echo "\n--- 授权密钥 ---"
for user_home in /home/* /root; do
if [ -f "$user_home/.ssh/authorized_keys" ]; then
count=$(wc -l < "$user_home/.ssh/authorized_keys")
echo "$user_home: $count keys"
fi
done
# 检查fail2ban
echo "\n--- fail2ban状态 ---"
sudo fail2ban-client status sshd 2>/dev/null || echo "fail2ban未安装"
# 创建SSH CA
# 1. 生成CA密钥
ssh-keygen -t ed25519 -f ssh_ca -C "SSH CA"
# 2. 签发用户证书
ssh-keygen -s ssh_ca -I user_zhangsan -n zhangsan -V +52w ~/.ssh/id_ed25519.pub
# -I: 证书标识
# -n: 允许登录的用户名
# -V: 有效期(52周)
# 3. 服务端信任CA
echo "TrustedUserCAKeys /etc/ssh/ca.pub" | sudo tee -a /etc/ssh/sshd_config
sudo cp ssh_ca.pub /etc/ssh/ca.pub
sudo systemctl restart sshd
# 优势:无需在每个服务器上部署公钥,仅信任CA即可
# 生产环境SSH架构
用户 → 跳板机(bastion) → 内网服务器
│
└── 仅跳板机有外网IP
内网服务器仅允许跳板机IP连接SSH
# ~/.ssh/config
Host bastion
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/id_ed25519
Host internal-*
ProxyJump bastion
User deploy
IdentityFile ~/.ssh/id_ed25519_internal
# Ansible通过SSH管理服务器
# ansible.cfg
[defaults]
inventory = hosts
host_key_checking = False
private_key_file = ~/.ssh/id_ed25519
ssh_args = -F ~/.ssh/ansible_ssh_config -o ControlMaster=auto -o ControlPersist=60s
# hosts文件
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[dbservers]
db1 ansible_host=192.168.1.20
[all:vars]
ansible_user=deploy
ansible_ssh_port=2222
# 场景1:安全访问内网Web服务
ssh -L 8080:internal-web:80 user@bastion
# 浏览器访问 localhost:8080
# 场景2:安全访问远程数据库
ssh -L 3306:db.internal:3306 user@bastion
# 本地MySQL客户端连接 localhost:3306
# 场景3:远程桌面(VNC)
ssh -L 5901:vnc-server:5901 user@bastion
# 场景4:临时反向代理
# 从家里访问办公室内网
ssh -R 2222:localhost:22 office-server
# 在办公室服务器上: ssh -p 2222 localhost 即可回家里的机器
# 场景5:SOCKS代理浏览
ssh -D 1080 user@server
# 配置浏览器SOCKS5代理 localhost:1080
# /etc/ssh/sshd_config - 生产级安全配置
# 基础设置
Port 2222
AddressFamily inet
ListenAddress 0.0.0.0
# 协议与加密
Protocol 2
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256@libssh.org
# 认证
PermitRootLogin no
MaxAuthTries 3
LoginGraceTime 30
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
# 访问控制
AllowUsers deploy admin@10.0.0.*
DenyUsers guest
# 会话
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 10
MaxStartups 10:30:100
# 日志
SyslogFacility AUTH
LogLevel VERBOSE
# SFTP(可选)
Subsystem sftp /usr/lib/openssh/sftp-server