建置 WordPress MU 多子網域 HTTPS for CentOS 7 + NGINX + PHP 7
如何建置 HTTPS 的 WordPress MU 多子網域,逹到多網址多網站功能,本教學從零開始在剛安裝好的 CentOS 7,從系統基本環境、NGINX、PHP 7 的設置,到最終的 WordPress。
WordPress Multi User (簡稱為 WPMU) 多用戶,一但建置完成即可從 WordPress 後台直接新增多個「子網域」或「子目錄」方式的全新網站,好處是能共享資源 (如外掛) 以便管理。
CentOS
這裡從 CentOS 7 "最小型安裝" 的初始環境開始,須先自行完成系統安裝。
環境設定
hostname (主機名稱) 設定:
- hostnamectl set-hostname ...:設定 hostname。
- logout:登出。
- hostname:顯示當前 hostname。
hostnamectl set-hostname smalljacky.com
logout
login as: root
root@61.216.xxx.xxx's password: **********
Last login: Sat Jan 20 09:29:43 2018 from 61.216.xxx.xxx
hostname
smalljacky.com
網路設定:
- nmcli connection show:查詢網路卡裝置。
- nmcli connection modify ...:設置 "固定 IP" 網路環境。
- nmcli connection up ...:啟用網路。
nmcli connection show
NAME UUID TYPE DEVICE
eth0 155337be-567d-4667-82b7-ae1d9f6e722c 802-3-ethernet
nmcli connection modify eth0 connection.autoconnect yes ipv4.address "61.216.xxx.xxx/24" ipv4.gateway "61.216.xxx.xxx" ipv4.dns 168.95.1.1 ipv4.method manual
nmcli connection up eth0
安裝後續須用軟體:
- bash-completion:Bash shell 指令自動補齊,透過雙擊鍵盤 Tab。
- wget:支持通過 HTTP、HTTPS 和 FTP 下載檔案。
- yum-utils:包含了一些在預設中未被啟用的 yum 插件。
yum install bash-completion wget yum-utils
免費萬用字元憑證
使用萬用字元憑證 (Wildcard Certificates),即可通用於所有子網域的網站,這裡使用 Let’s Encrypt 的免費萬用字元憑證,申請步驟請參考 Let’s Encrypt 免費 Wildcard 萬用字元憑證 SSL/TLS for CentOS 7。
NGINX
安裝
CentOS 7 中,NGINX 並未被正式收錄在 yum,因此須自行加入 NGINX 官方提供的 CentOS 7 yum repository,即可直接安裝。
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install nginx
修改網站根目錄的擁有者、群組為 NGINX:
chown -R nginx:nginx /usr/share/nginx/html/
虛擬主機設定檔
開啟 NGINX 預設的主機設定檔,針對 WordPress MU (多站點、子網站) 子網域和 HTTPS 設定。
參數 server_name:
- smalljacky.com 為主網站。
- *.smalljacky.com 為 WordPress MU (多站點、子網站) 子網域。
參數 root:
- 網站根目錄。
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
vi /etc/nginx/conf.d/default.conf
map $http_host $blogid {
default -999;
#Ref: http://wordpress.org/extend/plugins/nginx-helper/
#include /var/www/wordpress/wp-content/plugins/nginx-helper/map.conf;
}
# 將 http 301 永久轉跳至 https
server {
listen 80;
listen [::]:80;
server_name smalljacky.com *.smalljacky.com;
return 301 https://$server_name$request_uri;
}
server {
# 使用 https 和 http/2 協定
listen 443 ssl http2;
# 上述的 IPv6 方式
listen [::]:443 ssl http2;
server_name smalljacky.com *.smalljacky.com;
# 瀏覽器 Cache 期限 (1M = 1 Month)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff)$ {
expires 1M;
}
root /usr/share/nginx/html;
index index.php;
#
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
#
# SSL 憑證證書路徑
ssl_certificate /etc/letsencrypt/live/smalljacky.com-0001/fullchain.pem;
# 私鑰路徑
ssl_certificate_key /etc/letsencrypt/live/smalljacky.com-0001/privkey.pem;
# 緩存有效期
ssl_session_timeout 1d;
# 緩存憑證類型和大小
ssl_session_cache shared:SSL:50m;
#
# intermediate configuration. tweak to your needs.
#
# 使用的加密協定
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 加密演算法,越前面的優先級越高
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
# 交握過程使用 Server 的首選加演算法,這裡使用 Client 為首選
ssl_prefer_server_ciphers on;
#
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
#
# 增加 http header
add_header Strict-Transport-Security max-age=15768000;
location / {
try_files $uri $uri/ /index.php?$args ;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#WPMU Files
location ~ ^/files/(.*)$ {
try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1;
access_log off;
log_not_found off;
expires max;
}
#WPMU x-sendfile to avoid php readfile()
location ^~ /blogs.dir {
internal;
alias /usr/share/nginx/html/wp-content/blogs.dir;
access_log off;
log_not_found off;
expires max;
}
#add some rules for static content expiry-headers here
}
服務設定
啟用服務並開機自動啟用:
systemctl start nginx
systemctl enable nginx
Firewall (防火牆) 設定
查看 Firewall 針對當前網路裝置的設定:
firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client
# ... 以下省略 ..
刪除 Firewall 預設的 Services:
firewall-cmd --permanent --remove-service={ssh,dhcpv6-client}
success
設定 Firewall 僅允許哪些 IP 才能使用哪些 Services:
- ssh:透過該通道與 Server 建立連線。
- samba:File Server (檔案伺服器)。(為了撰寫程式的效率,小傑都透過此方式掛載 Web Server 的根目錄來撰寫程式)
firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv4' source address='61.216.xxx.xxx/32' service name='ssh' accept"
success
firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv4' source address='61.216.xxx.xxx/32' service name='samba' accept"
success
設定 Firewall 允許 http (80 Port) 與 https (443 Port) 封包通行:
[root@smalljacky ~]# firewall-cmd --permanent --zone=public --add-service={http,https}
success
重新載入 Firewall 設定:
firewall-cmd --reload
success
檢查 Firewall 設定:
firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: http https
# ... 中間省略 ...
rich rules:
rule family="ipv4" source address="61.216.xxx.xxx/32" service name="ssh" accept
rule family="ipv4" source address="61.216.xxx.xxx/32" service name="samba" accept
啟用 Gzip 壓縮
有人訪問網站時,伺服器會傳送相關檔案給瀏覽器,當傳送的檔案越大,所花費的時間就會越長,也就表示網頁開啟的速度就越慢,因此可先將檔案進行 Gzip 壓縮後在進行傳送給瀏覽器,將可有效減少傳輸的時間。
開啟 nginx.conf 進行設定:
vi /etc/nginx/nginx.conf
http {
# ... 以上省略 ...
# 啟用 gzip (預設為註解,也就是未啟用)
gzip on;
# 多小的檔案容量不進行 gzip 壓縮
gzip_min_length 1k;
# 壓縮緩衝區的的 number size
gzip_buffers 4 16k;
# 壓縮比例 1-9,數值越高壓縮越好 (也就是檔案越小),但系統處理速度越慢
gzip_comp_level 5;
# 要壓縮的檔案類型
gzip_types text/plain application/javascript application/json text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在 http header 加入 Vary: Accept-Encoding,通知瀏覽器有使用 Gzip 壓縮
gzip_vary on;
# ... 以下省略 ...
}
重新載入 NGINX 設定檔:
systemctl reload nginx
PHP
安裝
請參考 CentOS 7 安裝 PHP 7.x。
PHP-FPM
安裝:
yum install php-fpm
先備存 PHP-FPM 設定檔後在進行設定:
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak
vi /etc/php-fpm.d/www.conf
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock
;user = apache
user = nginx
;group = apache
group = nginx
; 預設帳戶、群組,為正在運作的帳戶
;listen.owner = nobody
;listen.group = nobody
listen.owner = nginx
listen.group = nginx
; 權限(預設為 0666)
;listen.mode = 0666
; session 的路徑
php_value[session.save_path] = /var/lib/php/session
修改 session 路徑的擁有者、群組為 NGINX:
chown nginx:nginx /var/lib/php/session/
服務設定
啟用 PHP-FPM 服務並開機自動啟用:
systemctl start php-fpm
systemctl enable php-fpm
重啟 NGINX 服務:
systemctl restart nginx
網站緩慢優化
如果遇到網站使用一段時間後越來越緩慢,而只要重新開機或重啟 NGINX 與 PHP-FPM 就又恢復正常,那就有可能是 PHP-FPM 預設連線數設定太高所導致的,如下查看記憶體使用狀況:(詳細說明可參考鳥哥的 Linux 私房菜 -- 第十六章、程序管理與 SELinux 初探)
free -m
total used free shared buff/cache available
Mem: 992 131 713 6 146 701
Swap: 1906 0 1906
可依伺服器效能自行調整 PHP-FPM 設定檔:
vi /etc/php-fpm.d/www.conf
# ... 以上省略 ...
# 如何控制子程序,值有 static (Web 專用 Server 設定它即可) 和 dynamic (預設值)。
# 設定值為 static 則由 pm.max_children 指定固定的子程序數量;值為 dynamic 則由下列參數設定決定。
pm = dynamic
# 子程序最大數
pm.max_children = 7
# 啟動時的程序數量
pm.start_servers = 2
# 空閒時程序最小值,如果空閒程序小於設定值,則建立新的子程序。
pm.min_spare_servers = 1
# 空閒程序最大值,如果空閒程序大於設定值,進行清理。
pm.max_spare_servers = 3
# ... 以下省略 ...
重新載入 PHP-FPM 設定檔:
systemctl reload php-fpm
SELinux 安全性限制
上傳檔案失敗 / 更新無法建立目錄
查看網站根目錄預設的文件類型為 httpd_sys_content_t:
ll -dZ /usr/share/nginx/html
drwxr-xr-x. nginx nginx system_u:object_r:httpd_sys_content_t:s0 /usr/share/nginx/html
使用遞迴來讓所有的目錄加入 SELinux 的 httpd_sys_rw_content_t 文件類型:
chcon -R -t httpd_sys_rw_content_t /usr/share/nginx/html
檢查 SELinux 設定:
ll -dZ /usr/share/nginx/html
drwxr-xr-x. nginx nginx unconfined_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html
無法網路連結 DataBase
設定 SELinux httpd_can_network_connect_db
允許網路連結 DataBase:
setsebool -P httpd_can_network_connect_db=1
無法發送 Email
訪客在文章留言後,WordPress 會自動寄發 Email 至管理員信箱,如一直無法收到信,請先查詢 maillog 的資訊,如下表示權限被拒:
vi /var/log/maillog
Feb 22 22:46:05 smalljacky postfix/sendmail[16892]: fatal: open /etc/postfix/main.cf: Permission denied
檢查允許透過 PHP 寄信的 SELinux httpd_can_sendmail 狀態,如下則不允許:
getsebool -a | grep httpd_can_sendmail
httpd_can_sendmail --> off
設定 SELinux httpd_can_sendmail 允許透過 PHP 寄信:
setsebool -P httpd_can_sendmail=1
WordPress
下載
- 至 WordPress 官網下載軟體壓縮檔。
- 開啟壓縮檔,將 wordpress 目錄下 (不含 wordpress 目錄) 所有檔案移至網站根目錄 。
- 將 WordPress 的設定檔案 wp-config-sample.php 另存為 wp-config.php。
設定
編輯 WordPress 設定檔 wp-config.php (僅列出修改部份):
- MySQL DataBase:填入對應的資訊。
- 認證唯一金鑰設定:開啟私密金鑰服務,並將自動產生的字串符號貼上取代原設定。
- WordPress 資料表前綴:增加安全性。
- 啟用多網誌站台與網誌網路功能:取消註解符號 //,並將參數改為 true。
vi /usr/share/nginx/html/wp-config.php
<?php
// ... 以上省略 ...
// ** MySQL 設定 - 您可以從主機服務提供商獲取相關資訊。 ** //
/** WordPress 的資料庫名稱,請更改 "database_name_here" */
define('DB_NAME', 'database_name_here');
/** MySQL 資料庫使用者名稱,請更改 "username_here" */
define('DB_USER', 'username_here');
/** MySQL 資料庫密碼,請更改 "password_here" */
define('DB_PASSWORD', 'password_here');
/** MySQL 主機位址 */
define('DB_HOST', 'localhost');
/** 建立資料表時預設的文字編碼 */
define('DB_CHARSET', 'utf8');
/** 資料庫對照型態。如果不確定請勿更改。 */
define('DB_COLLATE', 'utf8_unicode_ci');
/**#@+
* 認證唯一金鑰設定。
*
* 將這些更改為不同的唯一字串或符號。
* 您可以使用 {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org 私密金鑰服務} 來自動產生。
* 您可於任何時候修改這些字串讓 Cookies 失效。這將會強制所有使用者必須重新登入。
*
* @since 2.6.0
*/
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 設定不同的資料表前綴,則可在同個資料庫內安裝多個 WordPress。
* 前綴只能使用半型數字、字母和底線!
*/
$table_prefix = 'wp_';
// ... 中間省略 ...
/**
* 啟用多網誌站台與網誌網路功能
*
* 若 WP_ALLOW_MULTISITE 值為 true 可啟用多網誌站台功能。
*/
define('WP_ALLOW_MULTISITE', true);
// ... 以下省略 ...config.php
安裝
開啟 Browser 輸入 [網址]/wp-admin/install.php (小傑的為 smalljacky.com/wp-admin/install.php),依步驟安裝完成後登入後台。
進入工具 > 網誌網路安裝 > 選取 子網域 > 點擊安裝。
複製 1. 新增以下程式碼至 /usr/share/nginx/html/ 的 wp-config.php 檔案… (請務必貼至 啟用多網誌站台與網誌網路功能 的下面)。
vi /usr/share/nginx/html/wp-config.php
<?php
// ... 以上省略 ...
/**
* 啟用多網誌站台與網誌網路功能
*
* 若 WP_ALLOW_MULTISITE 值為 true 可啟用多網誌站台功能。
*/
define('WP_ALLOW_MULTISITE', true);
/**
* 啟用網誌網路站台的功能。
*/
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'smalljacky.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
// ... 以下省略 ...
點擊下方的登入,正確完成後就會發現後台介面有一些改變。
新增新網誌 (子網域網站):點擊最上面我的網站 > 網站 > 新增。
其它設定
最大上傳檔案大小
修改 NGINX 和 PHP 設定檔來調整上傳容量限制 (以上傳容量調至 200M 為例)。
NGINX 設定:
vi /etc/nginx/conf.d/default.conf
# ... 以上省略 ...
server {
# 使用 https 和 http/2 協定
listen 443 ssl http2;
# 上述的 IPv6 方式
listen [::]:443 ssl http2;
server_name smalljacky.com *.smalljacky.com;
#
# 上傳檔案相關設定
#
# 上傳檔案允許容量
client_max_body_size 200M;
client_header_timeout 600s;
client_body_timeout 600s;
# fastcgi 為使用本機的 php-fpm,如果是透過 proxy 則前綴要改成 proxy_
fastcgi_connect_timeout 600s;
fastcgi_read_timeout 600s;
fastcgi_send_timeout 600s;
# ... 以下省略 ...
PHP 設定 (僅列出須修改部份):
vi /etc/php.ini
upload_max_filesize = 200M
post_max_size = 200M
max_execution_time = 300
max_input_time = 600
後台調整設定:
上傳檔案型態
依需求調整允許上傳的副檔名:
參考
本著作係採用創用 CC 姓名標示-相同方式分享 3.0 台灣 授權條款授權.
在〈建置 WordPress MU 多子網域 HTTPS for CentOS 7 + NGINX + PHP 7〉中有 1 則留言