给wordpress增加Basic Auth密码

目录

最近几天博客一直被无聊的人扫描,尝试后台登陆及找回管理员密码。尽管博客没有什么有价值的东西,被攻破了也没有多大的损失,但这种扫描行为本身让人比较恶心,于是就想着增强下博客的安全性。

大的思路其实就三条,增加阿里云ESA的WAF和回源保护、wordpress的薄弱点加固、及增加额外的验证方式。阿里云ESA就不多说了,因为这个产品用的人可能不多,每家CDN的设置差异较大。下面主要集中在wordpress的薄弱点加固和增加额外的验证方式两方面总结下这次的经验。

 

一、主题中修复简单薄弱点

修复项 严重度 说明
统一登录错误消息 严重 无论用户名是否存在,一律返回“登录信息不正确”,防止攻击者通过错误提示枚举用户名
移除密码找回功能 严重 移除密码找回功能,以防无聊的人不断点击
增加登陆失败锁定 严重 随着登陆失败次数的增加不断增加锁定IP时长
增加登陆验证码 严重 将简单算数验证码改为图片显示的算数验证码,以增加机器识别的难度(需要OCR,会增加成本)
移除 WP 版本号 登录页+前端所有 CSS/JS 的 ver= 参数全部移除
移除 REST API Link 头 HTTP 响应头不再暴露 wp-json 端点
删除 readme.html 和 license.txt 这两个文件会暴露 WordPress 版本号
RSS Feed 隐藏作者名 Feed 中作者显示为“作者”而非真实昵称
移除 body class 主题名 不再暴露 wp-theme-nickel
移除登录页语言切换器 减少攻击面

 

二、增加额外的验证方式

增加额外的验证方式有两个思路,一个是增加2FA,就是类似于增加一个和手机端同步的动态密码,或邮件发送的6位数动态密码,从而形成wordpress的账户密码和动态密码的双重验证。另一个思路是增加一个nginx的Basic Auth密码,原理就是在访问登录页等敏感页面时会弹出一个登陆页面,只有通过了这个登陆页面才能看到真正的登录页。我最终选择了Basic Auth方案,原因有三个,一是2FA较复杂,因此插件普遍较重,我不想让网站加载这么多东西;二是除了登录页外/wp-admin/目录也需要保护,而轻量的2FA没有这个功能;三是Basic Auth完全由nginx处理,系统损耗最轻,即是被爆破小鸡也容易扛住。如果大家比较倾向于2FA方案,那么我推荐wp 2FA插件。

Basic Auth部署完后弹出的验证框如下,下面我贴上完整的部署步骤。

 

1、在nginx的配置文件中增加以下代码

记得要加在include enable-php-83.conf 之前,原因是正则 location 之间,先定义的优先。如果 enable-php-83.conf 中的 location ~ \.php$ 在前面,它就会抢先匹配 /wp-admin/index.php,auth_basic 就被绕过了。所以必须把 location ~ ^/wp-admin/.*\.php 放在它前面。

需要添加的代码如下:

NGINX
============= ★ 新增:Basic Auth 保护 wp-admin 和 wp-login =============

# 1) 登录页加密(精确匹配,优先级最高,不被任何正则覆盖)

location = /wp-login.php {

auth_basic “Restricted”;

auth_basic_user_file /www/server/nginx/htpasswd/wp-auth;

try_files $uri =404;

fastcgi_pass unix:/tmp/php-cgi-83.sock;

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}

# 2) wp-admin 下 PHP 文件加密(正则,必须在 enable-php-83 之前定义)

location ~ ^/wp-admin/.*\.php(/|$) {

auth_basic “Restricted”;

auth_basic_user_file /www/server/nginx/htpasswd/wp-auth;

try_files $uri =404;

fastcgi_pass unix:/tmp/php-cgi-83.sock;

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}

# 3) 放行 admin-ajax.php(精确匹配,优先级高于上面的正则)

location = /wp-admin/admin-ajax.php {

auth_basic off;

try_files $uri =404;

fastcgi_pass unix:/tmp/php-cgi-83.sock;

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}

# ============= ★ Basic Auth 结束 =============

 

2、创建密码目录

mkdir -p /www/server/nginx/htpasswd

 

3、安装 htpasswd 工具

# CentOS / AlmaLinux / Rocky
yum install -y httpd-tools

# Ubuntu / Debian
apt install -y apache2-utils

 

4、创建密码文件和用户

# -c 表示创建新文件(首次使用)
# 替换 admin 为你想要的用户名
htpasswd -c /www/server/nginx/htpasswd/wp-auth admin

系统会提示输入两次密码:

New password: ********
Re-type new password: ********
Adding password for user admin

 

5、如果要添加第二个用户(可选)

# 注意:不要加 -c,否则会覆盖已有用户
htpasswd /www/server/nginx/htpasswd/wp-auth user2

 

6、验证密码文件

cat /www/server/nginx/htpasswd/wp-auth

应该看到类似输出(用户名:加密密码):

admin:$apr1$Xk7Zb2Qw$LmN3R4h5K6j7P8qRs9TtU0

 

7、设置文件权限

chown www:www /www/server/nginx/htpasswd/wp-auth
chmod 640 /www/server/nginx/htpasswd/wp-auth

 

8、检查 Nginx 语法并重载

nginx -t

看到 syntax is oktest is successful 后:

nginx -s reload

 

三、最强的方案

CDN端WAF+CDN源站保护(只有CDN节点能回源)+CDN端机器人拦截+网站加固+2FA+Basic Auth(作为简单替代,如果有固定IP的话,可以只允许自己的IP访问敏感页面)。但设置的规则越多,对于小站来说越麻烦,平时容易出错,搬迁时耗费的精力更多,所以如果没有被骚扰,那么CDN端WAF是最好的选择。

一直没有用过静态博客,是不是如果用了静态博客就没有了这些烦恼?

 

作为个人博客原本不用这么折腾的,但无奈蛋疼的人太多,总干这种损人不利己的事情,逼迫着不懂一点点技术的我也不得不花时间来学习这些网站维护知识。

51 条评论

  1. 没找到留言处,就唐突地在这里留言了。
    我回复了你一个留言,应该邮件送达了,我是否可以发个博文?不知道你是否介意

    1. 水拍石

      完全不介意,你发吧,发了我去你那学习。

      1. 水拍石

        马上去读

  2. wp我不太熟,应该可以修改后台登录地址吧,再禁掉一些常见的攻击ua和ip,基本上就能消停些了。

    1. 水拍石

      改后台地址很容易,禁ua和ip我就不会了,除了防火墙我不会用自动规则仅止这些攻击,但现在刷的人IP太多了,不断轮换,手动禁太麻烦。

  3. 我前几天也收到改密验证,应该也有人扫。

    1. 水拍石

      加固网站,闲人太多了。

      1. 你的评论邮件回复是什么插件,我找了几个,用AI也写了,但是显示发件人是“X”,还方便告诉 我你的是什么插件,1233@163.com

        1. 水拍石

          这不是插件,是直接写到主题里的,我把相关的php发邮件给你。你也可以这样,所有功能都尽量让AI给写到主题里,后台的绝对不在前台调用js等,这样效率很高,还安全。

          1. 我现在用的主题,我也是让AI把评论回复邮件通知集成到主题里的,但是也是会出现发件人是“X”这个情况,后来找了两款插件测试下,怎么发现也是X。。你要方便就把代码发给我,1233@163.com

            1. 水拍石

              已经发了,请查收。

                1. 水拍石

                  张老师客气了

            2. 水拍石

              友情提示下,如果用国产模型的话,我觉得还是GLM5.1比较好用,写模板和插件准确率确实高很多。

  4. WordPress 的垃圾评论太烦人了,又怕正常的评论误判为垃圾评论。
    bug 扫描我不知道,从来没看过日志啥的。
    可能是个小站,没人在意。

    1. 水拍石

      垃圾评论很难杜绝,感觉有些就是人工发的。
      扫bug和后台的人也很多,都不知道图什么。你的应该也被扫过,只是你没有关注而已。

  5. 我记得有个插件可以将后台地址修改,修改后机器人应该就扫描不了吧。
    WPS隐藏登录
    插件好像是这个名字

    1. 水拍石

      纯代码也能实现,隐藏登陆地址和我加的Basic Auth密码使用体验差不多,但Basic Auth密码更安全。隐藏了登陆地址就需要设置一个比较复杂的新地址,人要记这个新地址;在使用浏览器记忆的情况下,无论是那种方式都是浏览器记忆,所以对人的友好程度差不多。但从防守强度上来看Basic Auth要强很多,同时还能保护/wp-admin/目录,这个目录也会经常被扫。

  6. 确实不理解这些人攻击个人博客的意义,毫无性价比

    1. 水拍石

      就是闲的,损人不利己,即使攻克了也很难勒索到钱。

  7. 虽然麻烦了点儿,但是安全,自己心里也安心

    1. 水拍石

      安全性是大大提高了,按照豆包的说法,采用20位随机字符串密码理论上是不可能被破解的。

  8. 二次验证麻烦点,不过安全。也可以其他安全插件

    1. 水拍石

      确实变麻烦了,多了一次账户和密码输入。

  9. 其实最简单的办法是换系统,我看拾风都从WP换到了Typecho,最近还和我一样买了满心的主题,WP太热门了,再怎么防总有漏洞,问题层出不穷。之前我用WP的时候已经做得还行了,但是这世界通用的热门系统,全世界闲的人太多了,咱都成了很多没事干的练手网站了。自从换到国内的TY,啥都不放都没啥攻击。现在WP转TY也很简单,TY我这几年使用下来,生态体系都还不错,写插件啥的也很轻松。

    1. 水拍石

      就和安卓系统一样,太热门被攻击的可能性就大。我现在还不想换系统,WP用熟了,现在速度优化方面也学会了点,主题模板也刚做,所以先这么用着。

      1. 嗯嗯,先玩着。反正从WP到TP一下真的爽了太多了哈,节省了超级多的时间精力去做运维,但是转换还是需要点时间,尤其咱这年龄,去适应新系统多少还是有些不适。

        1. 水拍石

          你学习能力强,我看你的三股水已经用上了,也没有任何BUG。

          1. 我还是懒是个贪图享乐的人,打心底里还是不愿意折腾不愿意去学习,对自己还是不够狠或者说狠的不彻底,逼着去学习,不然真的少很多机会,逼着去折腾,但还好,慢慢适应这种强行调整的状态,估计后续坚持坚持就成为常态了。

            1. 水拍石

              你太谦虚了,这些年你一直再折腾新东西,不断地在改变,学习能力杠杠的。我觉得学习能力强是你性格优点的重要部分,另一个是韧性好,且自我调整能力很强。你一直是我学习的榜样,但我这两年真的躺平了。

  10. 我也有过被攻击扫描的经历,后来直接选择用 wordpress.com 的托管服务。让他们攻击去吧。

    1. 水拍石

      这样最安心,托管后他们有能耐就去攻击吧。但现在这种小鸡扛不住,稍微一攻击服务器就超负荷。

  11. 改后台地址、加验证,基本上够用了,我现在CDN没有提示,基本上不会去看日志,懒得去折腾了。

    1. 水拍石

      按道理说足够用了,wordpress更新这么及时,安全性应该是不错的。

  12. 我是设置了一个超级复杂的密码,放在微信收藏里面。

    1. 水拍石

      我怕他们有什么高深技术,密码被破解,所以又加了一道门。

  13. WP的后台地址和一些路径都比较熟知,很容易就会被别人扫描。我是直接将通用的后台地址禁止了,只有我指定的地址才能访问,减少不必要登录尝试。

    1. 水拍石

      也是一个方法,以前我也用过,但这次想一劳永逸的解决了,所以来了个双保险。

  14. 我也碰到过,挺烦的。我是懒得去处理

    1. 水拍石

      不处理我担心哪天真的被攻陷了,所以还是处理了下。

  15. 我这里访问貌似一切正常。

    1. 水拍石

      看来真可能和S的IP有关,但文章页正常就比较奇怪了。

  16. S

    为什么主页已暂停访问,被太多人爆破吗?
    「抱歉!该站点已经被管理员停止运行,请联系管理员了解详情!」

    1. 水拍石

      我自己测试是正常的,如果你那边过一个小时还不能恢复的话,我就检查下是那出了问题。如果能恢复的话就是限流策略太严了,放宽限流策略应该就好了。

      1. S

        跟一个小时应该没关系,已经几星期了。而且是换了好几个位置设备和ip。

        1. 水拍石

          那我排查下,首页没有走CDN,只有W3缓存,而W3缓存首页刷新的很及时。前段时间是停止了网站升级了下服务器环境,但按道理「抱歉!该站点已经被管理员停止运行,请联系管理员了解详情!」应该不会缓存到现在,页面的浏览器缓存我设置了2分钟。

          1. S

            好的。其实倒也没啥关系,反正主页一般人也不怎么去,更新文章在rss都能看。
            就是不能访问有点影响我的强迫症,哈哈哈!

            1. 水拍石

              我慢慢排查,现在就是想不到那里会出问题。

              1. S

                “只有主页显示‘站点已停止’,其他页面都正常”这个现象非常特殊,因为它直接指向了问题的根源——**这并不是一次全局性的服务器故障,而是WordPress的前端“首页”请求被单独拦截或错误配置了。**

                这个现象通常意味着网站的后台管理、数据库连接、主题和大部分插件功能都是正常的,问题大概率出在**WordPress的首页设置、重定向规则或安全插件**上。

                我为你整理了5个最有效的排查步骤,建议按照下面的顺序操作:

                ### 第一步:检查WordPress后台的“首页”设置(最常见原因)

                这是最符合你描述的场景。很有可能,你或某个插件将站点的“主页”设置成了一个**已被删除、设为私密或密码保护的页面**。

                1. **登录WordPress后台**,进入 **设置 → 阅读**。
                2. 查看 **“您的主页显示”** 这一项:
                * 如果选择了 **“一个静态页面”** ,检查“主页”下拉菜单里选中的页面是否存在且状态为“已发布”。如果不存在,或者是一个无法公开访问的页面(如受密码保护),那么前台就会报错。
                * **解决方法**:你可以临时将它改为 **“您的最新文章”** ,然后保存。保存后立刻去访问主页看看是否恢复了正常。如果恢复,再去重新设置一个正确的静态页面即可。

                ### 第二步:检查是否有安全插件拦截了首页请求

                一些WordPress安全插件(如 `All In One WP Security`、`Wordfence`、`WP Cerber` 等)或主机自带的防火墙,可能设置了“阻止恶意访问首页”的规则,但误伤了你。

                * 可以暂时**停用所有插件**(操作方法和之前提到的FTP重命名`plugins`文件夹一样)。
                * 停用后如果主页恢复,再**逐个激活**插件来找出是哪一个在拦截。找到后,进入该插件的“防火墙”或“访问限制”设置里,查看是否有相关规则。

                ### 第三步:检查URL重定向冲突(特别是HTTPS混用)

                重复或错误的强制跳转规则,有时也会导致服务器对首页请求做出混乱反应。这个问题通常来自**`.htaccess`文件**或**重定向插件**。

                * **刷新固定链接**:登录后台,进入 **设置 → 固定链接**,直接点击 **“保存更改”** 按钮。不要修改任何设置,只需点击一次。这会刷新WordPress的URL重写规则。
                * **检查WordPress地址**:进入 **设置 → 常规**,确保 **“WordPress地址(URL)”** 和 **“站点地址(URL)”** 完全一致,并且协议(`http://` 还是 `https://`)正确。
                * **检查.htaccess文件**:如果刷新固定链接没用,需要通过FTP或主机文件管理器,找到网站根目录下的 `.htaccess` 文件,将其**重命名为 `.htaccess_old`**,然后去后台**再次保存一次“固定链接”**。这会生成一个全新的默认规则文件,可以排除旧规则中的冲突。

                ### 第四步:检查父主题文件(如果你在使用子主题)

                这是一个不太常见但值得检查的情况。如果你使用的是**子主题**,且当前激活的是子主题,但父主题的主题文件(`functions.php` 或 `template-loader.php`)里可能通过代码(如 `is_home()` 判断句)指定了有问题的首页加载逻辑。

                * **临时切换主题**:在后台的 **外观 → 主题** 里,临时切换到WordPress默认的`Twenty Twenty-Four`等主题,然后访问主页。
                * 如果默认主题下主页正常,说明问题确实在之前的主题文件里。

                ### 第五步:检查PHP错误日志

                如果以上所有方法都无效,那么问题可能隐藏得更深。WordPress可能因为某个仅在主页调用的函数出错,但错误被服务器吞掉了,只显示了管理员设置的友好报错。

                * **开启WordPress调试模式**:通过FTP找到 `wp-config.php` 文件,在 `define(‘WP_DEBUG’, false);` 这行代码**之前**,添加以下几行代码:
                “`php
                define(‘WP_DEBUG’, true);
                define(‘WP_DEBUG_LOG’, true);
                define(‘WP_DEBUG_DISPLAY’, false);
                “`
                * **查看错误日志**:保存文件后,再次访问主页,然后回到FTP,查看 `wp-content` 文件夹下是否生成了一个 `debug.log` 文件。打开它,里面的信息会直接指向问题根源。

                总的来说,**“设置-阅读”中的静态页面出错**是导致这种特殊现象可能性最高的原因,可以优先检查。排查的核心思路就是利用其他页面正常这一特点,排除全局故障,集中检查只作用于“首页”的特定设置。

                如果以上步骤操作后仍无法解决,可以把排查到的情况(比如后台设置了什么,或者debug.log里有没有内容)告诉我,我再帮你看看~

                1. 水拍石

                  感谢大佬给的教程,我看了一遍,好像这些都不是。我自己浏览首页正常,在线测试工具中首页也能加载出来,所以你加载不出来大概率和IP段有关系,但如果是IP被拦截的话,你应该连文章页都打不开。我继续测试下,看问题到底出在那。