阅读视图

发现新文章,点击刷新页面。

关于博客被重庆运营商阻断

起因

昨天将近凌晨一点,躺在床上的时候突然想到最近日志有评论还没回复,太忙碌的生活导致我跟其他博主的互动都少了很多。点开我的博客,却发现浏览器显示“被拒绝访问”,我第一反应是博客又被打导致 CDN 那边停服,可是排查下来发现 CDN 那边一切正常,服务器也没有任何问题。

排查

然后我关掉 WIFI ,使用重庆移动的数据网络访问,浏览器显示“已重置的连接”——经常直接访问 Github 的朋友对此应该很熟悉。我用阿里云拨测了一下,发现暂时只有重庆三大运营商对我的域名解析进行了阻断(或劫持、污染),重庆移动能解析到正确的 IP,但是丢包率为 100%,重庆电信更是很干脆地给我解析到了0.0.0.0,重庆联通拨测也不正常,但是上午让朋友帮忙测试时是可以正常访问的。

重庆电信拨测主站

可是我的博客并没有在境外,在国内开办也按照要求分别进行了 ICP 备案和公安网备,难道是最近写的那篇博文被小题大做给举报了吗?可是看到其他博友的经历,如果有不适合的文章,网信办会首先打电话要求撤下文章,而我并未接到相关的通知。

重庆移动拨测

时间太晚,又要早起上班,所以只得放下手机先睡觉了。

询问

姑且忙完上午的工作后,八点四十左右我开始考虑如何去解决。咨询了某群的一位大佬,他建议问问反诈。

发微信给我网备时加的本地网安支队的叔叔(去面审时看到他们那也是反诈中心),却发现不知何时已经被删除好友。

于是我几经周转,最终通过 96110 联系上了重庆反诈中心,没有联系网信办是我居然找不到重庆网信办(貌似也不是经信委)。电话那边的叔叔问了我域名,叫我不要挂断等他核实。六七分钟后对方回复,还要进一步核实,让我等待他们的回复。

挂断电话,我又联系了 10000,结果和我想的一样,电信的客服根本不懂这是怎么回事,一直问我在哪个区域,转到分公司给我排查。我多番解释,对方答应向上级反馈,然后我们结束了通话。

挂断电话后,我觉得电信肯定给不了什么回复,也不一定是反诈中心做的,于是我联系了腾讯云。腾讯云的工作人员很热情,说报障给重庆运营商,正在核实排查,有进展了第一时间给我同步到会话中。

至此,能询问的已经问完,只能等待结果了。

答复

上午十一点多的时候,主站已经能直接访问了,但是主站引用静态资源的子域名尚未恢复,我将此情况报告给了腾讯云。

中午十二点左右,正在食堂吃饭的时候接到 96110 的电话,那边答复我说确实是他们给我拦截了,不过现在已经解开了。我想了解具体情况,以便我更正错误和进行更严格的自我审查,但是对方说:“肯定就是触碰到反诈了嘛,具体情况不便透露。”我表明仍有两个子域名还未恢复正常访问,对方询问域名,我说了一个之后,可能是觉得难记,就说他们会处理的,然后挂掉了电话。

下午两点多,本地电信分公司的工作人员来电,答复也和我想的差不多,就是他们第一次接到这种工单。我也知道这种事不是分公司的问题,也不是他们可以处理的,就吐槽了一下电信客服啥也不懂依然转到分公司的行为。

下午三点多,腾讯云在售后支持的会话里说,主域名和子域名解析异常的情况已经报障给运营商,因为他们那边处理反馈时间不定,计划晚上九点前和我同步最新进展。在我回复后,下午四点多,腾讯云回复“重庆这边反馈已经解封,您那边确认下”。但是我通过 nslookup、本地 trace和阿里云拨测子域名,使用运营商 DNS 时发现重庆电信和重庆移动这边依然如故,使用第三方 DNS 则解析正常。

本地拨测和云拨测

腾讯云回复继续反馈。我问对方运营商有没有同步阻断原因,对方没有正面回复,只是说:

之前测试是因为域名被劫持,所以解析到了0.0.0.0。域名劫持可能是域名被第三方恶意重定向到了其他网站,运营商为了保护域名将解析改为0.0.0.0,不是您的网站有问题。重庆这边经过拨测判断,根据以往类似情况看,是因为资源没有在本地覆盖被运营商缓存,不是说您那边有问题。运营商解析这边有时会出现问题,所以一般通过报障解决,具体原因的话抱歉运营商那边无法获取到更详细的。

最后腾讯云再次向我确认已经将子域名报障给了运营商,等待次日中午 12 点前反馈。

处理

31 日傍晚,实测重庆移动已经解除了其中一个子域名(反代的 jsdelivr)的封禁,另一个依然无法访问;重庆电信则是两个都还没处理。而此时拨测里发现除了重庆以外,也有个别省份的个别运营商拨测状态不正常。

nslookup 子域名依然解析错误

我批量替换了 jsdelivr 反代的域名,暂时用上了第三方公益反代项目;批量替换了静态资源子域名,临时启用了另一个子域名来保障到运营商处理子域名之前都能正常访问。

最后

老实说,在国内写独立博客,本身就是一件比较严苛的事情,尤其是在叔叔那里备案时我碰了好几次壁。在写博文时我常常有意识地自我审查,克制自己的表达,以免惹上什么麻烦。

而这一次莫名其面的运营商阻断,发生在我的两个备案都正常的情况下,没有人事先告诉我网站存在什么问题(或者确实根本不存在什么问题),就能直接联系运营商给我域名封了,想起来还是觉得很不是滋味。

以后还会更好一些吗,我也不知道了。

题外话,这种麻烦事谁也不愿意惹上,我也非常不想因为某些事和他们打交道。所以评论区的评论如果有些激烈,我可能不会审核通过——保护我,也是保护你。

PCDN 和近期网络攻击频繁的那些事

前段时间接到父母电话,说有自称宽带运营商的工作人员上门检查。父母的安全意识还是很好的,担心会动手脚,人家还没进门,电话就过来了。这让杜老师想起 PCDN 事件,今日整理相关内容,给小伙伴们普及下!

什么是 PCDN

PCDN 或 P2P 是一种基于 P2P 技术和 CDN 的内容分发加速网络。它通过在网络中添加大量的低成本缓存服务器,将用户请求的内容从原始服务器分发到这些缓存服务器,从而实现内容更快、更稳定传输到终端用户。

随着网络技术发展,我们对大带宽的需求也不断增长。各大站群为了用户访问体验,通过 CDN 将用户的请求直接发送到用户所在城市的服务器,从而实现快速、稳定访问。

在内容分发网络服务领域业界普遍采用两种主流的计费模式:流量计费、带宽计费。无论选择哪种计费方式,随着流量的增加其运营成本相应上升,对于任何规模的网站都是一个不容忽视的经济压力。

大型网站由于其庞大的用户基础和高流量需求,对 CDN 服务的依赖则更为显著,因此成本控制成为其运营中关键环节。在这样背景下,一些领先的技术公司开始探索利用家庭宽带资源以优化成本结构。家庭宽带通常有较高的下行速率,而上行速率则相对较低,且普通用户往往未能充分利用其上行带宽。

为更高效地利用这些未被充分利用的上行带宽资源,一些企业推出了挂机宝。这类服务通过在用户设备上部署特定软件,利用用户的闲置带宽进行数据缓存和存储。在需要时,这些数据可以通过用户的家庭网络传输给其他的需求方,从而在减轻大型网站 CDN 负载同时,也为用户带来一定激励回报。

这种模式不仅有效降低了大型网站对传统 CDN 节点的依赖,降低运营成本,而且在经济上对用户也具有一定的吸引力。尽管需要向用户提供一定的激励,但与高昂的 CDN 节点带宽费用相比,这种成本节约是显著的。通过这种方式,企业能够以较低的成本扩展其 CDN 网络,同时为用户提供了一种将闲置资源变现的途径,实现了双方的共赢。

运营商限制 PCDN 原因主要

网络压力:PCDN 产生的海量流量对运营商的骨干传输网络形成了巨大压力。由于用户宽带通常是包月的,而不是按流量计费,因此用户使用越多,运营商网络的压力越大,而且运营商并不能因此收到更多费用。

盈利影响:视频类服务商搭建常规 CDN 服务节点需要租用运营商的高价机房和带宽。而用 PCDN 后,服务商对资源租用需求大幅减少,这直接影响了运营商的盈利。

安全风险:PCDN 节点与其它设备存在数据交互,可能导致隐私数据泄露,甚至产生安全漏洞,遭到恶意攻击。

成本问题:PCDN 业务会导致设备长期开启,增加电能浪费,影响硬盘寿命,甚至整个设备寿命。

PCDN 节点的排查逻辑

运营商对 PCDN 的打击已经产生了扩大化影响。一些地方运营商的政策更加激进,如全面回收 IPv6 地址、限制网络连接数量、网络类型改为 NAT4 等。

运营商需要对网络流量进行监控,区分正常上行流量和 PCDN 流量。这无疑又增加了人力和物力成本,所以大多数运营商都选择封杀 PCDN。

在现代互联网架构中运营商通过精细化的流量数据分析技术,对用户的网络行为进行深入洞察。特别是对上行和下行流量的对比分析,已经成为识别 PCDN 行为的关键指标之一。

普通用户在互联网中主要扮演资源获取者的角色而非资源提供者。因此,从流量分布的一般规律来看,用户的下行流量通常会显著高于上行流量。

这种流量分布的不对称性是家庭宽带非对称带宽特性的直接体现。所谓的非对称带宽,是指在数据传输过程中,上行和下行的带宽速率存在差异,通常情况下下行带宽会高于上行带宽,以适应用户更多下载而非上传的需求。

然而,在特定情况下,如果监测到用户的上行流量异常高甚至超过了下行流量,亦或者上行流量与下行流量的比例超出了正常阈值,这可能表明用户正在作为资源提供方参与到 PCDN 活动。PCDN 利用普通用户的闲置资源,通过 P2P 技术实现内容的分发,这在一定程度上改变了传统上下行流量的分布比例。

近期网络攻击频繁猜想

所谓,上有政策,下有对策。PCDN 服务商面对这种筛查机制,也有其应对的方法「以下内容是杜老师对近期网络攻击频繁的猜想,信息来自于互联网」

上面提到筛查的规则是判断上下行流量的比例,所以一些 PCDN 服务商开始使用刷流量的方式躲避筛查。

他们会在闲时「一般指午夜后」下发指令给 PCDN 设备,使其访问互联网的部分站点,来获得大量的下行流量。

很多博主反馈自己网站在后半夜会有短暂的高流量访问,很有可能就是因为 PCDN 刷流量导致。

面对这种情况,杜老师采用的方式就是根据时段限制流量,如闲时段可以限制带宽,或者流量上限。如触发后及时中断流量,避免因流量造成的资金损失。

最后补充一句,除 PCDN 之外,部分运营商对 PT 的政策也开始收紧了。杜老师的想法非常简单:要么别给那么高的带宽,既然给了,就不要限制我们的使用!

Linux 安装杀毒软件 ClamAV

前两天有小伙伴找到杜老师询问是否可以帮忙查杀服务器的木马病毒,原因是凉心云的安全中心提示有病毒,但自动查杀功能要付费,而且费用较高。正好杜老师最近在研究 Linux 平台的杀毒软件,分享一下 ClamAV 的使用方法。

软件介绍

ClamAV 是一个开源防病毒工具包,专为邮件网关上的电子邮件扫描设计。

它提供了许多实用程序,包括灵活且可扩展的多线程守护程序、命令行扫描程序和用于自动数据库更新的高级工具。

该软件包的核心是以共享库形式提供的防病毒引擎。

除了邮件之外,还可用其扫描系统中的木马病毒。

软件特征

  • 实时保护。ClamD 扫描守护程序 ClamOnAcc 客户端在现代版本的 Linux 上提供按访问扫描。这包括在扫描文件之前阻止文件访问可选功能。

  • ClamAV 可检测数百万种病毒、蠕虫、特洛伊木马和其他恶意软件,包括 Microsoft Office 宏病毒、移动恶意软件以及其它威胁。

  • ClamAV 的字节码签名运行时由 LLVM 或自定义字节码解释器提供支持,允许 ClamAV 签名编写器创建和分发非常复杂的检测例程,并远程增强扫描仪功能。

  • 签名数据库确保 ClamAV 将仅执行受信任的签名定义。

  • ClamAV 扫描存档和压缩文件,还可防止存档炸弹。支持几乎所有邮件文件格式。

  • 高级数据更新程序,支持脚本更新、数字签名和基于 DNS 的数据库版本查询。

软件安装

在 CentOS 操作系统上安装 ClamAV,请分别执行以下的命令「其中 clamav 是扫描工具,clamavd 是实时保护服务,clamav-update 是毒库升级工具」

1
2
yum -y install epel-release
yum -y install clamav clamavd clamav-update

在 Ubuntu 操作系统上安装 ClamAV,请分别执行以下的命令「其中 clamav 是扫描工具,clamav-daemon 是实时保护服务」

1
2
apt update
apt -y install clamav clamav-daemon

软件使用

安装完后,我们在扫描签,建议先运行以下命令更新病毒库:

1
freshclam

然后使用下面命令扫描即可「其中-r 是递归扫描,-i 是仅显示被感染文件,/tmp/ 是设置扫描路径,-l /var/log/clamav.log 是保存日志文件位置」需要注意的是,该命令仅扫描病毒,不会删除病毒文件,需 rm 手动删除。

1
clamscan -r -i /tmp/ -l /var/log/clamav.log

通过 OpenSSL 生成 SSL 证书

随着互联网技术发展和普及,网络安全问题日益突出。SSL 证书作为一种有效的网络安全解决方案,可以确保数据在传输过程中的保密性和完整性。OpenSSL 是一个开源 SSL 工具包,它可用于生成和管理 SSL 证书。本文详细说明如何使用 OpenSSL 生成 SSL 证书,并提供详细的操作步骤。

生成 RSA 密钥对

1
openssl genrsa -out key.pem 2048

注意:要生成 RSA 密钥对可使用以下命令,这个命令将生成一个 2048 位的 RSA 密钥对,并将其保存在 key.pem 文件中。

生成 DSA 密钥对

1
openssl dsaparam -out dsa.pem 2048

注意:要生成 DSA 密钥对可使用以下命令,这个命令将生成一个 2048 位的 DSA 密钥对,并将其保存在 dsa.pem 文件中。

生成证书请求

1
openssl req -new -key key.pem -out cert.csr

注意:生成密钥对后下一步是生成证书请求。证书请求文件将包含公钥和其他信息,这些信息被 CA 用于验证证书请求。要生成证书请求可使用上面命令,这个命令生成一个证书请求文件,并将其保存在 cert.csr 文件中。在生成过程中,您需提供一些信息,例如国家代码、城市、组织名称、组织单位名称等等。

签署证书

1
openssl x509 -req -in cert.csr -signkey key.pem -out cert.pem

注意:生成证书请求后最后一步是签署证书。签署证书是将证书请求与密钥对结合起来,生成一个完整的 SSL 证书。要签署证书可使用上面命令,这个命令将生成一个 X.509 格式证书文件,并将其保存在 cert.pem 文件中。

MySQL 预编译语句

MySQL 预编译语句是一种强大的工具,它不仅提高了应用程序性能,还提升数据安全性。本文将深入探讨 MySQL 预编译语句的原理、优势及如何在实际应用中有效地使用它们。

简介

预编译语句也被称为参数化查询,是一种在数据库层面处理 SQL 语句方法。

它允许开发者在编译时将 SQL 语句中参数值替换为占位符,然后在运行时再将实际的参数值传递给数据库。

原理

预编译语句的工作原理分为两个阶段:编译阶段、执行阶段。

在编译阶段时,MySQL 将 SQL 语句进行语法分析和优化,生成对应执行计划。

在执行阶段是,MySQL 根据执行计划执行 SQL 语句,并将结果返回给客户端。

以此提升执行效率。

优势

  1. 提高安全:预编译语句可以防止 SQL 注入攻击,这是一种常见安全漏洞,攻击者可以利用它修改或删除数据库中的数据。通过用预编译语句,开发者可以确保所有 SQL 语句在编译时都已经过验证,从而防止 SQL 的注入攻击。

  2. 提升性能:预编译语句可以显著提高应用程序的性能。当相同 SQL 语句被多次执行时,预编译语句可以重用编译后的 SQL 语句,从而节省编译时间。此外,预编译语句还可减少 SQL 解析器的负担,进一步提高 MySQL 性能。

  3. 简化代码:使用预编译语句可简化 SQL 语句的编写,特别是在处理动态 SQL 语句时。开发者可将参数值直接传递给预编译语句,而无需手动拼接 SQL 语句,从而降低出错的可能性。

使用

1
2
3
4
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();

注意:在这个示例中,我们首先定义了一个 SQL 语句,然后通过 prepareStatement 方法创建一个预编译语句。紧接着我们通过 setInt 方法将参数值传递给预编译语句,最后执行查询并获取结果集。

MySQL 如何启用 SSL 加密连接

MySQL 是一种流行的开源数据库管理系统,广泛应用于各种 Web 应用程序和数据存储中。然而,传统的 MySQL 连接在传输数据时并未加密,可能存在安全风险。启用 SSL 加密连接可确保数据在传输过程中的安全性和完整性。本文详细说明如何在 MySQL 中启用 SSL 加密连接。

准备工作

SSL 是一种被广泛使用的网络协议,用于在客户端和服务器之间建立安全通信通道。通过使用 SSL 可以确保传输的数据不被第三方窃听或篡改。启用 SSL 加密连接第一步是准备 SSL 证书。SSL 证书由可信证书颁发机构签发,用于验证服务器的身份。您可以从 CA 购买 SSL 证书,也可使用 OpenSSL 等工具自行生成。

在开始启用 SSL 之前,需要确保 MySQL 服务器和客户端已经安装了 SSL 模块。如果您使用的是 MySQL 二进制包,那么可能已经安装了 SSL 模块。如果您使用的是源码包,则需手动编译并安装 SSL 模块。

安装证书

将 SSL 证书安装到 MySQL 服务器上。通常,您需要将 SSL 证书和私钥文件复制到 MySQL 服务器的指定目录,如 /etc/mysql/ssl

编辑 MySQL 服务器配置文件,以启用 SSL 并指定 SSL 证书和私钥文件的路径。

配置示例

以下是一个 SSL 示例配置:

1
2
3
4
[mysqld]
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem

以下是 SSL 配置参数说明:

参数说明
ssl-caCA 证书的路径
ssl-cert服务器证书的路径
ssl-key服务器私钥的路径

重启测试

保存 MySQL 配置文件后,重启 MySQL 服务以应用新的配置。在 Linux 系统中可以使用以下命令重启 MySQL 服务:

1
sudo systemctl restart mysql

在配置完成后,您可以使用 mysql 命令行工具测试 SSL 连接。要启用 SSL 连接,您可以使用--ssl-ca, --ssl-cert--ssl-key 选项。以下是一个测试 SSL 连接示例:

1
mysql --host=localhost --port=3306 --user=root --password=your_password --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem

验证连接

测试 SSL 连接无误后,您可以在 MySQL 服务器中启用 SSL。要启用 SSL,您需要在 my.ini 配置文件中添加以下参数:

1
2
require_secure_transport=ON
ssl=ON

要验证 SSL 连接是否成功启用,您可在 MySQL 命令行工具中输入以下命令:

1
SHOW STATUS LIKE 'Ssl_cipher';

结果总结

如果看到类似以下输出,则表示 SSL 连接已经启用:

1
2
3
4
5
+--------------------+--------------------------------------------------------------+
| Variable_name | Value |
+--------------------+--------------------------------------------------------------+
| Ssl_cipher | DHE-RSA-AES256-GCM-SHA384 |
+--------------------+--------------------------------------------------------------+

启用 MySQL 的 SSL 加密连接可有效提高数据传输的安全性。我们建议您在生产环境中始终启用 SSL,以确保数据安全性。最后分享一个 OpenSSL 创建公私秘钥的示例:

1
2
openssl genrsa -out rsa_private.key 2048
openssl rsa -in rsa_private.key -pubout -out rsa_public.key

如何屏蔽掉令人讨厌的评论

最近有小伙伴们反馈总是收到一些令人讨厌的评论,虽然成功被垃圾评论插件过滤了,但看到后还是会很闹心。杜老师也收到这类评论,虽说手动屏蔽但感觉很麻烦。这里我们分享一下如何借助面板插件,实现对该类评论的拦截~

写在前面

常访问的小伙伴都知道杜老师有个聊天室,有些小伙伴没事会过来摸鱼聊天。

其中 obaby 经常来,前段时间分享一张截图,是博客后台的评论管理页面,里面的留言内容很令人反感。

虽说被插件拦截了,但看到还是很闹心。杜老师也收到类似留言,除手动屏蔽外,还提交到不良信息举报中心。

可能是举报中心需处理的数据量较大,这个留言者迟迟未处理。

杜老师等其它博友依旧可以收到相关评论,故杜老师决定通过技术手段,拦截该类信息提交。

经过分析发现,评论提交者会经常变动昵称、邮箱,但网址一直没变动。所以对关键词进行拦截即可。

某塔面板

如果使用某塔面板,可以安装 Nginx 免费防火墙。打开防火墙页面后,切换到全局配置项,找到 POST 过滤的规则:

Nginx 免费防火墙默认包含很多的拦截项,这些都不用管。将需要拦截的域名,输入到下图中 dusays.com 处,点击后面添加即可:

某 Panel 面板

如果使用某 Panel 面板,并使用 OpenResty 引擎,则无需安装额外的插件。该引擎自带过滤器。点击左侧网站,进入到需要过滤的网址:

在网站设置页面中,切换到安全项。找到下方的 POST 参数校验「默认关闭,需要手动开启」在数据项后添加过滤的网址,点击下面添加即可:

写在最后

对这种 antisocial personality disorder 人格,杜老师墙裂建议看到该类评论后,第一时间提交不良信息举报中心。

还要保持心态,不要因为这类评论扰乱自己心态,也不要考虑到报复。这种人格特征是高度攻击性,且缺乏羞惭感,不能从经历中取得经验教训,行为受偶然动机驱使等。

发病原因来自父母养育方式不仅与父母自身文化等有关,还与另一方的情况,如配偶是否健在以及家庭婚姻的状况息息相关。

该人格障碍人群的人格特征明显偏离正常,通常在个人生活风格和人际关系方面具有异常行为模式。常于童年期或青少年期就出现了品行问题,并长期持续发展至成年或者终生。

Nginx 的 WAF 规则 LuaJIT 严重版本

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为严重风险的防护规则!

fastjson漏洞拦截

过滤阶段:请求阶段

规则描述:拦截fastjson漏洞漏洞攻击

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local jsonFilter = waf.jsonFilter

local function rMatch(v)
if v == "@type" then
return true, v
end
return false
end

local form = waf.form
if form then
local raw = form["RAW"]
local m = jsonFilter(raw, rMatch, false)
if m then
return m, raw, true
end
end

return false

json格式校验

过滤阶段:请求阶段

规则描述:高级攻击者会构造一些异常json绕过WAF检测,该规则对json格式进行安全校验,可以拦截异常json请求。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local form = waf.form
local rct = waf.reqContentType
local rgx = waf.rgxMatch

if rct and waf.contains(waf.toLower(rct), "application/json") and form then
local raw = form["RAW"]
if raw then
if rgx(raw, "^\\s*$", "jos") then
return false
end
local err = waf.checkJson(raw)
if err then
return true, err .. ":" .. raw, true
end
end
end

return false

XSS跨站脚本攻击

过滤阶段:请求阶段

规则描述:攻击者通常会在有漏洞的程序中插入 JavaScript、VBScript、 ActiveX或Flash以欺骗用户。一旦得手,他们可以盗取用户帐户,修改用户设置,盗取/污染cookie,做虚假广告等。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
local kvFilter = waf.kvFilter
local checkXSS = waf.checkXSS


local function sMatch(v)
if v then
local m = checkXSS(v)
if m then
return m, v
end
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = sMatch(waf.userAgent)
if m then
return m, d, true
end

local m, d = sMatch(waf.referer)
if m then
return m, d, true
end

return false

java安全规则集

过滤阶段:请求阶段

规则描述:检测spring、struts、java序列化等相关安全漏洞

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local urlDecode = waf.urlDecode
local requestLine = waf.requestLine
local check = waf.plugins.javaClassDetection.check

local function sMatch(v)
local m = rgx(v, "(?:\\$\\{)+(?:j(?:n|\\$\\{)|\\$\\{(?:\\w*:)+)", "joi")
if m then
return m, "Potential Log4j / Log4shell Attack: " .. v
end
m = rgx(v, "\\xac\\xed\\x00\\x05|rO0ABQ|KztAAU|Cs7QAF", "jo")
if m then
return m, "Magic bytes Detected, probable java serialization Attack: " .. v
end
m = rgx(v, "classLoader\\s*\\.\\s*resources\\s*\\.\\s*context\\s*\\.\\s*parent\\s*\\.\\s*pipeline|springframework\\s*\\.\\s*context\\s*\\.\\s*support\\s*\\.\\s*FileSystemXmlApplicationContext", "jos")
if m then
return m, "Spring Framework RCE(CVE-2022-22965): " .. v
end
m = check(v)
if m then
return m, "Potential dangerous java class: " .. v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
local raw = form["RAW"]
m = rgx(raw, "\\xac\\xed\\x00\\x05|rO0ABQ|KztAAU|Cs7QAF", "jo")
if m then
return m, raw, true
end
m = check(raw)
if m then
return m, raw, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end

local m = rgx(urlDecode(requestLine), "(?:\\$\\{)+(?:j(?:n|\\$\\{)|\\$\\{(?:\\w*:)+)", "joi")
if m then
return m, requestLine, true
end

return false

Shellshock漏洞

过滤阶段:请求阶段

规则描述:检测对“Shellshock”(CVE-2014-6271和CVE-2014-7169) GNU Bash RCE漏洞的攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local requestLine = waf.requestLine
local urlDecode = waf.urlDecode

local function rMatch(v)
local m = rgx(urlDecode(v), "\\(\\s*\\)\\s+{", "jos")
if m then
return m, v
end
return false
end

local m, d = kvFilter(waf.reqHeaders, rMatch)
if m then
return m, d, true
end

local m, d = rMatch(requestLine)
if m then
return m, d, true
end

return false

远程文件包含 (RFI)

过滤阶段:请求阶段

规则描述:该规则寻找常见类型的远程文件包含(RFI)攻击方法。 #-PHP“include()”函数 #-JSP <jsp:include page= 或 <c:import url= #-RFI主机与本地主机不匹配

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local host = waf.host
local counter = waf.strCounter
local str_find = string.find
local str_sub = string.sub

local function rMatch(v)
local m = rgx(v, "^(?:url:)?file|ftps?|https?)://(?:[^@]+@)?([^/]+", "joi")
if m then
local i, j = str_find(v, host, 1, true)
if i then
if counter(str_sub(v, 1, j), "/") == 2 then
return false
end
end
end
return m, v
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

return false

json 命令注入检测

过滤阶段:请求阶段

规则描述:解析请求body中的json内容,并检测命令注入攻击。采用RCE语义检测引擎可以检查各种变形,如:cat$IFS/etc/os-release或c$()at /e??/p???等

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local checkRCE = waf.checkRCE
local jsonFilter = waf.jsonFilter

local function rMatch(v)
local m = checkRCE(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = jsonFilter(form["RAW"], rMatch, false, true)
if m then
return m, d, true
end
end

return false

常规命令注入检测

过滤阶段:请求阶段

规则描述:检测url、cookie、form中的shell命令注入攻击,采用RCE语义检测引擎可以检查各种变形,如:cat$IFS/etc/os-release或c$()at /e??/p???等

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
local checkRCE = waf.checkRCE
local kvFilter = waf.kvFilter

local function rMatch(v)
local m = checkRCE(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch, true)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch, true)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch, true)
if m then
return m, d, true
end
end
return false

json sql注入检测

过滤阶段:请求阶段

规则描述:解析请求body中的json内容,并检测sql注入攻击。采用SQL语义检测引擎,可以降低误报。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local checkSQLI = waf.checkSQLI
local jsonFilter = waf.jsonFilter

local function rMatch(v)
local m = checkSQLI(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = jsonFilter(form["RAW"], rMatch, false)
if m then
return m, d, true
end
end

return false

常规sql注入检测

过滤阶段:请求阶段

规则描述:检测url、cookie、form中的sql注入攻击。采用SQL语义检测引擎,可以降低误报。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
local checkSQLI = waf.checkSQLI
local kvFilter = waf.kvFilter

local function sMatch(v)
local m = checkSQLI(v)
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end

return false

Invalid protocol

过滤阶段:请求阶段

规则描述:请求header数过多,超过64个。

规则内容:

1
2
3
4
if waf.hErr and waf.hErr=="truncated" then
return true,waf.hErr,true
end
return false

XXE漏洞

过滤阶段:请求阶段

规则描述:XML外部实体注入(XML External Entity)漏洞简称XXE漏洞。当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

规则内容:

1
2
3
4
5
6
7
if waf.form and waf.form["RAW"] then
local m = waf.rgxMatch(waf.form["RAW"], "<!(?:DOCTYPE|ENTITY)[^>]+?\\bSYSTEM\\b", "jos")
if m then
return m, waf.form["RAW"], true
end
end
return false

ImageMagick漏洞

过滤阶段:请求阶段

规则描述:ImageMagick是一个功能强大的开源图形处理软件,该漏洞可以执行任意命令和读写文件

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function imgContentMatch(v)
local m = rgx(v, "\\bpush\\s+graphic-context\\b|\\<\\s*image\\b", "joi")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], imgContentMatch, 0)
return m, d, true
end
return false

header头漏洞

过滤阶段:请求阶段

规则描述:httpoxy漏洞可被用来针对CGI环境设置非法代理,从而窃取服务器敏感数据。在CVE-2017-7269(IIS 6.0 WebDAV远程代码执行漏洞)中if和lock_token http头会造成溢出攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
if waf.reqHeaders.proxy ~= nil then
return true, "Proxy: " .. waf.reqHeaders.proxy, true
end

if waf.reqHeaders.lock_token ~= nil then
return true, "Lock-Token: " .. waf.reqHeaders.lock_token, true
end

if waf.reqHeaders["If"] ~= nil then
return true, "If: " .. waf.reqHeaders["If"], true
end

return false

LDAP Injection

过滤阶段:请求阶段

规则描述:拦截LDAP注入攻击

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(htmlEntityDecode(v), "^[^:\\(\\)\\&\\|\\!\\<\\>\\~]*\\)\\s*(?:\\((?:[^,\\(\\)\\=\\&\\|\\!\\<\\>\\~]+[><~]?=|\\s*[&!|]\\s*(?:\\)|\\()?\\s*)|\\)\\s*\\(\\s*[\\&\\|\\!]\\s*|[&!|]\\s*\\([^\\(\\)\\=\\&\\|\\!\\<\\>\\~]+[><~]?=[^:\\(\\)\\&\\|\\!\\<\\>\\~]*)", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
end
return false

HTTP Splitting

过滤阶段:请求阶段

规则描述:此规则检测请求文件名中的\n或\r。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function fMatch(v)
local m = rgx(v, "[\\n\\r]", "jo")
if m then
return m, v
end
return false
end
local m, d = fMatch(waf.uri)
if m then
return m, d, true
end
return false

HTTP Header Injection

过滤阶段:请求阶段

规则描述:HTTP头注入查找回车符(CR)%0d和换行符(LF)%0a字符,单独或与header字段名称组合使用。如果数据在响应头中返回并由客户端解释,这些字符可能会导致问题。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode
local concat = table.concat

local function hMatch(v)
local m = rgx(htmlEntityDecode(v), "[\\n\\r]", "jo")
if m then
return m, v
end
return false
end

local function vMatch(v)
local m = rgx(htmlEntityDecode(v), "[\\n\\r]+(?:\\s|location|refresh|(?:set-)?cookie|(?:x-)?(?:forwarded-(?:for|host|server)|host|via|remote-ip|remote-addr|originating-IP))\\s*:", "josi")
if m then
return m, v
end
return false
end

local m, d = waf.kvFilter(waf.reqHeaders, hMatch)
if m then
return m, d, true
end

local queryString = waf.queryString
if queryString then
for k, v in pairs(waf.queryString) do
m, d = hMatch(k)
if m then
return m, d, true
end
if type(v)=="table" then
v = concat(v,",")
end
m, d = vMatch(v)
if m then
return m, d, true
end
end
end

local form = waf.form
if form then
for k, _ in pairs(form["FORM"]) do
m, d = hMatch(k)
if m then
return m, d, true
end
end
end

return false

boundary异常拦截

过滤阶段:请求阶段

规则描述:拦截请求content type头中multipart/form-data的异常boundary,如php在上传解析boundary时没有符合rfc规范,对逗号产生了错误解析。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local ct = waf.reqContentType

if ct then
if type(ct) ~= "string" then
return true, "Malform Content-Type", true
elseif waf.contains(ct, "boundary") and (waf.strCounter(ct, "boundary") > 1 or not waf.rgxMatch(ct, "boundary=[\\w\\-]+$", "jo")) then
return true, ct, true
end
end

return false

asp畸形编码过滤

过滤阶段:请求阶段

规则描述:asp中unicode畸形编码会造成waf绕过危害

规则内容:

1
2
3
4
if waf.rgxMatch(waf.reqUri,"%u00(?:aa|ba|d0|de|e2|f0|fe)","i") then
return true,waf.reqUri,true
end
return false

HTTP Response Splitting

过滤阶段:请求阶段

规则描述:该规则查找回车符(CR)%0d和换行符(LF)%0a字符。如果在响应报头中返回数据,这些字符可能会导致问题,并且可能会被中间代理服务器解释并被视为两个单独的响应。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(v, "[\\r\\n]\\W*?(?:content-(?:type|length)|set-cookie|location):\\s*\\w", "josi")
if m then
return m, v
end
return false
end

local function hMatch(v)
local m = rgx(htmlEntityDecode(v), "(?:\\bhttp/\\d|<(?:html|meta)\\b)", "josi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
m, d = kvFilter(form["FORM"], hMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
m, d = kvFilter(queryString, hMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
m, d = kvFilter(cookies, hMatch)
if m then
return m, d, true
end
end
return false

HTTP Request Smuggling

过滤阶段:请求阶段

规则描述:此规则查找与单词HTTP/\d或CR/LF字符组合的HTTP/WEBDAV方法名。这将指向试图将第二个请求注入到请求中,从而绕过对主请求执行的测试,如CVE-2019-20372(Nginx<1.17.7 请求走私漏洞)。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local htmlEntityDecode = waf.htmlEntityDecode

local function rMatch(v)
local m = rgx(htmlEntityDecode(v), "(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\s+[^\\s]+\\s+http/\\d", "josi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], rMatch)
if m then
return m, d, true
end
m, d = rMatch(form["RAW"])
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, rMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, rMatch)
if m then
return m, d, true
end
end
return false

上传文件内容过滤

过滤阶段:请求阶段

规则描述:过滤上传的文件内容,拦截webshell上传

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
local rgx = waf.rgxMatch
local function fileContentMatch(v)
local m = rgx(v, "<\\?.+?\\$(?:GLOBALS|_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION|ENV))|<\\?php|<jsp:|<%(?i:!|\\s*@|.*?\\brequest\\s*(?:\\.|\\())", "jos")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], fileContentMatch, 0)
return m, d, true
end
return false

上传文件名过滤

过滤阶段:请求阶段

规则描述:过滤上传文件名中的网页脚本扩展名,拦截webshell上传

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local rgx = waf.rgxMatch

local function fileNameMatch(v)
local m = rgx(v, "\\.(?:as|cer\\b|cdx|ph|jsp|war|class|exe|ht|env|user\\.ini)|php\\.ini", "joi")
if m then
return m, v
end
return false
end
if waf.form then
local m, d = waf.knFilter(waf.form["FILES"], fileNameMatch, 1)
return m, d, true
end

return false

防持续攻击

过滤阶段:请求阶段

规则描述:累计攻击超过100次,则在10分钟内拦截该ip访问

规则内容:

1
2
3
4
5
6
7
local ib = waf.ipBlock
local c = ib:get(waf.ip)
if c and c >= 100 then
ib:set(waf.ip, c, 600, 1)
return true, "ip blocked for continue attack: " .. waf.ip, true
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:非法post协议

规则内容:

1
2
3
4
5
6
7
if waf.form == nil then
if waf.contains(waf.fErr, "content_type") then
return true, waf.fErr .. ": " .. waf.reqContentType, true
end
return true, waf.fErr, true
end
return false

Nginx 的 WAF 规则 LuaJIT 高危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为高危险防护规则!

SQL报错检测

过滤阶段:返回页面

规则描述:返回页面的sql报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
local check = waf.plugins.sqlErrorDetection.check
local rb = waf.respBody
local rgx = waf.rgxMatch
local has = waf.contains

if waf.status == 500 then
local m = check(rb)
if m then
if rgx(rb, "JET Database Engine|Access Database Engine|\\[Microsoft\\]\\[ODBC Microsoft Access Driver\\]", "jo") then
return m, "Microsoft Access SQL Information Leakage: " .. rb, true
end
if rgx(rb, "ORA-[0-9][0-9][0-9][0-9]|java\\.sql\\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*", "jo") then
return m, "Oracle SQL Information Leakage: " .. rb, true
end
if rgx(rb, "DB2 SQL error:|\\[IBM\\]\\[CLI Driver\\]\\[DB2/6000\\]|CLI Driver.*DB2|DB2 SQL error|db2_\\w+\\(", "jo") then
return m, "DB2 SQL Information Leakage: " .. rb, true
end
if rgx(rb, "\\[DM_QUERY_E_SYNTAX\\]|has occurred in the vicinity of:", "jo") then
return m, "EMC SQL Information Leakage: " .. rb, true
end
if has(rb, "Dynamic SQL Error") then
return m, "firebird SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Exception (?:condition )?\\d+\\. Transaction rollback\\.", "jo") then
return m, "Frontbase SQL Information Leakage: " .. rb, true
end
if has(rb, "org.hsqldb.jdbc") then
return m, "hsqldb SQL Information Leakage: " .. rb, true
end
if rgx(rb, "An illegal character has been found in the statement|com\\.informix\\.jdbc|Exception.*Informix", "jo") then
return m, "informix SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Warning.*ingres_|Ingres SQLSTATE|Ingres\\W.*Driver", "jo") then
return m, "ingres SQL Information Leakage: " .. rb, true
end
if rgx(rb, "<b>Warning</b>: ibase_|Unexpected end of command in statement", "jo") then
return m, "interbase SQL Information Leakage: " .. rb, true
end
if rgx(rb, "SQL error.*POS[0-9]+|Warning.*maxdb", "jo") then
return m, "maxDB SQL Information Leakage: " .. rb, true
end
if rgx(rb, "System\\.Data\\.OleDb\\.OleDbException|\\[Microsoft\\]\\[ODBC SQL Server Driver\\]|\\[Macromedia\\]\\[SQLServer JDBC Driver\\]|\\[SqlException|System\\.Data\\.SqlClient\\.SqlException|Unclosed quotation mark after the character string|'80040e14'|mssql_query\\(\\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\\.|ADODB\\.Field \\(0x800A0BCD\\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\\WSystem\\.Data\\.SqlClient\\.", "jo") then
return m, "Mssql SQL Information Leakage: " .. rb, true
end
if rgx(rb, "MyS(?:QL server version for the right syntax to use|qlClient\\.)|(?:supplied argument is not a valid |SQL syntax.*)MySQL|Column count doesn't match(?: value count at row)?|(?:Table '[^']+' doesn't exis|valid MySQL resul)t|You have an error in your SQL syntax(?: near|;)|Warning.{1,10}mysql_(?:[a-z_()]{1,26})?|ERROR [0-9]{4} \\([a-z0-9]{5}\\):|mysql_fetch_array\\(\\)|on MySQL result index|\\[MySQL\\]\\[ODBC", "jo") then
return m, "Mysql SQL Information Leakage: " .. rb, true
end
if rgx(rb, "PostgreSQL query failed:|pg_query\\(\\) \\[:|pg_exec\\(\\) \\[:|PostgreSQL.{1,20}ERROR|Warning.*\\bpg_.*|valid PostgreSQL result|Npgsql\\.|PG::[a-zA-Z]*Error|Supplied argument is not a valid PostgreSQL .*? resource|Unable to connect to PostgreSQL server", "jo") then
return m, "Postgres SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Warning.*sqlite_|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\\.Exception|System\\.Data\\.SQLite\\.SQLiteException", "jo") then
return m, "SQLite SQL Information Leakage: " .. rb, true
end
if rgx(rb, "Sybase message:|Warning.{2,20}sybase|Sybase.*Server message", "jo") then
return m, "Sybase SQL Information Leakage: " .. rb, true
end
end
end

return false

数据泄露检测

过滤阶段:返回页面

规则描述:从返回页面检测列目录漏洞和源代码泄露问题

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
local rgx = waf.rgxMatch
local rb = waf.respBody

local m = rgx(rb, "<(?:TITLE>Index of.*?<H|title>Index of.*?<h)1>Index of|>\\[To Parent Directory\\]</[Aa]><br>", "jo")
if m then
return m, "Directory Listing: " .. rb, true
end

m = rgx(rb, "^\\s*(?:#\\!\\s?/|<%|<\\?\\s*[^x]|<jsp:)", "jo")
if m then
return m, "Source code leak: " .. rb, true
end

return false

固定会话(Session Fixation)攻击

过滤阶段:请求阶段

规则描述:会话固定攻击(session fixation attack)是利用应用系统在服务器的会话ID固定不变机制,借助他人用相同的会话ID获取认证和授权,然后利用该会话ID劫持他人的会话以成功冒充他人,造成会话固定攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch
local referer = waf.referer
local host = waf.host
local endWith = waf.endWith

local function sMatch(v)
local m = rgx(v, "\\bhttp-equiv\\W+set-cookie\\b", "joi")
if m then
return m, v
end
return false
end

local function nMatch(v)
local m = rgx(v, "^(?:jsessionid|aspsessionid|asp\\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$", "joi")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
for k, v in pairs(form["FORM"]) do
m, d = nMatch(k)
if m then
if not referer then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
else
m = ngx.re.match(referer, "^https?://(.*?)/", "jo")
if m and not endWith(m[1], host) then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
end
end
end
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
for k, v in pairs(queryString) do
m, d = nMatch(k)
if m then
if not referer then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
else
m = ngx.re.match(referer, "^https?://(.*?)/", "jo")
if m and not endWith(m[1], host) then
if type(v) == "table" then
v = table.concat(v)
end
return m, d .. ":" .. v, true
end
end
end
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

return false

通用攻击

过滤阶段:请求阶段

规则描述:本规则拦截ruby、node、js、perl注入和SSRF攻击

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch

local function sMatch(v)
local m = rgx(v, "Process\\s*\\.\\s*spawn\\s*\\(", "jos")
if m then
return m, "Ruby Injection Attack: "..v
end
m = rgx(v, "t(?:his\\.constructor|runcateSync\\s*\\()|\\b(?:spawn|eval)\\s*\\(|_(?:\\$\\$ND_FUNC\\$\\$_|_js_function)|String\\s*\\.\\s*fromCharCode", "jos")
if m then
return m, "Node.js Injection Attack: "..v
end
m = rgx(v, "__proto__|constructor\\s*(?:\\.|\\[)\\s*prototype", "jos")
if m then
return m, "JavaScript Prototype Pollution: "..v
end
m = rgx(v, "(?:s(?:sh(?:2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?)?|m(?:[bs]|tps?)|vn(?:\\+ssh)?|n(?:ews|mp)|ips?|ftp|3)|p(?:op(?:3s?|2)|r(?:oxy|es)|h(?:ar|p)|aparazzi|syc)|c(?:ompress.(?:bzip2|zlib)|a(?:llto|p)|id|vs)|t(?:e(?:amspeak|lnet)|urns?|ftp)|f(?:i(?:nger|sh)|(?:ee)?d|tps?)|i(?:rc[6s]?|maps?|pps?|cap|ax)|d(?:a(?:ta|v)|n(?:tp|s)|ict)|m(?:a(?:ilto|ven)|umble|ms)|n(?:e(?:tdoc|ws)|ntps?|fs)|r(?:tm(?:f?p)?|sync|ar|mi)|v(?:iew-source|entrilo|nc)|a(?:ttachment|f[ps]|cap)|b(?:eshare|itcoin|lob)|g(?:o(?:pher)?|lob|it)|u(?:nreal|t2004|dp)|e(?:xpect|d2k)|h(?:ttps?|323)|w(?:ebcal|s?s)|ja(?:bbe)?r|x(?:mpp|ri)|ldap[is]?|ogg|zip):\\/\\/(?:(?:[\\d.]{0,11}(?:(?:\\xe2(?:\\x92(?:[\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5]|[\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b]|[\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf]|[\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87])|\\x93(?:[\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f]|[\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9]|[\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b]|[\\xbf\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe]|[\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4])|\\x91(?:[\\xaa\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3]|[\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf]))|\\xe3\\x80\\x82))+)|[a-z][\\w\\-\\.]{1,255}:\\d{1,5}(?:#?\\s*&?@(?:(?:\\d{1,3}\\.){3,3}\\d{1,3}|[a-z][\\w\\-\\.]{1,255}):\\d{1,5}\\/?)+|(?:0x[a-f0-9]{2}\\.){3}0x[a-f0-9]{2}|(?:0{1,4}\\d{1,3}\\.){3}0{1,4}\\d{1,3}|\\d{1,3}\\.(?:\\d{1,3}\\.\\d{5}|\\d{8})|0x(?:[a-f0-9]{16}|[a-f0-9]{8})|\\[[a-f\\d:]+(?:[\\d.]+|%\\w+)?\\]|(?:\\x5c\\x5c[a-z\\d-]\\.?_?)+|\\d{10})", "josi")
if m then
return m, "Possible Server Side Request Forgery (SSRF) Attack: "..v
end
m = rgx(v, "\\@\\{.*?\\}", "jos")
if m then
return m, "Perl Injection Attack: "..v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end
return false

php安全规则集

过滤阶段:请求阶段

规则描述:检测php相关的对象序列化等漏洞

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
local kvFilter = waf.kvFilter
local rgx = waf.rgxMatch

local function sMatch(v)
local m = rgx(v, "php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)|(?:ssh2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?|z(?:lib|ip)|(?:ph|r)ar|expect|bzip2|glob|ogg)://", "joi")
if m then
return m, v
end
m = rgx(v, "[oOcC]:\\d+:\"\\w+\":\\d+:{.*?}", "jos")
if m then
return m, v
end
return false
end

local function fileContentMatch(v)
local m = rgx(v, "<\\?.+?\\$_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION)|<\\?php", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], sMatch)
if m then
return m, d, true
end
m, d = waf.knFilter(form["FILES"], fileContentMatch, 0)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, sMatch)
if m then
return m, d, true
end
end

local cookies = waf.cookies
if cookies then
local m, d = kvFilter(cookies, sMatch)
if m then
return m, d, true
end
end

local m, d = kvFilter(waf.reqHeaders, sMatch)
if m then
return m, d, true
end
return false

路径遍历攻击

过滤阶段:请求阶段

规则描述:检测url、上传文件或参数中的路径遍历攻击。采用LFI语义检测引擎,可以检查如://///…\…\etc///passwd等变形攻击。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
local checkPT = waf.checkPT
local kvFilter = waf.kvFilter

local function ptMatch(v)
local m = checkPT(v)
if m then
return m, v
end
return false
end

local url = waf.urlDecode(waf.reqUri)
if checkPT(url) then
return true, url, true
end

local form = waf.form
if form then
local m, d = kvFilter(form["FORM"], ptMatch)
if m then
return m, d, true
end
m, d = waf.knFilter(waf.form["FILES"], ptMatch, 1)
if m then
return m, d, true
end
end

local queryString = waf.queryString
if queryString then
local m, d = kvFilter(queryString, ptMatch)
if m then
return m, d, true
end
end

return false

异常请求字符编码拦截

过滤阶段:请求阶段

规则描述:黑客通常会在Content-Type头中使用异常的charset定义字符集编码来绕过waf保护,如IBM037, IBM500, cp875等

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local rct = waf.reqContentType
local has = waf.contains
local counter = waf.strCounter
local rgx = waf.rgxMatch
if rct then
rct = waf.toLower(rct)
if has(rct, "charset") and (not rgx(rct, "charset\\s*=\\s*(utf\\-8|gbk|gb2312|iso\\-8859\\-1|iso\\-8859\\-15|windows\\-1252)","jo") or counter(rct, "charset") > 1) then
return true, rct, true
end
end
return false

代理头sql注入

过滤阶段:请求阶段

规则描述:过滤http请求中X-Forwarded-For、Client-IP请求头中单引号sql注入

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local rip=waf.reqHeaders.x_forwarded_for
if rip then
if type(rip) ~= "string" then
return true,"Malform X-Forwarded-For",true
elseif waf.contains(rip,"'") then
return true,rip,true
end
end
rip=waf.reqHeaders.client_ip
if rip then
if type(rip) ~= "string" then
return true,"Malform Client-IP",true
elseif waf.contains(rip,"'") then
return true,rip,true
end
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:cookie参数过多

规则内容:

1
2
3
4
if waf.cookies==nil then
return true,waf.cErr,true
end
return false

Invalid protocol

过滤阶段:请求阶段

规则描述:querystring参数过多

规则内容:

1
2
3
4
if waf.queryString==nil then
return true,waf.qErr,true
end
return false

Nginx 的 WAF 规则 LuaJIT 中危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为中危险防护规则!

机器人攻击防护

过滤阶段:请求阶段

规则描述:通过生成滑动旋转验证码来拦截机器人攻击,如漏洞扫描、网络爬虫、CC攻击等自动化攻击行为,Token有效期30分钟。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
local sh = ngx.shared.ipCache
local robotIp = 'rb:' .. waf.ip
local c, f = sh:get(robotIp)

-- 如果是静态页面且没有进行滑动旋转验证码验证则返回
if not (waf.isQueryString or waf.reqContentLength > 0) and f ~= 2 then
return false
end

if not c then
sh:set(robotIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间段
else
if f == 2 then
return waf.checkRobot(waf) -- 启动机器人滑动旋转验证码验证
end
sh:incr(robotIp, 1)
if c + 1 >= 360 then
sh:set(robotIp, c + 1, 1800, 2) -- 达到了60秒内请求超过360次的阈值,进入机器人验证模式
return true, robotIp, true
end
end

return false

弱口令检测

过滤阶段:请求阶段

规则描述:检测常见登录页面的弱口令问题

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local check = waf.plugins.weakPwdDetection.check
local toLower = waf.toLower
local has = waf.contains

local form = waf.form
local uri = toLower(waf.uri)
if form and (has(uri, "login") or has(uri, "logon") or has(uri, "signin")) then
local f = form["FORM"]
if f then
for k, v in pairs(f) do
k = toLower(k)
if (k == "pass" or has(k, "pwd") or has(k, "passwd") or has(k, "password")) and check(v) then
return true, form["RAW"], false
end
end
end
end

return false

敏感文件泄露检测

过滤阶段:请求阶段

规则描述:检测url中各种敏感泄露文件的路径,如svn、git、sql、log、bak等,防止被攻击者利用

规则内容:

1
2
3
4
5
local m, d = waf.plugins.fileLeakDetection.check()
if m then
return true, d, true
end
return false

请求body大小限制

过滤阶段:请求阶段

规则描述:限制请求body大小为8M以下,黑客会尝试大数据包绕过waf过滤

规则内容:

1
2
3
4
if waf.reqContentLength>8388608 then
return true,"reqBody length is "..waf.reqContentLength ,true
end
return false

HTTP Parameter Pollution

过滤阶段:请求阶段

规则描述:http参数污染攻击,该规则查找具有相同名称的多个参数,并检查一些后端参数弱校验时产生的绕过问题,如:foo[1]a=bar&foo[1]b=或foo[1]x[1]=bar&foo[1]x[2]=等。

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
local rgx = waf.rgxMatch

local function rMatch(v)
local m = rgx(v, "(?:][^\\]]+$|][^\\]]+\\[)", "jos")
if m then
return m, v
end
return false
end

local form = waf.form
if form then
for k, v in pairs(form["FORM"]) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end

local queryString = waf.queryString
if queryString then
for k, v in pairs(queryString) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end

local cookies = waf.cookies
if cookies then
for k, v in pairs(cookies) do
if type(v) == "table" then
return true, k.."="..table.concat(v, ","), true
end
local m, d = rMatch(k)
if m then
return m, d, true
end
end
end
return false

扫描器检测

过滤阶段:请求阶段

规则描述:检测常见的各种扫描器,如awvs、sqlmap、nessus、appscan、nmap等,拦截它们有助于减少黑客发现漏洞的风险

规则内容:

1
2
3
4
5
local m, d = waf.plugins.scannerDetection.check()
if m then
return true, d, true
end
return false

Nginx 的 WAF 规则 LuaJIT 低危险版

前段时间杜老师发表了一篇《自建 CDN 服务器思路》其中介绍南墙 Web 应用防火墙,有些小伙伴们对其名字很感兴趣,而杜老师注意到了它的防护规则,感觉非常实用,顺手整理了下,分享给需要的小伙伴们。此篇为低危险防护规则!

防CC攻击规则

过滤阶段:请求阶段

规则描述:当一分钟访问/api/路径频率超过360次,则在5分钟内拦截该ip访问

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if not waf.startWith(waf.toLower(waf.uri), "/api/") then
return false
end

local sh = ngx.shared.ipCache
local ccIp = 'cc-' .. waf.ip
local c, f = sh:get(ccIp)
if not c then
sh:set(ccIp, 1, 60, 1) -- 设置1分钟也就是60秒访问计数时间
else
if f == 2 then
return waf.block(true) -- 重置TCP连接,不记录日志
end
sh:incr(ccIp, 1)
if c + 1 >= 360 then
sh:set(ccIp, c + 1, 300, 2) -- 设置5分钟也就是300秒拦截时间
return true, ccIp, true
end
end

return false

IIS报错检测

过滤阶段:返回页面

规则描述:IIS返回页面的报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
local rgx = waf.rgxMatch
local rb = waf.respBody

local m = rgx(rb, "[a-z]:\\x5cinetpub\\b", "jo")
if m then
return m, rb, true
end

if waf.status == 500 then
local m = rgx(rb, "Microsoft OLE DB Provider for SQL Server(?:</font>.{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \\(0x80040e31\\)<br>Timeout expired<br>)|<h1>internal server error</h1>.*?<h2>part of the server has crashed or it has a configuration error\\.</h2>|cannot connect to the server: timed out", "jo")
if m then
return m, rb, true
end
local m = rgx(rb, "\\b(?:A(?:DODB\\.Command\\b.{0,100}?\\b(?:Application uses a value of the wrong type for the current operation\\b|error')| trappable error occurred in an external object\\. The script cannot continue running\\b)|Microsoft VBScript (?:compilation (?:\\(0x8|error)|runtime (?:Error|\\(0x8))\\b|Object required: '|error '800)|<b>Version Information:</b>(?:&nbsp;|\\s)(?:Microsoft \\.NET Framework|ASP\\.NET) Version:|>error 'ASP\\b|An Error Has Occurred|>Syntax error in string in query expression|/[Ee]rror[Mm]essage\\.aspx?\\?[Ee]rror\\b", "jo")
if m then
return m, rb, true
end
end

if waf.status == 404 then
local m = rgx(rb, "\\bServer Error in.{0,50}?\\bApplication\\b", "jo")
if m then
return m, rb, true
end
end

return false

php报错检测

过滤阶段:返回页面

规则描述:返回页面的php报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local check = waf.plugins.phpErrorDetection.check
local rb = waf.respBody

if waf.status == 500 then
local m, d = check(rb)
if m then
return m, "php error: " .. d, true
end
end

return false

Java报错检测

过滤阶段:返回页面

规则描述:返回页面的java报错可能会泄露服务器敏感信息

规则内容:

1
2
3
4
5
6
7
8
9
10
11
local check = waf.plugins.javaErrorDetection.check
local rb = waf.respBody

if waf.status == 500 then
local m,d = check(rb)
if m then
return m, "Java error: " .. d, true
end
end

return false

请求方法加强

过滤阶段:请求阶段

规则描述:不常用的http请求方法会出现一些安全漏洞,如:历史上Apache平台TRACE请求方法出现过XSS相关漏洞

规则内容:

1
2
3
if not waf.rgxMatch(waf.method, "^(?:GET|HEAD|POST|PUT|DELETE|OPTIONS)$") then
return true, waf.method, true
end

介绍 5 款漏洞扫描工具

最近去不图床频繁遭受攻击,除流量攻击外,还有一些漏洞攻击。今天杜老师为小伙伴们推荐 5 款漏洞扫描工具,部分工具是开源的,有些是收费的,但其试用版本也满足我们这种小博主需求,感兴趣的可以试试!

sqlmap

sqlmap 是款用来检测与利用 SQL 注入漏洞的免费开源工具,有一个非常棒的特性即对检测与利用的自动化处理「问底层文件系统、执行命令」

Nikto2

Nikto2 是款开源的网页服务器扫描器,它可以对网页服务器进行全面的多种扫描,包含超过 3300 种有潜在危险的文件;有超过 625 种服务器版本;有超过 230 种特定服务器问题:

skipfish

谷歌创建的 Web 应用程序安全扫描程序,是种活跃的 Web 应用程序安全侦察工具。通过执行递归爬网和基于字典的探针为目标站点准备交互式站点扫描。然后使用许多活动「但希望无中断」安全检查的输出对结果映射进行注释。该工具生成的最终报告旨在作为专业 Web 应用程序安全评估的基础:

ZAP

Zed Attack Proxy 攻击代理服务器是世界上最受欢迎免费安全工具之一。ZAP 可以帮助我们在开发和测试应用程序过程中,自动发现 Web 应用程序中安全漏洞。另外,它也是一款提供给具备丰富经验的渗透测试人员进行人工安全测试的优秀工具:

OpenVAS

OpenVAS 漏洞扫描器是种漏洞分析工具,由于其全面的特性,可以使用它来扫描服务器和网络设备。这些扫描器将通过扫描现有设施中的开放端口、错误配置和漏洞来查找 IP 地址并检查任何开放服务。扫描完后,将自动生成报告并以电子邮件的形式发送,以供进一步研究和更正。OpenVAS 也可以从外部服务器进行操作,从黑客的角度出发,从而确定暴露端口或服务并及时进行处理。如果您已经拥有一个内部事件响应或检测系统,则 OpenVAS 将帮助您使用网络渗透测试工具和整个警报来改进网络监控:

DDoS 的攻击鉴赏下章

本不想说那么多的,但讲了两篇攻击鉴赏了,也聊一下如何防御。当然面对这种几乎无解的 DDoS,也没有太好的防御手段,仅分享些杜老师了解的思路,供需要的小伙伴们参考!

语音部分

需要手动点击播放:

文字部分

DDoS 攻击还有一些其它的方式,这里就不再一一列举了。但所谓有攻就有防,哪有压迫哪里就有反抗,所以有哪些应对 DDoS 攻击的方法呢?目前有两种大方向。激进的手术治疗以及稳妥的保守治疗。

捣毁僵尸网络并让用户做好个人防护。避免被感染成为僵尸设备是种很好的方法,但这是需要长期持续进行的方案。

我们举两个典型的在技术层面上根治 DDoS 攻击的方法,从 DDoS 的攻击原理上我们可以看出,伪造 IP 地址是 DDoS 攻击的核心技术之一,一旦攻击者无法伪造 IP 地址,那几乎就形同强弩之末。

而治理伪造 IP 方法并不复杂,现代互联网的下游,也就是用户设备接入的一端,设备通过路由接入互联网服务提供商。

所以只要让路由设备检测 IP,把源地址 IP 不属于本路由所在网段的数据都过滤掉,这样试图伪造 IP 的流量就无法发出了。

还有一个稍微复杂一点的分布式过滤方案。我们知道在庞大的互联网中,不同的网段依靠路由把彼此连接,一个数据从 A 发送到 B,它的 IP 可伪造成 C,但它所经过的真实路线则不可能作假。

换句话说,从 C 到 B 的数据不可能经过某路由器,但这个伪造 IP 数据从 A 发送到 B 却经过了某路由器,如果该路由能够根据 IP 地址的路径逻辑检测出矛盾,那就可以过滤掉这样的流量,从而消灭伪造 IP 的伎俩。

当然一个涉及到用户的服务商设备商,甚至是监管部门的多方技术方案,那就不能只是一个技术问题。

这两种方案很难被执行,只有一定影响力的大型企业和机构才能撬动这种涉及全球的多方合作,对于中小企业甚至是刚起步的创业者来说并不现实。

所以人们提出一些大家都能够承担得起的缓解 DDoS 攻击的保守治疗方案,我们列举两个目前使用比较多的方法。

DDoS 攻击的可怕之处在于 D 分布式,当多个僵尸网络对目标发起攻击时很难处理这些来自四面八方的流量,那作为守法公民我们又何尝不能联合起来,把一个网络服务的流量分散到不同的地方,从而稀释攻击流量。

比如目前各个站点普遍采用的 CDN 技术,把一些相对静态的资源作为缓存分发给各个 CDN 节点,用户在请求的时候从最近的节点返回,这样就在一定程度上缓解了 DDoS 的攻击。

当然 CDN 的缓解作用比较有限。有一种目前比较主流的,并有一些厂商专门为此开发产品方案:流量清洗。

我们在服务器前架设一台流量清洗的设备,这个设备就像一个身高马大的保镖和秘书,帮我们对抗 DDoS 流量。

比如面对 TCP 协议的 SYN 洪水 DDoS 攻击,客户端发起的 SYN 先经过清洗设备,由清洗设备回复 SYN+ACK,如果对方应答了那说明是正常的流量,清洗设备再把本次的连接交给后方服务器正常通信。

如对方不应答,则清洗设备该重试重试,超时后就断开连接。但清洗设备因人高马大,且作为专门应对攻击的角色,对连接资源做了极大的专门优化,能应对极其海量的连接请求,所以攻击者想通过 SYN 洪水打垮它非常困难。

比如威胁极大的 HTTP 洪水攻击,正常来说一个 HTTP 请求很难用传统方式检测出是恶意流量还是正常流量,而清洗设备往往会提供专业流量清洗平台,这些专业做流量清洗的服务商通过多年和 DDoS 攻击的对抗,积累大量的经验和技术。

比如由于 HTTP 无法伪造 IP 地址,所以通过多年数据积累建立 IP 信用库,从那些经常发起攻击的 IP 发来的流量就会被过滤掉。这有点像现在安卓手机上的来电标记,这就是流量清洗厂商在数据积累上的优势。

再比如恶意流量由于是通过程序自动发出,而不是人类的操作,所以利用算法对流量进行模式的识别,就可以被检测出来,这就是流量清洗厂商在技术上的优势。

但不论怎样 DDoS 作为一种历史悠久,但破坏能力巨大的黑客攻击手段,时至今日仍无法被彻底解决。

或许可以说 DDoS 攻击源自于互联网通信构架在设计之初考虑的缺失,而人们现在又缺乏壮士断腕的决心从根本上消灭它。

但不论怎样这种破坏与对抗将长久地存在于互联网世界之中,而我们能做的只是做好防护保持警惕!

DDoS 的攻击鉴赏中章

因为内容太多,杜老师一时间想不出那么多台词,故打算另起一文继续说。杜老师尽量使用通俗易懂的语言描述,所以文字量会比较多些,希望感兴趣的小伙伴能耐心听完。

语音部分

需要手动点击播放:

文字部分

IP 协议让不同的子网络被互联了起来,从这个通信过程中我们发现从数据离开到最终到达,这一路几乎每个地方都有被 DDoS 攻击的机会。

比如霸占服务器的网络带宽资源,我们只需要向一台服务器发送大量的 IP 协议数据包就可以慢慢的消耗掉对方的网络带宽。

比如用大家耳熟能详的 Ping 工具就可以发起一次攻击,Ping 产生的 ICMP 协议包。ICMP 是 IP 协议用来进行插错控制的一个补充,本质上是一个 IP 包,这种攻击方式也称为 ICMP 洪水。

这种攻击手段类似于我们不断的给某个人投递信件。写了什么并不重要,重要的是让信件多的邮递员在对方的家门口排起长队从而打断正常的信件收发。

同样思路我们还可以发送传输层的 UDP 协议包发起一次 UDP 洪水攻击。当然这里会有一个问题就是会暴露攻击设备的 IP 地址而被对方封禁。

所以攻击者一般会通过伪造 IP 地址来隐藏自己。比如张三给李四写信却把发件地址写成了王五,这样即使是一封祖安问候信李四也只能迁怒于王五。

或者干脆写一个不存在的地址让李四无处泄愤。但出于隐藏自己这个目的人们发明了一种更有趣的攻击方式:反射攻击,既然可以伪造 IP 那就不必拘泥于伪造发件人的身份。

同样可以伪造收件人的身份达到借刀杀人效果,我们把信封上的发件地址改为攻击目标 IP 地址,然后把收件地址设置为互联网上大量的第三方机器,从而把数据发送到这些第三方机器上。

这些机器在接收到数据之后,回复数据会涌入发件地址指向的攻击目标,这些第三方机器也被称为反射器。这有点像把别人电话号码挂在一些网站上,然后机主被不明真相的推销员给呼死,很损但很有效。

反射攻击更难追踪来源,更厉害的是人们在此基础之上又发明了一种把攻击流量放大以达到更强攻击效果的手段:放大攻击。

比如 DNS 服务器用来把域名解析为 IP 地址的设备,我们在浏览器中输入像 dusays.com 这样的域名地址。

实际上需要先查询 DNS 服务器,获得这个域名对应的 IP 地址,再用 IP 地址访问杜老师说服务器,同时 DNS 查询通常用 UDP 这个不用验证来源的传输协议。

综合来看 DNS 服务器就是一个很好的放大器。因为一次 DNS 的查询请求,返回数据往往大于请求数据。这里有个宽带放大因子 BAF 的概念。

在 DNS 的查询中,一般 60 个字节的请求数据可以获得将近 3000 个字节的返回数据,那么 BAF 就等于 3000/60=50 产生 50 倍的放大效果。

这样如果我们让攻击者不断的去对 DNS 服务器发起查询请求并把原地址伪造成为攻击目标的 IP,那么这样的反射攻击就会产生 50 倍的流量放大效果,可谓四两拨二十斤。

除了对目标的宽带资源进行霸占,以达到 DDoS 攻击的效果外,因为 TCP 协议中有连接的概念,所以还可以攻击服务器连接资源。

服务器和客户端每次建立一个 TCP 连接要经历三次握手,然后把连接信息放入到连接表中进行维护。而连接表大小是有限的,我们可以让发起攻击的设备直接发起大量的 TCP 连接,从而占满服务器连接表。

而无法响应后续 TCP 连接请求从而达到 DDoS 攻击的效果,这种直接的方式也称之为 TCP 洪水,但因为有三次握手存在所以 TCP 洪水无法通过伪造 IP 隐藏自己。

在建立连接时如果我们在第一次握手中伪造了 IP,那么服务器向客户端发送数据的第二次握手就无法到达。

相当于给别人写了一封伪造发现地址的信,那么是不可能收到回信,因此连接无法建立。但是可以在建立连接的三次握手本身上做文章,比如只发送 SYN,不进行后续回答这样虚晃一枪 SYN 洪水。

这样做的好处是如果不回答攻击目标的 SYN+ACK 数据,那么考虑到可能是网络环境问题。TCP 协议有重传机制,对方会多次尝试发送 SYN+ACK 直到超时。

问题是这时候受害者会不断的向攻击者发送 SYN+ACK,比如重试 10 次,这就相当于我们每攻击目标一次,对方就会回击 10 次,所谓杀敌一千自损一万不过如此。

所以 SYN 洪水攻击一般都会伪造 IP,或是一个不存在的 IP 让受害者拔剑四顾心茫然,或是某个真实倒霉蛋的 IP 把祸水东移。

同样思路在 TCP 协议中也可以通过反射发起攻击,向各个反射器发送 SYN 并把发现地址伪造成攻击目标的 IP,这样大量 SYN+ACK 数据就会从各个反射器上涌入攻击目标。

当然这种攻击方式因为无法在目标上建立连接,所以还是属于是在攻击网络带宽。而针对 TCP 协议还有一种巧妙攻击手段:洪水攻击。

在 TCP 协议中一般用四次挥手结束连接,但为防止出现异常,一方可以发送一个 RST 数据包强制切断连接。

这样我们让攻击设备不断尝试伪造各种 IP 地址,并发送 RST 数据进行盲打。一旦 IP 和其他的一些配置和某个正常用户匹配上就能切断正常用户和服务器之间的连接。

这种攻击方式更针对于用户。比如在一场网络游戏对战中,在获悉对手的 IP 地址后,就可以不断切断对方的游戏设备和服务器的连接以干扰他的正常游戏。

不论是利用 IP、UDP 还是 TCP 协议攻击,针对的都是网络和连接资源。还有一种直接针对服务器内部资源的攻击方式:消耗目标的 CPU 和 IO。

如开头所说一次网络访问的过程是这样的:客户端通过网络线路向远程的服务器请求内容,服务器按照客户端的需求或查询或计算出相应数据,再通过网络线路送给客户端。

作为在第五层用户,一般在网上冲浪时接触的都是应用层中像 HTTP 这样的协议。比如我们在访问杜老师说的时候,浏览器输入 dusays.com,所以我们可以对一个站点发起 HTTP 洪水攻击。

比如利用博客的搜索功能不断的生成大量的关键词送入查询地址,因为 HTTP 作为用户直接发起涉及具体业务的请求,服务器在收到请求后需进行像数据库查询这样的 IO 操作,所以这样的攻击手法会对目标产生更大的消耗。

当然 HTTP 洪水攻击有一个问题,那就是不能伪造 IP 地址。因为 HTTP 协议实际上是基于 TCP 协议,需经历三次握手的过程,所以常见的方法是借助网络代理主机得到不同的真实 IP 发起攻击。

这对于一次资金充足有计划有组织的攻击来说并不是件难事,DDoS 攻击还有一些其它的方式,这里就不一一列举。

但所谓有攻就有防,哪里有压迫哪里就会有反抗,所以有哪些应对 DDoS 攻击的方法呢?

DDoS 的攻击鉴赏上章

就在杜老师在外出差的几天,去不图床又遭受攻击了。在周末返程休息时,从圈内小伙伴的口中得知有小伙伴博客也被攻击了。面对常见网络攻击技术,杜老师打算聊下 DDoS!

语音部分

需要手动点击播放:

文字部分

每个励志成为传奇黑客的年轻人都面临一个 Hello World,而每个所谓安全的网络系统,最终都有一个不安全的隐患,恰巧他们都是同一个东西 DDoS。

作为一个历史悠久网络攻击手段,DDoS 攻击手法暴力且直接,但破坏力惊人,也缺乏彻底的根治方法,人们在它的身上吃尽了苦头。

在现代网络战争中,DDoS 往往作为一场有规模有组织的黑客攻击行动佯攻手段,在 DDoS 洪水的掩护下,伺机而入万军中取上将首级。

那么 DDoS 攻击为何在各种黑客的技术中起起伏伏,攻伐思路的来来去去之间能如此恒久远涌流传下去,至今仍为网络安全的一个心头大患呢?我们不妨来赏析下 DDoS 攻击的技术细节。

1996 年 9 月 6 日美国纽约著名的互联网服务商服务器受到每秒高达 150 次异常连接攻击,导致服务器疲於应对这些非法的流量而拒绝正常用户的合法请求。这是目前大家比较认可的历史上第一次 DDoS 攻击。

DoS 拒绝服务顾名思义即通过占用网络资源让它应接不暇,从而拒绝正常的业务流量的一种网络攻击方式。而我们所说的 DDoS 则是 DoS 攻击的分布式版本,俗称群殴。

单台设备攻击能力有限,治理起来也较容易。但是当几十几百甚至成千上万个设备组成一个网络同时对目标发起 DoS 攻击时无异于一场灾难。故大家一般用 DDoS 指代一般意义的拒绝服务攻击。

而发起攻击的网络一般称为僵尸网络。每一个僵尸可以是一台个人电脑,可以是一台服务器,甚至可以是部智能手机。

而为了得到这样的一个僵尸网络则是八仙过海各显神通。或因为穷,或因为技术过硬的人士利用木马、蠕虫、后门等恶意程序感染大量的设备形成僵尸网络。

而富人则比较轻松,通过某些渠道直接花钱就可以购买到。理论上花的钱越多得到的僵尸网络规模就越大、攻击力就越强。

1999 年 8 月 17 日美国明尼苏达大学的服务器在至少 200 多台设备的 DDoS 攻击下服务被迫中止了两天,而这 200 多台发起攻击的设备都是在不知情的情况下被感染而成为僵尸网络中的一员。

在通过 IP 追踪并让设备停止攻击之后问题还是未能完全解决,因为不断的有新的攻击设备加入进来。

DDoS 攻击和其它利用程序漏洞攻击阴谋不同,这种直接粗暴的方式算是种阳谋,大家知道是怎么发生的但又无可奈何。直到今天 DDoS 问题都没有也无法被完全解决。

为了了解 DDoS 攻击手段的巧妙,我们要先了解一点互联网的工作方式。

一次网络访问过程简化来看是这样的,客户端通过网络线路向远程的服务器请求内容,服务器按照客户端需求或查询或计算出相应的数据,再通过网络线路送给客户端。

这个数据在两端流转的行为和传统的邮递过程是相似的,传统邮递依靠的是邮政系统。而现代互联网中数据的流转依靠的是以 TCP/IP 协议为核心的通信系统。

TCP/IP 参考模型是一个四层结构,我们可借助传统的邮递系统对此做个模拟。

写信的时候大家一般会遵从约定格式,比如先写对方称呼,加个冒号换行再写正文,结尾写上此至敬明,最后写上署名、日期。

类似于四层结构中的应用层规定了一些数据内容的协议规则,如我们上网时常用的 HTTP 协议就属于这一层。

写完信以后我们可以做一个标记,比如使用特定图案蜜蜡封信,或是盖上一个红戳。对方根据这些标记决定如何回复,要不要加急要不要确认一下对方的身份等。

这类似于四层结构中的传输层规定数据的传输方式。比如这层中大家都熟悉的 TCP 协议,为了保证通信的可靠性需要先经历三次握手再发起数据传输。

实际上对于一次可靠的通信过程事先的沟通是很必要的,这在日常生活中很常见。

TCP 协议用三次握手做到了这一点,换句话说在正式写信说正事之前先发送三封确定彼此的信建立一种可靠的连接。

第一次在 TCP 协议的信件上有几个关键的字段,发起 TCP 连接时我方先把 SYN 设为 1,ACK 设为 0,再选择一个顺号 X,然后发送出去。

第二次对方收到之后回复一封信,把 SYN 设置为 1,ACK 设为 1,确认号设为 X+1,同时也选择一个顺号 Y。

第三次我方收到回信后,把 SYN 设置为 0,ACK 设为 1,确认号设为 Y+1,顺号设置为 X+1,再次发送出去。

如此一个 TCP 连接就建立起来,接下来就可以发送用户的数据了。

因为有三次握手的存在,通信要更可靠,类似于即时通信这样的软件多采用 TCP 协议在客户端和服务器之间建立一个连接信道。

而这一层中还有一个著名的 UDP 协议它没有那么麻烦,不需要反复握手建立连接直接把数据投递出去,也不管对方是否收到,所以这是一种不可靠的协议。

而用来装信件的信封类似四层结构中的网络层,主要规定了通信双方地址的编码规则,这一层采用的是 IP 协议,所以大家经常会听到所谓设备 IP 地址。

而一封信的投递最终依靠是邮局,邮局把信件打包装车后,根据收件的地址把信件投递到目的地。

这一层对应四层网络中的子网层是信息传递的物理载体,如以太网卫星网等。

这四层结构从应用层到子网层数据按照不同的协议被不断的打包,到达目的地后刚好是相反的拆包过程而最终被目标接收。

可以看出来其中最为核心的是互联网层中的 IP 协议,只要是按照 IP 协议封装的数据都能被发送。

不论是以太网卫星网还是其它物理实现的子网,正如只要按照信封上的格式写好收发地址装入信件就可以被投递到目的地,不论是走陆运空运还是海运。

IP 协议让不同的子网络被互联了起来,从这个通信过程中我们发现从数据离开到最终到达,这一路几乎每个地方都有被 DDoS 攻击的机会。

Linux 服务器安全加固参考

杜老师出差回来了,刚好得空拜访了小伙伴们的网站,发现近期有些小伙伴的网站被攻击了。其实除了常见的 DDoS,还有一些技术流的攻击形式,主要是通过系统和服务漏洞进行攻击。今天杜老师分享 Linux 服务器安全加固项,供需要的小伙伴们参考。

高危

高危加固项如下表:

项目编号风险描述配置建议
1CVE-2021-4034 polkit pkexec 本地提权漏洞检测更新polkit 组件
2CVE-2023-0386 Linux Kernel OverlayFS 权限提升漏洞漏洞检测根据提示检查内核版本是否低于指定版本【uname -r】
若是CentOS 8 Stream,则执行【yum install kernel】命令升级内核版本,并重启服务器
若是Ubuntu 22.04,则执行【apt install linux-image】查看可安装版本号,选择高于5.15.0-70的版本号,再次执行【apt install linux-image-版本号】,并重启服务器
3检测MySQL root用户是否具备数据库备份权限临时以无授权方式进入数据库,建议恢复root用户所有权限。
4Docker API 未授权访问应开启认证来鉴权或关闭Dokcer Api
5Mysql 弱口令检测如果检测出为弱口令请及时修改密码
6检测MySQL root用户是否具备数据库备份权限临时以无授权方式进入数据库,建议恢复root用户所有权限。
7PHP未禁用危险函数在【php.ini】文件中设置【disable_functions】未配置system,exec,passthru,shell_exec,popen,proc_open等危险函数
提示:【php.ini】未配置system,exec,passthru,shell_exec,popen,proc_open等危险函数
8PHP存在版本泄露在【php.ini】文件中设置【expose_php】将配置为Off
提示:【expose_php】将配置为Off
9检测当前Redis密码是否安全1.Redis 密码太过于简单
2.请及时修改密码
10检测当前Redis是否安全若非必要,请勿将Redis的bind配置为0.0.0.0
若bind为0.0.0.0的情况下,请务必为Redis设置访问密码
请勿使用过于简单的密码作为Redis访问密码
推荐使用高安全强度的密码:分别包含数字、大小写、特殊字符混合,且长度不少于7位。
Redis一但出现安全问题,这将大概率导致服务器被入侵,请务必认真处理
11禁止SSH空密码登录在【/etc/ssh/sshd_config】文件中设置【PermitEmptyPasswords】将配置为no
提示:【PermitEmptyPasswords】将配置为no
12检测进程中是否有通过strace命令获取其他用户账号信息ps aux命令查看是否存在通过strace读取sshd登录凭证
ps aux
13系统后门用户检测在命令行中删除后门用户
注意:如果存在后门用户说明你服务器已经被入侵
14tomcat后台访问弱口令检测在【/usr/local/bttomcat/tomcat/conf/tomcat-users.xml】中修改password弱口令

中危

中危加固项如下表:

项目编号风险描述配置建议
1/etc/bashrc用户缺省权限检查【/etc/bashrc】 文件中所所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027
2是否启用Docker日志审计检查在【/etc/audit/rules.d/audit.rules】文件中添加-w /usr/bin/docker -k docker
重启auditd进程systemctl restart auditd
3检查审核日志满了后是否自动删除在【/etc/audit/auditd.conf】中max_log_file_action将ROTATE改为KEEP_LOGS
重启auditd服务systemctl restart auditd
4bootloader配置权限检查对【/boot/grub2/grub.cfg】文件,配置对应权限
chmod 600 /boot/grub2/grub.cfg、chown root /boot/grub2/grub.cfg
5检查重要文件是否存在suid和sgid权限使用chmod u-s/g-s 【文件名】命令修改文件的权限
6检查临时目录是否设置粘滞位权限使用chmod +t 【文件名】命令修改文件的权限
7/etc/csh.cshrc用户缺省权限检查【/etc/csh.cshrc】 文件中所所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027
8Apache 版本泄露检查在【httpd.conf】文件中添加ServerSignature Off以及ServerTokens Prod
9开启地址空间布局随机化【/proc/sys/kernel/randomize_va_space】 值为2:
操作如下:sysctl -w kernel.randomize_va_space=2
10检测是否限制密码重复使用次数配置文件备份cp -p /etc/pam.d/system-auth /etc/pam.d/system-auth.bak
在【/etc/pam.d/system-auth】文件【password sufficient】后面添加或修改remember=5
11检查是否存在危险远程访问文件hosts.equiv、.rhosts、.netrc删除在家目录下的.rhosts和.netrc文件以及删除根目录下的hosts.equiv文件
按照提示找到风险文件并删除
12检测所有已部署安全证书的网站是否过期请为您的站点续签或更换新的SSL证书,以免影响网站正常访问
SSL证书过期后,用户访问网站将被浏览器提示为不安全,且大部分浏览器会阻止访问,严重影响线上业务
13SSH 空闲超时时间检测在【/etc/ssh/sshd_config】文件中设置【ClientAliveInterval】设置为600到900之间
提示:SSH空闲超时时间建议为:600-900
14SSH 最大连接数检测在【/etc/ssh/sshd_config】文件中设置【MaxAuthTries】为3-5
提示:SSH最大连接数为:3-6,请设置为3-5
15SSH密码复杂度检查【/etc/security/pwquality.conf】 把minclass(至少包含小写字母、大写字母、数字、特殊字符等4类字符中等3类或4类)设置为3或4。如:
minclass=3
16检查SSH密码失效时间【/etc/login.defs】 使用非密码登陆方式密钥对。请忽略此项, 在/etc/login.defs 中将PASS_MAX_DAYS 参数设置为90-180之间
PASS_MAX_DAYS 90 需同时执行命令设置root密码到期时间 命令如下: chage --maxdays 90 root
17检查SSH密码修改最小间隔【/etc/login.defs】 PASS_MIN_DAYS 应设置为大于等于7
PASS_MIN_DAYS 7 需同时执行命令设置root 密码失效时间 命令如下: chage --mindays 7 root
18SSH过期提前警告天数在【/etc/login.defs】 PASS_WARN_AGE 大于等于7
提示:PASS_WARN_AGE 30 同时执行命令使root用户设置生效 chage --warndays 7 root
19SSH密码长度度检查【/etc/security/pwquality.conf】 文件中把minlen(密码最小长度)设置为9-32位
minlen=9
20检测是否使用安全的套接字层加密传输信息,避免被侦听敏感信息在【/etc/ssh/sshd_config】文件中添加或修改Protocol 2
随后执行命令systemctl restart sshd重启进程
21关闭非加密远程管理telnet检查尽可能使用加密远程管理sshd服务,关闭不安全的telnet服务
systemctl stop telnet.socket停止telnet服务
22检查是否设置无操作超时退出在文件【/etc/profile】中添加tmout=300,等保要求不大于600秒
执行命令source /etc/profile使配置生效

低危

低危加固项如下表:

项目编号风险描述配置建议
1检查ls和rm命令是否设置别名在文件【~/.bashrc】中添加或修改alias ls='ls -alh’以及alias rm=‘rm -i’
执行【source ~/.bashrc】使配置生效
2检测CVE-2019-5736容器逃逸漏洞docker version查看docker版本是否小于18.09.2,runc版本小于1.0-rc6
3CVE-2022-2068 OpenSSL任意命令执行漏洞检测升级OpenSSL至最新版本或是安全版本
1.0.2zf、1.1.1p、3.0.4及以上版本
4CVE-2022-25845 Fastjson 任意代码执行漏洞检测打开网站目录下的pom.xml文件,查看是否有fastjson依赖库
若fastjson版本小于1.2.83,则需升级到1.2.83或更高的安全版本
5检查关键文件的底层属性是否配置给系统日志文件【/var/log/messages】添加只可追加属性chattr +a
给关键文件【/etc/passwd /etc/shadow /etc/group /etc/gshadow】添加锁属性chattr +i
6检测是否限制账户认证失败的次数在【/etc/pam.d/sshd】文件第二行添加或修改
auth required pam_tally2.so onerr=fail deny=5 unlock_time=300 even_deny_root root_unlock_time=300
7检测系统用户列表中是否存在风险用户如果这些用户不是服务器管理员添加的,则可能系统已被入侵,应尽快处理
8检测所有网站是否部署安全证书请考虑为您的网站部署SSL证书,以提升网站的安全性
9限制SSH登录后使用图形化界面检查在【/etc/ssh/sshd_config】中修改X11Forwarding为no
10设置ssh登录白名单在【/etc/hosts.deny】添加ALL:ALL
在【/etc/hosts.allow】添加sshd:【来访者IP地址】
11检查SSH root是否可以登录【/etc/ssh/sshd_config】 添加PermitRootLogin no参数
PermitRootLogin no
12检查是否使用PAM认证模块禁止wheel组之外的用户su为root在文件【/etc/pam.d/su】中添加auth sufficient pam_rootok.so以及auth required pam_wheel.so group=wheel
如需配置用户可以切换为root,则将用户加入wheel组,使用命令gpasswd -a username wheel
13检查是否开启TCP-SYNcookie保护缓解syn flood攻击在【/etc/sysctl.conf】文件中添加net.ipv4.tcp_syncookies=1
然后执行命令sysctl -p生效配置
14/etc/profile用户缺省权限检查【/etc/profile】 文件中所设置的umask为002,不符合要求,建议设置为027
操作如下:修改 umask 为027

注意

  1. 杜老师并未对以上服务进行分类,需要的小伙伴可以按需查找;

  2. 以上加固项按杜老师服务器配置分享,部分服务如未安装则不需要加固;

  3. 有参考范围的,则按需要配置,如不知该如何配置,可以取中;

  4. 如果需要更多的安全加固项,可在评论区中留言。

博客攻击的常见方式及防御手段

最近又有小伙伴的博客遭受攻击,杜老师曾是受害者之一,下面简单聊聊博客的常见攻击方式及防御手段,尽可能站在理论和实用角度分享,希望对小伙伴们有帮助!

写在前面

之前和小伙伴聊过这个话题,在话题初我们谈到攻击原因。

站在商业角度,竞争企业之间可能存在攻击行为,就像杜老师之前的一家公司,就被同行公司攻击官网,导致活动期间网站无法访问。

那么对于我们这类的小站长,既无利益纠纷、也无个人恩仇,为什么我们成为了攻击目标。

说实话杜老师不太了解,讨论到最后时,只能说是一些人的无聊。也有些人怀疑是大厂的阴谋,通过流量耗损增加收费,虽说不无可能,但个人感觉没必要!

恶意代码

言归正传,首先聊到的是恶意代码。

这种攻击形式,主要针对动态博客。

动态博客不同的 URI 对应不同数据请求,而攻击者通过一些数据注入等方式将恶意代码传入,造成对网站数据库、源码,甚至服务器环境的篡改以及破坏,进而达到攻击目的。

静态博客用户也许注意恶意代码,毕竟服务器的服务环境也会存在漏洞,如被攻破也会导致服务器环境的篡改以及破坏。

杜老师使用宝塔面板专业版 Nginx 防火墙插件实现这类攻击防护,目前效果还是很不错的。如没有专业版,或是使用其它面板,还可自行安装防护模块实现效果,这里暂不做详细的介绍,如有需要可以留言探讨!

另外有小伙伴对网上的动态程序安全性做了个排序,大厂开源>商业程序>个人开源>破解程序。

需要说明的是,大厂开源是指如 WordPress 这种,源代码受全世界的使用者们监控,如果出现漏洞,会被第一时间发现并予修复;商业程序是指公司开发付费程序,这类程序为了企业的安全性,发布之前都会进行漏洞测试;个人开源可能由于作者疏忽,或是能力有限,导致存在漏洞,所以安全性差一些;破解程序并不代表一定会有漏洞,但一定是因为漏洞才可破解。

这里只是举了几种程序类型,主要是想提醒小伙伴们,不要轻易使用破解程序,请至官网获取相关源码!

拒绝访问

拒绝访问一般通过 CC 或是 DDoS。

CC 攻击的原理就是攻击者不停发大量数据包给对方服务器造成服务器资源耗尽,直到宕机崩溃。

DDoS 攻击可以使很多的计算机在同一时间遭受到攻击,使攻击的目标无法正常使用,在进行攻击的时候,可对源 IP 地址进行伪造,这样就使得这种攻击在发生的时候隐蔽性很好,同时对攻击进行检测也是非常困难的。

实际两者都称为 DDoS 攻击,只是相比于 DDoS,CC 攻击可防御。

以上攻击都是直接作用于服务器,通过大量请求数据包使服务器无法响应正常的请求数据,进而导致服务器负载大,最终导致无法响应各种请求。

目前可通过防火墙一定程序防御 CC 类攻击,但对 DDoS 除了高防 IP 外暂无有效的防御手段。

杜老师的方式是尽可能隐藏服务器 IP,防止攻击者直接针对服务器,比较推荐套 CDN。

另外 DDoS 攻击时,攻击者也会有成本产生,所以一般情况攻击不会太久,对于小博来说遇到攻击关站即可,攻击结束后服务器也可自动恢复。

大刷流量

上面提到通过套 CDN 防止服务器 IP 泄露,防止 DDoS 类攻击,并不意味着就一劳永逸,因为还有针对 CDN 的攻击方式。

针对 CDN 的攻击较为单纯。因为 CDN 的节点较多,DDoS 成本大,且效果不明显,所以攻击者会针对 CDN 的运营成本进行攻击。

杜老师的小伙伴们被攻击的方式大多都是这种:CDN 被刷了大量流量。轻者耗尽套餐流量,重者导致账号欠费。

一般的 CDN 厂家并不提供数据清洗服务,有的也是属于付费功能,所以对于这种恶意行为,都会按照正常流量进行付费。

当然也有防御手段。通过几次攻击行为分析,发现这种攻击在产生时,都会在短时间产生大量流量请求,而这就需要带宽的支持。

可以通过 CDN 自带的带宽上限功能进行限制,当达到一定带宽时,直接停用 CDN 或进行回源,避免流量被刷导致经济损失。

杜老师曾分析过部分的攻击来源,一般攻击行为产生都是源自境外,可以通过 DNS 做境外独立解析,比如杜老师说境外解析至 Vercel。

文章最后分享一下杜老师的带宽阈值参考,目前杜老师说带宽上限是 10M,去不图床带宽上限是 20M。小伙伴们如有不同想法,也可在评论区留言,大家互相交流学习!

安全组和 IPTABLES 的选择

不少的云服务商都提供了安全组功能,可替代系统中的防火墙功能。那么问题来了,究竟是该选择安全组呢,还是使用系统自带的防火墙。今天就来聊聊这个问题!

Windows 防火墙

Windows 防火墙是一种状态防火墙,检查并筛选 IPv4 和 IPv6 流量所有的数据包。在默认情况下阻止传入流量,除非是主机请求的响应,或者被特别允许的。Windows 防火墙使用两组规则,即数据流入规则和数据流出规则,通过规则设置,使防火墙可阻止进出服务器的数据流。

杜老师几乎不用 Windows 作为服务器的操作系统,所以对 Windows 自带的防火墙不作主观评价。而从小伙伴获得的信息,对其评价不是很好。很多人说如不开启,也没有遇到过安全问题。如果开启,反而会影响系统本身服务的运行。我想这也是为什么 Windows 平台下,有那么多第三方的防火墙厂家吧!

Linux 防火墙

Linux 平台下的两大防火墙,分别是 IPTABLES 和 firewalld,firewalld 操作更加的简单,而运维工程师偏向于 IPTABLES,问其原因,大多都是因为使用习惯。下图为 IPTABLES 的数据流走向,通过该图可知,IPTABLES 进行数据过滤时,需要经过多链多表,且这些都是依赖 Kernel,所以数据包较多时,会影响系统的运行效率:

云安全组

安全组是一种有状态的服务器虚拟防火墙,用于设置单台或多台云服务器的网络访问控制,是云厂商提供的重要的网络安全隔离手段。安全组是一个逻辑上的分组,可以将同一地域内具有相同网络安全隔离需求的云服务器实例加到同一个安全组内:

部分云厂家的轻云主机,也提供了云防火墙功能,同样可以实现网络访问控制:

写在最后

不管是哪种防火墙,我们最终的目的都是想实现网络访问控制,对于合理数据进行通过处理,对于不合理的数据进行拒绝或是丢弃操作。

根据杜老师的经验,建议在可行范围内,尽量选择云服务厂商提供的防护服务。对于 Windows 的防护,其安全性更高;对于 Linux 的防护,在保障安全性同时,也降低对 Linux 内核的消耗,提高系统运行效率。

当然杜老师指的是防护功能,如需要用到 Linux 的数据包转发功能,还是要依赖 IPTABLES。

最后建议大家混用时不要做冗余规则操作「就是一个限制做在两个防火墙中」这样不仅不会提升防护能力,也降低了系统运行效率。

云主机需哪些安全设置

信息安全是个大的话题,对于我们这些小站长们,有哪些是需要我们注意的呢?今天杜老师聊聊云主机需要哪些安全设置!

系统以及网站密码

  1. 简单密码。简单密码扫描无处不在,您现在访问的这个博客,几乎每隔几分钟就被扫一次,任何时候,任何场景,不要使用 123456/abcdef 这样的简单密码,哪怕就是改个简单密码给某人登陆下后台,几分钟后就改回来也会有极高的被扫风险;

  2. 陈年密码。您的扣扣密码、邮箱密码、主机密码、微博密码、微信密码等等,设置成都是一样的,或者都是从接触互联网就在用的密码,这很恐怖,在漫长的互联网使用过程中,可能注册了很多站点的会员,在长期使用过程中,您的密码可能早已泄露,说不定您到某工库一查,发现您所有在用的密码都在上面;

  3. 拼接密码。您的银行卡密码是您或您家人的生日,您的微信密码是您的姓名拼音加生日或电话或身份证的号码,也可能是其它个人信息拼接,这样的密码极容易被有心人暴力破解,只要掌握一定量的私人信息就很容易猜出您当前可能在用的密码;

  4. 特殊含义。如 P@ssw0rd12#$,这种密码看似特别复杂,包含大小写的字母,还有数字以及特殊符号,但这类的密码同样容易破解。

系统以及网络安全

  1. 定期检查并修复系统的漏洞;

  2. 开启系统的防火墙,只放行要用的端口;

  3. 修改 SSH 端口号;

  4. 禁 Ping;

  5. 限制 root 等用户权限;

  6. 安装悬镜、云锁、安全狗等安全软件「装一个就够了」

网站安全相关设置

  1. 隐藏后台管理入口;

  2. 除了 update/cache 等少数目录,其它所有目录都给只读权限;

  3. 在 Nginx/Apache 配置中限制除了入口目录及资源目录以外的所有目录的访问权限;

  4. 如若网站程序支持,尽量使用 PHP5.4 以上的版本;

  5. 如非必要,不要给站点创建 FTP,或者使用完就删除站点的 FTP 帐户;

  6. 如非必要,不要对外开放 3306 数据库端口,并且隐藏好 phpMyAdmin 位置,最好设个访问密码;

  7. 如果允许尽可能开启 SSL;

  8. 若使用 Nginx,尽量使用 WAF 防火墙,可有效防止绝大多数 Web 攻击。

其它辅助安全操作

  1. 保护好网站的源码及数据库备份,请不要将数据库备份及网站源码包放在站点根目录;

  2. 各大云服务的厂商都有安全检测服务,定期查看检测结果并处理警报项;

  3. 可添加 CDN 服务,避免暴露云主机真实 IP;

  4. 不要使用破解版的网站程序。

Linux 口令过期后账号最长有效天数策略

经常更换管理密码可以一定程度防止服务器被暴力破解,不过很多管理员都懒得、或者是忘记改密码,有什么样的强制形式可以督促管理员修改密码?今天杜老师就说下 Linux 口令过期后账号最长有效天数策略!

漏洞名称

1
Linux口令过期后账号最长有效天数策略

危险等级

1
低危

漏洞类型

1
安全基线

漏洞描述

1
设置口令过期后账号仍能保持有效的最大天数

修复方案

1
编辑/etc/default/useradd文件配置INACTIVE=365

设置效果

网站安全架设杂谈

搭建一个网站非常简单,只要购买一个域名、一个空间,选择一个程序,上传调试即可。但用这种方式搭建的网站,能走多远?如何搭建一个更安全的网站,今天我们来聊一聊。

网站类型

在搭建网站前,首先明确你的网站类型,是要分享,还是交流。这影响了你的受众群体。比如博客,它是个人平台,你的受众都是读者,他们主要操作就是阅读,而唯一个管理者会降低安全风险。如果是交流的社区,受众都是成员,那被盗号攻击的可能就很大。

当然主题也很重要,如果是个人流水账网站,估计不会有人攻击。但如果是一些网络安全技术交流网站,很有可能会有访客用你作为练习。

域名选择

首先是域名的问题,在你够买个域名时,需要选域名商,域名商有国内国外之分,国内的较便宜,但是手续麻烦;国外的没手续,但是万一出现问题,可能技术支持不是特别完善「咱不是说没有,主要国外都用英语交流,你能和人家说明白」那我们如何选择呢?

这里建议大家,尽量选择国内较大的服务商,例如万网等等,小的服务商在价格上更便宜,但是没准什么时候就跑路了,对于国内域名来说,从一家服务商转到另外一家,不管手续还是操作,都特别的繁琐。当然,也可以选择国外的,但记得不要选一些新起的域名商,尽量选老牌的。

空间选择

接下来是空间,如果后期你想安安稳稳更新网站,而不是为了空间的事情发愁「例如空间不够用啊,速度慢啊等等」建议大家选购云主机自己去搭建环境,这里需要我们注意两件事情。第一件事就是云主机属于高级类空间,因为环境需要自行搭建,如果你是网络新手,估计对你来说,难度很大;第二件事就是,云主机的安全运行问题,因为它相当于一台小型的服务器,里面只有你一个小网站,如果出现问题,只能自行解决。

这里建议选择云主机的朋友,尽量使用网上一键搭建环境的 Shell 脚本,而且选择较知名的,这类脚本比较完善,不会出现什么安全问题。

程序选择

最后就是程序,它决定了你要做什么类型的网站,以及后期主要操作界面以及形式。找一个好程序,就像找一个好老婆一样,因为你更新网站时,主要面对的就是它!

建议大家选择知名度比较高程序,这类程序功能完整,而且比较安全。个人写的程序,可能因为用户较少,测试还不完善,容易出现一些安全问题。

什么是 OWASP 安全项目

开放 Web 应用程序安全项目是致力于 Web 应用程序安全的国际非营利组织。OWASP 核心原则之一是,他们的所有资料都免费提供并可以在其网站上轻松访问,这使得任何人都能够改善自己的 Web 应用程序安全性。

注入

当不被信任的数据通过表单输入或其它一些提交到 Web 应用程序数据发送到代码解释器时,就会发生注入攻击。

如攻击者可能向本应填写纯文本用户名的表单输入 SQL 数据库代码。

如果该表单输入未得到正确保护,则将导致执行该 SQL 代码。这称为 SQL 注入攻击。

可通过验证或清除用户提交的数据来防止注入攻击。

验证表示拒绝看似可疑数据,而清理指清除数据中可疑的部分。

此外,数据库管理员可以设置控件以最大程度地减少注入攻击可能接触的信息量。

身份验证失效

攻击者可通过身份验证系统中的漏洞访问用户帐户,甚至可以使用管理员帐户来破坏整个系统。

例如,攻击者可以获取一个包含在数据泄露中获得的数千个已知用户名与密码组合的列表。

并使用脚本尝试在登录系统尝试所有这些组合,以查看是否有任何有效组合。

一些防护身份验证漏洞的策略要求双要素身份验证以及使用限制或延迟重复的登录尝试。

敏感数据暴露

如果 Web 应用程序不保护财务数据和密码等敏感数据,则攻击者可访问这些数据并将其用于恶意目的。

窃取敏感信息的一种热门方法是使用在途攻击。

通过加密所有敏感数据并禁用任何敏感信息的缓存,可最大程度地降低数据暴露风险。

此外,Web 应用程序开发人员应注意确保避免不必要地存储任何敏感数据。

缓存是一种临时存储数据以供重用的做法。

例如,网络浏览器通常会缓存网页,这样一来,如用户在特定时间段内重新访问这些页面,浏览器就不必从 Web 获取页面。

外部实体

这是对解析 XML 输入 Web 应用程序的攻击。

此输入可引用外部实体,以尝试利用解析器中的漏洞。在此,外部实体是指存储单元,如硬盘驱动器。

攻击可欺骗 XML 解析器将数据发送到未经授权的外部实体,然后后者可将敏感数据直接传递给攻击者。

防止 XEE 攻击的最佳方法是让 Web 应用程序接受不太复杂的数据类型,如 JSON,或者至少给 XML 解析器打补丁并禁止在 XML 应用程序中使用外部实体。

XML 全称可扩展标记语言,是种旨在同时实现人类可读和机器可读的标记语言。

由于其复杂性和安全性漏洞,许多 Web 应用程序现在已经逐步淘汰了这种语言。

JavaScript 对象表示法是一种简单的、人类可读的表示法,通常用于通过网络传输数据。

尽管 JSON 最初是为 JavaScript 创建,但它不受语言限制,并且可以由许多不同的编程语言解释。

访问控制中断

访问控制是指控制对信息或功能的访问权限的系统。

损坏的访问控制使攻击者可以绕过授权并执行任务,像他们是管理员等特权用户一样。

例如,Web 应用程序可能允许用户仅通过更改 URL 的一部分即可更改他们登录的帐户,无需任何其它验证。

通过确保 Web 应用程序使用授权令牌并对其设置严格控制,可确保访问控制的安全。

许多服务在用户登录时都会发布授权令牌。用户发出每个特权请求都需出示授权令牌。

这是确保用户身份与声称相符的安全方法,而无需他们不断的输入登录凭据。

安全配置错误

安全配置错误是列表上最常见的漏洞,通常是使用默认配置或显示过多详细错误结果。例如,一个应用程序可能在向用户显示错误时描述得过于详尽,以致于揭示出应用程序中的漏洞。

这种情况可通过删除代码中任何未使用的功能并确保错误消息更加笼统来防护。

XSS 跨站点脚本

跨站点脚本漏洞在 Web 应用程序允许用户将自定义代码添加到 URL 路径或其他用户可看到的网站上时发生。

利用漏洞,可在受害者的浏览器上运行恶意的 JavaScript 代码。

例如,攻击者可向受害者发送似乎来自受信任银行的电子邮件,并随附指向该银行网站链接。

链接可能在 URL 的末尾标记一些恶意 JavaScript 代码。

如银行的站点没有得到适当的跨站点脚本保护,则当受害者单击链接时,该恶意代码将在受害者的 Web 浏览器中运行。

跨站点脚本的缓解策略包括对不受信任的 HTTP 请求转义以及验证和、或清除用户生成的内容。

不安全的反序列化

这种威胁目标是各种经常对数据进行序列化和反序列化的 Web 应用程序。

序列化意味着从应用程序代码中获取对象,并将其转换为可用于其它目的的格式,例如将数据存储到磁盘或对其进行流传输。

反序列化正好相反:将序列化的数据转回应用程序可以使用的对象。序列化就像在搬家前将家具打包到箱子里,而反序列化就像在搬家后拆开箱子并组装家具。

不安全的反序列化攻击就像搬家公司在拆箱前篡改箱子中的物品。

不安全的反序列化漏洞利用是不可信来源的数据反序列化的结果,并可能导致严重的后果,例如 DDoS 攻击和远程代码执行攻击。

尽管可采取措施尝试检出攻击者,如监视反序列化和实施类型检查,但防止不安全的反序列化攻击的唯一肯定有效方法是禁止来自不受信任来源的数据反序列化。

使用具有已知漏洞组件

许多现代 Web 开发人员在其 Web 应用程序中使用库和框架之类的组件。

这些组件是可帮助开发人员避免多余工作并提供所需功能的软件。

一些攻击者会在这些组件中寻找漏洞,然后利用这些漏洞组织攻击。

一些较为热门组件在数十万个网站上使用。攻击者如在其中一个组件中发现安全漏洞,就可能使数十万个站点易受攻击。

组件开发人员通常会提供安全补丁和更新程序修补已知漏洞,但 Web 应用程序开发人员并不总是在其应用程序上运行组件修补版本或最新版本。

为最大程度地降低运行具有已知漏洞的组件的风险,开发人员应从项目中删除未使用组件,并确保他们从受信任的来源接收组件并确保它们是最新版本。

记录监控不足

许多 Web 应用程序没有采取足够措施来检测数据泄露。

漏洞发生后平均发现的时间约为 200 天。

这使攻击者有大量时间在开发人员没任何响应之前造成破坏。

OWASP 建议 Web 开发人员实施日志记录和监视及事件响应计划,以确保他们了解应用程序遭到的攻击。

推荐 10 个 Linux 下的防病毒软件

在 Linux 系统,虽然由于设计上的安全性使得病毒和恶意软件的感染率相对较低,但在某些特定场景,如服务器环境或需要处理敏感数据的系统,安装防病毒软件仍然是一个明智选择。

ClamAV

特点:ClamAV 是一款免费开源的防病毒程序,专为类 Unix 系统设计。它提供强大的病毒检测引擎,能够识别清除各种病毒、间谍软件、蠕虫和其它的恶意软件。

优势:它支持多线程扫描,提高了扫描速度和效率;免费开源,拥有活跃社区支持;病毒库更新较频繁,保持对新威胁快速响应。

Sophos Protection for Linux

特点:Sophos Protection for Linux 是一款功能强大安全软件,集成了防病毒、防火墙和入侵检测多种功能,能够有效地保护 Linux 服务器和端点免受各种网络威胁侵害。

优势:提供实时保护、扫描文件目录、定期扫描功能;与 Sophos 中央管理平台集成,实现集中管理监控;支持多种 Linux 发行版,如 Ubuntu、Red Hat 等。

Avast Antivirus for Linux

特点:Avast Antivirus for Linux 是一款功能强大跨平台防病毒软件,专门为 Linux 系统设计。它提供了实时保护、手动扫描、定时扫描多种安全功能。

优势:拥有强大的病毒库和出色的保护能力;界面设计简洁直观,操作简便;与多种 Linux 发行版本兼容,如 Ubuntu、Fedora 等。

Kaspersky for Linux

特点:Kaspersky 为 Linux 系统提供一款防御性安全程序,旨在抵御可能渗透到 Linux 系统病毒、木马、间谍软件、广告软件。

优势:功能全面、兼容性强、易用性高;通过实时威胁检测、恶意软件扫描清除、防火墙保护等多种手段提供全面安全保护;支持多种 Linux 发行版,如 Ubuntu、Fedora 等。

ESET NOD32 Antivirus for Linux

特点:ESET NOD32 Antivirus for Linux 是 ESET 公司开发一款专为 Linux 系统设计的防病毒软件。它提供了高效的恶意软件检测和防护功能。

优势:拥有独特的 ThreatSense 技术,能够通过行为分析和模式识别快速准确地识别新的威胁;提供实时保护功能,监控系统运行中的进程、文件、网络连接;提供免费限时试用版供用户评估。

Comodo Antivirus for Linux

特点:Comodo Antivirus for Linux 是一款功能强大、兼容性好、用户友好的防病毒软件。它提供了实时保护功能,能够主动监控系统运行中的进程、文件、网络连接。

优势:集成了防火墙功能;独特的沙箱技术允许在虚拟环境中运行未知或可疑文件;提供电子邮件过滤功能和反垃圾邮件系统;跨平台支持多 Linux 发行版。

F-Prot Antivirus for Linux

特点:F-Prot Antivirus for Linux 是一款由 Cyren 开发跨平台防病毒软件。它提供了高效的病毒和恶意软件检测功能。

优势:支持 32/64 位体系结构;能够保护用户免受超过 2100 万种威胁及其变种的侵害;免费且可移植;允许扫描内部驱动器和驱动程序以及木马、宏病毒等。

chkrootkit

特点:chkrootkit 是一款轻量级的便携式防病毒程序,专注于检测 rootkit。

优势:易于使用;可以从命令行轻松运行;提供一次管理和解决多个错误的功能。

Rootkit Hunter

特点:Rootkit Hunter 是一款通过命令行使用防病毒工具,专注检测和消除病毒和木马软件。

优势:提供高效的 rootkit 检测功能;支持 SHA-1 比较和检测恶意软件;提供详细的调查结果报告和日志。

Firetools

特点:Firetools 是一个开源的沙箱 GUI 工具,允许用户在隔离环境中运行脚本和软件以验证其安全性。

优势:与其它防病毒扫描程序结合使用可以提高系统的整体安全性;特别适用于处理恶意 Web 脚本。

关于今日被攻击

今天 9:58 分,接到上海云盾的电话,说我在他们那接入的一个域名正在被攻击,问我是迁移走还是他们给我回源。

我记得云盾是防 CC 的,遇到 DDOS 会回源,于是问了一句,对方回复是 CC 攻击。

登陆控制台,看到攻击大概从九点开始,那时候已经消耗了 500 GB 左右的流量,带宽峰值 1.2Gbps,刷的是我静态资源域名的一张图片,攻击 IP 来自香港的亚马逊云。

我首先把该 IP 添加到了黑名单,但是紧接着来的就是境内大多数省份的高并发访问,峰值带宽和流量在不停上升。

我给云盾回复我迁移走,请求给我一个小时左右的时间。在这期间,我临时把该域名迁移走了,11:15分,还是收到了云盾给我该域名设置回源的短信。

切走静态资源域名后,发现主站也开始被攻击,为了避免主站被解析回源,我又切走了主站。截止一切操作完毕,云盾控制台那边显示今日流量 1.01TB,带宽峰值 4.25Gbps,请求量 450W 次以上,工作人员告诉我 QPS 已经达到了一万次。

切走后也不知道是新接入商的清洗还是攻击停止,目前来看流量正常。

群里有大佬说这个带宽峰值让云盾为一个免费用户平白无故付出了 4W 块的账单,这让我觉得很惭愧,理解并且打心底里感谢上海云盾。

以前总觉得写博客是一件很自由的事,也无暇顾及写的东西是否会伤害到别人。我本质上应该是一个善良的人吧,每年都会捐一千多块钱用于贫困助学,虽然这对真正贫困的人来说可能是杯水车薪。

2020年年底开始写博客以来,也想象过自己能一直坚持下去,毕竟没有爱情和其它爱好的生活,总得有一个可以支撑我的东西,所以我加入了十年之约。但是确实从没想到过个人站长做博客原来是一件这么困难的事,本来生活就已经够累了。我最近因为太忙也没有在网上乱窜,甚至博客互访互评的频次都少了很多,也不知道是因为什么得罪了谁。

如果攻击者会再一次回来看的话,看到这里的时候,我想对你说:可怜的人,我原谅你。

SamWaf 网站防火墙工具安装使用

SamWaf 网站防火墙是一款适用于小型公司、工作室和个人网站的免费的轻量级网站防火墙,可完全私有化部署,数据加密且仅保存本地,一键启动,支持 Linux/Windows 等 64 位操作系统。

主要功能

  • 完全独立引擎,防护功能不依赖 IIS/Nginx。

  • 可自定义防护规则,支持脚本、界面编辑。

  • 可支持白名单访问。

  • 支持 IP 黑名单。

  • 支持 URL 白名单。

  • 可支持限制 URL 访问。

  • 支持指定界面数据隐私输出。

  • 可支持 CC 频率访问。

  • 支持全局一键配置。

  • 可支持分网站单独防护策略。

工具安装

使用下面的命令安装 Docker:

1
curl -sSL https://get.docker.com/ | sh

创建目录,并启动 SamWaf 容器:

1
2
3
4
mkdir -p /data/samwaf/conf
mkdir -p /data/samwaf/data
mkdir -p /data/samwaf/logs
docker run -d --name=samwaf-instance -p 26666:26666 -p 80:80 -p 443:443 -v /data/samwaf/conf:/app/conf -v /data/samwaf/data:/app/data -v /data/samwaf/logs:/app/logs samwaf/samwaf

面板访问

在容器启动后,使用下面的地址可访问面板:

1
http://IP:26666

默认用户名和密码如下:

1
2
admin
admin868

工具截图

SamWaf 网站防火墙概览:

从日志中进行快速处理:

自动创建规则脚本:

界面编辑:

配置 CC 攻击的规则。速率如 1 限制次数 100 则代表每秒访问 100 次将被限制:

防御日志记录查询所有正常、异常请求。可以根据规则名称,时间进行查询:

Linux 安全 Auditd 审计工具使用说明

Auditd 是 Linux 系统中的一个强大的审计框架,它能帮助系统管理员监控和记录系统中的安全相关事件。杜老师整理了一些关于 Auditd 审计工具的详细使用说明。

安装工具

在大多数 Linux 发行版中可以通过包管理器安装 Auditd。例如,在银河麒麟高级服务器操作系统/CentOS 上,可以使用以下命令安装:

1
yum -y install audit

在银河麒麟桌面操作系统上,可以使用以下命令安装:

1
sudo apt -y install auditd audispd-plugins

配置工具

Auditd 的主要配置文件是/etc/audit/auditd.conf

此外,审计规则的配置文件通常位于/etc/audit/audit.rules

相关工具

以下是 Auditd 中常用的工具:

工具名称功能描述
auditctl用于添加、删除审计规则,及查看审计规则等。
aureport用于生成审计报告。
ausearch用于搜索审计事件。
auditspd用于将事件通知转发给其它应用程序。
autrace用于跟踪进程。

审计规则

审计规则可以分为三类:控制规则、文件系统规则、系统调用规则。控制规则用于更改审计系统本身的配置和设置。例如,设置审计缓冲区的最大数量:

1
auditctl -b 8192

文件系统规则用于监控特定文件或目录的访问。例如,监控/etc/passwd 文件写入和属性修改:

1
auditctl -w /etc/passwd -p wa -k passwd_changes

系统调用规则用于记录特定程序系统调用。例如,记录使用 adjtimexsettimeofday 系统调用的行为:

1
auditctl -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change

例如,要监控/etc/passwd 文件读写访问,可以使用以下命令。这条规则表示监控/etc/passwd 文件当有读写操作时,使用关键字 passwd_monitor 记录审计事件:

1
auditctl -w /etc/passwd -p rw -k passwd_monitor

使用命令查看当前配置审计规则:

1
auditctl -l

使用 auditctl -D 可删除所有规则,或使用下面命令删除指定路径的规则:

1
auditctl -W

日志报告

审计日志默认存储在/var/log/audit/audit.log 文件。使用 ausearch 工具可以搜索和查看审计日志。例如,要搜索所有与 passwd_monitor 相关的日志条目,可以使用:

1
ausearch -k passwd_monitor

使用 aureport 命令可生成审计报告。例如,要生成一个关于用户登录失败的报告,可以使用:

1
aureport -au

保存规则

要使规则永久生效,需要将规则添加到/etc/audit/audit.rules 文件中,然后重启或重新加载 Auditd 服务:

1
sudo systemctl restart auditd

或者重新加载规则:

1
sudo auditctl -R /etc/audit/audit.rules

服务管理

Auditd 服务默认开机自启动。可使用以下命令来管理服务:

描述命令
查看服务状态systemctl status auditd
开启服务systemctl start auditd
停止服务systemctl stop auditd
重启服务systemctl restart auditd

确保 Linux 审计日志安全性和完整性

  1. 配置审计守护进程:

将日志文件路径设置在单独挂载点上,以防止其它的进程消耗空间,并确保审计守护进程能够准确的检测剩余空间。
设置 max_log_file 参数以充分利用保存审计日志文件分区上的可用空间。
max_log_file_action 设置为 keep_logs,防止审计日志文件被覆盖。
配置 space_left 以及 space_left_action 参数,以确保在磁盘空间不足时能够及时通知管理员。
设置 admin_space_left 以及 admin_space_left_action 参数,为记录管理员所执行的操作保留足够空间。
disk_full_action 设置为 haltsingle,以确保在磁盘空间耗尽时系统能够关闭或以单用户模式运行。
disk_error_action 设置为 syslogsingle 或者 halt,以便在检测到磁盘错误时采取适当的行动。

  1. 配置审计规则:

auditctl 命令添加规则,监控关键文件以及系统调用,确保只有授权的更改被记录。
将规则持久化到/etc/audit/audit.rules 文件,以确保在系统重启后规则仍有效。

  1. 保护审计日志文件:

确保审计日志文件的存储位置具有适当的权限设置,只有授权用户才能访问。
考虑使用加密存储审计日志,以防止未授权的访问或篡改。

  1. 日志轮转、归档:

配置日志轮转策略,避免日志文件无限制增长并填满磁盘空间。
定期归档旧的审计日志,确保归档过程不会破坏日志文件的完整性。

  1. 监控、响应:

定期监控审计日志,用 ausearchaureport 命令分析日志,以识别异常行为或潜在安全威胁。
根据审计结果,采取相应响应措施,并且生成审计报告。

  1. 定期审查、更新:

定期审查审计策略、规则,以适应不断变化的安全需求。
更新审计规则以覆盖新安全场景,并确保审计系统有效性。

多方式防止网站被镜像

最近好多小伙伴的博客都被镜像,包括杜老师的。整理了多种方式放置网站被镜像,需要的小伙伴可以试试。虽说被镜像会增加流量,但却减少了域名的权重,还是要避免的!

检查域名

1
2
3
4
var domain = "dusays.com";
if (location.href.indexOf(domain) === -1) {
window.location = 'https://dusays.com';
}

注意:在前端使用 JavaScript 判断当前域名是否合法,如果不是授权域名,则会跳转到原域名。为增强安全性,可对这段代码进行混淆处理,以防止被替换。

设置头部

1
2
add_header X-Frame-Options "DENY";
add_header Content-Security-Policy "frame-ancestors 'none'";

注意:使用 X-FRAME-OPTIONSContent-Security-Policy 头部来防止网站被嵌入到 iframe 中,可在 Nginx 配置中添加上面内容。

限制访问

定期分析访问日志,将可疑的 IP 地址加入黑名单,或者限制访问频率。

这可以通过 Nginx 的 limit_connlimit_req 指令实现。

过滤爬虫

1
2
3
if ($http_user_agent ~* "curl|wget|python") {
return 403;
}

注意:通过检查请求的 User-Agent,拒绝来自已知爬虫或代理的请求。

使用证书

强制使用证书,可通过配置 Nginx 来实现。

确保所有流量都通过安全的连接传输,这样可增加安全性。

监控访问

定期检查访问日志,识别异常流量模式,并采取相应的措施。

通过结合这些方法,可以有效降低网站被镜像的风险。

怎样在 Nginx 中配置防盗链

防盗链技术主要用于防止未经授权的网站直接链接到另一个网站上的资源,如图片等。这种技术通过各种方法验证请求的合法性,以确保只有授权的用户或网站才能访问特定的资源。

解决思路

在 Nginx 中配置防盗链主要是通过验证 HTTP 请求中的 Referer 头部来实现。如果请求的 Referer 头部不满足特定的条件,则 Nginx 可以拒绝服务。

可使用 valid_referers 指令,这指令用来定义哪些 Referer 是有效的。

可以使用 none 来拒绝所有没有 Referer 的请求,或 blocked 来拒绝所有 Referer 被屏蔽的请求。

可使用 if 语句和 return 指令,在 server 块中,可使用 if 语句来检查$invalid_referer 变量,如果这个变量为 true,则返回一个 403 禁止访问的状态码。

配置文件

打开 Nginx 的配置文件,通常这个文件位于:

1
/etc/nginx/nginx.conf

或者某个特定的站点配置文件中,比如:

1
/etc/nginx/sites-available/default

配置方法

下面是一个简单的配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name dusays.com;
location ~ .*\.(jpg|jpeg|gif|png|js|css)$ {
valid_referers none blocked dusays.com www.dusays.com;
if ($invalid_referer != ok) {
return 403;
}
root /var/www/html;
index index.html index.htm;
}
}

在这个配置中,location 一行用于匹配请求 URI,匹配所有以 jpg|jpeg|gif|png|js|css 结尾请求:

1
2
location ~ .*\.(jpg|jpeg|gif|png|js|css)$ {
}

下面一行内容定义哪些 Referer 是被允许的,none 表示不接受任何的 Referer,blocked 表示不接受被屏蔽 Referer,后面跟着的是被允许的域名:

1
valid_referers none blocked dusays.com www.dusays.com;

下面一行的内容检查$invalid_referer 变量,如果它不是 ok,则会返回 403 状态码:

1
2
3
if ($invalid_referer != ok) {
return 403;
}

注意事项

这种方法并不是完全安全的,因为 Referer 头部可以被伪造。

更安全的做法是使用基于 IP 地址、用户身份验证或者其它更复杂的安全措施来防止未经授权的访问。

如何配置 Nginx 防止 CC 攻击

CC 攻击是一种网络攻击手段,属于 DDoS 攻击的一种形式。CC 攻击的主要目的是通过发送大量看似合法的请求到目标服务器,耗尽服务器的资源,使得服务器无法处理正常的用户请求,从而导致网站服务无法访问。

限制请求速度

1
2
3
4
5
6
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
location /login.html {
limit_req zone=one;
}
}

注意:在安装 Nginx 时加载 ngx_http_limit_req_module 模块,通过 limit_req_zone 指令定义请求速率限制的区域,并使用 limit_req 指令在特定的 location 中应用这些限制。这样设置可限制每个客户端 IP 每分钟最多发起 30 个请求。

限制连接数量

1
2
3
4
5
6
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /store/ {
limit_conn addr 10;
}
}

注意:在安装 Nginx 时加载 ngx_http_limit_conn_module 模块,通过 limit_conn_zone 指令定义连接数量限制的区域,并使用 limit_conn 指令在特定的 location 中应用这些限制。这将限制每个客户端的 IP 同时最多只能有 10 个连接。

关闭慢速连接

1
2
3
4
server {
client_body_timeout 5s;
client_header_timeout 5s;
}

注意:通过设置 client_body_timeoutclient_header_timeout 指令来定义读取客户端请求的超时时间,可以关闭慢速连接。这样可防止攻击者通过慢连接攻击耗尽服务器资源。

设置 IP 黑名单和白名单

1
2
3
4
location / {
allow 192.168.1.0/24;
deny all;
}

注意:使用 allowdeny 指令可控制特定 IP 地址或 IP 范围的访问权限。这样可以允许特定 IP 段访问,而拒绝其它所有 IP 访问。

限制文件类型和请求大小

1
2
3
4
5
6
7
8
server {
location /upload/ {
client_max_body_size 10M;
if ($content_type ~* "^image/") {
return 403 "Only non-image files are allowed.";
}
}
}

注意:通过 client_max_body_size 指令限制上传文件大小和类型,防止因大文件上传或超大数据包导致的服务中断或资源耗尽。

其它限制

可集成 Fail2Ban 工具,对日志文件进行自动化监控,一旦检测异常行为或恶意 IP 地址,立即将其加入黑名单并封锁。

定制化错误页面不仅能提升用户体验,还能在遭遇攻击时减少攻击者获取的有用信息。

持续关注 Nginx 的错误日志,借助日志分析工具,及时发现并响应任何异常行为或攻击迹象。

强制所有的数据传输通过 HTTPS 加密,可以有效抵御中间人攻击和数据泄露风险。

Nginx 集成 ModSecurity 实现 Web 应用防火墙功能

ModSecurity 是一个开源、跨平台的 Web 应用程序防火墙引擎,适用于 Apache 和 Nginx。具有强大的基于事件的编程语言,可抵御针对 Web 应用程序的一系列攻击,并允许进行 HTTP 流量监控、日志记录、实时分析。

安装步骤

首先,需要安装一些必要的依赖包,例如 libxml2/libpcre3/libapr1 等。可以通过包管理器完成,例如在 Debian 或 Ubuntu 系统上使用 apt

1
2
sudo apt update
sudo apt -y install libxml2 libxml2-dev libpcre3 libpcre3-dev libapr1 libapr1-dev libaprutil1 libaprutil1-dev

接着,从 GitHub 克隆 ModSecurity 源代码,编译安装:

1
2
3
4
5
6
git clone --recursive https://github.com/owasp-modsecurity/ModSecurity ModSecurity
cd ModSecurity
./build.sh
./configure
make
sudo make install

安装模块

然后,下载 Nginx ModSecurity 模块并编译 Nginx 以包含模块:

1
2
3
4
5
git clone https://github.com/owasp-modsecurity/ModSecurity-nginx.git
cd /path/to/nginx/source
./configure --add-module=/path/to/ModSecurity-nginx
make
sudo make install

在 Nginx 的配置文件中启用 ModSecurity 并指定规则文件。例如,在 nginx.conf 添加:

1
2
3
4
5
6
7
server {
modsecurity on;
location / {
root /var/www/html;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
}
}

配置规则

可使用默认的 OWASP 核心规则集,这是一个广泛认可的标准规则集,专门用于检测和阻止 Web 应用程序攻击。克隆并将其配置到 ModSecurity 中:

1
2
git clone https://github.com/coreruleset/coreruleset.git /etc/nginx/modsec/coreruleset
cp /etc/nginx/modsec/coreruleset/crs-setup.conf.example /etc/nginx/modsec/coreruleset/crs-setup.conf

修改 /etc/nginx/modsec/main.conf 来包含配置:

1
2
Include /etc/nginx/modsec/coreruleset/crs-setup.conf
Include /etc/nginx/modsec/coreruleset/rules/*.conf

测试防御

最后,重启 Nginx 以应用更改:

1
sudo service nginx reload

可以使用以下命令测试防护功能,如返回 403 Forbidden,说明防护已经生效,此处匹配规则是 User-Agent 中不能包含漏洞扫描器名字:

1
curl -H "User-Agent: Nikto" http://IP

记一次被渗透测试

起因

昨天早上醒来,发现博客推送了几条无意义的评论,根据 IP 反查到域名,大致了解了一下,也没多想,把评论删掉了。

今天早上醒来,又一次遇到了同样的情况。大概是我设置了评论提交频率,所以垃圾评论只有几条。但是我想挖掘一下对方到底是何方神圣,记录下来复盘。

基本信息

评论提交者的昵称:gBqsPxAZ或者匿名

评论提交者的邮箱:testing@example.com,显然是假的;

评论提交者的 IP :222.180.198.54。

收集IP情报

在微步云情报社区查询到,该 IP 属于位于重庆的企业专线,早些时候就已经被打上了“恶意”标签。根据微步情报局掌握的信息,该 IP 地址在2021年07月22日到2024年08月16日期间发起了多次网络攻击。有2个与该 IP 同 C 段的 IP 地址也被判定为恶意/可疑。

微步云IP情报概览

既然是企业专线,那大概可以反查一下其解析的域名。该 IP 解析了很多xway.cn的子域名,尝试访问了一下,子域名无法直接访问。

到这一步的时候我还在想,会不会是某个安全意识薄弱的小微企业的服务器沦陷,被当成肉鸡发起网络攻击。但访问该域名主站后,这个想法被彻底打消,与之而来的还有一点阴谋论的感觉。

该域名主站截图

按理说,一个网络安全企业是不会发生上面我猜想的这种情况。看到右下角的“中小企业免费基础防护对接人”,总感觉哪里有点不对劲,脑海中浮现了以前某厂商攻击自己用户再借机卖防御的案例。

审计日志和措施

考虑到这种情况是连续出现,所以我查看了网站访问日志和 CDN 的统计信息。

截至写这篇日志时,网站访问日志的大小已有29MB,从六点多开始,该 ip 的访问记录超过两万次,请求内容大概就是扫描器访问的不存在路径;

CDN 控制台那边可以看到,8:30 的时候达到了最大带宽4.41Mbps,当时(不是截止当时)流量157.73MB,回源流量7.45MB,来自该 IP 的请求次数超过15万次。

在漏洞入侵分析中,该 IP 的攻击类型包括敏感文件访问、sql 注入和 xss 跨站攻击等。好在我博客是纯静态,所以通常情况下不存在这些漏洞,加上日志数量过大,所以没有逐一去分析。

态势感知里的攻击类型占比

这些攻击不像是 CC 那样具有很强的目的性,但为了安全起见,我还是采取了以下操作:

1.备份网站访问日志,当初公安网备的时候有要求,在特殊情况下可能会交给叔叔;

2.在评论系统中把其评论的昵称和邮箱设为违禁词,不允许提交评论;

3.将该 IP 添加到黑名单,当然也不是完全禁止访问,而是采用了比较温和的 js 质询。

其它猜想

在通过注册人反查域名的时候发现该注册人(企业)还有三个域名,其中两个是互联网安全相关的网站和论坛,另外两个看起来就像针对微软和office用户的钓鱼网站。

注册人反查域名结果

两个看起来像钓鱼网站的内容让我一度怀疑是不是护网行动带来的渗透测试(叔叔当初说过,每年都会对备案网站进行渗透测试),但是很快又打消了这种猜测,因为 Twikoo 群里有小伙伴也经历了类似的垃圾评论事件,而他的网站没有备案。

貌似钓鱼网站的单页内容

写在最后

11 点的时候我与对方工作人员取得联系,工作人员询问了我所在地域后,告知应该是网安总队的监测。同时一位大佬告诉我:公安网信授权网安公司对其辖区系统进行扫描或渗透,不需要你的授权,也不会违反网安法。但同时允许你直接向网安公司提交停止扫描的要求。

其实我每天面临的恶意扫描非常之多,CC 攻击也一直在持续。因为此前学习过网络web渗透,对网络安全还是有比较深刻的感触,所以我一直坚持使用纯静态的博客系统,相比动态网站程序,纯静态网页面对 sql 注入、xss 跨站等威胁时更安全一些。

服务器操作系统安全加固项

应宋童鞋需求,整理了一些服务器操作系统的安全加固项。因为涉及大量内容,所以直接用 PDF 文档形式展示,供需要的小伙伴们借鉴。需要注意的是:由于服务器配置和操作系统版本不同,部分内容可能无法直接复制粘贴,需要根据实际情况进行修改。

安全加固的必要性

服务器操作系统的安全加固是确保网络设施安全的关键步骤,可以有效降低安全风险,保护数据安全,提高服务器可用性和可靠性。安全加固必要性主要体现在以下几个方面:

  1. 增强防护能力。通过安全加固,可增强服务器的防病毒和防黑客攻击能力,提高其物理和网络安全防护水平;
  2. 保护数据安全。防止数据泄露、损坏,确保服务器上存储和处理的数据的安全性;
  3. 保证系统稳定运行。通过加固,可提高服务器的可用性和可靠性,确保业务的连续性;
  4. 提高可管理性、可维护性。方便日常的监控和维护工作,及时发现并解决潜在的安全问题。

实施服务器加固的步骤通常包括:

  1. 及时更新操作系统、应用程序,打上最新安全补丁;
  2. 配置合理安全策略,包括账户权限管理、访问控制;
  3. 加密数据传输,使用 SSL 等技术确保数据传输过程中的安全;
  4. 配置防火墙的规则,限制不必要的网络访问,防止非法入侵;
  5. 定期备份数据,以便在数据损坏或丢失时能及时恢复;
  6. 评估现有安全状况,找出安全隐患、漏洞;
  7. 制定加固方案,包括操作系统、应用程序、网络设备配置;
  8. 实施加固措施,例如更新补丁、配置安全策略、设置防火墙等;
  9. 测试、验证加固效果,确保符合预期;
  10. 持续监控、维护,解决新出现的安全问题。

服务器安全加固项

需要指出的是,安全加固并非一劳永逸,而是一个持续过程。定期更新系统补丁和部署具有一流防护能力的安全防护系统,及使用自动化加固工具,都是确保服务器安全的有效手段。同时,安全加固服务的实施是一个系统工程,涉及多个层面的策略与实践,需要持续关注安全动态,不断优化加固措施:

❌