PostgreSQLでWordPress断念→MariaDBでWordPress
OSのインストールができたので、次はWordpressです。もともとテレワークのためにVPNサーバを立てるつもりで自宅サーバを作り始めたのですが、Softether VPNの情報を収集していたときに、NTT東日本とIPAが「シン・テレワークシステム」を提供開始したので、VPNサーバを作るのはやめちゃいました。
でも、スティックPC買ったから、何か有効活用できないものかと考え、勉強もかねてWordpressの環境を作ることにしました。
WordPressはMySQL(とMariaDB)しかサポートしていません。個人的には、仕事で使うならMySQLよりPostgreSQLだと思っているので、勉強するならPostgreSQLだろう。というこで、WordpressをPostgreSQLで動かしてみることにしました。
結論から言いますと、今はMariaDBで動かしています。PostgreSQLで一応動作はしたのですが、サイトヘルスやプラグインで問題が発生し、そのたびにWordpressのPHPのソースをちまちま直すのが嫌になって、MariaDBに移行しました。
ということで、以下は、一応動く状態までもっていったWordpress powered by PostgreSQLの記録です。
DDNS
まずサーバのFQDNを決めてDDNSに登録しなきゃなので、フリーのDDNSサービスを調べました。以前、ieServer.Net を使ったことがあったのですが、AAAAレコードが登録できるかわからなかったので、今回はMyDNSにしました。
MyDNSは独自ドメインを取得した時にもDNSサービスを利用可能なのも理由のひとつです。
無料で使える0am.jpドメインにzzzのホスト名で zzz.0am.jp にしました。”0 AM”、午前0時って正しくは”12 PM”だと思うんだけど、アホっぽくて気に入ったので、眠くなる時間にちなんで”Zzz”に決めました。
で、DDNSだからIPアドレスの変更があったときに更新しなければならないので、シェルスクリプトを作って、cronで動かします。
前回から1430秒(23時間59分50秒)以上経過しているか、前回MyDNSに通知した時とIPアドレスが変わっていたら、MyDNSにIPアドレスを通知するスクリプトが以下のものです。IPv4アドレスはルータの管理画面から取得し、IPv6アドレスはipコマンドでglobalスコープのアドレスを取得しています。
#!/bin/sh -f
ipv4addr=$(wget -q -O- --user=admin --password=****** http://192.168.10.100/status.htm | perl -ne '$is_wan = 0; while (<>) {if ($is_wan && $_ =~ /IP/) {print "$1\n" if (<> =~ />([0-9.]+)</); exit(0);} $is_wan = 1 if ($_ =~ /showWanStatus\(/);}')
ipv6addr=$(ip -o -6 addr |perl -ne 'print "$1\n" if ($_ =~ /^.*inet6 ([:0-9a-f]+).* global .*$/);')
if [ x"$ipv4addr" = x -o x"$ipv6addr" = x ]
then
echo "$0: Cannot get IP address. (v4:$ipv4addr, v6:$ipv6addr)" 1>&2
exit 1
fi
. $HOME/.pre_ip
cur_sec=$(date +%s)
if [ $(($cur_sec - $pre_sec)) -gt 1430 -o $ipv4addr != $pre_ipv4 -o $ipv6addr != $pre_ipv6 ]
then
wget -q -O/tmp/mydns_directip.html --post-data='MID=mydnsXXXXXX&PWD=*********&IPV4ADDR='"$ipv4addr"'&IPV6ADDR='"$ipv6addr" https://www.mydns.jp/directip.html
fi
if [ $ipv4addr != $pre_ipv4 -o $ipv6addr != $pre_ipv6 ]
then
cat <<EOF > $HOME/.pre_ip
pre_ipv4='$ipv4addr'
pre_ipv6='$ipv6addr'
pre_sec='$cur_sec'
EOF
fi
cronは3分毎に起動するように設定しました。
*/3 * * * * $HOME/update_mydns.sh
PostgreSQL
aptでPostgreSQLをインストールして、データ領域を変更するために、いったん止めます。
# apt install postgresql postgresql-contrib
# /etc/init.d/postgresql stop
データ領域は60GBのSDカードにしました。EXT4ファイルシステムを作り、自動でマウントするようにfstabに追加します。
# mkfs.ext4 -L microSD60GB /dev/mmcblk1p1
# vi /etc/fstab
# tail -1 /etc/fstab
LABEL=microSD60GB /mnt/sd ext4 defaults 0 0
データ領域を、新しく作成したデータ領域にコピーして、confファイルでパスを変更します。
# mount /mnt/sd
# mkdir /mnt/sd/pg_data
# cd /mnt/sd/pg_data
# (cd /var/lib/postgresql && tar cf - .) | tar xf -
# vi /etc/postgresql/12/main/postgresql.conf
# grep data_directory $!
data_directory = '/mnt/sd/pg_data/12/main'
# /etc/init.d/postgresql start
WordPress用のアカウントとDBを作成します。どちらも”wordpress”です。
# sudo -u postgres createuser -E -P -U postgres wordpress
# sudo -u postgres createdb -O wordpress wordpress
PHP
PHPもaptでインストールしますが、”php”パッケージをインストールするとApacheも入ってしまいます。Nginxにしたいので、Apacheに依存しない”php-fpm”パッケージをインストールします。
fpmは”FastCGI Process Manager”の略で、NginxとWordpress(PHP)をつなぐためのパッケージです。
# atp install php-fpm
Nginx
Nginxのパッケージは、ビルド時にリンクされている機能の違いで、3つのパッケージが用意されています。Wordpressの手前に置くだけなので、一番軽い”nginx-light”を入れました。
PostgreSQLのデータ領域と同様に、ドキュメントルートをSDのパスに変更します。
# apt install nginx-light
# cd /var
# mv www /mnt/sd
# ln -s /mnt/sd/www .
# vi /etc/nginx/sites-available/default
修正箇所:
root /mnt/sd/www/html
server zzz.0am.jp
# service nginx reload
ところでmvコマンドって、いつからファイルシステムをまたいで移動できるようになったんですかね?昔はできなかったと記憶しているんですが。昔、mv ってrename(2)してるだけからできないんだろうなーと思ってました。
UFW
ufwはiptablesのルールを簡単に作れる、いわゆるファイアーウォールです。iptablesのルール書くのめんどくさいなーと思っていたら、今はこういう便利なものがあるのを発見しました。
オープンするポートは ssh、http、https。WAN側に公開するのはhttpとhttpsで、sshはLAN内のみ公開。ただし、WAN/LANどちらに公開するかはルータのポートフォワーディングで設定するので、ufwではWAN/LANの区別なく公開するようにします。
# ufw allow ssh
# ufw allow http
# ufw allow https
# ufw enable
# ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
上記のように設定してしばらくしてsyslogを確認すると、こんなログがたくさん出ていました。
[UFW BLOCK] IN=wlp1s0 OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=192.168.10.100 DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=58798 DF PROTO=2
SRCはルータ②で、DSTがマルチキャストアドレスなので、ルータ②の設定画面でそれらしい項目がないか探しましたが、見つからなかったので、denyのルールを追加したら出なくなりました。
# ufw deny to 224.0.0.0/4
iptables -Lで確認し、問題なさそうだったので、ルータのポートフォワーディングを設定します。IPv4はルータ②、IPv6はルータ①なので、それぞれのルータのポートフォワーディングを設定します。
設定後、スマホなどで、外部からアクセスできることを確認したらOK。NginxのSSL証明書の設定に入ります。
Cerbot
証明書は、以前さくらインターネットで使ったことのある、無料のLet’s Encryptを使うつもりでした。さくらは更新も自動でやってくれてたのですが、自宅サーバの場合は自分で更新もやらなくちゃなので、自動更新するためのツールを探したら、Cerbotというドンピシャなツールを見つけたので、さっそくインストールしました。
# apt install python3-certbot-nginx
# certbot --nginx -d zzz.0am.jp --preferred-challenges=http
このあと、対話的に何か聞かれたような気がしますが、これだけでLet’s Encryptから証明書をとってきて、Nginxの設定もしてくれました。自動更新のスケジュールはどうするの?と思ったのですが、そつなく1日2回チェックするようになってました。
# systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Wed 2020-06-03 15:55:42 JST; 3 weeks 6 days ago
Trigger: Wed 2020-07-01 08:28:06 JST; 9h left
Triggers: ● certbot.service
Jun 03 15:55:42 zzz systemd[1]: Started Run certbot twice daily.
WordPress
https://ja.wordpress.org/download/releases/ からtar ballをダウンロードし、Nginxのドキュメントルート(/md/sd/www/html)に展開します。最初 ja 版じゃないのをダウンロードしたら、日本語表示できなかったので、ja版を再インストールしました。
# wget https://ja.wordpress.org/wordpress-5.4.2-ja.tar.gz
# tar xfz wordpress-5.4.2-ja.tar.gz
# rm !$
# chown -R www-data:www-data wordpress
ここにPG4WPというPostgreSQL用のプラグインを入れるのですが、まず情報収集。 https://wordpress.org/support/plugin/postgresql-for-wordpress/ でPG4WPの情報を確認できますが、メンテナンスされていないようです。
とりあえず、https://github.com/kevinoid/postgresql-for-wordpress の wp4pg をダウンロードして展開します。
他の検索で見つけた https://github.com/php4dev/heroku-wordpress/tree/d65081fc8c942d8c8bfb4a78e6bd03aa10ceffbe の driver_pgsql.php のほうがよさげだったので、上書きします。
wp4pg ディレクトリを /md/sd/www/html/ にまるごとコピー。wp-config.phpを用意し、php関係の必要なパッケージをインストール。
# cp -rp wp4pg /md/sd/www/html
# cd /md/sd/www/html
# cp wp-config-sample.php wp-config.php
# vi wp-config.php
# apt install php-pgsql
# apt install php-gd
この状態で起動すると、wp-includes/load.php でエラーが発生したので、以下を追記。
if ( ! defined( 'WP_CONTENT_DIR' ) ) {
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // No trailing slash, full paths only - WP_CONTENT_URL is defined further down.
}
再起動。
systemctl restart nginx.service
systemctl restart php7.4-fpm.service
以上で一応初期画面が表示できるようになりました。その後、いくつかエラーが発生したので、都度対応していたのですが、さすがにモチベーションが保てませんでしたので、mariaDBへ変更しました。
MariaDB
PostgreSQLのdebをアンインストール、MariaDBのdebをインストール、データ領域変更、再起動、mariadb_secure_installationの実行、wordpressアカウント作成、wordpress DB作成。php-mysqlインストール。
# apt autoremove postgresql-client-common postgresql-common postgresql-client-12 postgresql-12 postgresql
# apt autoremove php-pgsql php7.4-pgsql
# apt install mariadb-server
# vi /etc/mysql/mariadb.conf.d/50-server.cnf
datadir = /mnt/sd/mysql_data に変更
# systemctl restart mariadb
# mysql_secure_installation
# mysql
MariaDB [(none)]> grant all privileges on wordpress.* to wordpress@localhost identified by '*********';
MariaDB [(none)]> create database wordpress;
# apt install php-mysql
で、前のWordpressを消して、素のWordpressを展開し再起動したら、あっけなく立ち上がりました。サイトヘルスで確認も可能でした。
セキュリティ対策
WordPressは便利な反面、セキュリティ対策をちゃんとしないと、勝手に書き換えられたり、トロイの木馬を置かれたりするリスクが高いので、セキュリティ対策は必須だと思います。
“All In One WP Security”プラグインを入れ、ほぼ全ての機能をONにしました。
Nginxのほうでアクセスコントロールの設定をしました。
location ~ /(wp-admin|wp-login.php|wp-activate.php|wp-signup.php) {
allow 127.0.0.1;
allow 192.168.10.0/24;
allow FE80::/64;
allow 2404:xxxx:xxxx:xxxx::/64;
deny all;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
エラーページなどでNginxのバージョンを表示しないように、nginx.conf に以下を追加しました。
server_tokens off;