HTTPS接続のリバプロ下にあるWEBサーバにWordpressを導入する

#この記事を書いた理由
Qiitaになんか書いてみよう
↓
書けるネタと技術がない
↓
業務中悩んだけどネットでまとまった答えがなかったことについてでもまとめてみよう

#今回の要件

- ネットワーク構成は以下のイメージ

外部インターネット　～(https通信)～　リバプロサーバ(Nginx)　～(LAN内http通信)～　WordPress導入サーバ(wpサーバ)

- WordPressはサーバ内に2つ設置し、外部からは同ドメインでアクセスし、
　ディレクトリ名に応じてリバプロサーバが2つのWordPressのアドレスへ振り分ける
例）
https://www.example.com/wp1/~ →WordPress1
https://www.example.com/wp2/~ →WordPress2


- 実装環境は全サーバ共通でCentOS7.5

- WordPress及び関連ミドルウェアのバージョン要求は以下の通り
 - WordPress 4.9.x
 - PHP 7.2.x
 - MySQL 5.7.x

#リバプロサーバでの準備

```:/etc/nginx/conf.d/proxy.conf

server {
        listen 443 ssl;
        server_name  www.example.com;

        ssl_certificate      /etc/nginx/ssl/server.cer;
        ssl_certificate_key  /etc/nginx/ssl/server.key;

        （省略）

        location /wp {
                proxy_pass              http://192.168.100.10;     #wpサーバのプライベートIP
                proxy_redirect                         default;
                proxy_set_header Host                  $host;
                proxy_set_header X-Real-IP             $remote_addr;
                proxy_set_header X-Forwarded-Host      $host;
                proxy_set_header X-Forwarded-For       $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto     $scheme; 
                proxy_set_header X-Forwarded-Port      443;

        }
}

```



やっていることは
・プロキシ先にアクセス元の正しいIPを伝える設定
・クライアント~リバプロ間がhttps通信であることを伝える設定
これをしないとWordPressがうまくリンクやリダイレクトを作れなくなり、ログを見ても誰のアクセスかわからなくなる

#導入
##apacheとPHPのインストール

apacheをインストールする
`# yum -y install httpd`

apacheの設定ファイルのバックアップを作成
`# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org`

apacheの設定ファイルを編集
`# vi /etc/httpd/conf/httpd.conf`

```httpd.conf
(157行目付近　.htaccessによる個別の設定上書きを許可するように追記)
</Directory>
#以下の１０行を追記
<Directory "/var/www/html/wp1">
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>
<Directory "/var/www/html/wp2">
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#

(略）

(196行目付近 アクセス元ipの表示がリバプロサーバのipではなく実際にアクセスしているホストのIPになるように変更)
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b" common
 # %h を \"%{X-Forwarded-For}i\" に変更

```

php5.4系が既にインストールされてる場合、競合する可能性があるので確認
`# yum list installed |grep php`

もしphpに関するパッケージがあった場合削除
`# yum remove php*`

centosの標準リポジトリにはphp7.2がないので追加する
`# yum -y install http://ftp.riken.jp/Linux/remi/enterprise/remi-release-7.rpm`

追加リポジトリを利用してphpと関連するパッケージをインストールする
`# yum -y install --enablerepo=remi,remi-php72 php php-mysql php-mbstring php-gd`

インストール完了後、バージョン確認
`# php -v`

```
PHP 7.2.9 (cli) (built: Aug 31 2018 00:00:00) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

ブラウザからPHPのバージョンが見えないようにする
`# vi /etc/php.ini`

```
(374行目付近)
expose_php = Off   #OnをOffに変更する
```


apache起動
`# systemctl start httpd`
`# systemctl enable httpd`

##MySQLのインストール及び初期設定

MariaDBがあると競合するので確認
`# yum list installed|grep maria`

ある場合

```
mariadb-libs.x86_64                 1:5.5.60-1.el7_5               @updates
```

アンイストールする
`# yum -y remove mariadb-libs`

MySQLのリポジトリ入手
最新版はこちらで確認→　https://dev.mysql.com/downloads/repo/yum/

`# yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm`

インストール予定のバージョン確認
`# yum info mysql-community-server`

```
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
 Available Packages
 Name        : mysql-community-server
 Arch        : x86_64
 Version     : 8.0.12
 （以下略）
```

このままだとMySQL8.0がインストールされるので変更する
`# vi /etc/yum.repos.d/mysql-community.repo`

```/etc/yum.repos.d/mysql-community.repo
（略）
# Enable to use MySQL 5.7
[mysql57-community]
name=MySQL 5.7 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
enabled=1    #0から1に変更
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

[mysql80-community]
name=MySQL 8.0 Community Server
baseurl=http://repo.mysql.com/yum/mysql-8.0-community/el/7/$basearch/
enabled=0    #1から0に変更
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

（略）
```

もう一度インストール予定のバージョン確認
`# yum info mysql-community-server`

```
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
 Available Packages
 Name        : mysql-community-server
 Arch        : x86_64
 Version     : 5.7.23
 （以下略）
```

5.7がインストールされることが確認できる

MySQL5.7をインストール
`# yum -y install mysql-community-server`

設定ファイルを編集
`# vi /etc/my.cnf`

```/etc/my.cnf
（最下行に3行追記）
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4
```

デーモンとして実行し、恒常起動の設定
`# systemctl start mysqld.service`
`# systemctl enable mysqld.service`

初回のrootログイン用の一時パスワードが発行されるので確認
`# grep 'temporary password' /var/log/mysqld.log`

```
2018-08-31T00:00:00 1 [Note] A temporary password is generated for root@localhost: {一時パスワード}
```

一時パスワードを利用してrootでログイン
`# mysql -u root -p`

データベース移動
`> use mysql`

rootのパスワードを設定
`> update user set authentication_string=password('パスワード') WHERE user='root';`

**※mysqlのパスワードポリシーはデフォルトでは以下の通り**
・8文字以上
・大文字、小文字、数字、特殊文字をすべて最低1文字使用する

設定を反映
`> flush privileges;`

Wordpress用のデータベースを作成
`> create database データベース名;`

WordpressがDBにアクセスするためのユーザを作成
`> create user 'ユーザ名'@'localhost' identified by 'パスワード';`

作成したユーザにDBへの権限付与
`> GRANT ALL ON データベース名.* TO ユーザ名@localhost;`

##Wordpressのインストールと初期設定
こちらで最新バージョンのダウンロードURLを確認
https://ja.wordpress.org/download/

ディレクトリを移動

`# cd /var/www/html`

tarファイルをダウンロード
`# wget https://ja.wordpress.org/wordpress-4.9.8-ja.tar.gz`

解凍・展開
`# tar xf wordpress-4.9.8-ja.tar.gz`

展開されたwordpressディレクトリの名前を変更・複製
`# mv wordpress wp1`


wp-configをサンプルから複製・編集
`# cp wp1/wp-config-sample.php wp1/wp-config.php`
`# vi wp1/wp-config.php`

```php:/var/www/html/wp1/wp-config.php
（27行目付近）
// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define('DB_NAME', 'データベース名');

/** MySQL データベースのユーザー名 */
define('DB_USER', 'ユーザー名');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'パスワード'); #ここまでの3項目はこれまでに設定した情報を入力

/** MySQL のホスト名 */
define('DB_HOST', 'localhost');

/** データベースのテーブルを作成する際のデータベースの文字セット */
define('DB_CHARSET', 'utf8mb4');           #utf8から変更

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', '');


（55行目付近）
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');

#ここを、https://api.wordpress.org/secret-key/1.1/salt/　にアクセスして取得した値で置き換える

（72行目付近）
$table_prefix  = 'テーブル接頭辞';　#適当な接頭辞に書き換える。今回はWordpressを2つ同時に使用するので、区別できるようにする(例:wp1_hoge_)

（94行目付近）

if ( !defined('ABSPATH') )
        define('ABSPATH', dirname(__FILE__) . '/');

#ここから追記
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];

define('FORCE_SSL_ADMIN', true);

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
    && $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
  define('WP_HOME', 'https://www.example.com/wp1');     #サイト名(wp1のディレクトリ名まで含める)
  define('WP_SITEURL', 'https://www.example.com/wp1');
  $_SERVER['HTTPS'] = 'on';
}
#追記ここまで。必ずこの位置に追記すること(最下行などはNG)

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

```

ディレクトリをコピー
`# cp -r wp1 wp2`

編集
`# vi wp2/wp-config.php`
wp1の部分をwp2にすればいい
もちろん`sed`コマンドでも可

所有者を変更
`# chown -R apache:apache wp1`
`# chown -R apache:apache wp2`

権限を変更
`# chmod 600 wp1/wp-config.php`
`# chmod 600 wp2/wp-config.php`

管理ページにアクセス
https://www.example.com/wp1/wp-admin

画面の案内に従って管理アカウント作成などを行い、完了
wp2でも同じことを行う

#感想等
個人的にハマったところですが、
最初wp-configを編集する前にwp-adminにアクセスしてしまい、
そちらである程度初期設定は出来たものの管理ページ内のリンクが軒並みhttpに…

その後wp-configを編集するも、追記位置が違って反映されない…
PHPのことをよくわかっていないのですが、
define()で定義されるのは変数ではなく定数で、
定数は再定義できず、
最後のrequire_once(ABSPATH . 'wp-settings.php');
で定数が定義される前に追記文を実行しないとだめってことですかね？

なら
if ( !defined('ABSPATH') )
        define('ABSPATH', dirname(\_\_FILE__) . '/');
の後である必要性は特にない？

初投稿なのもあって稚拙な文章ではありますが、ここまで読んでいただきありがとうございました。

ご指摘等有りましたらコメントしてください。