站点图标 久久日记本

在Ubuntu/Debian上部署wordpress

最后更新:2023-11-17
上次更新:2023-09-28
创建时间:2021-06-21

下面这篇文章记录的内容发生在 2021-06-18, 截至到 2023-11-17,本文经过多次更新。

以下内容在Ubuntu 20, Debian 10, Debian 12上经过测试,理论上Ubuntu 22也可以参考本文章。

1. 博客现状

之前换过多家vps服务商,很友好的是都有wordpress一键部署,用起来很方便,只需要自己简单的还原一下数据,端口简单的限制,配置一下DNS就好了,再不济自己改一下主题。

上次换的一家除了便宜,没有其他好处了,摸摸兜里的¥,想想算了,忍吧。

512M + 20G SSD

一键部署的ubuntu是16,vps商家屏蔽了内核的升级和安全补丁升级,使用了bitnami加打包的wp + php5 + apache, 查了查bitnmai的文档,如果要升级,比如将php从5升级到7,发现需要重装bitmai。

忍了很久,但是每次登录博客后写日志,受不了提示的红点点警告。

2. Bitnmai版的wordpress

在本地用vbox装了ubuntu,尝试了多次装wordpress,上传自己的主题。

确保无误后,演习完毕后准备到服务器上安装了。

开了一个同配置的机器,Ubuntu20: 512M RAM + 20G SSD, 装好后发现内存只剩下100多M了。

然后按照bitnmai给出的方案: How to update PHP version of WordPress in AWS Lightsail?

sudo /opt/bitnami/ctlscript.sh stop
sudo rm -rf /opt/bitnami
cd /tmp
wget https://downloads.bitnami.com/files/stacks/wordpress/5.7.2-0/bitnami-wordpress-5.7.2-0-linux-x64-installer.run
chmod +x bitnami-wordpress-5.7.2-0-linux-x64-installer.run
sudo ./bitnami-wordpress-5.7.2-0-linux-x64-installer.run --prefix /opt/bitnami

发现每次都安装一般都被vps机器给kill掉了,我大概终于明白了为什么服务器厂商不愿意将16升级到20,可能因为内存占用,低配的vps不能无法安装wp全家桶。

可能是强迫症发作了,终于决定要不要再从头开始,再用nginx作为http server

3. 在Ubuntu上安装wordpress

进入正题,备份好了原博客的数据后,开了个台:Ubuntu20: 1G RAM + 40G SSD

1.安装MariaDB

# 安装 mariadb
sudo apt-get install mariadb-server -y

# 启动 mariadb
sudo systemctl start mariadb

# 启用开机自动运行
sudo systemctl enable mariadb

# 运行下面命令提升数据库安全性(实际上设置数据库密码和远程访问的情况)
sudo mysql_secure_installation 

2.安装php

# 检查更新
sudo apt-get update 

# 我并没有执行添加源和安装php,应该已经内置,直接安装成功
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php 
sudo apt-get update
# Ubuntu 20
sudo apt-get install php7.4 php7.4-cli php7.4-fpm php7.4-mysql php7.4-json php7.4-opcache php7.4-mbstring php7.4-xml php7.4-gd php7.4-curl -y

# 而是直接执行了安装php,即安装了php7
sudo apt install php

# 2023-09-28更新: Debian 10
# 因为没有带一些基本的库:
# 除了安装php外,还需要以下支持
# <!-- 运行php程序 -->
sudo apt -y install php7.4-fpm
# <!-- 连接mysql -->
sudo apt -y install php7.4-mysql
# <!-- 第三方插件授权 -->
sudo apt -y install php7.4-curl
# <!-- 无法初始化AMP插件,需要装dom拓展。 -->
sudo apt -y install php7.4-xml

# 2023-11-17 更新: Debian 12
# 不指定版本号的安装会默认安装 8.2 版本的 php:

sudo apt -y install php-fpm
sudo apt -y install php-mysql
sudo apt -y install php-curl
sudo apt -y install php-xml

# 检查php版本
php -verson

3.创建wordpress数据库

命令用于 10.*+ 版本的 MariaDB (Mysql)

# 进入mysql命令行
sudo mysql -u root -p

# 创建名为 wordpress 的数据库
CREATE DATABASE wordpress;

use wordpress;

# 为 wordpress 数据库创建访问用户名和密码(将yourwpusername和yourwppassword替换成自己的数据库用户名和密码,)
create user yourwpusername@localhost identified by 'yourwppassword';
# 授予 yourwpusername@localhost 增删改查销毁更新表字段的权限
grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER  on wordpress.* to yourwpusername@localhost;

FLUSH PRIVILEGES;

exit

4.下载和配置wordpress目录权限

# 创建wordpress文件夹
mkdir wordpress

cd wordpress

# 下载,解压wordpress源码,并移动到wordpress文件夹根目录
sudo wget https://wordpress.org/latest.tar.gz  
sudo tar -zxvf latest.tar.gz  
sudo mv wordpress/* .  
sudo rm -rf wordpress latest.tar.gz

# 将wordpress文件夹中访问权限授权给 www-data:www-data 
# (因为wp插件,主题更新,程序更新用的是 www-data 用户),
sudo chown -R www-data:www-data * 
sudo chmod -R 755 *

# 2023-11-17:更新
对于权限的更为安全的设置,不建议按照上述内容直接设置为755。
建议仅参考下面内容,

对于wordpress所在的目录,设置 www-data 权限,这样wordpress本地和插件更新就没问题了;当前,安全的做法并不建议能自动更新,可以设置为当前用户权限。

又想能自动更新,又想安全的做法不存在。

sudo chown www-data:www-data -R wordpress;
cd wordpress;
sudo chown www-data:www-data  -R * # Let Apache be owner
sudo find . -type d -exec chmod 755 {} \;  # Change directory permissions rwxr-xr-x
sudo find . -type f -exec chmod 644 {} \;  # Change file permissions rw-r--r--

5.配置wordpress

wp-config.php

# 将 wp-config-sample.php 覆盖 wp-config.php  
sudo mv wp-config-sample.php wp-config.php  

# 配置 wp-config.php
sudo vim wp-config.php
/** 在wp-config.php文件中找出并更改以下内容 */ 
// 可以用 3. 创建wordpress数据库 这步 创建的数据库用户名和密码
...  
...  
define('DB_NAME', 'wordpress_db');  
define('DB_USER', 'wpuser');  
define('DB_PASSWORD', 'Passw0rd!');  
...  
... 

/** 在wp-config.php文件中找出并删除以下内容 */ 
... 
... 
define( 'AUTH_KEY', 'put your unique phrase here' ); 
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' ); 
define( 'LOGGED_IN_KEY', 'put your unique phrase here' ); 
define( 'NONCE_KEY', 'put your unique phrase here' ); 
define( 'AUTH_SALT', 'put your unique phrase here' ); 
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' ); 
define( 'LOGGED_IN_SALT', 'put your unique phrase here' ); 
define( 'NONCE_SALT', 'put your unique phrase here' ); 
... 
...

“为了保证 WordPress 网站的安全,在上面的 WordPress 配置文件中,在数据库配置选项之后,通过这个链接生成安全密钥,粘贴在上述删除内容的位置中。”

6.安装nginx

# 安装 nginx
sudo apt-get install nginx -y

# 检查 nginx 运行状态
sudo systemctl status nginx

# 启动 nginx
sudo systemctl start nginx

# 启用开机自动运行
sudo systemctl enable nginx

# 关闭开机自动运行 (2021-06-24 更新)
sudo systemctl disable nginx

7.配置nginx

sudo vim /etc/nginx/sites-available/wordpress.conf

wordpress.conf

替换 /home/xxx/wordpress为你的wordpress所在文件夹, yourdomainname 为你的域名

server {             
    listen 80;
    # 2023-09-28 更新:ipv6, 如果需要支持ssl 将这里改成443即可
    listen [::]:80;
    root /home/xxx/wordpress;
    index index.php index.html;
    server_name yourdomainname

    # access_log /var/log/nginx/www.access.log;
    # error_log /var/log/nginx/www.error.log;

    location / {
         try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
         include snippets/fastcgi-php.conf;
         fastcgi_pass unix:/run/php/php7.4-fpm.sock;
         # 2023-11-17 更新:
         如果你是debian 12,并且未指定版本号安装,这里安装的是 php-fpm,截至本文更新时间,默认版本号为8.2,这行配置改为下面内容
         fastcgi_pass unix:/run/php/php-fpm.sock;
    }

    location ~ /\.ht {
         deny all;
    }

    location = /favicon.ico {
         log_not_found off;
         access_log off;
    }

    location = /robots.txt {
         allow all;
         log_not_found off;
         access_log off;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
         expires max;
         log_not_found off;
    }
}

2023-11-17更新:

如果是 Ubuntu 20, Debian 10,上述配置保存为CRLF格式并不影响nginx配置生效,但是在Debian 12,上述nginx配置必须存为LF格式,否则会报换行符错误。

# 检查上述配置文件的正确性
nginx -t

cd /etc/nginx/sites-enabled  

# 我没有执行下面这一步(激活 nginx 文件,在 /etc/nginx/sites-enabled 文件夹中创建上述配置文件的符号链接)
# 2021-06-23 更新:这里需要激活一下将 sites-available 文件夹的配置映射到 sites-enabled
sudo ln -s ../sites-available/wordpress.conf .

# 重载以应用nginx配置
sudo systemctl reload nginx

8.安装 wordpress

上述配置成功后,访问域名即可看到wordpress 设置页面,

选择语言 -> 配置页面:

站点标题: 
用户名:wp登录名
密码:wp密码
您的电子邮件:
对搜索引擎的可见性:

WordPress 安装完成,恢复之前的数据库和主题,插件即可。

4. 其他必须配置

1.更新插件提示 web server 权限

在wordpress根目录下修改刚刚修改的文件:wp-config.php, 在文件末尾添加以下方法:

define( 'FS_METHOD', 'direct' );

如果不添加,每次更新插件都会弹出窗输入web server 文件夹用户名密码,提示无权限访问。

即使在 4.下载和配置wordpress目录权限 这一步中授予的www-data用户权限,

2.禁止 ip 访问

上述nginx配置后,访问 ip 会打开 nginx 默认页面

需要在 /etc/nginx/sites-available/default 默认配置中添加 return 444;

444 : CONNECTION CLOSED WITHOUT RESPONSE

server {
    listen      80 default_server;
    server_name ;
    return      444;
}

3.如果不小心删除了默认的 nginx 默认配置

这里备份一下:

/etc/nginx/sites-available/default

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #   include snippets/fastcgi-php.conf;
    #
    #   # With php7.0-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php7.0-fpm:
    #   fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}
}

# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#   listen 80;
#   listen [::]:80;
#
#   server_name example.com;
#
#   root /var/www/example.com;
#   index index.html;
#
#   location / {
#       try_files $uri $uri/ =404;
#   }
#}

5. 补充

2021-11-17

偶然间查看日志发现很多构造xshell的请求,被源源不断扫了wp-json/wp/v2/users/wp-includes/wlwmanifest.xml,查询了一些资料,比如这篇文章:

WordPress的管理员用户名是如何泄露的,以及如何防护~

攻击者可以以此来拿到用户名和确认是否使用了wp,然后流水线自动化xshell

所以在上述nginx配置中可以添加:

    location ~ ^/wp-json/wp/v2/users {
         deny all;
    }

    location ~ ^/wp-includes/wlwmanifest.xml {
         deny all;
    }

来禁止访问这两个路径

6. 参考资料

2023-11-17更新:关于wordpress的权限的配置参考:

allow upgrade: wordpress-hardened-permissions-with-automatic-updates

keep security: correct-file-permissions-for-wordpress

本文早期参考资料:
How to update PHP version of WordPress in AWS Lightsail?

本文shell部分内容主要参考自Kingson的这篇文章:在 Ubuntu 18.04 上使用 Nginx 安装 WordPress

How to block access using the Server IP in NGINX?(444 : CONNECTION CLOSED WITHOUT RESPONSE)

Nginx default server block (/etc/nginx/sites-available/default)

退出移动版