一直有外贸 Soho 抱怨 WordPress 的安全性不够高,自己辛辛苦苦建立的英文网站被黑客黑了。由于 WordPress 是个非常流行的开源的建站程序,所以全球研究 WordPress 的人也不少,也有很多黑客就盯上了 WordPress。
但是,我们不该责怪 WordPress,它本身并没有错。通常都是我们所做的防范措施太少,太过疏忽大意,导致黑客轻松就侵入。作为一个具有多年 WP 使用经验的用户,在此分享一些我个人的建议和措施,希望能帮助大家尽可能地有效防范黑客的破坏行为。
锁掉登录页面防范暴力攻击
每个用过 WordPress 的用户都知道 WP 的标准后台登录页面为 /wp-admin/
以及 /wp-login.php
。
你想象过没有你的登录页面每天正经历多少次的黑客攻击软件的扫描?我推荐你要做的第一件事就是更换后台登录页面的地址,这也是我一直在做的。
关于后台登录页面,建议如下:
1)对多次错误登录的行为进行监控和禁止
很多暴力破解的攻击手段都是不停的更换密码来尝试登录进 WP 后台。
我建议安装插件:Login LockDown,它在这方面的安全性做得很不错。如果某个访问者尝试不同的密码错误次数超过设定值,那么该 IP 会被记录,并且 IP 被拦截,禁止访问网站。
注意:SiteGround 安装 WordPress 时,如果安装了这个 Loginizer,就不用再安装 Login LockDown 了。
2)用户名也稍微复杂点
在你安装 WP 的过程中,有一步是要设置网站的管理员名称和密码。你可能会随便用个管理员名字,例如 sam, andy, 之类。你要知道,登录 WP 后台默认是用 username 来登录,显然这样简单的名字并不够安全。有些不够安全的主题,通过在域名后面加上 /?author=1 来访问的方式,会暴露 WordPress 的后台登录用户名。
而且有的建站者可能用户名起的跟域名又有某种联系,甚至用一些常见的 admin 来作为用户名,使得黑客很容易就能猜测并暴力尝试,这显然是很不安全的。
你可以从 PhpMyAdmin 里进入数据库里,修改用户名,别太简单。PhpMyAdmin 在虚拟主机 Cpanel 的 Database 模块中可以找到。
VPS 访问 PhpMyAdmin 的话,一般是 http://ipaddress/phpmyadmin/
3)改掉登录页面的 URL
黑客们会用暴力猜测数据库工具来扫描你的登录页面。这种工具会将他们数据库中存放的数百万的猜测的用户名和密码组合进行暴力倾泻,如果有命中的,那么你的 WordPress 就被侵入了。为了安全起见,我们改成一个特别并安全的 URL 地址吧。
分两种方法:一种是安装插件,一种不安装插件,添加功能代码。安装插件的方式容易引起兼容性问题,所以我比较喜欢加代码的方式。
手动加入代码
将你的 WP 主题(如果是带有子主题的,在子主题里)文件夹里面的 functions.php 文件下载到本地,注意先备份一份。
用文本编辑器 notepad++ 打开 functions.php,在最底下,粘贴以下代码
//保护后台登录 add_action('login_enqueue_scripts','login_protection'); function login_protection(){ if(($_GET['admin'] != 'whoareyou') || ($_GET['password'] != 'iamnobody'))header('Location: https://www.google.com'); }
然后保存并上传到空间将老的 functions.php 替换。从现在开始,想要登录后台,所有人必须都通过访问
https://www.xx.com/wp-login.php?admin=whoareyou&password=iamnobody
这个唯一的 URL 页面地址来访问你的网站后台了。即:
在原来的 wp-login.php 的后面多加了两个变量 admin 和 password,这两个变量和变量值组合构成唯一的一个页面 URL。
相当于别人想找到你府邸的大门,就要先找到我们设置的一道隐形的外门,这道隐形外门是通往府邸大门的唯一入口。想要进入,必须正确输入这道隐形外门的地址。(呵呵,是不是有点修真小说的感觉?)
如果 URL 输入错误,就会跳转到谷歌首页。注意:以上代码内的 admin 和 password 不要写你登录的账号和密码
本来我想做个 js 死循环不断弹窗的网页,但是一想万一我自己不小心输错转到这个页面不是惨了。
所以害怕自己输错的朋友,记得把这个地址收藏到收藏栏里。
安装插件的方式
相比较手动加入代码的方式,安装插件更适合动手能力差一些的 WP 用户。搜索插件 WPS Hide Login,安装,启用,然后自定义设置一个新的后台登陆地址链接。
设置完以后,到后台的 Settings(设置)- Permalinks(固定链接)那里,重新点一下保存更改的按钮,其它什么都不用改。
4)用个强力一点的密码
建议 数字+大写+小写+符号 的组合。有些人可能怕自己密码多了不好记,你可以借助一些密码工具来记录,或者使用石墨文档,印象笔记或有道云笔记来记录。
这里附上测试你密码强度的两个网站:
http://www.passwordmeter.com/ 注意:把这个网站 Addtions 部分每一项都点亮成蓝色。
https://password.kaspersky.com/ 建议安全级别达到 Centuries 级别。
不要使用组合规则。如果您习惯使用某种组合方式创建密码,例如“网站名称”+“年”,或者“公司网站域名”+“年份”,以后停止用这样的组合。
一旦攻击者使用的工具匹配到这样到方式,破解密码将非常容易。
WP 用户密码 和 数据库用户密码 最好分开设置成不一样的密码。
安装 WordPress 时不要用默认的 wp_ 前缀
这个在之前的安装 WordPress 的教程里( https://www.liaosam.com/guide-for-wordpress-newbees.html )讲过了,这里就不重复了。回顾一下看看截图吧:
如果你已经安装过了,想修改前缀,可以使用 WP-DBManager 插件即可修改 WordPress 数据表前缀。修改之后你可以再删除插件。
定期备份网站
关于备份数据库,你可以使用 WP Database Backup 插件来定期备份数据库。如果想要备份整个网站,那么推荐使用 BackUpWordPress 或 Duplicator 插件,它基本上可以把网站文件和数据库都备份好。
关于 BackUpWordPress,请参考这篇文章:BackUpWordPress 插件定时备份你的整个网站
如果你用的是 VPS,如 Linode,那么我建议你还可以考虑开通 BackUp 服务,每个月 2.5 美金,定期备份整个磁盘,生成快照。
不要嫌贵,如果你整个网站文件和数据库被删除,你就知道整盘备份这功能是多么重要了。
阻止文件目录浏览(Directory Browse)
大部分的虚拟主机对于文件目录浏览的权限都是开放的,这并不安全。
浏览者可以看到你目录里有哪些文件,文件名称是什么。如下图所示:
显然这是相当不安全的。一般是由于当前目录下没有主页文件引起的。有两种解决办法:
- 每个文件目录下放一个空的 index.html 或 index.php 文件
- 修改 .htaccess 配置文件不显示文件目录
- 使用虚拟主机的 Cpanel 里的索引管理器(Cpanle - Advances 下的 Index Manager)
前一种方式操作很简单,就是稍微有点麻烦,我们用第二种或者第三种方法。
先说第 2 种方法):如果你使用的是虚拟主机,并且安装了 Yoast SEO 插件,那么可以在 Yoast SEO 插件设置那里直接编辑 .htaccess 文件,加上以下代码即可关闭文件目录浏览:
Options All -Indexes
CTRL+F5 是彻底刷新(删除缓存后重新从服务器获取页面)
另外,除了在 Yoast SEO 插件中编辑 .htaccess 文件这种方式,你也可以用 SiteGround 或 Bluehost 后台的 Cpanel 里的 File Manager(文件管理器)。
点击 public_html 找到你的网站目录,在当前页面的 URL 后面加上 &showhidden=1 就可以自动显示隐藏文件。在网站根目录下找 .htaccess 文件。
找到以后,在文件上点击右键,选择菜单中的 "Code Edit"。
会出现一个对话框,只需点击“编辑”按钮继续,编辑器将在新窗口中打开。复制如下的代码:
Options All -Indexes
编辑完成后,点击右上角的“ save ”按钮。
在原本显示文件目录的页面按 Ctrl + F5,强制刷新生效。生效后我们看,文件目录下原本暴露文件目录的情况已经得到解决。网站返回 403 拒绝访问。
这代表我们已经成功设置好了!
再说说第三种办法)直接用 SiteGround 后台的 Cpanel 的 Advances(高级)下的 Index Manager 来设置哪个目录不显示文件索引。
直接上图说吧:
隐藏 config.php
WordPress 根目录下的 wp-config.php 文件中记录了我们的 wordpress 使用的 mysql 数据库表名、用户、以及明文的密码!
// ** MySQL 设置 ** // /** WordPress 数据库的名称 */ define('DB_NAME', 'xxxxxxxxxxxxxxxxxxxx'); /** MySQL 数据库用户名 */ define('DB_USER', 'xxxxxxxxxxxxxxxxxxxx'); /** MySQL 数据库密码 */ define('DB_PASSWORD', 'xxxxxxx 明文的密码 xxxxxxxx'); /** MySQL 主机 */ define('DB_HOST', 'localhost'); /** 创建数据表时默认的文字编码 */ define('DB_CHARSET', 'utf8'); /** 数据库整理类型。如不确定请勿更改 */ define('DB_COLLATE', '');
如果不加限制,wp-config.php 很容易就被黑客获取了。比如,各类黑客工具之中的网络爬虫程序,有些爬虫程序抓一些特定的 php 文件真是小菜一碟。看看下面的截图:
未加保护的 wp-config.php 文件,被网络爬虫抓取到了
所以,我们必须把 wp-config.php 文件保护起来,如何保护呢?我们需要修改 .htaccess 文件。
同上文,直接编辑 .htaccess 文件,加上以下代码:
<files wp-config.php> order allow,deny deny from all; </files>
这样一来,就阻止了各类恶意网络爬虫抓取文件。
阻止上传文件夹内的任何 php 文件执行
通常你被黑之后都能在 wp-content/uploads/ 文件夹下发现一个可疑的 php 文件,这是黑客上传的控制文件,我们要关闭访问任何 .php 文件的权限。
在网站根目录的 .htaccess 文件中添加代码。代码如下:
RewriteEngine on RewriteCond % !^$ RewriteRule uploads/(.).(php)$ – [F]
注意:代码写在 <IfModule mod_rewrite.c> </IfModule> 内。
OK,结合上面的一些我们需要添加到 .htaccess 文件中的代码,完整的添加代码有 3 处,截图如下:
记得点保存,然后在网站首页按 ctrl+F5 强制刷新生效。
我们来测试一下,我们上传一个 test.php 文件,此文件内我们写入 <?php echo phpinfo(); ?> ,此函数会显示 php 服务器信息。然后我们来访问看看:
没有添加截图 2 的代码时,显示了主机的详细信息:
稍微懂点 php 的人都知道,这个信息是黑客/攻击者最想获取的服务器信息,里面记录各种配置参数、路径、版本等等。黑客有了这个信息,简直如虎添翼!
我们添加截图中代码 2 以后,再访问此 php 文件,显示 403 不允许访问,拒绝访问一切 php 文件!
至此,你已经成功地配置了防御措施。
如果你是 VPS LNMP 环境的话,需要在虚拟主机配置文件 conf 中定义 ( 路径:/usr/local/nginx/conf/vhost/www.abc.com.conf ) 。添加在 Server 段:
location /wp-content/uploads/ { location ~ .*.(php)?$ { deny all; } }
记得重启 nginx。使用命令 /etc/init.d/php-fpm restart
不用来历不明的免费主题和插件
当年为了能免费使用 themeforest 上的那些高大上的英文主题,我在百度里搜索,在国内一些主题免费下载站下载了一些国外主题。
一开始不知道,后来偶然才发现这些英文主题里 functions.php 文件里竟然有一些伪装得很好的恶意代码,可以让人获得 uploads 文件夹的权限,我 TM 吓出一身冷汗~ 从此再也不用这些下载站的主题。
不管是免费还是付费的主题和插件,都尽量通过 WP 官方或者后台去获取安装。
另外,不怎么用的插件,可以及时取消启用或删除,避免留下任何漏洞。
如果你是 VPS,想办法改掉默认的 SSH 端口号
修改办法,参考这篇文章:https://www.liaosam.com/linode-ssh-cannot-connect.html
使用 SSL 加密数据
用 SSL(安全套接层协议)证书不只是为了浏览器地址栏上那个绿色的小锁,更是为了安全。并且 SSL 证书也会影响 Google 对你网站的信任度。Google 对没有启用 SSL 的网站都认为安全级别不够高,所以不久的将来 https 协议肯定会逐渐取代 http。
SSL 可以确保用户浏览器和服务器之间的安全数据传输,使黑客很难破坏连接信息。获取 SSL 证书不是问题,一些虚拟主机商如 SiteGround 是免费提供 SSL 证书。
如果你是 VPS,应该 LNMP 一件安装包已经集成了 SSL 证书安装步骤,免费的 Let's Encrpyt 证书,自动续期。
本站所有文章除注明“转载”的文章之外,均为原创。未经本站允许,请勿随意转载或用作任何商业用途,否则依法追究侵权者法律责任的权利。
Sam 老师,有个问题要请教下:
四、阻止文件目录浏览(Directory Browse)
五、隐藏 config.php
六、阻止上传文件夹内的任何 php 文件执行
如果你是 VPS LNMP 环境的话,需要在虚拟主机配置文件 conf 中定义 ( 路径:/usr/local/nginx/conf/vhost/www.abc.com.conf ) 。添加在 Server 段:
location /wp-content/uploads/ {
location ~ .*.(php)?$ {
deny all;
}
}
记得重启 nginx。使用命令 /etc/init.d/php-fpm restart
问: 四、阻止文件目录浏览(Directory Browse)和 五、隐藏 config.php 两部分都没提到 VPS 的操作,只有 六、阻止上传文件夹内的任何 php 文件执行 提到 VPS LNMP。
请问是四和五两部分 在 VPS LNMP 环境下都不用操作,而只有六需要操作吗?
顺便问一下,LNMP 环境下 WP 根目录下并没有找到.htaccess 文件。Yoast SEO 插件 tools -- File Editor 选项里也没看到.htaccess 文件。
您另一篇文章里提到 SEO Press 这个插件,和 Yoast SEO 相比,这两个插件,请问您现在推荐用哪个?
location / {
autoindex on;
}
五、VPS 无需操作
其它问题:.htaccess 文件只有虚拟主机有,Nginx 系统里控制访问规则的主要是 conf 文件。
SEO Press 这个插件,和 Yoast SEO 相比 —— SEO Press。
@料神Sam 好的,收到。我想把下面这个代码添加的位置也跟其他小伙伴补充一下,免得有一样的小白不知道该怎么操作:
六、阻止上传文件夹内的任何 php 文件执行
文章里代码也添加到网站 .conf 文件里 443 server 段。
料神,RewriteEngine on RewriteCond % !^$
RewriteRule uploads/(.).(php)$ – [F] 这个没有星号,你文章中截图有星号。那个是对的?
sam,您好!1、请问如何通过 phpMyAdmin 来访问数据库呢?在 google 浏览器中,我按照您的方法 https://你的 Linode IP/phpmyadmin 进去网站后,显示“您的连接不是私密连接”没有办法进去。应该是我设置了安全证书。那这种情况下,我应该如何来进入我的数据来修改用户名呢。谢谢!
2、我是 linode VPS 搭建的网站,如何知道 wp-config.php 文件已经被隐藏起来了。我只在虚拟主机配置文件 conf 中定义 ( 路径:/usr/local/nginx/conf/vhost/www.abc.com.conf ) 了。
@Liaosam Sam 大哥,我也遇到同样的问题,linode 的 IP 设置跳转到域名之后,无法通过 https://你的 Linode IP/phpmyadmin 这个网址访问 phpmyadmin 。(显示“您的连接不是私密连接”没有办法进去)
我的 phpmyadmin 路径是/home/wwwroot/default/phpmyadmin
网站路径是 /home/wwwroot/www.abc.com
Sam 老师您好,最近我在后台修改 page 后点 SAVE 都没有反应,就连右上角的 X 关闭窗口都没反应,是不是说明我的网站已经被黑了?
Sam,您好。如果通过 phpMyAdmin 来访问数据库呢?有没有相关的操作步骤。谢谢!
function.php 改后,abc.com/wp-admin 也能访问后台,怎么改才能 abc.com/wp-admin 访问不了。
@fui 你是不是没有退出当前登录呀?
阻止上传文件夹内的任何 php 文件执行
SAM,你好,根据你的方法更改了.htaccess 文件,
把 RewriteEngine on RewriteCond % !^$
RewriteRule uploads/(.).(php)$ – [F]写在 内
然后上传了 TEST.PHP 文件到 UPloads 下,仍可以执行这个 php 文件。
你好,Sam,
按照你的教程,改了登录 URL,但是我输入 http://www.mysite.com/wp-admin 的时候还是可以出现登录窗口,只不过上面会出现【Warning: Cannot modify header information - headers already sent by (output started at /home1/mysitec/public_html/wp-login.php:62) in /home1/mysitec/public_html/wp-content/themes/Avada/functions.php on line 1569】,通过重设的 URL 就不会出现这个,很疑惑为什么通过 wp-admin 还是会出现登录窗口,也可以登录,浏览器也清除缓存了也没用,不知道哪里出现问题了
@grant 我的也出现这种情况,还望料神老师回复下指点下。
Hi Sam, 您好!
加强网络安全做到第三步,改掉登录的 URL,如果按主题目录下 wp-content/themes 是找不到 funtions-php 文件的; 而打开 wp-admin 发现目录下有 admin-funtions-php, 还有 update-funtions-php, 这个位置对不对呢?那么我应该以那个来下载和修改呢?
麻烦指导一下。
谢谢!
为了安全,安装了这个插件以后,最好把用户名修改得复杂一些。通过 phpMyAdmin 来访问数据库,找到数据表 users 表并修改登录用户名 user_login。
这样,以后你就用 email 地址登录即可。至于复杂的用户名,用不到它。
万一以后要写 blog,到时候在后台 users 里面设置一个合适的英文昵称即可。
@Liaosam 谢谢指导。可否详细告知路径,小白扣谢!
@Liaosam Hi Sam, 麻烦看看这个界面去改用户名和密码,对吗?
Global
数据库
修改密码
登录信息
Edit Privileges: 用户 'root'@'127.0.0.1'
修改登录信息/复制用户
登录信息
User name:
An account already exists with the same username but possibly a different hostname.
Host:
密码:
重新输入:
生成密码:
谢谢!
@涛声依旧在 该评论为私密评论
@Liaosam 用的是 Linode VPS, 按照你说的路径,http://你的 Linode IP/phpmyadmin 进去的,现在看到左边列表,然后我点 Users 进去,将 User_login 原来的使用名改为邮箱地址就可以了,是吗?
有一行是 User_nicename, 需不需要改呢?
还有最后一行 display_name, 将原来使用名删掉留空就可以,还是要填什么呢?
谢谢!
@涛声依旧在 该评论为私密评论
@Liaosam 该评论为私密评论
@L1i2a3o4s5a6m7 昨天在等您回复怎么操作下去,应该没有弄其他并将插件取消启用,现在后台进不去,也看不到是否有不小心点到!
刚用更改的复杂的用户名登录,也登录不进去了!现在怎么办?要改回去吗?
大神,我的 wordpress 被黑了, 每次更改完密码过一段时间 用户名 username 就会变成 indoxploit(不可更改) (我也不知道这是啥,用英文查了下 好像有几个一样的问题 同时也是个印尼的 coder 组织名) 同时密码会被更改, 然后我可以用邮箱找回, 找回后删除被改过的用户正常使用, 网站其他地方看不出被改了啥。感觉是被安装了后台或者恶意插件 ,求助 不知道该如何解决
@dan 我也出现同样的问题,找不到解决方案。。。
你都装了哪些插件?看看和我有没有共同的
@施阳 我也中招了 请问有解决方案吗?
该评论为私密评论
.htaccess 是虚拟主机范畴下的文件,一般虚拟主机商都使用 apache。而你用的是 VPS,使用的是 nginx,所以就跟 .htaccess 没有关系了,你只要关注 nginx 的配置即可。
对于你说的“重启后还是可以看到很多 PHP 重要信息。”这一点我不太明白,从哪里可以看到很多 PHP 的重要信息?
咨询一下,按照你的教程,一步步部署 VPS 和 WP,原来在 BLUEHOST 上的网站用 DUPLICATOR 备份了,现在想恢复,发现在 WP 中安装让提供 HOST NAME,FTP Username,FTP Password,不知道怎么填了,没有 FTP 啊,是不是就是按你的教程部署中用到的 XSHELL 的 Username 和 PASSWORD?HOST NAME 就是我公司网址?输进去不行,出错,不懂该填什么,求教
@Liaosam 多谢大神,问题解决!!!!
料神,刚提的那个问题已经搞定了,Mac 用的 TextMator 有两种文件格式,一种是多信息文本,functions.php 等必须用纯文本格式,转换成纯文格式后,上传覆盖之前的 functions.php,就可以重新登录了,用 Mac 的小伙伴注意下。
料神,按照更改 URL 的方法把/home/wwwroot/www.xxx.com/wp-content/themes/enfold 下面的 functions.php 加了那段代码,覆盖了原来的 functions.php,然后重启了 php-fpm 后,用 https://www.xxx.com/wp-login.php?admin=whoareyou&password=iamnobody 链接访问进去,结果进不去后台了,用备份的 functions.php 覆盖了之前修改那个,也不行,不知道该如何解决了?
老师,我想问下,为什么我按照你的填写保护 PHP 文件,但出来的是 404 错误,不是 403,这个达到的效果一样吗,
Sam,恶意代码怎么找呢?
@Liaosam 多谢,怎么找出免费主题中 function 文件中的恶意代码呢?有没有某些关键词可以搜到?
@Liaosam 嗯嗯 谢谢
WP 本身就够安全了,相比某 DEDE 分分钟被黑那简直不可同日而语,服务器权限也很重要,.htaccess 是个好东西,可以做的事有很多
sam 哥,如果不是很麻烦的话,您能否抽空下一篇关于怎么在 Linode 安装 SSL 证书的流程呀?技术小白是在是没招了。
有用 谢谢
感谢 Sam 哥分享~