NGXIN + ngx_mrubyを用いたSSL動的読み込みの環境構築
構築環境
shell> hostnamectl status Static hostname: www.example.com Icon name: computer-vm Chassis: vm 〜 Virtualization: kvm Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-693.17.1.el7.x86_64 Architecture: x86-64
※ 全て管理者権限(root)のあるユーザで実行している
NIGNX + ngx-mrubyの環境構築
各種ソースコードをダウンロード
NGINXのソースコード
最新版(Ver 1.14.0)をダウンロード(2018/05/04現在)
shell> cd /usr/local/src/ && \ curl -O http://nginx.org/download/nginx-1.14.0.tar.gz && \ tar zxf /usr/local/src/nginx-1.14.0.tar.gz
ngx_mrubyのソースコード
最新版(Ver 1.20.2)をダウンロード(2018/05/04現在)
shell> cd /usr/local/src/ && \ curl -LO https://github.com/matsumotory/ngx_mruby/archive/v1.20.2.tar.gz && \ tar zxf /usr/local/src/v1.20.2.tar.gz
Rubyをインストール
ngx_mrubyのビルドには、RubyのRakeライブラリが必要なためインストール
shell> yum install -y ruby ruby-devel openssl openssl-devel shell> gem install rake
ngx_mrubyをビルド
shell> cd /usr/local/src/ngx_mruby-1.20.2/ shell> ./configure --with-ngx-src-root=/usr/local/src/nginx-1.14.0 shell> make build_mruby -j 2 shell> make generate_gems_config -j 2
NGINXをビルド
shell> cd /usr/local/src/nginx-1.14.0 shell> ./configure --with-compat \ --add-module=/usr/local/src/ngx_mruby-1.20.2/dependence/ngx_devel_kit \ --add-module=/usr/local/src/ngx_mruby-1.20.2 \ --with-http_realip_module \ --with-http_addition_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gzip_static_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_stub_status_module \ --with-http_auth_request_module \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_gunzip_module \ --with-threads \ --with-stream \ --with-stream_ssl_module \ --with-http_slice_module \ --with-mail \ --with-mail_ssl_module \ --with-file-aio \ --without-stream_access_module \ --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' shell> make install -j 2
NGINXに設定を投入
NGINXのコンフィグをバックアップ
既存のnginx.confをリネーム
shell> mv -v /usr/local/nginx/conf/nginx.conf{,.backup}
nginx.confを新規作成
shell> mkdir /usr/local/nginx/conf/conf.d
shell> cat /usr/local/nginx/conf/nginx.conf
user nginx; worker_processes auto; worker_rlimit_nofile 100000; pid /usr/local/nginx/logs/nginx.pid; events { worker_connections 2048; } http { log_format ltsv 'time:$time_iso8601\t' 'remote_addr:$remote_addr\t' 'request_method:$request_method\t' 'request_length:$request_length\t' 'request_uri:$request_uri\t' 'https:$https\t' 'uri:$uri\t' 'query_string:$query_string\t' 'status:$status\t' 'bytes_sent:$bytes_sent\t' 'body_bytes_sent:$body_bytes_sent\t' 'referer:$http_referer\t' 'useragent:$http_user_agent\t' 'forwardedfor:$http_x_forwarded_for\t' 'request_time:$request_time\t' 'upstream_response_time:$upstream_response_time'; access_log /usr/local/nginx/logs/access.log ltsv; error_log /usr/local/nginx/logs/error.log info; 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_set_header X-Forwarded-Proto https; client_max_body_size 2G; gzip on; gzip_types text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/jpeg application/octet-stream; server_tokens off; sendfile on; tcp_nopush on; tcp_nodelay on; include mime.types; default_type application/octet-stream; keepalive_timeout 10; server_names_hash_bucket_size 20000; include /usr/local/nginx/conf/conf.d/*.conf; }
NGINXユーザを作成
shell> useradd -M --shell /sbin/nologin nginx
NGINXのシンボリックリンクを作成
shell> ln -s /usr/local/src/nginx-1.14.0/objs/nginx /usr/local/bin/nginx
シンタックスチェック
shell> nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
NGINXをSystemdに登録
sehll> cat /usr/lib/systemd/system/nginx.service
[Unit] Description=nginx - high performance web server After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/bin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target
NGINXを起動
shell> systemctl enable nginx && systemctl start nginx
動作確認用
テストページ用のコンフィグを作成
http://www.example.com/hello
にアクセスして「hello ngx_mruby world」が表示される設定を追加
shell> /usr/local/nginx/conf/conf.d/www.example.com.conf
server{ listen 80; server_name www.example.com; location /hello { mruby_content_handler_code 'Nginx.echo "hello ngx_mruby world"'; } location ^~ /.well-known/acme-challenge/ { root /usr/local/nginx/html; } }
追加したコンフィグを反映
shell> nginx -s reload
テストページにアクセス
shell> curl -s http://www.example.com/hello hello ngx_mruby world
Let’s Encryptの導入
SSL証明書を入手するために無料で期間の短い証明書を無料で発行してくれるサービスを利用する
ソースコードをダウンロード
shell> cd /opt && git clone https://github.com/letsencrypt/letsencrypt
Let’s Encryptの環境構築
shell> cd letsencrypt && ./letsencrypt-auto --help all
証明書を発行
コマンドオプションには、ドキュメントルート(-w)・コモンネーム(-d)・メールアドレス(-m)を指定
shell> ./letsencrypt-auto certonly \ --rsa-key-size 4096 \ --webroot -w /usr/local/nginx/html \ -d www.example.com \ -m root@www.example.com
SSL証明書を確認
shell> tree /etc/letsencrypt/live/ /etc/letsencrypt/live/ `-- www.example.com |-- README |-- cert.pem -> ../../archive/www.example.com/cert1.pem |-- chain.pem -> ../../archive/www.example.com/chain1.pem |-- fullchain.pem -> ../../archive/www.example.com/fullchain1.pem `-- privkey.pem -> ../../archive/www.example.com/privkey1.pem
SSL証明書のパーミッションを変更
NGINXユーザからSSL証明書にアクセスする場合、「live」「archive」のパーミッションを700 -> 755に変更必要がある
shell> chmod 755 /etc/letsencrypt/{live,archive}
テストページ用のコンフィグにSSLの設定を追加
shell> /usr/local/nginx/conf/conf.d/www.example.com.conf
server{ listen 80; listen 443 ssl http2; server_name www.example.com; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_timeout 1h; ssl_session_cache shared:SSL:10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_certificate "/etc/letsencrypt/live/www.example.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/www.example.com/privkey.pem"; ssl_dhparam "/usr/local/nginx/conf/dhparam.pem"; location /hello { mruby_content_handler_code 'Nginx.echo "hello ngx_mruby world"'; } location ^~ /.well-known/acme-challenge/ { root /usr/local/nginx/html; } }
dhparamを生成
shell> openssl dhparam 4096 -out /usr/local/nginx/conf/dhparam.pem
追加したコンフィグを反映
shell> nginx -s reload
テストページにアクセス
shell> curl -s https://www.example.com/hello hello ngx_mruby world
SSL証明書の動的読み込み
ドキュメントルートは、「/usr/local/nginx/html/< ドメイン名 >」でドメイン毎に作成
今回の場合は、「/usr/local/nginx/html/www.example.com」
shell> cat /usr/local/nginx/conf/conf.d/mruby.conf
server { listen 80; server_name _; location ^~ /.well-known/acme-challenge/ { root /usr/local/nginx/html; } location / { mruby_set_code $root ' r = Nginx::Request.new "/usr/local/nginx/html/#{r.hostname}" '; root $root; } } server { listen 443 ssl http2; server_name _; # SSL ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_timeout 1h; ssl_session_cache shared:SSL:10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; add_header Strict-Transport-Security max-age=31536000; ssl_certificate "/etc/letsencrypt/live/www.example.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/www.example.com/privkey.pem"; ssl_dhparam "/usr/local/nginx/conf/dhparam.pem"; mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new ssl.certificate = "/etc/letsencrypt/live/#{ssl.servername}/fullchain.pem" ssl.certificate_key = "/etc/letsencrypt/live/#{ssl.servername}/privkey.pem" '; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location / { mruby_set_code $root ' r = Nginx::Request.new "/usr/local/nginx/html/#{r.hostname}" '; root $root; } ## リバースプロキシの設定例 #location / { # resolver 8.8.8.8 1.1.1.1 8.8.4.4 valid=15m; # resolver_timeout 10s; # add_header Strict-Transport-Security max-age=31536000; # mruby_set_code $backend 'Nginx::Request.new.hostname'; # proxy_pass http://$backend; #} }
シンタックスチェック
murbyの記述箇所については、下記コマンドではエラーを確認できないので「/usr/local/nginx/logs/error.log」を確認すること
shell> nginx -t
設定の反映
shell> nginx -s reload
正しく設定が反映されない場合は、再起動を実施
shell> systemctl restart nginx