β

Nginx上多站点的https配置

搁浅St的blog 219 阅读

更新

此处接上篇 在ubuntu上安装和配置Nginx ,本文在之前的基础上配置https.

1 环境和目标

服务器:ubuntu server 16.04.2 LTS
主要工具:xshell
本文的目标是使用Nginx的TLS SNI技术,使用一个服务器(即一个ip),给多个域名配置https.我有一个腾讯云服务器,买了两个域名,都指向这台服务器,我现在想两个域名都上https,而且 www.bblove.me 跳转到 bblove.me ,我只想使用 bblove.me 这个较短的域名.
但是不是所有的浏览器都支持SNI,下面的截图来自屈大的博客
SNI支持情况
由于是个人博客,随意折腾,所以不犹豫,直接上https.

2 证书

我们使用Let’s Encrypt提供的免费证书,每次有90天的有效期,过期之后需要再更新,不过这对于程序员来说,根本就不是事儿对吧.点击 ACME ,我们使用ACME来自动获取证书.主要步骤分三步:

建议将脚本放在自己的home目录下,并且建立一个alias

acme.sh=~/.acme.sh/acme.sh

操作的目录都只会在 ~/acme.sh 目录,不会污染系统其他的文件夹和目录

2.2 生成证书

脚本安装好后,下一步开始生成证书,生成证书的过程中,Let’s Encrypt需要对域名的所有权进行验证,这个很好理解,证书发行机构需要确定你是否对该域名拥有所有权.验证的方式有两种:

本文采用的是http验证,DNS验证就不细说了,想使用DNS验证的直接看 ACME使用说明

我一共有两个域名 bblove.me huirongis.me ,主域名加上带 www 的子域名,也就是一共有4个域名.
生成证书有下面三种思路:

由于我最后只使用 https://bblove.me 这个域名,验证方式选择的http方式, bblove.me huirongis.me 指向不同的根目录,为了方便后续管理和维护,所以我选择方案二,即 bblove.me www.bblove.me 共用一个证书, huirongis.me 同理.
确定好方案后,下面开始生成证书,使用如下命令即可.

acme.sh --issue -d bblove.me -d www.bblove.me -w /home/chen/www/nginx_acme/bblove_me/ --force

其中 -d 表示域名,可以添加多个; -w 表示网站的根目录,一条命令执行完成,即可得到证书.
顺利的话,执行结果如下(此处配图输入命令未更新,输出结果是一致的):
生成证书
如果出错的话,在那条命令后面追加 --debug ,查看详细的信息,我有遇到过文件权限的错误,只要网站根目录权限和当前home目录对应的用户权限一样就可以了;我还遇到过验证不通过的问题,大家可以在浏览器中访问那个路径,看是否正常,类似 http://bblove.me/.well-known/acme-challenge/dfdfdfdafdfdfdfdfdfdfdfd 这样的格式

2.3 安装证书

在上一步中,我们已经成功的生成了我们要的证书.这一步我们将它安装在我们域名所对应的根目录中,操作很简单.

acme.sh --installcert -d bblove.me --keypath /home/chen/www/nginx_ssl/bblove_me/bblove_me.key --fullchainpath /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer --reloadcmd "service nginx force-reload"

执行结果如图所示:
安装证书
至此,证书部分已经操作完成,第二个域名操作同理.

#生成证书
acme.sh --issue -d bblove.me -d www.bblove.me -w /home/chen/www/nginx_acme/bblove_me/ --force
#安装证书
acme.sh --installcert -d bblove.me --keypath /home/chen/www/nginx_ssl/bblove_me/bblove_me.key --fullchainpath /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer --reloadcmd "service nginx force-reload"

#生成证书
acme.sh --issue -d huirongis.me -d www.huirongis.me -w /home/chen/www/huirongis_me/ --force
#安装证书
acme.sh --installcert -d huirongis.me --keypath /home/chen/www/nginx_ssl/huirongis_me/huirongis_me.key --fullchainpath /home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer --reloadcmd "service nginx force-reload"

3 修改Nginx配置

证书生成完成后,我们需要修改Nginx配置,主要就是启用之前注释掉的HTTPS相关的配置以及,修改对应的目录.
下面是我的第一个站点的配置:

server {
    listen 80;
    server_name       www.bblove.me bblove.me;
    server_tokens     off;

    access_log /home/chen/www/nginx_log/bblove_me.log;
    #access_log        /dev/null;

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return        444;
    }

    location ^~ /.well-known/acme-challenge/ {
        alias         /home/chen/www/nginx_acme/bblove_me/.well-known/acme-challenge/;
        try_files     $uri =404;
    }

    location / {
        rewrite       ^/(.*)$ https://bblove.me/$1 permanent;
    }
}
server{
        listen 443 ssl http2 fastopen=3 reuseport;

        server_name bblove.me;
        server_tokens   off;
        access_log /home/chen/www/nginx_log/bblove_me.log;


        ssl_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
        ssl_certificate_key     /home/chen/www/nginx_ssl/bblove_me/bblove_me.key;

		#使用openssl dhparam -out dhparams.pem 2048命令生成该文件,将下面配置注释也许
        ssl_dhparam    /home/chen/www/nginx_ssl/dhparams.pem;

        ssl_prefer_server_ciphers  on;


		#下面是推荐的加密算法配置,但是在我的机器上有bug,chacha20算法无法正常工作,所以我去掉了其中包含chacha20的算法
		# https://github.com/cloudflare/sslconfig/blob/master/conf
    	#ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
        ssl_ciphers                EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;


        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;

        ssl_session_cache          shared:SSL:50m;
        ssl_session_timeout        1d;

        ssl_session_tickets        on;
        ssl_stapling    on;
        ssl_stapling_verify     on;
        ssl_trusted_certificate /home/chen/www/nginx_ssl/bblove_me/bblove_me.cer;
        resolver        114.114.114.114 valid=300s;
        resolver_timeout        10s;
        if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$ ) {
                return           444;
        }
        if ($host != 'bblove.me'){
                rewrite ^/(.*)$ https://bblove.me/$1 permanent;
        }
        location / {
                root /home/chen/www/bblove_me;
                index index.html index.htm;
                add_header               Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
                add_header               X-Frame-Options deny;
                add_header               X-Content-Type-Options nosniff;
                add_header               Cache-Control no-cache;
                add_header               x-xss-protection " 1; mode=block";
                add_header               x-content-type-options nosniff;
        }
}

下面是我第二个站点的配置:

server{
	listen 443 ssl http2;

	server_name www.huirongis.me huirongis.me;
	server_tokens	off;
	access_log /home/chen/www/nginx_log/huirongis_me.log;

	
	ssl_certificate	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;
	ssl_certificate_key	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.key;
	#ssl_dhparam	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;
	ssl_ciphers                EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
	#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;

	ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;

	ssl_session_cache          shared:SSL:50m;
	ssl_session_timeout        1d;

	ssl_session_tickets        on;
	ssl_stapling	on;
	ssl_stapling_verify	on;
	ssl_trusted_certificate	/home/chen/www/nginx_ssl/huirongis_me/huirongis_me.cer;
	resolver	114.114.114.114 valid=300s;
	resolver_timeout	10s;
	if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$ ) {
        	return           444;
	}
	if ($host != 'huirongis.me'){
		rewrite ^/(.*)$ https://huirongis.me/$1 permanent;
	}	
	location / {
		root /home/chen/www/huirongis_me;
		index index.html index.htm;
	        add_header               Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
		add_header               X-Frame-Options deny;
	        add_header               X-Content-Type-Options nosniff;
		add_header               Cache-Control no-cache;
		add_header		 x-xss-protection " 1; mode=block";
		add_header		 x-content-type-options nosniff;
	}
}
server {
    server_name       www.huirongis.me huirongis.me;
    server_tokens     off;

    access_log        /dev/null;

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return        444;
    }

    location ^~ /.well-known/acme-challenge/ {
        alias         /home/chen/www/nginx_acme/huirongis_me/.well-known/acme-challenge/;
        try_files     $uri =404;
    }

    location / {
        rewrite       ^/(.*)$ https://huirongis.me/$1 permanent;
    }
}

该配置的主体内容,都是参考的屈大的配置,但是由于屈大的是单站点,所以为了对应多站点,做了一些改动.

有些配置的含义和原理,屈大都给了详细的分析,想了解的可以去看看.

再贴一下本站目录结构:
本站目录设置

4 修改http资源为https

ok,都这里基本都搞定了,应该可以看到小绿锁了.在chrome中按 F12 -> console ,查看原因.如果你的网站中包含其他第三方http资源,可能会没有看到小绿锁,只需要将http资源修改为https的就行,比如图片资源,本站使用新浪微博图床,只需要将原来的http格式的图片加个s,变成https就可以了.如果资源没有https的,那就需要将资源下载到服务器本地.
小绿锁
至此,整个网站的https配置完成.

5 问题和优化

现在还有问题没有解决:

参考文献

更新

此处接上篇

作者:搁浅St的blog
我最喜欢笨笨
原文地址:Nginx上多站点的https配置, 感谢原作者分享。

发表评论