wp 终极优化
wp 终极优化指的是通过使用PHP7.4+Memcached+OPcache+Mysql8+WP-Rocekt+nginx+阿里云cdn+阿里oss+WpJAM_Basic插件
加速网站,提高网站性能。
开发环境搭建
在 Linux 服务器上安装php7+mysql+nginx+memcache+opcache
安装 php7.4.5
- 安装依赖包
yum -y install php-gd php-bcmath php-mbstring php-xml curl curl-devel libcurl-devel net-snmp net-snmp-devel libxml2 \
libxml2-devel openssl-devel ncurses-devel zlib-devel pcre-devel libevent-devel\
gd-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libmcrypt-devel mhash sqlite-devel oniguruma-devel
- 下载并安装 php
wget https://www.php.net/distributions/php-7.4.5.tar.gz
tar -zxvf php-7.4.5.tar.gz
cd php-7.4.5
./buildconf
./configure --prefix=/usr/local/php7 --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-fpm \
--with-fpm-user=nginx --with-fpm-group=nginx \
--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql-sock=/tmp/mysql.sock \
--with-libdir=lib64 --enable-gd --with-jpeg --with-freetype \
--with-zlib=/usr --with-openssl=/usr --with-mhash --enable-bcmath --enable-mbstring \
--enable-xml --enable-opcache --enable-sockets --with-gettext --enable-session --with-curl --enable-ctype
sudo make -j 2 && sudo make install
Memcached 安装
需要安装 memcached 服务端和 php 的 memcached 扩展.
安装 memcached 服务端
sudo yum -y install libevent libevent-devel
wget http://www.memcached.org/files/memcached-1.6.5.tar.gz
tar xzvf memcached-1.6.5.tar.gz
cd memcached-1.6.5
./configure --prefix=/usr/local/memcached
sudo make && sudo make install
sudo ln -s /usr/local/memcached/bin/memcached /usr/bin/memcached
sudo cp ~/src/memcached-server/memcached-1.6.5/memcached.sysv /etc/init.d/memcached
sudo chmod +x /etc/init.d/memcached
sudo service memcached start
sudo chkconfig --add memcached
sudo chkconfig memcached on
安装 php 的 memcached 扩展
- 安装 libmemcached
sudo yum -y install cyrus-sasl-devel
# 让 memcached 支持用户名和密码
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
./configure --with-memcached=/usr/local/memcached --prefix=/usr/local/libmemcached
sudo make && sudo make install
- 安装 php 的 memcached 扩展
sudo yum -y install autoconf cyrus-sasl-devel
wget https://pecl.php.net/get/memcached-3.1.5.tgz
tar -zxvf memcached-3.1.5.tgz
cd memcached-3.1.5
/usr/local/php7/bin/phpize # 改为phpize的实际位置,下面的php-config路径也是
./configure --with-libmemcached-dir=/usr/local/libmemcached --with-php-config=/usr/local/php7/bin/php-config
sudo make && sudo make install
查看是否生效: /usr/local/php7/bin/php -m | grep memcached
下面这段是针对wordpress优化的:
另外利用 Memcached 加速 wp,还需要下载插件,去Memcached下载插件,
下载好后,将此插件放到wp-content
目录.
WARNING
一定要放在此目录,不能放到 plugins 目录,wp 会自动检测此目录有没有 memcached,有则启用。
查看 memcached 的命中率可通过telnet 127.0.0.1 11211
然后输入stats
可查看.
OPcache 配置
在编译 php7 时添加参数--enable-opcache
即可安装 opcache
编辑php.ini
中,添加如下内容:
[Zend Opcache]
zend_extension=opcache.so # 加载opcache扩展文件
opcache.enable=1 # 开启opcache
opcache.memory_consumption=128 # 共享内存的大小, 总共能够存储多少预编译的 PHP 代码(单位:MB),推荐128M(根据服务器内存大小调整)
opcache.interned_strings_buffer=8 # 暂存池中字符串的占内存总量.(单位:MB), 推荐 8
opcache.max_accelerated_files=4000 # 最大缓存的文件数目 200 到 100000 之间,推荐 4000
opcache.revalidate_freq=60 # 默认是2s检查一次文件更新 注意:0是一直检查不是关闭,推荐 60-120
opcache.fast_shutdown=1 # 打开快速关闭, 打开这个在PHP Request Shutdown的时候会收内存的速度会提高
opcache.enable_cli=1
具体可查看 LNMP 的 opcache.sh 脚本。
查看是否安装成功可通过 PHP -V 会有 zend 字样显示及成功
另可通过http://youIP/ocp.php
查看,安装了 opcache 后会有此文件,默认是放在 default 下。
php-fpm 配置
sudo vim /usr/local/php7/etc/php-fpm.d/www.conf
添加如下内容:
user = nginx
group = nginx
pm.max_children = 500
php-fpm初始/空闲/最大worker进程数,根据服务器内存来定,基本上每个进程占20-30m内存,自己按照内存大小计算合理数字。
pm.start_servers = 10
pm.min_spare_servers = 7
pm.max_spare_servers = 10
# 最大处理请求数是指一个php-fpm的worker进程在处理多少个请求后就终止掉,master进程会重新respawn一个新的,这个配置的主要目的是避免php解释器或程序引用的第三方库造成的内存泄露。
pm.max_requests = 3000
最大执行时间在php.ini和php-fpm.conf里都可以配置,配置项分别为max_execution_time和request_terminate_timeout,建议设置300秒。
php-fpm 启动项
sudo vim /etc/init.d/php-fpm
修改如下内容:
#prefix=@prefix@
#exec_prefix=@exec_prefix@
#php_fpm_BIN=@sbindir@/php-fpm
#php_fpm_CONF=@sysconfdir@/php-fpm.conf
#php_fpm_PID=@localstatedir@/run/php-fpm.pid
prefix=/usr/local/php7
php_fpm_BIN=/usr/local/php7/sbin/php-fpm
php_fpm_CONF=/usr/local/php7/etc/php-fpm.conf
php_fpm_PID=/usr/local/php7/var/run/php-fpm.pid
详细的 php-fpm 请参考: PHP-FPM 安装与配置
WARNING
上述 php-fpm 文件也可去PHP-FPM 官方下载地址下载
php-fpm 命令
启动: sudo /usr/local/php-7.3.8/sbin/php-fpm
或者sudo /etc/init.d/php-fpm start
关闭: sudo kill -INT pid(php-fpm master进程号)
重启: sudo kill -USR2 pid(php-fpm master进程号)
或者sudo /etc/init.d/php-fpm restart
DANGER
/etc/init.d/
下自定义脚本全部设置权限 700
- php-fpm 启动报错:
报错信息: NOTICE: PHP message: PHP Warning: PHP Startup: Unable to load dynamic library 'curl.so'
类似的错误大概有 18 个。
解决办法:
将/etc/php.d/*.ini
文件里面的extension=
这一行全部注释即可.
然后用sudo /usr/local/php-7.3.8/bin/php -m
查看加载的模块.
php 7自动化配置脚本
此脚本主要是自动配置 php.ini:
#!/bin/bash
php_install_dir=/usr/local/php7
cp php.ini-production $php_install_dir/etc/php.ini
Mem=`free -m | awk '/Mem:/{print $2}'`
if [ $Mem -gt 1024 -a $Mem -le 1500 ];then
Memory_limit=192
elif [ $Mem -gt 1500 -a $Mem -le 3500 ];then
Memory_limit=256
elif [ $Mem -gt 3500 -a $Mem -le 4500 ];then
Memory_limit=320
elif [ $Mem -gt 4500 ];then
Memory_limit=448
else
Memory_limit=128
fi
sed -i "s@^memory_limit.*@memory_limit = ${Memory_limit}M@" $php_install_dir/etc/php.ini
sed -i 's@^output_buffering =@output_buffering = On\noutput_buffering =@' $php_install_dir/etc/php.ini
sed -i 's@^;cgi.fix_pathinfo.*@cgi.fix_pathinfo=0@' $php_install_dir/etc/php.ini
sed -i 's@^short_open_tag = Off@short_open_tag = On@' $php_install_dir/etc/php.ini
sed -i 's@^expose_php = On@expose_php = Off@' $php_install_dir/etc/php.ini
sed -i 's@^request_order.*@request_order = "CGP"@' $php_install_dir/etc/php.ini
sed -i 's@^;date.timezone.*@date.timezone = Asia/Shanghai@' $php_install_dir/etc/php.ini
sed -i 's@^post_max_size.*@post_max_size = 50M@' $php_install_dir/etc/php.ini
sed -i 's@^upload_max_filesize.*@upload_max_filesize = 50M@' $php_install_dir/etc/php.ini
sed -i 's@^;upload_tmp_dir.*@upload_tmp_dir = /tmp@' $php_install_dir/etc/php.ini
sed -i 's@^max_execution_time.*@max_execution_time = 600@' $php_install_dir/etc/php.ini
sed -i 's@^;realpath_cache_size.*@realpath_cache_size = 2M@' $php_install_dir/etc/php.ini
sed -i 's@^disable_functions.*@disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen@' $php_install_dir/etc/php.ini
sed -i 's@^session.cookie_httponly.*@session.cookie_httponly = 1@' $php_install_dir/etc/php.ini
sed -i 's@^mysqlnd.collect_memory_statistics.*@mysqlnd.collect_memory_statistics = On@' $php_install_dir/etc/php.ini
[ -e /usr/sbin/sendmail ] && sed -i 's@^;sendmail_path.*@sendmail_path = /usr/sbin/sendmail -t -i@' $php_install_dir/etc/php.ini
#如果编译时去掉了 --enable-opcache,则以下包含opcache的都请忽略
sed -i 's@^\[opcache\]@[opcache]\nzend_extension=opcache.so@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.enable=.*@opcache.enable=1@' $php_install_dir/etc/php.ini
sed -i "s@^;opcache.memory_consumption.*@opcache.memory_consumption=$Memory_limit@" $php_install_dir/etc/php.ini
sed -i 's@^;opcache.interned_strings_buffer.*@opcache.interned_strings_buffer=8@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.max_accelerated_files.*@opcache.max_accelerated_files=4000@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.revalidate_freq.*@opcache.revalidate_freq=60@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.save_comments.*@opcache.save_comments=0@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.fast_shutdown.*@opcache.fast_shutdown=1@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.validate_timestamps.*@opcache.validate_timestamps=1@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.enable_cli.*@opcache.enable_cli=1@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.use_cwd.*@opcache.use_cwd=1@' $php_install_dir/etc/php.ini
sed -i 's@^opcache.max_accelerated_files.*@opcache.max_accelerated_files=100000@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.max_wasted_percentage.*@opcache.max_wasted_percentage=5@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.consistency_checks.*@opcache.consistency_checks=0@' $php_install_dir/etc/php.ini
sed -i 's@^;opcache.optimization_level.*@;opcache.optimization_level=0@' $php_install_dir/etc/php.ini
mysql 开启 query cache
show variables like 'have_query_cache'; # 查看mysql版本是否支持查询缓存
show variables like '%query_cache%'; # 查看是否开启了查询缓存
- 开启查询缓存:
在 my.cnf 中[mysqld]
添加:
query_cache_size=128M
query_cache_type=1
然后重启 mysql
安装与配置 nginx
sudo yum install yum-utils
sudo vim /etc/yum.repos.d/nginx.repo
添加:
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
启用 nginx 源
sudo yum-config-manager --enable nginx-mainline
安装 nginx
sudo yum install nginx
开机启动 nginx
systemctl enable nginx
nginx 开机启动
通过上面的操作就自动将 nginx 开机启动了,所以下面的操作可不用执行:
sudo vim /usr/lib/systemd/system/nginx.service
添加:
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
开机启动 nginx: sudo systemctl enable nginx
配置 nginx
下面贴上完整的 nginx.conf 配置文件:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 65535;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
#fastcgi_intercept_errors on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server_tokens off;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include /etc/nginx/conf.d/default.conf;
}
下面的是虚拟主机配置文件内容:
server {
listen 80;
server_name api.echoxu.cn;
rewrite ^/(.*)$ https://api.echoxu.cn/$1 permanent;
}
server {
listen 443 ssl;
server_name api.echoxu.cn;
root /usr/share/nginx/html/iweb;
index index.php index.html index.htm;
ssl_certificate /etc/nginx/ssl/api.echoxu.cn.pem;
ssl_certificate_key /etc/nginx/ssl/api.echoxu.cn.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /usr/share/nginx/logs/Access.log;
error_log /usr/share/nginx/logs/Error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.php$ {
root /usr/share/nginx/html/iweb;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ /\. {
deny all;
}
location ~* \.(sh|docx|txt|doc|php|php5|pl|py|zip|gz|bx|)$ {
deny all;
}
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 30d;
log_not_found off;
}
}
WP-Rocek 安装及配置
先设置固定链接: https://dev.echoxu.cn/%postname%.html
其实都是一些常见的前端优化技巧,如: 压缩图片,合并文件,使用 CDN 等
下面是 wp-rocket3.3.5.2 版本的设置:
相同的插件还有wp-super-cache
,实际使用下来 wp-rocket 的效果更好.
使用 WPJAM_Basic 插件优化
wordpress 使用 cdn 进行静态资源加速
阿里云 OSS 及 CDN 配置
加速 OSS 架构如下图所示:
阿里云对象存储 OSS 配置
操作过程:
1: 开通阿里云对象存储 OSS 服务
2: 去 OSS管理控制台---传输管理---域名管理
绑定一个自定义的域名,注意:此域名需备案,另外此项操作不用设置域名解析.
3: 去 OSS管理控制台---基础设置---镜像回源
添加一个规则,镜像回源指的是当访问 oss 里的文件不存在时就去源网站(你的网站域名)抓取并复制一份然后存储到 oss 存储空间里.
4: 去 OSS管理控制台---权限管理---跨域设置
创建一个规则,允许你的网站进行跨域访问.
5: 去 OSS管理控制台---权限管理---防盗链
添加规则,也可不设置
阿里云 CDN 配置
1: 去 CDN管理控制台---传输管理---域名管理---阿里云 CDN 加速
进行 cdn 加速配置,此操作需设置域名解析.
2: 去 CDN管理控制台---HTTPS配置---HTTPS证书
添加一个 ssl 证书,可申请一个免费的证书,等证书生成后直接点击部署---CDN
即可完成此项操作.
3: 去 CDN管理控制台---回源配置---回源HOST
设置当访问 CDN 不存在的文件时,应该去对象存储 oss 里获取文件,所以此处填写的是对象存储 oss 的域名,可以是阿里云对象存储 oss 提供的域名或者是你给 oss 绑定的域名.
4: 去 CDN管理控制台---回源配置---回源协议
选择协议为HTTPS
验证静态文件是否使用 cdn 进行加速
1: 先通过dig cache.echoxu.cn
验证 oss 使用 cdn 加速是否配置正确,当出现cache.echoxu.cn.w.kunlunca.com
即表示 oss 已经使用 cdn 加速了.
2: 查看 wordpress 网站源码,看静态文件是不是使用 cdn 域名cache.echoxu.cn
进行访问.
wp 常见问题
安装插件时需要提供 ftp 账号信息
这是因为没有访问权限导致的,假如你使用的是 nginx,将你的 wp 主目录的属主设为 nginx 进程启动的用户名,且设置 wp 主目录权限为 755,文件权限为 644
sudo chown -R nginx用户名.root wp主目录
sudo chmod 755 wp主目录
如果还不行请在wp-config.php
添加:
/** 绕过FTP验证*/
define(‘FS_METHOD’, ‘direct’);
define(‘FS_CHMOD_DIR’, 0777);
define(‘FS_CHMOD_FILE’, 0777);
修改主题名
请尽量不要修改此项,做到尊重主题作者.
1: 将下载好的主题文件夹改名为你想好的名称.
2: 修改下载好的主题目录下的style.css
里面的Theme Name
即可.
wp 更换域名
假如你的域名由https://dev.echoxu.cn
改为https://api.echoxu.cn
,请替换下面的域名并在数据库中执行:
UPDATE iweb_options SET option_value = REPLACE(option_value, 'https://dev.echoxu.cn', 'https://api.echoxu.cn') WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE iweb_posts SET post_content = REPLACE (post_content, 'https://dev.echoxu.cn', 'https://api.echoxu.cn');
UPDATE iweb_postmeta SET meta_value = REPLACE (meta_value, 'https://dev.echoxu.cn','https://api.echoxu.cn');
UPDATE iweb_comments SET comment_content = REPLACE (comment_content, 'https://dev.echoxu.cn', 'https://api.echoxu.cn');
UPDATE iweb_comments SET comment_author_url = REPLACE (comment_author_url, 'https://dev.echoxu.cn','https://api.echoxu.cn');
UPDATE iweb_posts SET guid = REPLACE (guid, 'https://dev.echoxu.cn', 'https://api.echoxu.cn') WHERE post_type = 'attachment';
上面的 sql 可通过工具生成,更换域名 sql 生成器
更换数据库前缀
下面的 sql 是将数据库前缀由iweb_
改为isite_
RENAME TABLE iweb_comments TO isite_comments;
RENAME TABLE iweb_commentmeta TO isite_commentmeta;
RENAME TABLE iweb_links TO isite_links;
RENAME TABLE iweb_options TO isite_options;
RENAME TABLE iweb_postmeta TO isite_postmeta;
RENAME TABLE iweb_posts TO isite_posts;
RENAME TABLE iweb_terms TO isite_terms;
RENAME TABLE iweb_termmeta TO isite_termmeta;
RENAME TABLE iweb_term_relationships TO isite_term_relationships;
RENAME TABLE iweb_term_taxonomy TO isite_term_taxonomy;
RENAME TABLE iweb_usermeta TO isite_usermeta;
RENAME TABLE iweb_users TO isite_users;
UPDATE isite_options SET option_name = REPLACE(option_name, 'iweb_', 'isite_') WHERE option_name LIKE 'iweb_%';
UPDATE isite_usermeta SET meta_key = REPLACE(meta_key, 'iweb_', 'isite_') WHERE meta_key LIKE 'iweb_%';
修改 wp 后台 logo
去wp-admin/css/login.min.css
中找到background-image:none,url(../images/wordpress-logo.svg?ver=20131107)
替换为你自定义的 logo 地址即可.
嫌麻烦可以直接替换wp-admin/images/wordpress-logo.svg
为你的 logo,并重命名为wordpress-logo.svg
wp 后台慢
优化如下三项:
- Google 字体
可用 vscode 打开下载好的 wp 文件,然后在 查看
-搜索
然后输入 google
即可找到 wp 中使用 google ajax 和 google fonts 服务的文件路径.在 wp5.4 中只有wp-includes/script-loader.php
使用了 google 服务,可通过 vps 下载好 google ajax 文件,然后将其放在自己的服务器上,最后修改wp-includes/script-loader.php
里的 google 服务为本地路径即可.
Gravatar 头像
Emoji 图片
查看 wp 建立了多少查询
add_action( 'wp_footer', 'wpjam_page_speed' );
function wpjam_page_speed() {
date_default_timezone_set( get_option( 'timezone_string' ) );
$content = '[ ' . date( 'Y-m-d H:i:s T' ) . ' ] ';
$content .= '页面生成时间 ';
$content .= timer_stop( $display = 0, $precision = 2 );
$content .= ' 查询 ';
$content .= get_num_queries();
$content .= ' 次';
if( ! current_user_can( 'administrator' ) ) $content = "<!-- $content -->";
echo $content;
}
显示后台的远程请求
/**显示后台的远程请求*/
add_filter('pre_http_request', 'wpjam_admin_display_http_request', 10, 3);
function wpjam_admin_display_http_request($status, $r, $url){
if(is_admin() && isset($_GET['debug'])){
echo 'http_request:'.$url."\n<br />";
return $status;
}
}
注意该代码只能检测使用 WP_Http 方式实现的远程请求,如果插件作者直接使用 cURL 来实现的远程请求则无法打印出来。
附加一个小技巧,让后台的远程请求快速完成,比如 1 秒内必须完成:
/**让后台的远程请求在1s内快速完成*/
add_filter('http_request_timeout', 'wpjam_admin_short_http_request_timeout');
function wpjam_admin_short_http_request_timeout($timeout){
if(is_admin()){
return 1;
}
return $timeout;
}
wp 安全优化
wordpress 安全很重要,请确保做到如下:
wp 目录权限设置
按下图修改 wp 目录权限,不要设置目录权限为 777
数据库权限设置
数据库配置不要使用 root 账号,需要新建个账号,开放其只能对 wp 数据库进行增删改查,且其只能在本地操作,不能开放数据库端口.
# mysql8
CREATE DATABASE IF NOT EXISTS wpdata DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
CREATE USER IF NOT EXISTS 'wpdata'@'localhost' IDENTIFIED WITH mysql_native_password BY '数据库密码';
GRANT ALL ON isite.* TO 'wpdata'@'localhost';
FLUSH PRIVILEGES;
其他命令:
update mysql.user set host='localhost' where user='root'; # 修改root只能在本地登录
delete from mysql.user where user='test'; # 删除多余的用户
show grants for 'wpdata'@'localhost'; # 查看某个用户分配的权限
TIP
wp-config.php
中数据库配置项改为非 root 以及只能本地登录,不要使用默认的数据库前缀
wp 登录界面跳转
使用过 wp 的人都知道 wp 的后台地址是域名+wp-admin
,所以这样是非常不安全的.
现在我们可以通过如下代码对 wp 登录界面进行跳转:
/**
* 修改后台登录地址
*/
add_action('login_enqueue_scripts','login_protection');
function login_protection(){
if($_GET['iwantlogin'] != 'loginpara')
header('Location: 你的域名');
}
这样当我们通过域名+wp-admin
登录就会跳转到你的网站首页,只有通过https://域名/wp-login.php?iwantlogin=loginpara
才能进行登录.
TIP
if($_GET['iwantlogin'] != 'loginpara')
里的 iwantlogin
和 loginpara
可改成自己喜欢的
wp 登录账号密码设置
不要使用 admin 作为登录账号,账号密码最好要用数字+字母+特殊符合
组合
全站使用 https
使用 https 加密网站
关闭 XML-RPC
在当前主题的 functions.php 文件添加如下代码:
add_filter('xmlrpc_enabled', '__return_false');
当然也可利用 nginx 禁止所有 xmlrpc.php 请求
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
这样你再通过https://网站域名/xmlrpc.php
访问就变成 403 了
安装的 wpjam-basic 插件已集成了此功能.
关闭注册功能
取消 设置
-成员资格
-任何人都可以注册
前面的对勾
定期更新 wp 版本和插件
使用旧的 wp 会有安全风险,尽量更新到最新的 wp 版本
TIP
有关 wp 安全的插件有 hide my wp
以及ithemes-security-pro
定期备份 wp 网站
可以使用BackupBuddy
插件进行网站备份和迁移
封禁入侵 ip
打开 nginx 日志你会看到有很多进行破解的 ip,我们需要找到他们并封禁其 ip:
cat nginx.log | cut -d ' ' -f 1 | sort | uniq -c | awk '{if ($1 > 5) print $0}' | sort -nr | less > ip.txt
通过上面的命令我们找到了进行 5 次尝试破解的 ip 地址.下面我们对其 ip 进行封禁:
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address="181.174.83.226" drop'
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address="129.213.59.142" drop'
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address="60.248.159.139" drop'
重启防火墙firewall-cmd --reload
,可通过firewall-cmd --zone=public --list-rich-rules
查看刚添加的规则.
如果发现误封了 ip,可通过sudo firewall-cmd --permanent --remove-rich-rule='rule family=ipv4 source address="181.174.83.226" drop'
进行解封 ip。
下面是自动化封禁 ip 的脚本 (分析 Error.log 日志也能得到相同的效果) :
#!/bin/bash
# drop ip
# author: echoxu
# todo: 异步执行,提高运行效率
ip_lock_file=/root/ip_lock_file.txt
ip_arr=()
ip_limit_count=5
ip_from_firewall_rules=`firewall-cmd --zone=public --list-rich-rules |awk -F ' ' '{print $4}' |grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"`
ip_from_nginx_log=`cat /usr/share/nginx/logs/Access.log | awk -F ' ' '{if ($9 == 404 || $9 == 403 || $9 == 400) print $1}' | sort -rn |uniq -c | awk -F ' ' '{if ($1 > $ip_limit_count) print $2}'`
ip_from_secure_log=`cat /var/log/secure-20231119 |grep -E 'Did not|Bad protocol' | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" |sort -u`
getIPFromFirewallRules(){
for firewallip in $ip_from_firewall_rules
do
echo "$(date +'%F %T') 已封禁入侵ip: $firewallip " >> $ip_lock_file
done
}
getIPFromNginxLog(){
for nginxlogip in $ip_from_nginx_log
do
ip_arr[${#ip_arr[*]}]=${nginxlogip}
done
#echo "从 Nginx log 中获得 ${#ip_arr[*]} 个 ip,分别为:${ip_arr[*]}"
}
# kill ip from /var/log/secure
getIPFromSecureLog(){
for securelogip in $ip_from_secure_log
do
ip_arr[${#ip_arr[*]}]=${securelogip}
done
#echo "从 secure log 中获得 ${#ip_arr[*]} 个 ip,分别为:${ip_arr[*]}"
}
generateBaseData(){
if [ ! -f $ip_lock_file ];then
getIPFromFirewallRules # 将 firewall rules 里的数据导入到 ip_lock_file (程序首次运行时执行此函数)
fi
}
killIP(){
for ip in ${ip_arr[*]}
do
ip_is_exist=`cat $ip_lock_file |grep $ip|wc -l`
if [ $ip_is_exist -eq 0 ];then
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=$ip drop"
echo "$(date +'%F %T') 已封禁入侵ip: $ip " >> $ip_lock_file
fi
#echo "入侵ip: $ip 已在黑名单中存在。 "
done
}
main(){
generateBaseData
getIPFromNginxLog
getIPFromSecureLog
killIP
firewall-cmd --reload
}
main
添加定时任务,让其每半小时执行一次脚本并封禁破解次数>7 的 ip 地址:
crontab -e 然后添加如下:
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.daily.0/nginx >/dev/null 2>&1
*/30 * * * * sh /root/killIP.sh > /dev/null 2>&1 &
最好对 nginx 的日志进行一些切割处理,让其每天产生一个日志:
sudo vim /etc/logrotate.daily.0/nginx
添加如下内容:
/usr/share/nginx/logs/*.log {
daily
missingok
rotate 30
compress
dateext
delaycompress
notifempty
create 640 root root
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
添加定时任务,每天 00:00 产生新的日志文件:
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.daily.0/nginx >/dev/null 2>&1
wp 软件优化
主要分为如下几类:
替换 Avatar 头像加载地址、禁用 Emoji 表情、后台禁用 Google Open Sans 字体
通过 WordPress Hook(钩子),当然这部分您也可以自定义,路径在主题目录:/functions.php
解决 Avatar 头像问题
function dmeng_get_https_avatar($avatar) {
//~ 替换为 https 的域名
$avatar = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com"), "secure.gravatar.com", $avatar);
//~ 替换为 https 协议
$avatar = str_replace("http://", "https://", $avatar);
return $avatar;
}
add_filter('get_avatar', 'dmeng_get_https_avatar');
这里是将访问 Avatar 的链接改为通过 https 来访问,如果不用 Avatar 功能,可取消 设置
-讨论
-头像
-头像显示
-显示头像
前面的对勾
也可使用 v2ex
或者 cdnjs
提供的 Avatar 图像加速服务
WordPress 禁用 Emoji 功能
function disable_emojis() {
remove_action( ‘wp_head’, ‘print_emoji_detection_script’, 7 );
remove_action( ‘admin_print_scripts’, ‘print_emoji_detection_script’ );
remove_action( ‘wp_print_styles’, ‘print_emoji_styles’ );
remove_action( ‘admin_print_styles’, ‘print_emoji_styles’ );
remove_filter( ‘the_content_feed’, ‘wp_staticize_emoji’ );
remove_filter( ‘comment_text_rss’, ‘wp_staticize_emoji’ );
remove_filter( ‘wp_mail’, ‘wp_staticize_emoji_for_email’ );
add_filter( ‘tiny_mce_plugins’, ‘disable_emojis_tinymce’ );
}
add_action( ‘init’, ‘disable_emojis’ );
function disable_emojis_tinymce( $plugins ) {
return array_diff( $plugins, array( ‘wpemoji’ ) );
}
wp 通过本地加载 google ajax
wp54 中使用 google ajax 服务的文件路径为wp-includes/script-loader.php
738: $scripts->add( 'prototype', 'https://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1' );
739: $scripts->add( 'scriptaculous-root', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array( 'prototype' ), '1.9.0' );
740: $scripts->add( 'scriptaculous-builder', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/builder.js', array( 'scriptaculous-root' ), '1.9.0' );
741: $scripts->add( 'scriptaculous-dragdrop', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/dragdrop.js', array( 'scriptaculous-builder', 'scriptaculous-effects' ), '1.9.0' );
742: $scripts->add( 'scriptaculous-effects', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/effects.js', array( 'scriptaculous-root' ), '1.9.0' );
743: $scripts->add( 'scriptaculous-slider', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/slider.js', array( 'scriptaculous-effects' ), '1.9.0' );
744: $scripts->add( 'scriptaculous-sound', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/sound.js', array( 'scriptaculous-root' ), '1.9.0' );
745: $scripts->add( 'scriptaculous-controls', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/controls.js', array( 'scriptaculous-root' ), '1.9.0' );
1663: $open_sans_font_url = "https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets&display=fallback";
1734: * translators: Use this to specify the proper Google Font name and variants
1738: $font_family = _x( 'Noto Serif:400,400i,700,700i', 'Google Font Name and Variants' );
1740: $fonts_url = 'https://fonts.googleapis.com/css?family=' . urlencode( $font_family );
我已将下载好的文件上传到阿里 cdn 里,所以修改后的内容如下:
// WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source.
$scripts->add( 'prototype', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/prototype.js', array(), '1.7.1' );
$scripts->add( 'scriptaculous-root', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/scriptaculous.js', array( 'prototype' ), '1.9.0' );
$scripts->add( 'scriptaculous-builder', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/builder.js', array( 'scriptaculous-root' ), '1.9.0' );
$scripts->add( 'scriptaculous-dragdrop', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/dragdrop.js', array( 'scriptaculous-builder', 'scriptaculous-effects' ), '1.9.0' );
$scripts->add( 'scriptaculous-effects', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/effects.js', array( 'scriptaculous-root' ), '1.9.0' );
$scripts->add( 'scriptaculous-slider', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/slider.js', array( 'scriptaculous-effects' ), '1.9.0' );
$scripts->add( 'scriptaculous-sound', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/sound.js', array( 'scriptaculous-root' ), '1.9.0' );
$scripts->add( 'scriptaculous-controls', 'https://echoxucdn.oss-cn-shanghai.aliyuncs.com/googleajaxapis/controls.js', array( 'scriptaculous-root' ), '1.9.0' );
当然我已经将这些文件下载并打包了,下面是下载地址:
这样我们就可以让 wp 通过本地加载 google ajax 服务了.
TIP
另外还可使用cdnjs
提供的代理服务进行访问 google ajax. cdnjs 项目地址 CDNJS 加速 google ajax 库
移除 google fonts
/**WordPress 后台禁用 Google 字体*/
add_filter( 'gettext_with_context', 'wpjam_disable_google_fonts', 888, 4);
function wpjam_disable_google_fonts($translations, $text, $context, $domain ) {
$google_fonts_contexts = array('Open Sans font: on or off','Lato font: on or off','Source Sans Pro font: on or off','Bitter font: on or off');
if( $text == 'on' && in_array($context, $google_fonts_contexts ) ){
$translations = 'off';
}
return $translations;
}
如果想继续使用 google fonts 也可通过 cdnjs 或者中科大提供的代理服务加载 google fonts
阻止站内文章互相 Pingback
/**
* 阻止站内文章互相Pingback
*/
function Bing_noself_ping($links) {
$home = get_option( ‘home’ );
foreach ( $links as $l => $link )
if ( 0 === strpos( $link, $home ) )
unset($links[$l]);
}
add_action(‘pre_ping’,’Bing_noself_ping’);
彻底关闭 WordPress 自动更新和后台更新检查
把如下代码 copy 到你主题的 functions.php,刷新后台.
add_filter('automatic_updater_disabled', '__return_true'); // 彻底关闭自动更新
remove_action('init', 'wp_schedule_update_checks'); // 关闭更新检查定时作业
wp_clear_scheduled_hook('wp_version_check'); // 移除已有的版本检查定时作业
wp_clear_scheduled_hook('wp_update_plugins'); // 移除已有的插件更新定时作业
wp_clear_scheduled_hook('wp_update_themes'); // 移除已有的主题更新定时作业
wp_clear_scheduled_hook('wp_maybe_auto_update'); // 移除已有的自动更新定时作业
remove_action( 'admin_init', '_maybe_update_core' ); // 移除后台内核更新检查
remove_action( 'load-plugins.php', 'wp_update_plugins' ); // 移除后台插件更新检查
remove_action( 'load-update.php', 'wp_update_plugins' );
remove_action( 'load-update-core.php', 'wp_update_plugins' );
remove_action( 'admin_init', '_maybe_update_plugins' );
remove_action( 'load-themes.php', 'wp_update_themes' ); // 移除后台主题更新检查
remove_action( 'load-update.php', 'wp_update_themes' );
remove_action( 'load-update-core.php', 'wp_update_themes' );
remove_action( 'admin_init', '_maybe_update_themes' );
移除 WordPress 后台左上角 logo
/** 移除 WordPress 后台 logo */
function remove_logo($wp_toolbar) {
$wp_toolbar->remove_node('wp-logo');
}
add_action('admin_bar_menu', 'remove_logo', 999);
七牛 CDN(可不配置)
因为使用了阿里云 cdn 进行加速,所以此项可不配置:
去七牛官网先注册七牛账号,会获得永久的 10G 空间。
然后新建一个对象存储空间,空间名随便取,空间权限选择“公开”。
然后绑定 CDN 加速域名,注意:此域名一定要是二级域名(此域名不用进行 A 标记解析),如果是网站域名,会导致网站打不开。
这里需要等七牛验证,验证通过会有一个 cname,然后将此域名在域名解析里解析即可。
注意:一定要用 cname 标记,然后主机记录填绑定的二级域名的前面部分,如我的是 image.echoxu.cn,那这里就填 image。
记录值填七牛给的 cname 值。
具体可参考七牛融合 CDN 官方文档
七牛镜像
在七牛的对象存储里选择相应的空间名,然后选择镜像存储,这里填的域名是网站主域名。
解释下镜像存储,其实就相当于复制文件,及将主站的 jpg,css,js 等静态文件通过七牛云存储插件复制到新建的七牛对象存储空间中。
这里需要注意的是一定要选择七牛提供的 Robots.txt 文件,不然你的网站会被降权。
安装七牛云存储插件,需先安装 wpjam 插件并激活。
这两个插件是 wp 大神 我爱水煮鱼开发的,可在百度搜索 水煮鱼及可查看他的博客,里面会介绍很多 wp 的东西。
注意:wpjam 第一次激活时可能会提示“无效的主题内容”
可多点击几次激活,如果不行可删掉重新安装即可解决。
另需注意的是:启用后你还需扫描二维码关注 wpjam 的公众号,可通过扫码在公众号中查看 4 位验证码,但可能你会发现输入验证码后还是会停在扫码界面,根据水煮鱼大神的解释是服务器的原因,好像是 5 秒没反应,微信会拒绝。
我的解决办法是多扫几次,或者先取消关注公众号,再重新扫码,我就是这样通过的,再不行就只能换服务器了。
wpjam 的插件功能很多,具体可根据需要选择。
七牛镜像配置及七牛云存储插件使用可参考
wp 优化加速就写到这里,后续有补充再更新。