例行安全检测 — 加固WordPress

因为我正在使用 cloudflare 提供的内网穿透服务, 相当于整个服务器只对外开放了 Web 服务, 所以我基本是围绕 Web 服务在加固. 如果读者的 wordpress 跑在租用的 VPS 上, 极有可能同时开放了数据库、SSH、FTP 服务, 对这些的防护不在本文讨论范围内.

本文主要是参考了这篇官方教程. 如果你英文好的话, 不妨自己读一读这篇教程, 写的很详细, 基本每一个改动都有解释.

检测手段

https://github.com/wpscanteam/wpscan

下载 wpscan, 然后在终端敲入

wpscan --url https://example.com

可能需要关闭 CF 防火墙.

删除无关文件

cd /www/wordpress

# 删除根目录下无关文件
rm readme.html
rm license.txt

# 递归删除插件、主题 Readme
find . -name readme.txt -type f -print -exec rm -rf {} \;

检查用户权限

关于用户权限说明, 请跳转至 wordpress 官方教程

默认情况下, 目录权限应当是 755 (drwxr-xr-x), 文件权限 644 (-rw-r–r–), 由一个专门的非管理员帐户管理 (通常是www).

要更改权限, 请使用以下命令:

# 对于目录
find /path/to/your/wordpress/install/ -type d -exec chmod 755 {} \; 

# 对于文件
find /path/to/your/wordpress/install/ -type f -exec chmod 644 {} \; 

保护 wordpress 文件

所谓的保护 wordpress 文件, 并不是防止访客访问这些文件, 而是防止出内鬼. ( PHP 脚本 ) 访客在访问这些文件时要么是 403 要么就是空白, 而网站内的 PHP 脚本则可能有权限读取并修改它们.

下述的 .htaccess 只存在于使用 Apache 提供服务的服务器中. 如果你是使用 Nginx 或者其他软件, 下述教程并不适合你.

保护 wp-includes

wp-includes 的概念类似头文件, 属于 include-only, 这一整个文件夹的内容都不应该被修改. 为了防止恶意插件或者恶意主题搞破坏, 可以在 .htaccess 中添加如下几行:

# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

注意把上述内容添加在 BEGIN...END... 之外, 不然可能遭到复写.

保护 wp-config.php

在 .htaccess 文件的开头添加如下内容:

<files wp-config.php>
order allow,deny
deny from all
</files>

关闭编辑文件功能

我因为可以使用 ftp、vscode 远程编辑, 并没有怎么在意过 wordpress 自带的 「主题编辑器」和「插件编辑器」, 所以关掉也无所谓. 如果你对这些功能重度依赖, 我并不推荐关闭: 因为这项设置是防止已经获得后台访问权限的黑客乱改文件, 而都能进入后台的黑客估计也不是非要通过图形编辑器来干掉你的网站.

要关闭这项功能, 在 wp-config.php 中加入

define('DISALLOW_FILE_EDIT', true);

这个设置并没有关掉插件对文件的写入权限, 所以插件应该都还能正常工作.

保护 wp-login.php

被 Cloudflare 防火墙挡下来一大部分攻击都是针对 wp-login.php

所谓的攻击, 大多数都是在暴力枚举密码, 比如说 admin/123456 这样子.
当然我不怕这样的攻击, 首先我的用户名就不是 admin, 其次我有自信自己的密码在互联网上是独一无二的 ( cat /proc/sys/kernel/random/uuid ). 只不过烦倒是蛮烦的, 带宽本身就有限还要和这群工具小子打交道?

解决方案就是编辑 .htaccess , 添加访问口令.

通过直接编辑 .htaccess

  1. 狂戳这个链接, 根据 apache 版本生成 .htpasswd 文件.
  2. 它会生成一个字符串. 在网站根目录创建一个 .htpasswd 文件站贴进去.
  3. 在 .htaccess 中添加如下内容 (仍然在 BEGIN 和 END 之外)
# Stop Apache from serving .ht* files
<Files ~ "^\.ht">
  Order allow,deny
  Deny from all
</Files>
# Protect wp-login.php
<Files wp-login.php>
  AuthUserFile [path]/.htpasswd
  AuthName "Private access"
  AuthType Basic
require user [username]
</Files>

注意修改框出来的内容, [path] 填网站根目录绝对路径, [username] 填认证的用户名.

这样就 OK. 这样子如果不通过验证, 访问 wp-login.php 就显示访问权限错误.
另外, 那个 .htpasswd 文件是允许多行的, 一行对应一个用户, 就这个样子.

阻止垃圾留言

点击提交留言的按钮, WordPress 会跳转到 wp-comments-post.php 来提交留言. 但是直接 POST 到这个地址也可以提交留言. (机器人) 但是直接 POST 没有 referrer, 下面这个方法可以阻挡没有 referrer 的 POST 操作.

# Stop spam attack logins and comments
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{REQUEST_METHOD} POST
	RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
	RewriteCond %{HTTP_REFERER} !.*[example.com].* [OR]
	RewriteCond %{HTTP_USER_AGENT} ^$
	RewriteRule (.*) http://%{REMOTE_ADDR}/$1 [R=301,L]
</ifModule>

同样, 替换 [example.com] 为实际网址.

做完了之后不要忘记开隐私模式测试一下.

7 月 29 日 补充:

以上的操作 (密码保护 wp-admin 和阻止垃圾留言) 有奇效. 自从发布这篇文章到今天, Jetpack 检查到的垃圾留言和暴力登陆只新增了区区几例.

《例行安全检测 — 加固WordPress》上有1条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注