记本博客搭建过程(二):Nginx 配置

编译

准备工作

为了能同时支持 HTTP/2Spdy ,所以我使用了 Nginx 1.9.7 + Cloudflare 的补丁.
我使用的系统是 Debian 8.0,请根据自己的系统调整相应的包管理器命令.

首先安装编译要用到的依赖库和工具.

1
sudo apt-get install build-essential libpcre3 libpcre3-dev zlib1g-dev unzip git

然后获取 OpenSSL , Cloudflare 的补丁和 Certificate Transparency 补丁.

1
2
3
4
5
6
7
8
9
wget -O openssl.zip -c https://github.com/openssl/openssl/archive/OpenSSL_1_0_2h.zip
unzip openssl.zip && mv openssl-OpenSSL_1_0_2h/ openssl
wget -O nginx-ct.zip -c https://github.com/grahamedgecombe/nginx-ct/archive/v1.2.0.zip
unzip nginx-ct.zip

git clone https://github.com/cloudflare/sslconfig
cd openssl
patch -p1 < ../sslconfig/patches/openssl__chacha20_poly1305_draft_and_rfc_ossl102g.patch
cd ../

开始编译

默认安装到 /usr/local/nginx ,如果想更改路径可以在编译时指定 --prefix 参数.

1
2
3
4
5
6
7
8
9
10
wget -c http://nginx.org/download/nginx-1.9.7.tar.gz
tar zxf nginx-1.9.7.tar.gz

cd nginx-1.9.7
patch -1 < ../sslconfig/patches/nginx__http2_spdy.patch

./configure --add-module=../nginx-ct-1.2.0 --with-openssl=../openssl --with-http_v2_module --with-http_spdy_module --with-http_ssl_module --with-ipv6 --with-http_gzip_static_module

make
sudo make install

配置

创建管理脚本

为了方便管理 Nginx ,我使用脚本来对 Nginx 进行操作.

sudo vim /etc/init.d/nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#! /bin/sh

### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# 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
# Nginx 路径
DAEMON=/etc/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /etc/nginx/logs/$NAME.pid \
--exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /etc/nginx/logs/$NAME.pid \
--exec $DAEMON || true
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/etc/nginx/logs/$NAME.pid --exec $DAEMON || true
sleep 1
start-stop-daemon --start --quiet --pidfile \
/etc/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /etc/nginx/logs/$NAME.pid \
--exec $DAEMON || true
echo "$NAME."
;;
status)
status_of_proc -p /etc/nginx/logs/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
exit 1
;;
esac

exit 0

为脚本增加执行权限

sudo chmod a+x /etc/init.d/nginx

Nginx 全局配置

打开 Nginx 安装目录下的 conf/nginx.conf 配置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#user  nobody;
worker_processes 4;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
worker_connections 1024;
}


http {
include mime.types;
default_type application/octet-stream;

#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 logs/access.log main;
# Display Version
server_tokens off;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

#keepalive_timeout 0;
keepalive_timeout 60;

gzip on;
gzip_vary on;

gzip_comp_level 6;
gzip_buffers 16 8k;

gzip_min_length 1000;
gzip_proxied any;
gzip_disable "msie6";

gzip_http_version 1.0;

gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;

# 加载配置文件路径
include /point/to/your/path/*;
}

Nginx 站点配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Port 80
server {
# Go to Https
listen 80 default_server;
server_name _;
# listen [::]:80 ;
rewrite ^(.*) https://yooooex.com/$1 permanent;
}

# Port 443
server {
listen 443 ssl http2 fastopen=3 reuseport;
# listen [::]:443;
server_name www.yooooex.com yooooex.com;

if ($host != 'yooooex.com') {
rewrite ^/(.*)$ https://yooooex.com/$1 permanent;
}

##
# SSL Settings
##

# 证书设置
ssl_certificate /etc/letsencrypt/live/yooooex.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yooooex.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_trusted_certificate /etc/letsencrypt/live/yooooex.com/root_CA_cert_plus_intermediates;

# 协议选择和加密方法
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;

# Http 头字段
# 开启HSTS
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
# 不允许 iFrame 嵌套
add_header X-Frame-Options SAMEORIGIN;
# 禁止内容类型嗅探
add_header X-Content-Type-Options: nosniff;
# XSS
# add_header X-XSS-Protection: 1; mode=block;
# 指数密钥交换,推荐使用2048位
# 生成:sudo openssl dhparam -out /path/dhparam.pem 2048
ssl_dhparam /root/nginx/ssl/dhparam.pem;

# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

resolver lv3ns1.ffdns.net lv3ns2.ffdns.net;

# 日志
access_log /root/nginx/logs/yooooex.com.access.log;
error_log /root/nginx/logs/yooooex.com.error.log;
root /var/www/blog/static;

index index.html index.htm;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

location ~ /\. {
return 403;
}

location /imgs/ {
alias /var/www/blog/imgs/;
}

}

测试

当配置完成后,可以到 Qualy’s SSL LABS 来测试配置.
如果配置没出现什么问题的话,你的网站测试应该是像我这样的:

ssl

问题

  • OCSP Stapling 未启用,可能与我使用的证书有关.
  • Public Key Pinning (HPKP) 未配置,找个时间看看.