你的服务器刚上线,全世界就都来敲门了——但别慌,咱普通开发者也能轻松防住

前段时间看了一位老哥做的实验,特有意思:他在网上租了台最便宜的云服务器,装好系统,故意开着 22 端口(SSH 远程连接的默认端口),啥额外保护都没加,然后就放着不管了。你猜多久之后有人来敲门?

一分钟都不到。

54 天里,这台“空房子”一共被敲了 26 万多次门,来自全世界 7500 多个 IP,试了将近 5 万个不同的密码。最常用的密码你肯定猜得到——123456,占了全部尝试的一成多。而且 99.6% 的敲门者不是人,是脚本,是全天候自动运行的机器人程序,日夜不停地在整个互联网上地毯式扫描,专找没关门的服务器。

听起来是不是特吓人?但其实,这事儿暴露了一个又扎心又有点好笑的真相:绝大多数攻击并不是有黑客在屏幕前盯着你,而是机器在无差别地撞大运。 它们就像小偷挨家挨户拧门把手,你家门没锁,他们就进来逛逛。如果你把门锁好,他们立马扭头去拧下一家。

那咱们普通开发者该怎么办?又不是安全专家,没时间整天盯着日志,也不想花大价钱买一堆设备。别急,这事儿其实没那么复杂。下面我就用最接地气的话,给你整几个马上就能动手操作的步骤,让你花个把小时,就能把服务器从“筛子”变成“防盗门”。


第一步:把密码锁扔掉,换钥匙

蜜罐实验里所有成功的登录,全是靠猜密码猜中的。你只要把密码登录这扇门彻底封死,那99%的机器人自动攻击就跟你没关系了。

具体怎么做?

1. 给自己弄一把“钥匙”——SSH 密钥对

打开你自己电脑上的终端(Windows 用 PowerShell 或者装个 Git Bash),输入:

ssh-keygen -t ed25519 -C "你的邮箱或者随便写个备注"

一路回车就行,它会自动在你的电脑里生成两样东西:一把“私钥”(自己留着,死也别给别人),一把“公钥”(相当于锁,装到服务器上)。生成完了之后,私钥就躺在 ~/.ssh/id_ed25519 这个文件里。

2. 把“锁”装到服务器上

运行下面这个命令,它会自动把你的公钥传到服务器上:

ssh-copy-id 你的用户名@你的服务器IP

输一次服务器密码(最后一次用密码了!),以后连接就不需要密码了。

3. 彻底关掉密码登录这扇门

连上服务器,编辑 SSH 配置文件:

sudo nano /etc/ssh/sshd_config

找到 PasswordAuthentication 这一行,把后面的 yes 改成 no。同时,如果你的系统是较新的 Ubuntu 22.04/24.04,把 KbdInteractiveAuthentication 也改成 no(旧教程里常见的 ChallengeResponseAuthentication 现在已经被这个替代了,写旧指令虽然可能仍生效,但咱们用新标准)。再确认 PubkeyAuthentication yes 是开启状态。

再顺手把 root 直接登录也禁了,找到 PermitRootLogin,改成 no。这样就算有人拿到了你的 root 密码,也进不来。

改完之后保存,重启 SSH 服务:

sudo systemctl restart sshd

别急着关掉当前的连接窗口! 另开一个终端窗口试一下用密钥能不能登进去,确认没问题了再关原来的。不然把自己锁外面可就尴尬了。

搞定这一步,你的服务器就直接免疫了所有靠猜密码的攻击。就这么简单。


第二步:给你的“钥匙”再焊一层钢板

上面这招已经防住了绝大部分自动攻击,但还有个隐患:万一你电脑里的私钥文件被偷了怎么办?有没有办法让这把钥匙只能在你自己的电脑上使用,就算文件被拷走也白搭?

还真有,而且很可能你电脑里已经自带了这个能力,一分钱不用花。不过实现方式比我想象中要绕一点,我之前的说法有误,现在给出准确的方案。

方案A:用 macOS 钥匙串 + Touch ID 保护你的密钥(最省钱)

如果你用的是带指纹识别的 MacBook,可以把已有的 SSH 密钥存进系统钥匙串,并用 Touch ID 来解锁。这样即使私钥文件被复制出去,没有你的指纹也解密不了。

首先生成普通密钥(如果已经生成过可跳过):

ssh-keygen -t ed25519

然后把密钥添加到钥匙串,并启用 Touch ID 确认:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

之后把密钥拷贝到服务器(用 ssh-copy-id)就行了。每次新开终端连服务器时,系统会弹出 Touch ID 提示,按一下指纹即可。注意这个方案依赖的是 macOS 的钥匙串加密,并不是 FIDO2 协议,但已经能很好地防止私钥文件泄露后被直接使用。

方案B:使用物理安全钥匙(YubiKey 等,约 200 元)

如果你经常在不同设备间切换,或者想要最高级别的安全,可以买一个支持 FIDO2 的硬件密钥,比如 YubiKey。插上之后,运行:

ssh-keygen -t ed25519-sk

这时它会检测到硬件密钥,按提示触碰一下钥匙上的金属触点,私钥就被生成并锁死在硬件里,永远不会离开设备。以后登录时都需要插上钥匙并触碰确认。这才是真正意义上的“硬件多因素认证”。


第三步:把大门藏起来,再加个“门卫”

关了密码登录,黑客虽然猜不对密码了,但他们还是可以天天来敲你的门,把你的日志塞满,看着也烦。对付这些机器人,有个特别简单粗暴但极其有效的方法:

把门牌号从“22”改成一个只有你知道的数。

不过有个新手必踩的坑,必须先说:在改端口之前,一定要先到云服务商的安全组/防火墙里,把新端口放行! 比如你用腾讯云、阿里云,去控制台找到安全组规则,入方向添加一个 TCP 规则,端口写你准备换的数字(比如 22222),授权来源暂时可以设为 0.0.0.0/0。之后再上服务器改配置,否则你会立刻断连,只能靠云服务商的后台 VNC 去救了。

编辑 SSH 配置:

sudo nano /etc/ssh/sshd_config

找到 #Port 22 这行,把前面的 # 删掉,把 22 改成比如 22222(别用 222、2222 这些太常见的)。保存、重启 sshd。

现在,全世界 99% 的扫描脚本发现 22 端口没反应,直接扭头就走。你的日志瞬间清静了。以后你自己连接的时候,记得在 ssh 命令后面加 -p 22222

再配一个真正好用的“门卫”——Fail2Ban

这里要纠正一个常见的误解:在你关闭密码登录后,Fail2Ban 默认的规则可能会“罢工”。因为默认规则是靠抓取日志里 “Failed password” 这样的关键字来封禁 IP 的,而密码认证被完全禁用后,攻击者连输密码的机会都没有,日志里就不会出现这些关键字,Fail2Ban 也就无从下手。

所以我们需要给它定制一个能抓到“敲门动作”本身的规则。创建一个本地配置文件:

sudo nano /etc/fail2ban/jail.local

填入以下内容(针对 SSH 低级别连接失败的封禁):

[sshd]
enabled = true
port = 22222   # 改成你实际使用的端口
filter = sshd
maxretry = 3
findtime = 10m
bantime = 1h

然后编辑(或创建)自定义过滤器,让 Fail2Ban 监控连接断开之类的底层行为:

sudo nano /etc/fail2ban/filter.d/sshd-custom.conf

写入:

[Definition]
failregex = ^%(__prefix_line)sConnection closed by authenticating user .* \[preauth\]$
            ^%(__prefix_line)sConnection closed by invalid user .* \[preauth\]$
            ^%(__prefix_line)sDid not receive identification string from <HOST>
ignoreregex =

接着告诉 Fail2Ban 使用这个自定义过滤器,再次编辑 jail.local,把 filter = sshd 改成 filter = sshd-custom。然后重启 Fail2Ban:

sudo systemctl restart fail2ban

现在,哪怕密码登录已经被禁用,那些反复来扫描、尝试建立连接但不成功的 IP,也会被自动关进小黑屋。


第四步:网站登录,用脸或指纹代替密码

上面说的都是服务器的远程连接。那咱们自己开发的网站或者用的各种在线服务呢?密码这东西天生就有硬伤——容易被猜、容易泄露、容易被钓鱼。

现在有个好东西叫 Passkey(通行密钥),你大概率已经在用了。用指纹、人脸或者屏幕解锁来登录网站,没有任何密码在网络上传输,钓鱼网站根本骗不走你的登录凭证,因为私钥从来就不离开你的设备。

作为普通用户,现在就可以做的:

  • Google、GitHub、微软账号、Apple ID 这些,都去安全设置里把 Passkey 或无密码登录打开,之后用指纹/面容就能登录。
  • 以后看到网站提示“使用通行密钥登录”,别犹豫,点它。

作为开发者,在自己项目里想加上这功能:

前端确实就两个浏览器 API:navigator.credentials.create()navigator.credentials.get()。但后端验证过程极其复杂,涉及二进制数据解析、证书链验证等等,绝对不要自己手搓算法,非常容易搞出安全漏洞。强烈建议直接用成熟的开源库,比如 Node.js 生态里口碑很好的 SimpleWebAuthn,照着官方文档配一下,远比你自己折腾来得安全、省心。


再啰嗦几个顺手就能做的小事

  • 定期升级系统sudo apt update && sudo apt upgrade -y,每周跑一次,堵住已知漏洞。
  • 关掉用不着的端口:你的项目只用到 80、443 端口,那就在云服务商的安全组里把其他端口统统关掉,少一个端口就少一份被攻击的风险。
  • 看日志用这个命令,全平台通用journalctl -u ssh -f。它能实时显示 SSH 服务的日志,无论是 Ubuntu 还是 CentOS,只要用 systemd 都一个样。比去记 /var/log/auth.log 还是 /var/log/secure 方便得多。

你看,从头到尾,咱们没花一分钱(或者最多花两百块买个硬件钥匙),没有多复杂的配置,也不需要成为安全专家。密码登录关掉,换端口,给 Fail2Ban 打个补丁让它干正事,甚至再进一步把密钥锁在硬件里,这几件事加在一起,就能让你那台小服务器从“谁都能踹一脚的破木门”变成“装了密码锁的防盗门”。

前面那个蜜罐实验最让人感触的一点是:有个来自柏林的“慢打字黑客”,登录之后没搞破坏,只是小心翼翼地敲着命令,到处看看。一位喀麦隆的朋友像是第一次发现新大陆,好奇地浏览了一圈。这说明并不是所有敲门的人都有恶意,但当你的服务器上跑着真实的项目、存着用户数据时,你不能赌每一次开门遇到的都是好人。

花一个小时,照着上面挑几件事做了。安全感这种东西,从来不是等来的,是自己动手挣来的。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容