个人的网站防护分享

本文首发在知乎,链接:https://www.zhihu.com/question/558788111/answer/3517971858

1. 双线cdn隐藏源站ip

服务器腾讯云境内,有两个域名,主域名已备案放dnspod(阿里云也行,假设域名为 example1.com ,平常访问也是这个),另一个放cloudflare(以下简称cf,假设域名为 example2.com ),这是前置条件

如果没有第二个域名,可以去白嫖 cloudnseu.org 这种能迁移到cf的二级域名

购买腾讯云境内地区cdn流量包(主要是腾讯便宜,一二十块钱就能买一年 100G 的流量,阿里云华为云cdn最低是 500G,就要贵一些,这个看自己的选择)直接做cdn加速,根据自己的实际情况配置cc防御,用量封顶等规则,这步比较常规

另一个域名去Cloudflare添加一条A记录指向服务器IP,开启小云朵(用作回退源,后面以 cname.example2.com 为例)

找到 SSL/TLS -自定义主机名,把 SaaS 启用(需要验证 Paypal ,直接用银联卡绑定 Paypal 就能过,不需要花钱)

然后新建一个回退源(假设为 cname.example2.com ),等回退源可用后添加自定义主机名,添加的网站就是你的主站(比如 www.example1.com , blog.example1.com 等等),根据提示回到dnspod添加两条txt解析用于签发SSL证书

下面我以你的网站是 blog.example1.com 为例

注意这里有个坑,假如你添加的自定义主机名为 blog.example1.com ,你的txt记录值需要把后面的 example1.com 去掉

就像这样(两条都要哦):_cf-custom-hostname.blog

等cf那边证书状态和主机名状态都变成有效之后,点击 SSL/TLS 概述,把加密模式改成完全(重要!!!否则网站打不开)

回到dnspod添加一个 cname 解析,记录名称为 blog,线路选择境外,记录 cname.example2.com

如果不使用境内CDN,全站用Cloudflare,则需要进行优选,或者使用第三方的优选域名等

这样你的网站就会接入腾讯云+cloudflare两个cdn,并且境外的流量由cf来抗

我这个方案是考虑到cf在境内糟糕的体验加上服务器位于境内才这么做的。兼顾了境内和境外区域的访问体验,如果你不在乎cf到底是加速还是减速,建议直接把域名的ns改到cf,由cf提供dns解析就能直接有cf的cdn了

全部使用cf或者腾讯云的cdn都有弊端,前者大陆区域访问体验很差,后者流量包太少不够攻击者挥霍,而且据我所知攻击者用境外ip攻击的概率会比较大

访问的时候ip来自境内会被dns分流到腾讯云cdn,境外就是cloudflare

但是假如你在境内,使用了 1.1.1.1 这种境外公共dns,全部流量都会直接走cf,这点需要注意,详情看Welcome to my Blog | lm379のBlog

下面是效果图,测试结果来自itdog.cn

2. 防火墙设置

使用fail2ban

如果使用了宝塔面板,可以直接去应用商店搜索Fail2ban,有图形化界面配置端口防扫描和防止ssh爆破
不喜欢宝塔的人也可以直接通过命令安装,以ubuntu为例

1
sudo apt-get install fail2ban

然后复制配置并修改

1
2
3
4
5
cd /etc/fail2ban
## 复制默认配置
sudo cp fail2ban.conf fail2ban.local
sudo cp jail.conf jail.local
nano jail.local

修改服务器防火墙

如果使用了有安全组的云服务商(如阿里云腾讯云),可以前往控制台安全组的位置,放通你常用的网络的IP段

什么意思呢?(下面的看不懂可以直接跳过看实操)

你可以先去 https://ipw.cn 这个网站查询到你本地或者区域的公网ipv4地址,运营商一般会分配一个或者两个/24的ip段给你所在的区域使用,因为家里路由器光猫等设备重启后ip基本都会变动,但是这个ip段是不变的,所以像ssh端口,面板管理端口这些高危端口我们只需要放通这个ip段即可,这样安全组就能帮你拦截大部分端口扫描

就算你向运营商要不到公网ip也没关系,反正你所在的区域都是这个ip段,私网和公网都一样,包括手机流量也是一样的

实操部分

先去下面这个网站获取你的公网ipv4地址

https://ipw.cn/

ipv6防火墙也是类似的

比如你的ip是 114.51.41.91,那么ssh端口就放通 114.51.41.0/24 这个段

此图片仅供娱乐

当然实际用的时候建议将服务器22端口修改为别的

另外将ping直接拒绝

因为我服务器只有web服务,所以来源全部的仅保留 80443 两个端口,其他的web服务全部通过 nginx 转发

问题来了,在其他端口都没放通的情况下,我想在访问服务器上配置的MySQL等服务,应该怎么做呢

答案就是通过SSH转发

比如转发MySQL默认3306端口的命令格式如下

1
ssh -N -L 3306:127.0.0.1:3306 [USER]@[HOST]

这段命令表示将本地的 3306 端口转发到服务器的 3306 端口,后面的 user host 分别表示用于ssh连接的用户名和远程主机ip

如果你修改了SSH端口,也需要添加 -p参数来指定ssh端口

这样你就可以在本地通过 SSH 隧道连接到服务器上的 MySQL,其他服务同理,只需要修改 127.0.0.1 前后的端口即可

如果你使用的是 Navicat 连接数据库,Navicat 内置了 ssh 隧道连接数据库的功能,就不需要单独用SSH命令开隧道

这样一番操作下来,Cloudflare为你抗下了大部分海外的攻击,境内cdn再抗一些,云服务商再帮你拦截掉非本ip段的端口扫描,除非运气好碰上有跟你同一个段的人在爆破你的SSH或者端口,否则全部都扫不出来,应该能防下挺多攻击了吧?

除此之外还可以部署一些WAF项目,比如开源的雷池WAF社区版

Github: chaitin/SafeLine: serve as a reverse proxy to protect your web services from attacks and exploits. (github.com)

官方文档: 雷池 WAF 社区版 | 下一代 Web 应用防火墙 | 免费使用 (chaitin.cn)