593 lines
19 KiB
Markdown
593 lines
19 KiB
Markdown
+++
|
|
categories = [ "nginx" ]
|
|
author = "kazu634"
|
|
description = "nginx + Let's Encryptを用いてhttp/2環境を構築してみました。"
|
|
tags = []
|
|
date = "2016-01-11T23:32:47+08:00"
|
|
title = "nginx + let's encryptを利用してHTTP/2を有効化した"
|
|
thumnail = "images/24021542270_0971890cc8_z.jpg"
|
|
+++
|
|
|
|
`nginx`+`Let's Encrypt`で`http/2`環境を構築したのでその時のメモです。
|
|
|
|
## `nginx`のインストール・セットアップ
|
|
### `nginx`で必要になる前提パッケージ
|
|
`libgeoip-dev`をインストールします:
|
|
|
|
```
|
|
% aptitude install libgeoip-dev
|
|
```
|
|
|
|
### nginx-buildのインストール
|
|
[cubicdaiya/nginx-build](https://github.com/cubicdaiya/nginx-build)をインストールします:
|
|
|
|
```
|
|
% wget https://github.com/cubicdaiya/nginx-build/releases/download/v0.6.5/nginx-build-linux-amd64-0.6.5.tar.gz
|
|
```
|
|
|
|
### nginxのインストール
|
|
以下の手順で`nginx`をインストールします:
|
|
|
|
```
|
|
% vi configure.sh
|
|
|
|
% ./nginx-build -d temp -v 1.9.9 -c configure.sh -zlib -pcre -openssl
|
|
|
|
% cd temp/nginx/1.9.9/nginx-1.9.9
|
|
|
|
% sudo make install
|
|
```
|
|
|
|
なお、`configure.sh`は以下の内容です:
|
|
|
|
```
|
|
#!/bin/bash
|
|
|
|
./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' ¥
|
|
--prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log ¥
|
|
--error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid ¥
|
|
--http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi ¥
|
|
--http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi ¥
|
|
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module ¥
|
|
--with-http_v2_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module ¥
|
|
--with-http_addition_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module ¥
|
|
--with-http_sub_module
|
|
```
|
|
|
|
### `nginx`のセットアップ
|
|
`nginx`をセットアップします。
|
|
|
|
#### `nginx`起動に必要となるディレクトリ作成
|
|
`nginx`起動に必要となるディレクトリを作成します:
|
|
|
|
```
|
|
% sudo mkdir -p /var/lib/nginx/{body,fastcgi,proxy,scgi,uwsgi}
|
|
```
|
|
|
|
#### `nginx`設定ファイルなどのデプロイ
|
|
`nginx`設定ファイルなどをデプロイします:
|
|
|
|
```
|
|
% sudo mkdir -p /etc/nginx/{sites-available,sites-enabled}
|
|
|
|
% vi /etc/nginx/nginx.conf
|
|
|
|
% vi /etc/init.d/nginx
|
|
% sudo update-rc.d nginx defaults
|
|
|
|
% vi /etc/nginx/sites-enabled/default
|
|
```
|
|
|
|
`nginx.conf`の中身は以下のとおりです:
|
|
|
|
```
|
|
user www-data;
|
|
|
|
# Newer version of Nginx calculates the worker_processes,
|
|
# based on the CPU cores. Use this feature:
|
|
worker_processes auto;
|
|
|
|
pid /run/nginx.pid;
|
|
|
|
# number of file descriptors used for nginx
|
|
# the limit for the maximum file descriptors on the server is usually set by the OS.
|
|
# if you don't set FD's then OS settings will be used.
|
|
worker_rlimit_nofile 100000;
|
|
|
|
events {
|
|
# determines how much clients will be served per worker
|
|
# max clients = worker_connections * worker_processes
|
|
# max clients is also limited by the number of socket connections available on the system (~64k)
|
|
worker_connections 4096;
|
|
|
|
# accept as many connections as possible
|
|
multi_accept on;
|
|
|
|
# mutex config:
|
|
accept_mutex on;
|
|
accept_mutex_delay 100ms; # default: 500 -> 100 ms
|
|
|
|
# optmized to serve many clients with each thread, essential for linux
|
|
use epoll;
|
|
}
|
|
|
|
http {
|
|
|
|
##
|
|
# Basic Settings
|
|
##
|
|
|
|
sendfile on;
|
|
tcp_nopush on;
|
|
tcp_nodelay on;
|
|
keepalive_timeout 30;
|
|
types_hash_max_size 2048;
|
|
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
server_names_hash_bucket_size 128;
|
|
|
|
# cache informations about FDs, frequently accessed files
|
|
# can boost performance:
|
|
open_file_cache max=200000 inactive=20s;
|
|
open_file_cache_valid 30s;
|
|
open_file_cache_min_uses 2;
|
|
open_file_cache_errors on;
|
|
|
|
# allow the server to close connection on non responding client,
|
|
# this will free up memory
|
|
reset_timedout_connection on;
|
|
|
|
# request timed out -- default 60
|
|
client_body_timeout 10s;
|
|
|
|
# if client stop responding, free up memory -- default 60
|
|
send_timeout 2s;
|
|
|
|
##
|
|
# Logging Settings
|
|
##
|
|
|
|
log_format ltsv "time:$time_local\thost:$remote_addr"
|
|
"\tforwardedfor:$http_x_forwarded_for\t"
|
|
"method:$request_method\tpath:$request_uri\tprotocol:$server_protocol"
|
|
"\tstatus:$status\tsize:$body_bytes_sent\treferer:$http_referer"
|
|
"\tua:$http_user_agent\ttaken_sec:$request_time"
|
|
"\tbackend:$upstream_addr\tbackend_status:$upstream_status"
|
|
"\tcache:$upstream_http_x_cache\tbackend_runtime:$upstream_response_time"
|
|
"\tvhost:$host";
|
|
|
|
access_log /var/log/nginx/access.log ltsv;
|
|
error_log /var/log/nginx/error.log;
|
|
|
|
##
|
|
# Gzip Settings
|
|
##
|
|
|
|
gzip on;
|
|
gzip_disable "msie6";
|
|
gzip_min_length 10240;
|
|
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
|
|
|
##
|
|
# Virtual Host Configs
|
|
##
|
|
|
|
include /etc/nginx/conf.d/*.conf;
|
|
include /etc/nginx/sites-enabled/*;
|
|
}
|
|
```
|
|
|
|
`nginx`の設定ファイルの中身は以下のとおりです:
|
|
|
|
```
|
|
#!/bin/sh
|
|
|
|
### BEGIN INIT INFO
|
|
# Provides: nginx
|
|
# Required-Start: $local_fs $remote_fs $network $syslog $named
|
|
# Required-Stop: $local_fs $remote_fs $network $syslog $named
|
|
# Default-Start: 2 3 4 5
|
|
# Default-Stop: 0 1 6
|
|
# Short-Description: starts the nginx web server
|
|
# Description: starts nginx using start-stop-daemon
|
|
### END INIT INFO
|
|
|
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/share/nginx/sbin/
|
|
DAEMON=/usr/share/nginx/sbin/nginx
|
|
NAME=nginx
|
|
DESC=nginx
|
|
|
|
# Include nginx defaults if available
|
|
if [ -r /etc/default/nginx ]; then
|
|
. /etc/default/nginx
|
|
fi
|
|
|
|
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}"
|
|
|
|
test -x $DAEMON || exit 0
|
|
|
|
. /lib/init/vars.sh
|
|
. /lib/lsb/init-functions
|
|
|
|
# Try to extract nginx pidfile
|
|
PID=$(cat /etc/nginx/nginx.conf | grep -Ev '^\s*#' | awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1)
|
|
if [ -z "$PID" ]
|
|
then
|
|
PID=/run/nginx.pid
|
|
fi
|
|
|
|
# Check if the ULIMIT is set in /etc/default/nginx
|
|
if [ -n "$ULIMIT" ]; then
|
|
# Set the ulimits
|
|
ulimit $ULIMIT
|
|
fi
|
|
|
|
#
|
|
# Function that starts the daemon/service
|
|
#
|
|
do_start()
|
|
{
|
|
# Return
|
|
# 0 if daemon has been started
|
|
# 1 if daemon was already running
|
|
# 2 if daemon could not be started
|
|
start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON --test > /dev/null \
|
|
|| return 1
|
|
start-stop-daemon --start --quiet --pidfile $PID --exec $DAEMON -- \
|
|
$DAEMON_OPTS 2>/dev/null \
|
|
|| return 2
|
|
}
|
|
|
|
test_nginx_config() {
|
|
$DAEMON -t $DAEMON_OPTS >/dev/null 2>&1
|
|
}
|
|
|
|
#
|
|
# Function that stops the daemon/service
|
|
#
|
|
do_stop()
|
|
{
|
|
# Return
|
|
# 0 if daemon has been stopped
|
|
# 1 if daemon was already stopped
|
|
# 2 if daemon could not be stopped
|
|
# other if a failure occurred
|
|
start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PID --name $NAME
|
|
RETVAL="$?"
|
|
|
|
sleep 1
|
|
return "$RETVAL"
|
|
}
|
|
|
|
#
|
|
# Function that sends a SIGHUP to the daemon/service
|
|
#
|
|
do_reload() {
|
|
start-stop-daemon --stop --signal HUP --quiet --pidfile $PID --name $NAME
|
|
return 0
|
|
}
|
|
|
|
#
|
|
# Rotate log files
|
|
#
|
|
do_rotate() {
|
|
start-stop-daemon --stop --signal USR1 --quiet --pidfile $PID --name $NAME
|
|
return 0
|
|
}
|
|
|
|
#
|
|
# Online upgrade nginx executable [67/1833]
|
|
#
|
|
# "Upgrading Executable on the Fly"
|
|
# http://nginx.org/en/docs/control.html
|
|
#
|
|
do_upgrade() {
|
|
# Return
|
|
# 0 if nginx has been successfully upgraded
|
|
# 1 if nginx is not running
|
|
# 2 if the pid files were not created on time
|
|
# 3 if the old master could not be killed
|
|
if start-stop-daemon --stop --signal USR2 --quiet --pidfile $PID --name $NAME; then
|
|
# Wait for both old and new master to write their pid file
|
|
while [ ! -s "${PID}.oldbin" ] || [ ! -s "${PID}" ]; do
|
|
cnt=`expr $cnt + 1`
|
|
if [ $cnt -gt 10 ]; then
|
|
return 2
|
|
fi
|
|
sleep 1
|
|
done
|
|
# Everything is ready, gracefully stop the old master
|
|
if start-stop-daemon --stop --signal QUIT --quiet --pidfile "${PID}.oldbin" --name $NAME; then
|
|
return 0
|
|
else
|
|
return 3
|
|
fi
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
|
do_start
|
|
case "$?" in
|
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
|
esac
|
|
;;
|
|
stop)
|
|
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
|
do_stop
|
|
case "$?" in
|
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
|
esac
|
|
;;
|
|
restart)
|
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
|
|
|
# Check configuration before stopping nginx
|
|
if ! test_nginx_config; then
|
|
log_end_msg 1 # Configuration error
|
|
exit 0
|
|
fi
|
|
|
|
do_stop
|
|
case "$?" in
|
|
0|1)
|
|
do_start
|
|
case "$?" in
|
|
0) log_end_msg 0 ;;
|
|
1) log_end_msg 1 ;; # Old process is still running
|
|
*) log_end_msg 1 ;; # Failed to start
|
|
esac
|
|
;;
|
|
*)
|
|
# Failed to stop
|
|
log_end_msg 1
|
|
;;
|
|
esac
|
|
;;
|
|
reload|force-reload)
|
|
log_daemon_msg "Reloading $DESC configuration" "$NAME"
|
|
|
|
# Check configuration before reload nginx
|
|
#
|
|
# This is not entirely correct since the on-disk nginx binary
|
|
# may differ from the in-memory one, but that's not common.
|
|
# We prefer to check the configuration and return an error
|
|
# to the administrator.
|
|
if ! test_nginx_config; then
|
|
log_end_msg 1 # Configuration error
|
|
exit 0
|
|
fi
|
|
|
|
do_reload
|
|
log_end_msg $?
|
|
;;
|
|
configtest|testconfig)
|
|
log_daemon_msg "Testing $DESC configuration"
|
|
test_nginx_config
|
|
log_end_msg $?
|
|
;;
|
|
status)
|
|
status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
|
|
status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
|
|
;;
|
|
upgrade)
|
|
log_daemon_msg "Upgrading binary" "$NAME"
|
|
do_upgrade
|
|
log_end_msg 0
|
|
;;
|
|
rotate)
|
|
log_daemon_msg "Re-opening $DESC log files" "$NAME"
|
|
do_rotate
|
|
log_end_msg $?
|
|
;;
|
|
*)
|
|
echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}" >&2
|
|
exit 3
|
|
;;
|
|
esac
|
|
|
|
:
|
|
```
|
|
|
|
`/etc/nginx/sites-enabled/default`の中身は以下のとおりです:
|
|
|
|
```
|
|
server {
|
|
# allow access from localhost
|
|
listen 80 reuseport backlog=1024;
|
|
server_name test.kazu634.com;
|
|
|
|
root /usr/share/nginx/html;
|
|
index index.html index.htm;
|
|
|
|
location / {
|
|
gzip on;
|
|
gzip_types text/css text/javascript;
|
|
gzip_vary on;
|
|
|
|
gzip_static always;
|
|
gunzip on;
|
|
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
}
|
|
}
|
|
|
|
# Denies the access without the pre-defined virtual host.
|
|
server {
|
|
listen 80 default_server;
|
|
server_name _;
|
|
|
|
return 444;
|
|
}
|
|
```
|
|
|
|
|
|
|
|
## Let's Encyptを用いて証明書を取得する
|
|
以下の手順で[Let's Encrypt](https://letsencrypt.org/)から証明書を取得します:
|
|
|
|
```
|
|
% git clone https://github.com/letsencrypt/letsencrypt
|
|
|
|
% cd letsencrypt
|
|
|
|
% ./letsencrypt-auto certonly --webroot -d test.kazu634.com --webroot-path /usr/share/nginx/html/
|
|
```
|
|
|
|
途中で以下のダイアログが表示されます。ひとつ目のダイアログではメールアドレスを入力します:
|
|
|
|
<a data-flickr-embed="true" href="https://www.flickr.com/photos/42332031@N02/24290975906/in/dateposted/" title="1. tmux"><img src="https://farm2.staticflickr.com/1482/24290975906_26411cea6e_z.jpg" width="640" height="485" alt="1. tmux"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>
|
|
|
|
次のダイアログでは`[Agree]`ボタンを押します:
|
|
|
|
<a data-flickr-embed="true" href="https://www.flickr.com/photos/42332031@N02/24021542300/in/dateposted/" title="2. tmux"><img src="https://farm2.staticflickr.com/1609/24021542300_efacda5ea8_z.jpg" width="640" height="485" alt="2. tmux"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>
|
|
|
|
すると以下のような注意書きが表示されます:
|
|
|
|
```
|
|
IMPORTANT NOTES:
|
|
- If you lose your account credentials, you can recover through
|
|
e-mails sent to simoom634@yahoo.co.jp.
|
|
- Congratulations! Your certificate and chain have been saved at
|
|
/etc/letsencrypt/live/test.kazu634.com/fullchain.pem. Your cert
|
|
will expire on 2016-04-02. To obtain a new version of the
|
|
certificate in the future, simply run Let's Encrypt again.
|
|
- Your account credentials have been saved in your Let's Encrypt
|
|
configuration directory at /etc/letsencrypt. You should make a
|
|
secure backup of this folder now. This configuration directory will
|
|
also contain certificates and private keys obtained by Let's
|
|
Encrypt so making regular backups of this folder is ideal.
|
|
- If you like Let's Encrypt, please consider supporting our work by:
|
|
|
|
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
|
|
Donating to EFF: https://eff.org/donate-le
|
|
```
|
|
|
|
これで終わりです:
|
|
|
|
### Grade A+取得の道
|
|
[Qualys SSL Labs](https://www.ssllabs.com/index.html)で評価A+を目指した軌跡です。基本は[nginx - 我々はどのようにして安全なHTTPS通信を提供すれば良いか - Qiita](http://qiita.com/harukasan/items/fe37f3bab8a5ca3f4f92)を参考にして設定しています。
|
|
|
|
#### 暗号化スイートの選択
|
|
以下のように設定しました:
|
|
|
|
```
|
|
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA;
|
|
ssl_prefer_server_ciphers on;
|
|
```
|
|
|
|
#### OCSP Staplingの設定
|
|
以下のように設定しました:
|
|
|
|
```
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
resolver 8.8.4.4 8.8.8.8 valid=300s;
|
|
resolver_timeout 10s;
|
|
```
|
|
|
|
#### ssl_dhparam
|
|
以下のコマンドを実行し、`DH鍵交換`に使用する暗号化ファイルを作成しました:
|
|
|
|
```
|
|
% sudo openssl dhparam -out /etc/letsencrypt/live/test.kazu634.com/dhparams_4096.pem 4096
|
|
```
|
|
|
|
作成後以下のように設定を実施しました:
|
|
|
|
```
|
|
ssl_dhparam /etc/letsencrypt/live/test.kazu634.com/dhparams_4096.pem;
|
|
```
|
|
|
|
#### HTTP Strict Transport Security(HSTS)の付与
|
|
以下のように設定を行います:
|
|
|
|
```
|
|
# Enable HSTS (HTTP Strict Transport Security)
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
|
|
```
|
|
|
|
#### TLS Session Ticketsの有効化
|
|
以下のコマンドで鍵ファイルを作成します:
|
|
|
|
```
|
|
# openssl rand 48 > /etc/letsencrypt/live/test.kazu634.com/ticket.key
|
|
```
|
|
|
|
その後、以下のように設定を実施します:
|
|
|
|
```
|
|
ssl_session_tickets on;
|
|
ssl_session_ticket_key /etc/letsencrypt/live/test.kazu634.com/ticket.key;
|
|
```
|
|
|
|
#### 結論
|
|
まとめると、以下のような`nginx`の設定ファイルを作成します:
|
|
|
|
```
|
|
server {
|
|
# allow access from localhost
|
|
# listen 80 reuseport backlog=1024;
|
|
listen 443 ssl http2 backlog=1024;
|
|
server_name test.kazu634.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/test.kazu634.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/test.kazu634.com/privkey.pem;
|
|
ssl_dhparam /etc/letsencrypt/live/test.kazu634.com/dhparams_4096.pem;
|
|
|
|
ssl_session_cache shared:SSL:3m;
|
|
ssl_buffer_size 4k;
|
|
ssl_session_timeout 10m;
|
|
|
|
ssl_session_tickets on;
|
|
ssl_session_ticket_key /etc/letsencrypt/live/test.kazu634.com/ticket.key;
|
|
|
|
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA;
|
|
ssl_prefer_server_ciphers on;
|
|
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
resolver 8.8.4.4 8.8.8.8 valid=300s;
|
|
resolver_timeout 10s;
|
|
|
|
# Enable HSTS (HTTP Strict Transport Security)
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
|
|
|
|
root /var/www/blog_cache;
|
|
index index.html index.htm;
|
|
|
|
location / {
|
|
gzip on;
|
|
gzip_types text/css text/javascript;
|
|
gzip_vary on;
|
|
|
|
gzip_static always;
|
|
gunzip on;
|
|
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
}
|
|
}
|
|
|
|
# Denies the access without the pre-defined virtual host.
|
|
server {
|
|
listen 80 default_server;
|
|
server_name _;
|
|
|
|
return 444;
|
|
}
|
|
```
|
|
|
|
<a data-flickr-embed="true" href="https://www.flickr.com/photos/42332031@N02/24021542270/in/dateposted/" title="SSL Server Test_ test.kazu634.com (Powered by Qualys SSL Labs)"><img src="https://farm2.staticflickr.com/1510/24021542270_0971890cc8_z.jpg" width="640" height="448" alt="SSL Server Test_ test.kazu634.com (Powered by Qualys SSL Labs)"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>
|
|
|