ConoHa で、CentOS7+nginx+mariadb+SSL化+http2+spdy対応サイトを構築する

スポンサーリンク


可愛いマスコットキャラクター、三雲このはで有名なVPSサービス「ConoHa」。
オールSSDクラウドでかつ月料金が900円〜契約できるので、人気を博しています。

今回は、ConoHaの月額900円プランで、http2に対応したモダンなWordpressサイトを構築する手順をご紹介します。



時代はSSLへ

Googleが、2016年9月8日にChromeで非SSLサイトへアクセスした際に、段階的に警告を表示する方針であることを発表しました。

SSL

まずは2017年1月から、クレジットカードの番号、パスワードを送信するページに対して、「Not Secure」と表示されるようになります。

screenshot-2016-10-23-15-22-04

して、いずれは全てのhttpサイトに対して、「Not Secure」と表示していく方針とのこと。

また、SSL化しているサイトについてはSEOで優遇されるという話もあがってきています。
そこで、この機会を利用して所有している全ドメインについてSSL化してみました。

当記事では、備忘録も兼ねてSSL化手順を紹介したいと思います。

事前準備

必要なパッケージをyum経由でインストールします。

yum groupinstall -y "Development Tools"
yum install -y pcre-devel openssl-devel libxslt-devel gd-devel perl-ExtUtils-Embed epel-release patch git wget

次に、ファイアウォールの80/TCPポート、443/TCPポートを接続許可設定します。

firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

systemdのサービス登録などが面倒なので、一旦yumでnginxをインストールします。

yum install -y nginx
systemctl enable nginx
systemctl start nginx

PHP7のインストール

rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum install -y --enablerepo=epel,remi-php70 php php-mbstring php-pear php-fpm php-mcrypt php-mysql

php-fpmの設定

userとgroupがapacheとなっているので、nginxに変更します。

systemctl enable php-fpm
systemctl start php-fpm
スポンサーリンク

最新のmariadbをインストール

標準リポジトリからインストールできるmariadbのバージョンは古いので、mariadbのリポジトリを登録して、最新バージョンをインストールします。

rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
vim /etc/yum.repos.d/mariadb.repo

mariadb.repoを下記の通り編集します。

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2.1/centos7-amd64/
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
enabled=0

リポジトリの登録ができたら、下記のコマンドでmariadbをインストールします。

yum update
yum install -y --enablerepo=mariadb mariadb mariadb-server

mariadbの起動と自動起動登録

systemctl enable mariadb
systemctl start mariadb

mariadb初期設定

一番最初にrootのパスワードを聞かれますが、初期設定はパスワード設定されていないため、そのままEnterキーを押します。

Set root password? [Y/n]と聞かれるので、yを入力してEnterキーを押すと新しいrootパスワードの設定ができますので、そこでrootパスワードの設定をします。

mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

nginxのビルド

本来であれば、yumからインストールするのが手っ取り早いのですが、http2対応に必要ですので、nginxをソースからビルドします。

必要ファイルのダウンロード

nginxをビルドする際、opensslも必要ですのでついでにダウンロードします。

cd /usr/local/src
wget https://www.openssl.org/source/openssl-1.0.2-latest.tar.gz
wget http://nginx.org/download/nginx-1.9.7.tar.gz

OpenSSLのビルド

OpenSSLをビルドします。
執筆当時のOpenSSL 1.0.2の最新バージョンは OpenSSL 1.0.2jです。

tar zxf openssl-1.0.2-latest.tar.gz
cd openssl-1.0.2j
./config
make
make test
make install

nginxをビルドします。その際、CloudFlareのspdyおよびhttp2両方を有効化するパッチを当ててからビルドします。

cd /usr/local/src
wget https://raw.githubusercontent.com/cloudflare/sslconfig/master/patches/nginx__http2_spdy.patch
tar zxf nginx-1.9.7.tar.gz
cd /usr/local/src/nginx-1.9.7
patch -p1 < ../nginx__http2_spdy.patch
./configure --with-http_spdy_module --with-http_v2_module --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.2j
make
make install
mv /sbin/nginx /root/
mv /usr/local/nginx/conf/ /root/
ln -s /usr/local/nginx/sbin/nginx /sbin/nginx
ln -s /etc/nginx /usr/local/nginx/conf
mkdir /var/nginx
mkdir /var/nginx/cache1
スポンサーリンク

nginxの設定

nginx.confを編集

1つのサーバ上で複数のドメインを運営することを考えていますので、
各ドメインの設定は、/etc/nginx/sites-available内に作成し、
/etc/nginx/sites-enableへシンボリックリンクを張り、nginxから
/etc/nginx/sites-enable内を見に行くように設定します。

mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enable

vimで/etc/nginx/nginx.confに下記の内容を記載します。

# 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        16;
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 10240;
    accept_mutex_delay 100ms;
}

http {
    include             mime.types;

    open_file_cache     max=100 inactive=20s;
    access_log          off;


    server_tokens off;
    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;

    gzip                on;
    gzip_vary           on;
    gzip_proxied        any;
    gzip_http_version   1.0;
    gzip_types          text/plain
                        text/xml
                        text/css
                        application/xml
                        application/xhtml+xml
                        application/rss+xml
                        application/atom_xml
                        application/javascript
                        application/x-javascript
                        application/x-httpd-php;
    gzip_disable        "MSIE [1-6]\.";
    gzip_disable        "Mozilla/4";
    gzip_comp_level     1;
    gzip_buffers        4 8k;
    gzip_min_length     1100;


    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    proxy_cache_path  /var/cache/nginx/cache1 levels=1 keys_zone=cache1:128m;
    proxy_cache cache1;
    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-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache_valid 200 404 30m;


    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.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enable/*;
    include /usr/share/nginx/modules/*;
#    server {
#        listen       80 default_server;
#        listen       [::]:80 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

設定ファイルの編集が完了したら、設定ファイルに誤りが無いことを確認した後、nginxを再起動します。

nginx -t
systemctl restart nginx

各ドメイン用の設定ファイル作成

hogehoge.comが対象とします。

touch /etc/nginx/sites-available/hogehoge.com
ln -s /etc/nginx/sites-available/hogehoge.com /etc/nginx/sites-enable/hogehoge.com

/etc/nginx/sites-available/hogehoge.comを下記の通り記載します。

server {
    etag off;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options nosniff;

    #サーバ設定
    listen       80;
    #ドメイン名を設定
    server_name  hogehoge.com;
    # ドキュメントルートを設定
    root        /var/www/hogehoge/html;
    index       index.php index.html index.htm;

    # ログファイルの設定
    access_log   /var/log/nginx/hogehoge.com/access.log;
    error_log    /var/log/nginx/hogehoge.com/error.log;

    # WordPress用リダイレクト
    try_files $uri $uri/ /index.php?q=$uri&$args;

    # PHP FPM
    location ~ \.php$ {
        fastcgi_pass            127.0.0.1:9000;
        fastcgi_index           index.php;
        fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include                 fastcgi_params;
    }
}

ドキュメントルートの作成とログディレクトリを作成します。

mkdir -p /var/www/hogehoge/html
touch /var/www/hogehoge/html/index.html
mkdir /var/log/nginx/hogehoge.com
touch /var/log/nginx/hogehoge.com/access.log
touch /var/log/nginx/hogehoge.com/error.log

もし、冒頭のyum install nginxでnginx 1.9.11をインストールしてしまった場合、1.9.11からサポートされる動的モジュールが原因でnginxが起動できない場合があります。その際は、下記のコマンドを実行し、動的モジュールを退避させることで解決できます。

mv /usr/share/nginx/modules/ /root

nginxの起動

最低限の設定が完了したので、nginxの起動および自動起動登録を行います。

systemctl enable nginx
systemctl start nginx

SSL証明書の発行

SSL証明書にはLet’s Encryptを使用します。

Let’s Encryptは起動毎にアップデートを実施するため、依存ソフトウェアの取得や更新を行います。そのため、初回起動時はhelpを表示し、Let’s Encryptのクライアントを構築します。

cd /usr/local/bin
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help --debug
cd /etc/nginx
openssl dhparam 2048 -out dhparam_2048.pem

各ドメイン向けのSSL証明書を発行

次にSSL証明書を発行します。

cd /usr/local/bin/letsencrypt
./letsencrypt-auto certonly --webroot --webroot-path /var/www/hogehoge/html -d hogehoge.com

SSL証明書の発行が完了したら、hogehoge.comの設定ファイルを下記の通りに編集します。

server {
        listen          80;
        server_name     hogehoge.com;
        return 301 https://$server_name$request_uri;
}

server {
    client_max_body_size 20m;
    etag off;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options nosniff;
    listen       443 ssl spdy http2;
    ssl         on;

    ssl_certificate             /etc/letsencrypt/live/hogehoge.com/fullchain.pem;
    ssl_trusted_certificate     /etc/letsencrypt/live/hogehoge.com/chain.pem;
    ssl_certificate_key         /etc/letsencrypt/live/hogehoge.com/privkey.pem;
    ssl_session_timeout         1d;
    ssl_session_cache           shared:SSL:50m;

    ssl_dhparam                 /etc/nginx/dhparam_2048.pem;

    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                 AESGCM:HIGH:ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS;
    ssl_prefer_server_ciphers   on;

    add_header                  Strict-Transport-Security max-age=15768000;

    ssl_stapling                on;
    ssl_stapling_verify         on;
    resolver                    8.8.8.8 8.8.4.4;

    # サーバー名を設定します。
    server_name  hogehoge.com;
    # ドキュメントルートディレクトリを設定します。
    root         /var/www/hogehoge/html;
    # index file タイプの優先順を設定します。
    index       index.php index.html index.htm;

    # ログファイル名を設定します。
    access_log   /var/log/nginx/hogehoge.com/access.log;
    error_log    /var/log/nginx/hogehoge.com/error.log;

    # WordPress用のリダイレクト設定
    # ファイルが存在しないURIの場合は、index.phpへ転送させる。
    try_files $uri $uri/ /index.php?q=$uri&$args;

    # PHP FPM との接続を行うため 拡張子phpに対して処理します。

    location ^~ /.well-known/acme-challenge/ {
        root            /var/www/hogehoge/html;
    }

    location = /.well-known/acme-challenge/ {
        return          404;
    }

    location / {
        if (!-e $request_filename) {
            rewrite ^.+?(/wp-.*) $1 last;
            rewrite ^.+?(/.*\.php)$ $1 last;
            rewrite ^ /index.php last;
        }
    }

    location ~ \.php$ {
        if (!-f $request_filename) {
                return 404;
                break;
        }
        fastcgi_pass            127.0.0.1:9000;
        fastcgi_index           index.php;
        fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include                 fastcgi_params;
        fastcgi_send_timeout    5m;
        fastcgi_read_timeout    5m;
        fastcgi_connect_timeout 5m;
        fastcgi_pass_header     "X-Accel-Expires";
    }



        location ~ .*\.(html?|jpe?g|gif|png|css|js|ico|woff) {
                access_log              off;
                expires                 10d;
        }
}

これでSSL証明書の発行および設定が完了しました。

あとは、設定ファイルに間違いが無いことを確認した後、nginxを再起動します。

nginx -t
systemctl restart nginx

もし他のドメインに対してもSSL証明書を発行したい場合は、各ドメイン向けのSSL証明書発行をドメイン分実行してください。

SSL証明書の自動更新

Let’s Encryptが発行するSSL証明書は有効期限が3ヶ月しかありません。これはLet’s Encryptが新興サービスであるための措置とのことでした。

certbot-auto renew –force-renewコマンドを実行し、WEBサーバを再起動すれば更新されますが、手動ですると更新忘れなどの恐れがあるので、crontabに登録します。

crontab -u root -e

以下の内容を最下行に追記します。

00 05 01 * * /usr/local/bin/letsencrypt/certbot-auto renew --force-renew && /bin/systemctl reload nginx.service

nginxの再起動

ここまで完了したら、nginxの設定ファイルに問題が無いことを確認してから、nginxを再起動します。

nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

systemctl restart nginx

まとめ

長くなりましたが、これでHTTP2およびSPDYに対応したWEBサーバーを構築することができます。

SSL Check

この通りに設定すれば、SSLスコアも高水準な物が取得できるはずです。

Source:Google Security Blog | CloudFlare | mariadb | nginx | OpenSSL | Let’s Encrypt

スポンサーリンク






コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

ABOUTこの記事をかいた人

スマートフォンからIoT、サーバーに至るまで、ありとあらゆるデジタルガジェットを好みます。

ネタに走ることが好きな性格上、日頃からバカみたいな事に全力で取り組んでいます。

例えば、Googleで「ICOCA残高 Twitter」と検索すると、検索結果の一番上にTwitterのアカウントページが表示されたりします。