CentOS7+nginx+php7+MariaDBでWordPressを再構築したときのメモ

このブログを始めてすぐのことでしたが、引っ越しました。 当サイトはhttpsから始まるSSLを使用したサイトで、サブドメインを使用していました。 しかしHSTS Preload listにはサブドメインのサイトを申請することはできなかったのが理由です。 ついでにAzureではなくCentOSで試しに稼働させてみることにしたので、構築の流れをまとめておきます。前提として、さくらのVPSにてCentOS7を標準インストールしたものとしています。  
HSTS Preload listとは
httpsのサイトをhttpからアクセスしようとしたときに、自動的にhttpsに変えて接続する仕組みのひとつです。 このPreload listに申請して登録され、さらにそのリストを接続する人のブラウザが持っていることが条件です。

CentOS7 初期設定

ユーザー名をdmoritaと仮定して進めます。各環境で置き換えてください。
Shell
// user作成
# useradd dmorita
# passwd dmorita

// rootになれるユーザーを限定
# usermod -G wheel dmorita
# vi /etc/pam.d/su
auth required pam_wheel.so use_uid //コメント解除

// viでvimが開くようにする
# vi ~/.bashrc
alias vi='vim' //エイリアス追加

# source ~/.bashrc

// アップデート
# yum -y update

// ファイアウォール追加
# firewall-cmd --permanent --add-service=http
# firewall-cmd --permanent --add-service=https

SSHの設定

VPSは自宅のようにポートを塞ぐことができないので、公開鍵認証のみとします。
Shell
# vi /etc/ssh/sshd_config
// 詳細は下記
# $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
# The default requires explicit activation of protocol 1
Protocol 2
# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 1024
# Ciphers and keying
#RekeyLimit default none
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
RSAAuthentication no
PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
AuthorizedKeysCommand none
AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
IgnoreUserKnownHosts yes
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
PermitEmptyPasswords no
PasswordAuthentication no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
#GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
UsePrivilegeSeparation sandbox # Default for new installations.
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
AllowUsers dmorita nginx
view raw sshd_conf hosted with ❤ by GitHub
Shell
# mkdir -p /home/dmorita/.ssh

# vi /home/dmorita/.ssh/authorized_keys
ssh-dss xxxxx・・・xxxxx //公開鍵

# chmod 700 /home/dmorita/.ssh
# chmod 600 /home/dmorita/.ssh/authorized_keys
# chown dmorita. /home/dmorita/.ssh

// sshd再起動
# systemctl restart sshd
この状態で秘密鍵を使ってログイン可能か、パスワードやrootログインできないようになっているか確認しましょう。

nginx初期設定

Shell
# sudo yum -y install epel-release
# rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

# yum -y install nginx

// 初期のconfigファイルをリネームしてとっておく
# mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
# vi /etc/nginx/conf.d/test.conf
//test.confは下記

# mkdir /var/www/html
# vi /var/www/html/index.html
//適当に何か

// nginx有効化
# systemctl enable nginx

// configファイルチェック
# nginx -t

// nginx起動
# systemctl start nginx
server_nameは適宜置き換えてください。
Shell
server {
  listen 80;
  server_name kiyo.space;
  root /var/www;
  index index.php index.html index.htm;

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

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    include fastcgi_params;
  }
}
この時点でindex.htmlが表示されるかを確認しましょう。
Shell
// nginxユーザーでSSHアクセスできるようにする場合(VaultPress用)
# usermod -s /bin/bash nginx
# passwd nginx

# systemctl stop nginx
# usermod -d /var/www nginx
# systemctl start nginx

# mkdir -p /var/www/.ssh

# vi /var/www/.ssh/authorized_keys
ssh-dss xxxxx・・・xxxxx //公開鍵

# chmod 700 /var/www/.ssh
# chmod 600 /var/www/.ssh/authorized_keys
# chown dmorita. /var/www/.ssh

phpの設定

Shell
# yum -y --enablerepo=epel,remi,remi-php70 install php php70-php-mbstring php-mbstring php-pear php70-php-fpm php-fpm php70-php-mcrypt php-mcrypt php70-php-mysqlnd php-mysql php70-php-gd php-gd

# vi /etc/php-fpm.d/www.conf
user = nginx
group = nginx

listen = /var/run/php-fpm.sock
listen.owner = nginx
listen.group = nginx

# systemctl enable php-fpm
# systemctl start php-fpm

# php -v
// PHPのバージョンが7であることを確認

# vi /var/www/html/index.php
<?php phpinfo() ?>
index.phpを開いて、phpinfoが表示されることを確認しましょう。

MariaDBの設定

Shell
# vi /etc/yum.repos.d/MariaDB.repo
// バージョンは適宜書きかえること
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

# yum -y install mariadb mariadb-server mariadb-client

# systemctl enable mariadb.service
# systemctl start mariadb.service

// 初期設定
# mysql_secure_installation

// WordPress用データベース作成
// データベース名・ユーザー名・パスワードなど適宜置き換えること
# mysql -u root -p
> create database wordpress;
> grant all privileges on wordpress.* to user@localhost identified by 'password';
> quit;
Wordpressの設定
Shell
# cd /var/www/

// 適宜最新バージョンに置き換えること
# wget https://ja.wordpress.org/wordpress-4.7.2-ja.tar.gz
# tar zxvf wordpress-4.7.2-ja.tar.gz

// nginxのホームディレクトリ以下の所有者等をnginxに変更
# cd ..
# chown -R nginx. www

// nginx設定変更
# vi /etc/nginx/conf.d/test.conf
root /var/www/wordpress;

# systemctl restart nginx
Webサーバーにアクセスし、Wordpressの初期設定ができることを確認し、初期設定を済ませましょう。

nginx設定の最適化とSSL設定

Shell
// SSL証明書のファイルを用意しておくこと
# cp /home/dmorita/kiyo.space.pem /etc/nginx/kiyo.space.pem //例
# cp /home/dmorita/kiyo.space.key /etc/nginx/kiyo.space.key //例
# openssl dhparam 4096 -out /etc/nginx/dhparam.pem

# mv /etc/nginx/conf.d/test.conf /etc/nginx/conf.d/test.conf.bak
# mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

# vi /etc/nginx/nginx.conf
// 詳細は下記参照

# vi /etc/nginx/conf.d/default.conf
// 詳細は下記参照

# nginx -t
# systemctl restart nginx
upstream backend {
server unix:/var/run/php-fpm/php-fpm.sock;
}
server {
listen 80;
server_name kiyo.space;
charset utf-8;
location / {
return 403;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
return 301 https://$host$request_uri;
}
server {
listen 443 default_server ssl http2;
server_name kiyo.space;
root /var/www/wordpress;
index index.php index.html index.htm;
charset utf-8;
ssl_certificate /etc/nginx/kiyo.space.pem;
ssl_certificate_key /etc/nginx/kiyo.space.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload';
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
location / {
index index.php;
try_files $uri $uri/ /index.php?q=$uri&$args;
if (!-e $request_filename) {
rewrite ^.+?(/wp-.*) $1 last;
rewrite ^.+?(/.*\.php)$ $1 last;
rewrite ^ /index.php last;
}
}
location ~* /\. {
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param https on;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache CZONE;
fastcgi_cache_valid 200 302 1d;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 5m;
#add_header X-Cache $upstream_cache_status;
#add_header Vary 'User-Agent';
set $skip_cache 0;
if ($request_method = "GET") {
set $skip_cache 1;
}
if ($request_method = "POST") {
set $skip_cache 1;
}
if ($request_method = "HEAD") {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
if ($request_uri ~* "(/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $skip_cache 1;
}
if ($request_uri ~* "(/wp-admin/|wp-login.php|wp-config.php|comments.php)") {
set $skip_cache 1;
}
if ($request_uri ~* "preview=true") {
set $skip_cache 1;
}
if ($request_uri ~* "amp=1") {
set $skip_cache 1;
}
if ($request ~* "/wp-includes/.*") {
set $skip_cache 1;
}
set $mobilef '';
if ($http_user_agent ~* '(iPhone|iPod|incognito|webmate|Android.*Mobile|Windows.*Phone|dream|CUPCAKE|blackberry9500|blackberry9530|blackberry9520|blackberry9550|blackberry 9800|webOS|s8000|bada|Googlebot-Mobile)') {
set $mobilef 'mobile.';
set $skip_cache 0;
}
if ($http_cookie ~ "(wordpress_logged_in_|comment_author_)(.*)") {
set $skip_cache 1;
}
location ~ .*\.(jpg|jpeg|gif|png|swf|woff|ico) {
access_log off;
expires 30d;
}
location ~ .*\.(css|js) {
access_log off;
expires 1d;
}
location ~ .*\.(html|htm) {
access_log off;
expires 10m;
}
}
}
view raw default.conf hosted with ❤ by GitHub
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 2048;
accept_mutex_delay 100ms;
use epoll;
multi_accept on;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
server_tokens off;
charset UTF-8;
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
access_log off;
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;
client_header_timeout 10;
client_body_timeout 10;
reset_timedout_connection on;
send_timeout 10;
limit_conn_zone $binary_remote_addr zone=addr:5m;
limit_conn addr 100;
# Gzip Settings
gzip on;
gzip_static always;
gunzip on;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_http_version 1.0;
gzip_comp_level 1;
gzip_proxied any;
gzip_types text/plain text/css application/javascript text/xml application/atom+xml application/xml+rss application/json text/json text/javascript+json;
gzip_disable "MSIE [1-6]\.";
gzip_disable "Mozilla/4";
gzip_vary on;
# Enable FastCGI cache
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=CZONE:10m max_size=1000M inactive=1d;
fastcgi_cache_key "$mobilef$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_cache_use_stale error timeout invalid_header http_500;
# Open file cache
open_file_cache max=100000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
include /etc/nginx/conf.d/*.conf;
}
view raw nginx.conf hosted with ❤ by GitHub

HTST preload listへの追加とSSL Reportの確認

変なプラグインを入れていなければ、多分この時点でHSTS Preload listへ登録することができると思います。 SSL ReportでもA+がとれるかと思います。

参考になるかもしれないページ

参考 HTTP Strict Transport Security (HSTS) and NGINXNGINX 参考 Strong SSL Security on nginxRaymii.org  

コメントを残す