👀

WordPress入門……?

15 min read

業務としてはバックエンドとかアーキテクチャとかをやりたい。しかし非フロントエンドのエンジニアだけで短期でWebサービスを作らなきゃいけない、みたいな。
現実的にWordPressでさくっと仮サイトを作れると有用なんじゃないかと感じたので入門しておくことにしました。

前提

  • PHP未経験、WordPress未経験
  • Linux、Docker、Webサーバ、Webセキュリティ等の基礎知識あり
  • C++経験あり、Python常用、Flask使用中、Redmine構築経験あり

とにかく動かしてみる

Dockerで起動

WordPressのDockerイメージはDocker Hub公式で提供されているのでこれを利用します。

https://hub.docker.com/_/wordpress
[centos@pmsv02 dev]$ sudo docker pull wordpress:php8.0-apache
php8.0-apache: Pulling from library/wordpress
(略)
Digest: sha256:c0d9b4c07608afca1f25307e8544857f241ca15f459b84e60bc94024ce11e959
Status: Downloaded newer image for wordpress:php8.0-apache
docker.io/library/wordpress:php8.0-apache
[centos@pmsv02 dev]$ sudo docker run -d --name wp -p 8800:80 wordpress:php8.0-apache
a2960b8cf9f2e1f1046dda00ae2d5309358d0f4e2b0a8b68d8445131c7c65cac
[centos@pmsv02 dev]$ sudo docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS        PORTS                  NAMES
a2960b8cf9f2   wordpress:php8.0-apache   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds  0.0.0.0:8800->80/tcp   wp

起動させたポートの通信を許可してブラウザでアクセスすると表示されました。
Dockerを学んで以来、何でも簡単に実行できてしまうのでスタートが楽です。

wordpress_初回アクセス

そのまま画面に任せて進めます。

  1. 日本語を選択 -> 続ける
  2. さあ、始めましょう!
  3. 適当にDB情報を入力 -> 送信
  4. データベース接続確立エラー

適当に入力ではダメでした……。ちゃんとDBを用意しろってことですね。
(なんかSQLiteとかで適当に起動してくれたりしないのかなー)

DBを用意してリトライ

私の場合は同サーバにMariaDBのコンテナがあるので、ここにユーザーとデータベースを作成しておいてリトライします。

[centos@pmsv02 dev]$ sudo docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED       STATUS       PORTS                    NAMES
a2960b8cf9f2   wordpress:php8.0-apache   "docker-entrypoint.s…"   4 days ago    Up 4 days    0.0.0.0:8800->80/tcp     wp
dc372d29e2a2   mariadb:10.5.8            "docker-entrypoint.s…"   2 weeks ago   Up 2 weeks   0.0.0.0:3306->3306/tcp   mariadb
[centos@pmsv02 dev]$ sudo docker exec -it mariadb mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 318
Server version: 10.5.8-MariaDB-1:10.5.8+maria~focal mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database wp;
Query OK, 1 row affected (0.068 sec)

MariaDB [(none)]> create user 'wp'@'172.17.0.%' identified by 'password';
Query OK, 0 rows affected (0.046 sec)

MariaDB [(none)]> grant all privileges on wp.* to 'wp'@'172.17.0.%';
Query OK, 0 rows affected (0.014 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.026 sec)

MariaDB [(none)]> \q
Bye

wordpress_データベース設定

これで大丈夫でした。
ポート指定いらないのはMariaDBのデフォルトだからでしょうか?

  1. インストール実行
  2. ユーザー情報などを入力 -> WordPressをインストール
  3. ログイン
  4. ユーザー名・パスワードを入力 -> ログイン

ダッシュボードが表示されました。

wordpress_ダッシュボード

サイトを表示することもできる。一応ログアウトして確認。

wordpress_サイト表示

Hello world!

いろいろ確認

実行まではイメージ通りで簡単でした。
問題はこのあと、ちゃんと思い通りのサイトにできるのかといところですが、まずはざっくりと状況を確認していきます。

管理画面の確認

更新とかは無視して設定を見ていきます。
見ていると、なるほどこれはブログだな、と思います。

  • 随時追加生成する<投稿>と、<固定ページ>とでサイトを構成する。
  • リソース類は<メディア>として管理する。
  • <コメント>の管理がある。

WordPressでサイトを構築するということは、こういった様式に当てはめる形で構成を考えないといけないということでしょう。
あまりブログを作る意味はないので、会員制サイトとかを作れるように理解しておきたいところ。

  • <外観>は、<テーマ>、<ウィジット>、<メニュー>、<背景>などで作成する。
    → <テーマ>ってのは単なるCSSのこと?
  • <プラグイン>は機能的な拡張だろうけれど、有効化したらどうなるのかが見えにくい
  • <ユーザー>の管理機能では、権限グループも設定できる
    → つまり管理ユーザーだけではなく、サイト利用者としてのユーザーにも使える模様
  • <設定>の<一般設定>に誰でもユーザー登録できるようにする設定がある。
  • <設定>の<表示設定>や<パーマリンク設定>はカスタマイズの基本か。

機能が充実してるのはいいんだけどプログラムを書かせない作りになっているので、管理画面だけでできない機能を付け加えるのは難しそう。

DBの確認

DBのほうにどんな感じでデータが入っているのかもさらっと見ておきます。

[centos@pmsv02 dev]$ sudo docker exec -it mariadb mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 926
Server version: 10.5.8-MariaDB-1:10.5.8+maria~focal mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use wp
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [wp]> show tables;
+-----------------------+
| Tables_in_wp          |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
12 rows in set (0.002 sec)

MariaDB [wp]> show columns from wp_comments;
+----------------------+---------------------+------+-----+---------------------+----------------+
| Field                | Type                | Null | Key | Default             | Extra          |
+----------------------+---------------------+------+-----+---------------------+----------------+
| comment_ID           | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| comment_post_ID      | bigint(20) unsigned | NO   | MUL | 0                   |                |
| comment_author       | tinytext            | NO   |     | NULL                |                |
| comment_author_email | varchar(100)        | NO   | MUL |                     |                |
| comment_author_url   | varchar(200)        | NO   |     |                     |                |
| comment_author_IP    | varchar(100)        | NO   |     |                     |                |
| comment_date         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| comment_date_gmt     | datetime            | NO   | MUL | 0000-00-00 00:00:00 |                |
| comment_content      | text                | NO   |     | NULL                |                |
| comment_karma        | int(11)             | NO   |     | 0                   |                |
| comment_approved     | varchar(20)         | NO   | MUL | 1                   |                |
| comment_agent        | varchar(255)        | NO   |     |                     |                |
| comment_type         | varchar(20)         | NO   |     | comment             |                |
| comment_parent       | bigint(20) unsigned | NO   | MUL | 0                   |                |
| user_id              | bigint(20) unsigned | NO   |     | 0                   |                |
+----------------------+---------------------+------+-----+---------------------+----------------+
15 rows in set (0.001 sec)

MariaDB [wp]> show columns from wp_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field                 | Type                | Null | Key | Default             | Extra          |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   |     | NULL                |                |
| post_title            | text                | NO   |     | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(255)        | NO   |     |                     |                |
| post_name             | varchar(200)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.001 sec)

MariaDB [wp]> show columns from wp_options;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| option_id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| option_name  | varchar(191)        | NO   | UNI |         |                |
| option_value | longtext            | NO   |     | NULL    |                |
| autoload     | varchar(20)         | NO   | MUL | yes     |                |
+--------------+---------------------+------+-----+---------+----------------+
4 rows in set (0.001 sec)

MariaDB [wp]> select count(*) from wp_options;
+----------+
| count(*) |
+----------+
|      147 |
+----------+
1 row in set (0.012 sec)

DBのテーブル構成は思ってたよりずっとシンプルでした。
プラグイン入れたらテーブル増えたりとかするんでしょうか?

記事やコメントに使用されているtext型は65,535byteまでしか保存できないらしいけれど、それ以上書き込もうとしたらどうなるんでしょう?
と思って検索したら過去にそれが原因のXSS脆弱性があったらしいですね。ちょっと不安……。
結局どう処理されるのかわからないので、暇なときに試してみましょう。

テーブル構成はシンプルなんですが、wp_optionsに何が入ってるのかなと思って覗いてみたら、longtext型でわりと大量のデータがあったので、そんなバケツに放り込む感じでやってるんですかね。

HTTPレスポンスヘッダー

あまり意味はないですが見ておきます。

Wordpress_レスポンスヘッダー

WebサーバーやPHPのバージョンがわかりますね。
api.w.orgは何でしょうか?
→検索してみると、WordPressのREST API機能の関連のようです。そしてまた過去の脆弱性。
デフォルトでREST APIを公開しているんですか? 不要ですよね?

サーバーの中身

一応見ておきます。

[centos@pmsv02 dev]$ sudo docker exec -it wp /bin/bash
root@00dbff533853:/var/www/html# ls -l 
total 216
-rw-r--r--.  1 www-data www-data   405 Feb  6  2020 index.php
-rw-r--r--.  1 www-data www-data 19915 Feb 12  2020 license.txt
-rw-r--r--.  1 www-data www-data  7278 Jun 26  2020 readme.html
-rw-r--r--.  1 www-data www-data  7101 Jul 28  2020 wp-activate.php
drwxr-xr-x.  9 www-data www-data  4096 Feb 22 15:10 wp-admin
-rw-r--r--.  1 www-data www-data   351 Feb  6  2020 wp-blog-header.php
-rw-r--r--.  1 www-data www-data  2328 Oct  8 21:15 wp-comments-post.php
-rw-r--r--.  1 www-data www-data  2913 Feb  6  2020 wp-config-sample.php
-rw-rw-rw-.  1 www-data www-data  3183 Mar 11 21:38 wp-config.php
drwxrwxrwx.  7 www-data www-data    97 Mar 12 15:16 wp-content
-rw-r--r--.  1 www-data www-data  3939 Jul 30  2020 wp-cron.php
drwxr-xr-x. 25 www-data www-data  8192 Feb 22 15:10 wp-includes
-rw-r--r--.  1 www-data www-data  2496 Feb  6  2020 wp-links-opml.php
-rw-r--r--.  1 www-data www-data  3300 Feb  6  2020 wp-load.php
-rw-r--r--.  1 www-data www-data 49831 Nov  9 10:53 wp-login.php
-rw-r--r--.  1 www-data www-data  8509 Apr 14  2020 wp-mail.php
-rw-r--r--.  1 www-data www-data 20975 Nov 12 14:43 wp-settings.php
-rw-r--r--.  1 www-data www-data 31337 Sep 30 21:54 wp-signup.php
-rw-r--r--.  1 www-data www-data  4747 Oct  8 21:15 wp-trackback.php
-rw-r--r--.  1 www-data www-data  3236 Jun  8  2020 xmlrpc.php
root@00dbff533853:/var/www/html# ls -l ../
total 4
drwxrwxrwx. 5 www-data www-data 4096 Mar 11 21:38 html
root@00dbff533853:/var/www/html# ls -l wp-admin
total 1080
(省略)
root@00dbff533853:/var/www/html# ls -l wp-content
total 8
(省略)
root@00dbff533853:/var/www/html# ls -l wp-includes
total 6388
(省略)
root@00dbff533853:/var/www/html# cat wp-config.php
(省略)
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wp' );

/** MySQL database username */
define( 'DB_USER', 'wp' );

/** MySQL database password */
define( 'DB_PASSWORD', 'password' );

/** MySQL hostname */
define( 'DB_HOST', '172.17.0.1' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
(省略)

こんな感じですか……なんかすごい剥き出しですね。
というかこんなんでいいんですか?
WordPressのライセンステキストってユーザーに公開しなきゃいけないんですか?
ブラウザでwp-cron.phpにアクセスしてみたらなんかグルグルしてからコード200で空レスポンスが返りますけど、そういう設計なんですか?

wp-config.phpはDB接続に必要な設定情報なので永続化しておかないといけないですね。
それ以外の保全すべきデータは全てDBにあると思っていていいのでしょうか?

続きはあとで

年度末で忙しいこともあり、ここで記事を切ります。
フリーのテーマといくつかのプラグインを入れてある程度カスタマイズしてみるところまではやりたいと思っていますが。

Discussion

ログインするとコメントできます