0. 写在前面:为什么你需要“神器”而非“常用命令
大家好,我是老杨,干货满满的老杨.欢迎来到互联网遥遥领先的博客. 欢迎点击原文链接或直接访问vps.top365app.com,来看老杨的全球vps信息还有各种咱们用得着的信息实时收集分析项目.
帮老杨点赞、转发、在看以及打开小星标哦
攒今世之功德,修来世之福报
聊聊SSH攻击,传说每天互联网上针对SSH的暴力破解攻击超过40万次。阿里云、腾讯云的安全报告也证实了这点,SSH的22端口一般都是重灾区。
今天老杨聊聊这个ssh的事,从最基础的密钥认证到现在流行的零信任架构,每一个都是用血泪换来的经验。
密码登录就像把钥匙藏在门口的花盆下面,你以为很巧妙,其实小偷早就知道这套路了。
我们现在都是这么给新员工配置SSH的。先生成密钥对:
ssh-keygen -t ed25519 -C "your_email@example.com"执行后你会看到这样的输出:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
...为什么选ed25519?这个算法是2011年发布的,安全性比传统的RSA要好,而且密钥长度更短,计算速度也快。相比RSA-2048,ed25519只需要256位就能提供同等级别的安全性。
把公钥传到服务器:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server然后修改服务器的SSH配置文件:
sudo vim /etc/ssh/sshd_config找到PasswordAuthentication这行,改成:
PasswordAuthentication no重启SSH服务:
sudo systemctl restart sshd这里有个坑我必须提醒你:禁用密码登录之前,务必确认密钥登录能正常工作。我见过不少人把自己锁在门外的惨案。
默认的22端口就像商场的正门,人人都知道。换个端口,就像走员工通道,清净不少。
sudo vim /etc/ssh/sshd_config把Port 22改成:
Port 2233记得在防火墙里开放新端口:
sudo ufw allow 2233
sudo ufw deny 22如果用的是云服务器,安全组也要同步调整。不过我要说句实话,换端口只是基础防护,真正有经验的攻击者照样能扫出来。但能挡住大部分脚本小子,也算值了。
root账户就像万能钥匙,丢了就全完了。我的做法是创建专门的运维账户:
sudo adduser ops
sudo usermod -aG sudo ops然后在SSH配置里限制登录用户:
AllowUsers ops
PermitRootLogin no这样即便有人破解了密码,也只能用ops账户登录。要获取root权限,还得再过一关。
深层原理是这样的:Linux的权限模型基于用户和组的概念,sudo组的成员可以通过sudo命令临时获取root权限。但这个过程需要再次输入密码验证,相当于双重保险。而且所有sudo操作都会记录在日志里,方便后续审计。
单纯的密钥认证还是有风险,万一密钥文件被盗了怎么办?双因素认证就像银行卡加密码,光有卡不行,还得知道密码。
安装Google Authenticator:
sudo apt install libpam-google-authenticator为用户配置2FA:
google-authenticator系统会生成一个二维码和一串备用码:
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/...
Your new secret key is: ABCDEFGHIJKLMNOP
Your verification code is 123456
Your emergency scratch codes are:
12345678
87654321
...这里的技术原理挺有意思:TOTP(Time-based One-Time Password)算法基于RFC 6238标准,使用HMAC-SHA1算法和当前时间戳生成6位数字验证码。服务器和客户端都知道相同的密钥,通过时间同步来验证代码的有效性。每个验证码只有30秒有效期。
修改PAM配置:
sudo vim /etc/pam.d/sshd添加这一行:
auth required pam_google_authenticator.so修改SSH配置:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive现在登录需要密钥加手机验证码。就算密钥被偷,没有手机也进不来。
跳板机的概念我很早就在用了,就像酒店前台,想进房间得先登记。
假设我有三台服务器:跳板机(Jump)、Web服务器(Web1)、数据库服务器(DB1)。跳板机只允许特定IP连接:
sudo vim /etc/ssh/sshd_config加上这些配置:
Match Address 192.168.1.100
AllowUsers admin
Match Address !192.168.1.100
DenyUsers *然后配置SSH客户端:
vim ~/.ssh/config写入这些内容:
Host jump
HostName jump.company.com
User admin
Port 2233
Host web1
HostName 10.0.1.10
User ops
ProxyJump jump
Host db1
HostName 10.0.1.20
User ops
ProxyJump jump这样连接Web服务器只需要:
ssh web1SSH会自动通过跳板机中转。ProxyJump指令底层使用的是SSH的端口转发机制,建立一个加密隧道,所有数据都通过这个隧道传输。而且所有连接都有完整的审计日志。
SSH连接就像水龙头,用完得关。我见过有人一个SSH连接挂机好几天,服务器资源白白浪费。
sudo vim /etc/ssh/sshd_config加上这些配置:
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
MaxSessions 3
MaxStartups 10:30:100解释一下这些参数:
ClientAliveInterval 300:每5分钟发送一次心跳包ClientAliveCountMax 2:心跳包无响应2次就断开连接MaxAuthTries 3:最多尝试认证3次MaxSessions 3:每个连接最多3个会话MaxStartups 10:30:100:同时最多10个未认证连接,超过后30%概率拒绝新连接,超过100个全部拒绝这套机制的核心是基于TCP keepalive和SSH协议的心跳机制。当网络连接异常或客户端崩溃时,服务器能及时清理僵尸连接,避免资源泄露。
出了安全问题,日志就是最重要的证据。我的习惯是把SSH日志设置得非常详细:
sudo vim /etc/ssh/sshd_config设置详细日志级别:
LogLevel VERBOSE然后配置rsyslog把日志发送到集中的日志服务器:
sudo vim /etc/rsyslog.conf添加这一行:
auth,authpriv.* @@logserver.company.com:514这样所有SSH相关的日志都会实时发送到日志服务器。我一般用ELK Stack或者阿里云的日志服务来分析这些数据,能快速发现异常登录模式。
查看实时SSH日志:
sudo journalctl -u ssh -f典型的日志输出:
Jan 15 10:30:15 server sshd[1234]: Accepted publickey for ops from 192.168.1.100 port 51234 ssh2
Jan 15 10:35:22 server sshd[1235]: Failed password for root from 1.2.3.4 port 12345 ssh2
Jan 15 10:35:25 server sshd[1235]: Connection closed by 1.2.3.4 port 12345 [preauth]
...通过日志分析,我能识别出很多攻击模式:比如短时间内大量失败登录、来自可疑地理位置的连接、非正常时间的访问等等。
网络层面的控制就像小区门禁,不是什么人都能进来。我通常用iptables来设置访问规则:
# 清空现有规则
sudo iptables -F
# 允许本地回环
sudo iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 只允许指定IP访问SSH
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 2233 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 10.0.1.0/24 --dport 2233 -j ACCEPT
# 拒绝其他SSH连接
sudo iptables -A INPUT -p tcp --dport 2233 -j DROP
# 保存规则
sudo iptables-save > /etc/iptables/rules.v4不过现在我更推荐用云厂商的安全组功能。阿里云的安全组配置更直观,而且是分布式的,性能比单机iptables好很多。
iptables的工作原理基于Linux内核的netfilter框架,它在数据包进入系统的不同阶段设置检查点。每个数据包都会按照规则链进行匹配,第一个匹配的规则决定数据包的命运。这种设计虽然灵活,但也要求管理员对网络协议栈有深入理解。
密钥就像密码,用久了总得换。我写了个自动化脚本来处理这事:
vim rotate_ssh_keys.sh脚本内容:
#!/bin/bash
# 生成新密钥
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -N "" -C "rotated-$(date +%Y%m%d)"
# 上传新密钥到所有服务器
for server in web1 web2 db1 db2; do
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub $server
done
# 测试新密钥是否正常工作
for server in web1 web2 db1 db2; do
ssh -i ~/.ssh/id_ed25519_new -o PasswordAuthentication=no $server "echo 'New key works on $server'"
done
# 如果测试成功,替换旧密钥
if [ $? -eq 0 ]; then
mv ~/.ssh/id_ed25519_new ~/.ssh/id_ed25519
mv ~/.ssh/id_ed25519_new.pub ~/.ssh/id_ed25519.pub
echo "Key rotation completed successfully"
else
echo "Key rotation failed"
rm ~/.ssh/id_ed25519_new*
fi设置定时任务,每90天执行一次:
crontab -e添加:
0 2 1 */3 * /home/ops/rotate_ssh_keys.sh >> /var/log/ssh_key_rotation.log 2>&1密钥轮换的理论基础来自于密码学中的密钥管理最佳实践。即使是数学上安全的加密算法,长期使用同一密钥也会增加被破解的风险。定期轮换可以限制单个密钥的暴露时间窗口。
零信任的核心思想是"从不信任,总是验证"。就算在内网里,也不能盲目相信。
我现在用HashiCorp Vault来管理SSH证书,这套方案特别适合大规模环境:
wget https://releases.hashicorp.com/vault/1.15.2/vault_1.15.2_linux_amd64.zip
unzip vault_1.15.2_linux_amd64.zip
sudo mv vault /usr/local/bin/启动Vault开发模式:
vault server -dev -dev-listen-address="0.0.0.0:8200"配置环境变量:
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN="your-root-token"启用SSH引擎:
vault auth enable ssh
vault write ssh/config/ca generate_signing_key=true创建角色:
vault write ssh/roles/ops \
key_type=ca \
default_user=ops \
allowed_users=ops,admin \
default_extensions="permit-pty,permit-user-rc" \
ttl=10m客户端获取短期证书:
vault write -field=signed_key ssh/sign/ops \
public_key=@$HOME/.ssh/id_ed25519.pub > ~/.ssh/id_ed25519-cert.pub
ssh -i ~/.ssh/id_ed25519 -i ~/.ssh/id_ed25519-cert.pub user@server这个证书只有10分钟有效期,过期了必须重新申请。
Vault的SSH CA模式基于OpenSSH的证书认证机制。传统的公钥认证需要在每台服务器上维护authorized_keys文件,而证书认证只需要在服务器上信任CA公钥。客户端的公钥由CA签名后形成证书,服务器验证证书的有效性和权限。
这种模式的好处是显而易见的:集中管理、细粒度权限控制、自动过期、完整审计链。当员工离职时,只需要在Vault中撤销权限:
vault write auth/userpass/users/zhangsan/policies policies=""所有相关的访问权限立即失效,不用逐台服务器去清理公钥。
ssh老重要了,这玩意被黑了,运维是百分百的锅.这个跑不了的
这里老杨先声明一下,日常生活中大家都叫老杨波哥,跟辈分没关系,主要是岁数大了.就一个代称而已. 老杨的00后小同事老杨喊都是带哥的.张哥,李哥的. 但是这个称呼呀,在线下参加一些活动时.金主爸爸也这么叫就显的不太合适. 比如上次某集团策划总监,公司开大会来一句:“今个咱高兴!有请IT运维技术圈的波哥讲两句“ 这个氛围配这个称呼在互联网这行来讲就有点对不齐! 每次遇到这个情况老杨就想这么接话: “遇到各位是缘分,承蒙厚爱,啥也别说了,都在酒里了.老杨干了,你们随意!” 所以以后咱们改叫老杨,即市井又低调.还挺亲切,老杨觉得挺好.
运维X档案系列文章:
企业级 Kubernetes 集群安全加固全攻略( 附带一键检查脚本)
看完别走.修行在于点赞、转发、在看.攒今世之功德,修来世之福报
点击阅读原文或打开地址实时收集分析全球vps的项目 vps.top365app.com
老杨AI的号: 98dev