KUSANAGIの中について
この記事は、KUSANAGI Advent Calender の22日目のエントリになります。
3日めには、はじめてのKUSANAGIということで、まったくもって初心者向けじゃないと大評判でした。ええはじめてとは言ったが初心者向けとは言ってないw
さて今回は、KUSANAGIで使用したり生成したりする設定ファイルを中心に、KUSANAGI内部の動作(の一部)について解説したいと思います。
KUSANAGIの設定ファイル
/etc/kusanagi
/etc/kusanagi は、KUSANAGIの仮想マシンデプロイ時に既に存在するファイルです。
以下のように、KUSANAGIのバージョンと、どのクラウドかという情報が記述されます。
KUSANAGI Version 8.0.2-1
aws
この情報は、kusanagi status で表示されます。
/etc/kusanagi.conf
kusanagiコマンドで使用するカレントプロファイルを設定するファイルです。
kusanagi targetで表示する プロファイル名が入ります。また、kusanagi target プロファイル名 を実行すると、このファイルが書き換えられます。
最初の kusanagi provision を行うまで空の文字列が設定されます。
PROFILE="kusanagi_html"
/etc/kusanagi.d/profile.conf
kusanagi provision した際に入力した情報を格納するファイルになります。
kusanagi コマンドでは、この情報を元に処理を行います。
[kusanagi_html]
PROFILE="kusanagi_html"
KUSANAGI_TYPE="WordPress"
KUSANAGI_FQDN="test.example.com"
KUSANAGI_DIR="/home/kusanagi/kusanagi_html"
KUSANAGI_DBNAME="kusanagi"
KUSANAGI_DBUSER="kusanagi"
KUSANAGI_DBPASS="パスワード"
WPLANG="ja"
OPT_WOO=""
[LAMP]
PROFILE="LAMP"
KUSANAGI_TYPE="lamp"
KUSANAGI_FQDN="lamp.example.com"
KUSANAGI_DIR="/home/kusanagi/LAMP"
KUSANAGI_DBNAME="lamp"
KUSANAGI_DBUSER="lamp"
KUSANAGI_DBPASS="パスワード"
WPLANG=""
OPT_WOO=""
/etc/kusanagi.d/ssl_sess_ticket.key
kusanagi init時に生成する、 TLSセッションチケットファイルです。
TLSセッションチケットとはTLSのセッション情報を暗号化してクライアント側に保存することで HTTPS通信時に行われるTLSハンドシェイクの手順を省略するしくみです。
これを採用すると、TLS接続時ののレイテンシを削減することができます。詳細は、https://techblog.yahoo.co.jp/infrastructure/ssl-session-resumption/ のTLS Session Ticket 拡張を参考にしてください。
/etc/kusanagi.d/ssl/dhparam.key
kusanagi init時に生成する、DH鍵交換に使用するパラメータファイルです。
KUSANAGIが生成するNGINXの設定では、DH鍵交換を含む暗号スイート(EECDH+CHACHA20、EECDH+CHACHA20-draft、EECDH+AESGCM、EDH+AESGCM、AES256+EECDH、AES256+EDH、ECDHE-RSA-AES256-GCM-SHA384 などなど)を含んでいます。この際、鍵交換に使用されるパラメータファイルを作成する必要があります。
この処理は、openssl dhparam 2048 -out /etc/kusanagi.d/ssl/dhparam.key として実行して、2048bitの暗号を生成するのでかなり時間がかかります。
NGINXの設定ファイル
NGINXの設定ファイルは、プロファイルごとにHTTP/HTTPS用の設定ファイルを用意し、VirtualHostで設定を行います。
/etc/nginx/nginx.conf
NGINXの共通設定となります。
このファイル中で、ログのフォーマット、gzip や brotli の圧縮設定、ファイル関係のチューニングパラメータを記述しています。
/etc/nginx/fastcgi_params
FastCGIのパラメータを記述しています。
/etc/nginx/conf.d/プロファイル_http.conf
HTTP接続で使用する設定ファイルです。
kusanagi provision 時に自動生成されます。この時、/usr/lib/kusanagi/resource/etc/nginx/conf.d/fqdn_http.conf* をテンプレートとしています。
この内容は、プロビジョンタイプによって異なります。
https redirect
kusanagi ssl –https redirect を実行すると、このファイル中の以下のコメントアウトを外します。
逆に、 kusanagi ssl –https noredirect では、コメントアウトします。
# rewrite ^(.*)$ https://test.example.com$request_uri permanent; # SSL ONLY
/etc/nginx/conf.d/プロファイル_ssl.conf
HTTPS接続で使用する設定ファイルです。
kusanagi provision 時に自動生成されます。この時、/usr/lib/kusanagi/resource/etc/nginx/conf.d/fqdn_ssl.conf* をテンプレートとしています。
SSL証明書
SSL証明書および秘密鍵は、デフォルトでは以下のように自己証明SSL証明書が設定されています。
ssl_certificate /etc/pki/tls/certs/localhost.crt;
ssl_certificate_key /etc/pki/tls/private/localhost.key;
Let’s EncryptのSSL証明書を取得したときは、以下のように変更されます。
ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;
kusanagi ssl –cert 証明書.pem –key 秘密鍵.pem を実行すると、以下のように変更されます。
この「証明書.pem 」は、中間証明書とサーバ証明書を一つのファイルに連結しておく必要があります。
ssl_certificate /etc/kusanagi.d/ssl/test.example.com/証明書.pem;
ssl_certificate_key /etc/kusanagi.d/ssl/test.example.com/秘密鍵.pem;
CT
CT(Cirtificate Transparency)の設定をonにする時、以下のコメントを外します。
off にするときは、再度以下の文をコメントアウトします。
#ssl_ct on;
#ssl_ct_static_scts /etc/letsencrypt/live/test001.myzkstr.tech/scts;
HSTS
HSTS(HTTP Strict Transport Security)の設定は、以下の文に対して書き換えを行います。off の状態は以下のようにコメントアウトされています。
kusanagi ssl –hsts weak を設定すると、下記のコメントアウトを外します。
#add_header Strict-Transport-Security "max-age=31536000";
kusanagi ssl –hsts mid の場合、以下のように書き換えます。
#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
kusanagi ssl –hsts high の場合、以下のように書き換えます。
#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
Apache2
Apache2の設定ファイルは、NGINX同様プロファイルごとにHTTP/HTTPS用の設定ファイルを用意し、VirtualHostで設定を行います。
通常のApache2とは違い、mpm_event_module を使用して、event MPM と FastCGIによる駆動にしているのが特徴です。
/etc/httpd/httpd.conf
Apache2 の共通設定となります。
このファイル中で、ログのフォーマット、gzip や brotli の圧縮設定、mpm_event_module の設定を記述しています。
/etc/httpd/conf.modules.d/00-http2.conf
kusanagi-httpd には、http/2用のモジュール mod_http2 を含んでいます。このモジュールを読み込む設定ファイルになります。
/etc/httpd/conf.d/プロファイル_httpd.conf
HTTP接続で使用する設定ファイルです。
kusanagi provision 時に自動生成されます。この時、/usr/lib/kusanagi/resource/etc/httpd/conf.d/fqdn_http.conf* をテンプレートとしています。
この内容は、プロビジョンタイプによって異なります。
https redirect
kusanagi ssl –https redirect を実行すると、以下の RewriteEngine Offを Onにします。
kusanagi ssl –https noredirect を実行すると、以下の RewriteEngine Offを Offにします。
RewriteEngine Off
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
/etc/httpd/conf.d/プロファイル_ssl.conf
HTTPS接続で使用する設定ファイルです。
kusanagi provision 時に自動生成されます。この時、/usr/lib/kusanagi/resource/etc/httpd/conf.d/fqdn_ssl.conf* をテンプレートとしています。
SSL証明書
SSL証明書および秘密鍵は、デフォルトでは以下のように自己証明SSL証明書が設定されています。
Let’s Encrypt の証明書を取得したとき、kusanagi ssl –cert/–key で証明書を指定したときは、NGINXと同様にファイル名を変更します。
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
HSTS
HSTS(HTTP Strict Transport Security)の設定は、以下の文のhsts の値を変更します。
kusanagi ssl –hsts offのときは0、weak のときは1、midのときは2、highのときは3を設定します。
これにより、NGINXと同様のHTTPヘッダを出力し、同様の動作をします。
Define hsts 0
<If "${hsts} = 1">
Header set Strict-Transport-Security "max-age=31536000"
</IF>
<ElseIf "${hsts} = 2">
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</ElseIF>
<ElseIf "${hsts} = 3">
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</ElseIF>
monit
KUSANAGIでは、monitでNGINX/Apache2のアクセスログを監視し、5xx エラーが連続して発生したときに kusanagi restart を行います。
この設定ファイルは、kusanagi provision 実行時に生成されます。また、NGINX と Apache2を切り替えたときに、設定を切り替えます。
/etc/monit.d/プロファイル_nginx.conf, プロファイル_httpd.conf
kusanagi provision 実行時に、プロファイルごとに /etc/monit.d 以下に、NGINXとApache2用の設定ファイルを生成します。
その内容は以下の通りです。
アクセスログファイルを監視し、5xx エラーが連続2回発生したらkusanagi restart します。
5回連続発生した場合はアラートメールを送信し、監視を終了します。そのため、メールが到着したら対処を行う必要があります。
また、この監視は nginx、httpd というグループに属しており、nginx起動時にはnginxグループを、Apache2(httpd)起動時には httpdグループを監視するようにします。
- NGINX用(プロファイル_nginx.conf)
check file プロファイル_nginx with path /home/kusanagi/プロファイル/log/nginx/access.log restart program = "/bin/kusanagi restart" depends on nginx if match '"(GET|POST) /.* HTTP/.*" 5[0-9][0-9] [0-9]+ ' for 2 cycle then restart if 5 restarts within 5 cycles then alert if 5 restarts within 5 cycles then unmonitor group nginx check file プロファイル_nginx_ssl with path /home/kusanagi/プロファイル/log/nginx/ssl_access.log restart program = "/bin/kusanagi restart" depends on nginx if match '"(GET|POST) /.* HTTP/.*" 5[0-9][0-9] [0-9]+ ' for 2 cycle then restart if 5 restarts within 5 cycles then alert if 5 restarts within 5 cycles then unmonitor group nginx
- Apache2用(プロファイル_httpd.conf)
check file プロファイル_httpd with path /home/kusanagi/プロファイル/log/httpd/access.log start program = "/bin/kusanagi restart" stop program = "/bin/systemctl stop httpd" depends on httpd if match '"(GET|POST) /.* HTTP/.*" 5[0-9][0-9] [0-9]+ ' for 2 cycle then start if 5 restarts within 5 cycles then alert if 5 restarts within 5 cycles then unmonitor group httpd check file プロファイル_httpd_ssl with path /home/kusanagi/プロファイル/log/httpd/ssl_access.log start program = "/bin/kusanagi restart" stop program = "/bin/systemctl stop httpd" depends on httpd if match '"(GET|POST) /.* HTTP/.*" 5[0-9][0-9] [0-9]+ ' for 2 cycle then start if 5 restarts within 5 cycles then alert if 5 restarts within 5 cycles then unmonitor group httpd
/etc/monitrc
monitrc は monitの設定ファイルです。
このファイルでは、監視間隔(デフォルトで30秒)、ログの設定、サービスポート(localhost:2812)を設定しています。
最後に /etc/monit.d/ 以下のすべてのファイルを読み込んでいます。
# grep -v -e '^#' -e '^$' /etc/monitrc
set daemon 30 # check services at 30 seconds intervals
set logfile syslog
set httpd port 2812 and
use address localhost # only accept connection from localhost
allow localhost # allow localhost to connect to the server and
allow admin:monit # require user 'admin' with password 'monit'
include /etc/monit.d/*
/etc/monit.d/nginx.conf, httpd.conf
このファイルは、NGINXもしくはApache2(httpd)のサービス監視を行う設定を記述しています。
各プロファイルの設定で depends on nginx や httpd となっていますが、このサービスが起動しているかどうかに依存して、プロファイルの監視設定が有効になるように設定しています。
# cat /etc/monit.d/nginx.conf, httpd.conf
check program nginx with path "/bin/systemctl is-enabled nginx"
#start program = "/bin/kusanagi restart"
if status != 0 then unmonitor
group nginx
# cat /etc/monit.d/httpd.conf
check program httpd with path "/bin/systemctl is-enabled httpd"
#start program = "/bin/kusanagi restart"
if status != 0 then unmonitor
group httpd
/etc/monit.d/alert
alertファイルには、アラート処理を行う設定を記述しています。ここを書き換えると処理を変更することが可能です。
KUSANAGIでは、アラートは localhost の rootへメールを送信します。
rootのaliasを変更する、もしくはこのファイルを変更することで任意のメールアドレスへアラートメールを送信することが可能です。
ただし、メールアドレスによっては postfixの設定を変更する必要があるかもしれません。
set alert root@localhost on {instance, timeout}
set mailserver localhost
set mail-format {
from: kusanagi@$HOST
subject: [KUSANAGI MONIT] $SERVICE $EVENT at $DATE
message: Monit alert this action.
Please check monit status on $HOST.
Service: $SERVICE
Event: $EVENT
Action: $ACTION
Data: $DATE
Host: $HOST
$DESCRIPTION.
}
monit status
monit status コマンドは、monit監視の状況を表示するコマンドです。
-g オプションと一緒に使うことで、nginx もしくは httpd グループの監視状況のみを出力することができます。
以下は、NGINX起動時の monit statusの表示例になります。
# monit status -g nginx
File 'kusanagi_html_nginx'
status Accessible
monitoring status Monitored
permission 644
uid 1000
gid 0
size 0 B
timestamp 0 B
data collected Wed, 21 Dec 2016 21:29:33
File 'kusanagi_html_nginx_ssl'
status Accessible
monitoring status Monitored
permission 644
uid 1000
gid 0
size 0 B
timestamp 0 B
data collected Wed, 21 Dec 2016 21:29:33
# monit status -g httpd
File 'kusanagi_html_httpd'
status Not monitored
monitoring status Not monitored
data collected Wed, 21 Dec 2016 06:07:12
File 'kusanagi_html_httpd_ssl'
status Not monitored
monitoring status Not monitored
data collected Wed, 21 Dec 2016 06:07:12
monit moniter/unmoniter
monit moniter/unmoniter コマンドは、項目に対して moniterを行う/行わない を切り替えるコマンドです。
kusanagi nginx/httpd では、内部でこのコマンドを起動して、有効なグループの設定のみmoniterを行うようにしています。
NGINX有効時
# monit monitor all -g nginx
# monit unmoniter all -g httpd
Apache2 有効時
# monit monitor all -g httpd
# monit unmoniter all -g nginx
bcache
bcache は KUSANAGIで提供しているプラグインで実現しているページキャッシュです。
wp-config.php
bcache は、wp-config.php の以下の文がコメントアウトしている、もしくは存在しない場合に off 状態になります。
bcache on で、下記の文のコメントアウト(先頭の#)が外れます。
#define('WP_CACHE', true);
上記文は、wp-config-sample.php に含まれており、WebUIからWordPressの設定を行う場合にはこの行が自動的に含まれます。
WordPress移設などで wp-config.php をコピーしたり、wp core config コマンドを使用してwp-config.phpを設定した場合は含まれないことがあります。
その場合、 /usr/lib/kusanagi/resource/wp-config-sample/(en_US|ja)/wp-config-extra.php の内容を wp-config.php に追記して下さい。
# cat /usr/lib/kusanagi/resource/wp-config-sample/ja/wp-config-extra.php
/**
* 開発者へ: WordPress デバッグモード
*
* この値を true にすると、開発中に注意 (notice) を表示します。
* テーマおよびプラグインの開発者には、その開発環境においてこの WP_DEBUG を使用することを強く推奨します。
*/
define('WP_DEBUG', false);
#define('WP_ALLOW_MULTISITE', true);
#define('FORCE_SSL_ADMIN', true);
#define('WP_CACHE', true);
bcacheの仕組み
bcacheを有効にすると、URLをキーにしてPHPで生成したページをMariaDBの以下のテーブルに格納します。
mysql> show columns from wp_site_cache;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| hash | varchar(32) | NO | MUL | NULL | |
| content | longtext | NO | | NULL | |
| device_url | text | NO | | NULL | |
| type | varchar(20) | YES | MUL | NULL | |
| post_type | varchar(200) | NO | | NULL | |
| headers | text | NO | | NULL | |
| user_agent | text | NO | | NULL | |
| server | varchar(16) | NO | | NULL | |
| updating | tinyint(1) | NO | MUL | 0 | |
| create_time | datetime | NO | | NULL | |
| expire_time | datetime | NO | MUL | NULL | |
+-------------+--------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
DBに格納することから、逆に遅くなるのでは?という懸念があると思いますが、KUSANAGIでは innodb_buffer_pool_size や query_cache_size を標準よりも多く設定していることから、上記で登録した内容はオンメモリであることが期待できます。ほぼオンメモリでクエリ処理を行うため、高速にページキャッシュを実現できます。
この仕組み上、MariaDB の binarylog が bcache 未使用の場合より肥大します。そのため、binarylog の最大値を設定するなど、ディスク領域を圧迫しない設定が必要になります。
HTTP レスポンスヘッダ
bcacheの状態は、HTTPのレスポンスヘッダ X-B-Cache で確認できます。
- bcache が無効のとき
X-B-Cache: BYPASS
- bcache でキャッシュにヒットしないとき(キャッシュをクリアしたときも含む)
X-B-Cache: create
- bcache でキャッシュにヒットしたとき
X-B-Cache: cache
fcache
fcacheは、FastCGIのキャッシュ機構を使用したページキャッシュになります。
FastCGI cacheの設定
FastCGIキャッシュは、PHPで生成したページをメモリ上に保持し、/etc/nginx/nginx.conf内のfastcgi_cache_pathで指定したメモリ量を超える場合は、指定したディレクトリ(/var/cache/nginx/wordpres)にファイルで保管します。
KUSANAGIでの設定は以下のようになっています。
# grep fastcgi_cache_path /etc/nginx/nginx.conf
fastcgi_cache_path /var/cache/nginx/wordpress levels=1:2 keys_zone=wpcache:30m max_size=512M inactive=600m;
HTTPレスポンスヘッダ
fcacheの状態は、HTTPのレスポンスヘッダ X-F-Cache で確認できます。
- fcache が無効のとき
X-F-Cache: BYPASS
- fcache でキャッシュにヒットしないとき(キャッシュをクリアしたときも含む)
X-F-Cache: MISS
- fcache でキャッシュにヒットしたとき
X-F-Cache: HIT
まとめ
ということで、KUSANAGIで生成する設定ファイル、利用する設定ファイルから、kusanagi のいろいろな機能をどう実現しているかを説明してみました。
まだまだ色々説明できることはあるのですが、ちょっと長くなりすぎたので別の機会にまた説明しようかと思います。