编译Nginx支持TLS1.3,并使用acme.sh获取证书

前言

TLS1.2发布于2008年8月,至今正好有10年,随着互联网安全越来越受到重视,新协议TLS1.3呼之欲出。值得一提的是,从第一份草案编写至今,已经有几年时间了,截止这篇文章编写,已经是第28份草案。在最近的Chrome版本更新中也逐步对TLS1.3进行支持,Chrome 65开始默认开启草案23,Chrome 68开始支持draft 28

TLS1.3对于TLS1.2有重大改写,既提高了安全性又提高了速度,以至于有争议称,应该把它叫做TLS2.0

关于TLS1.3的科普可以看下面的页面

https://wiki.openssl.org/index.php/TLS1.3

https://zhuanlan.zhihu.com/p/28850798

之前我也写过Nginx的https的配置https://zhih.me/nginx-http2-https/,当时是使用TLS1.2的

碰巧前几天发现可以免费用1年,就撸了一个来做为我onmp项目的页面,把它搭在4刀年付的virmach上,顺便测试TLS1.3

安装

我这里用的系统是Debian 8

安装依赖

$apt-get install git gcc make build-essential zlib1g-dev libpcre3-dev

下载源码和补丁

$mkdir -p /usr/src$cd/usr/src$gitclonegit://git.openssl.org/openssl.git openssl$gitclonehttps://github.com/hakasenyang/openssl-patch.git openssl-patch$gitclonehttps://github.com/kn007/patch.git nginx-patch$wget https://nginx.org/download/nginx-1.15.0.tar.gz$tar zxvf ./nginx-1.15.0.tar.gz

给OpenSSL打补丁

来自补丁https://github.com/hakasenyang/openssl-patch

此补丁的目的是让OpenSSL支持TLS1.3的23,26,28草案

$cd/usr/src/openssl$patch -p1 给Nginx打补丁

来自补丁https://github.com/kn007/patch

添加SPDY支持,添加HTTP2 HPACK编码支持,添加动态TLS记录支持

修复nginx的http2 push和http2 hpack兼容性问题

添加在使用OpenSSL1.1.1时SSL_OP_PRIORITIZE_CHACHA的支持

$cd/usr/src/nginx-1.15.0$patch -p1 其他编译配置

Nginx默认会以调试模式编译,我们需要注释掉中这行,这样可以减少生成文件的大小

编译安装

$cd/usr/src/nginx-1.15.0$./configure \--prefix=/etc/nginx \--sbin-path=/usr/sbin/nginx \--conf-path=/etc/nginx/nginx.conf \--pid-path=/var/run/nginx.pid \--lock-path=/var/lock/nginx.lock \--modules-path=/usr/lib/nginx/modules \--with-compat --with-file-aio --with-threads \--with-openssl=../openssl \--with-http_v2_module \--with-http_v2_hpack_enc \--with-http_spdy_module \--with-http_ssl_module \--with-http_gzip_static_module$make$make install

Nginx的可执行文件安装在,Nginx配置在里

配置

Nginx已经安装上了,现在我们来配置网站,让它跑起来

Nginx全局配置

把以下内容覆盖填入

worker_processesauto;pid/var/run/nginx.pid;error_log/var/log/nginx/error.log;events{useepoll;multi_accepton;worker_connections1024;}http{charsetutf-8;include/etc/nginx/mime.types;default_typeapplication/octet-stream;access_log/var/log/nginx/access.log;tcp_nopushon;tcp_nodelayon;keepalive_timeout60;sendfileon;sendfile_max_chunk256k;aiothreads;directio512k;output_buffers1128k;gzipon;gzip_varyon;gzip_proxiedany;gzip_min_length1k;gzip_buffers48k;gzip_comp_level2;gzip_disable"msie6";gzip_typestext/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;include/etc/nginx/vhost/*.conf;}

Nginx站点配置

我们已经在全局配置里设置了包含目录下的conf文件

$mkdir -p /etc/nginx/vhost

在然后里创建³³站点配置,比如我的是

server{listen80;server_nameonmp.ooo;root/wwwroot/onmp.ooo;location/ {indexindex.html; }}

这样HTTP的站点配置就弄好了,不过还站点还没页面,我们把Nginx的欢迎也面给放进去

$mkdir -p /wwwroot/onmp.ooo$cp /usr/local/nginx/html/index.html /wwwroot/onmp.ooo/$nginx

启动Nginx后HTTP页面就正常了,打开onmp.ooo就能看到欢迎来到nginx!

签发证书

配置HTTPS首先要有证书,我这里是使用acme.sh自动颁发让我们加密的证书

安装工具

$apt-get install cron socat

获取acme.sh

$curl https://get.acme.sh | sh

重启终端,如果你使用zsh可以这样

生成证书

使用http方式验证域名,这是我们先搭建HTTP站点的原因,接下来指定域名,指定站点目录,开始签发

$acme.sh --issue -d onmp.ooo --webroot /wwwroot/onmp.ooo/ --keylength ec-256 --nginx

如果是多域名,可以使用-d参数添加,如:

是签发ECC类型的证书,它的安全性更高,删除则使用默认的RSA证书

复制证书

证书已经签发了,默认不过的英文保存在里

$acme.sh --ecc --installcert -d onmp.ooo \--key-file /etc/nginx/ssl/onmp.ooo.key \ --fullchain-file /etc/nginx/ssl/onmp.ooo.cer \ --reloadcmd "nginx -s reload"

指定域名,指定证书保存目录,我这里设置在,指定Nginx重载命令,如果签发的不是ECC证书,把参数去掉

这样使用acme.sh就完成了证书的签发,如果证书快要过期了,脚本会自动更新证书

脚本自动更新,可以使用以下命令

$acme.sh --upgrade --auto-upgrade

HTTPS站点配置

因为我给OpenSSL打的是pre8_ciphers补丁,所以ssl_ciphers配置文件如下,如果你打的是别的补丁,则需要查看https://github.com/hakasenyang/openssl-patch给的配置

server{listen80;server_nameonmp.ooo;return301https://onmp.ooo$request_uri;}server{listen443ssl http2;server_nameonmp.ooo;root/wwwroot/onmp.ooo;ssl_certificate/etc/nginx/ssl/onmp.ooo.cer;ssl_certificate_key/etc/nginx/ssl/onmp.ooo.key;ssl_protocolsTLSv1.2TLSv1.3;ssl_ciphers[TLS13+AESGCM+AES128|TLS13+AESGCM+AES256|TLS13+CHACHA20]:[EECDH+ECDSA+AESGCM+AES128|EECDH+ECDSA+CHACHA20]:EECDH+ECDSA+AESGCM+AES256:EECDH+ECDSA+AES128+SHA:EECDH+ECDSA+AES256+SHA:[EECDH+aRSA+AESGCM+AES128|EECDH+aRSA+CHACHA20]:EECDH+aRSA+AESGCM+AES256:EECDH+aRSA+AES128+SHA:EECDH+aRSA+AES256+SHA:RSA+AES128+SHA:RSA+AES256+SHA:RSA+3DES;ssl_ecdh_curveX25519:P-256:P-384;ssl_prefer_server_cipherson;ssl_session_cacheshared:SSL:50m;ssl_session_timeout1d;ssl_session_ticketson;ssl_staplingon;ssl_stapling_verifyon;add_headerStrict-Transport-Security"max-age=31536000; includeSubDomains; preload";location/ {indexindex.html;http2_push/style.css; }location~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)${expires30d; }location~ .*\.(js|css)?${expires15d; }location~ /.git/{denyall; }}

以上就是完整的站点配置文件,覆盖后,使用重载Nginx再打开站点就能看到HTTPS的页面了

验证

在Chrome 65或更新的版本中,打开开发者工具的安全菜单,就能在里面看到站点是否以TLS1.3连接

或者可以到SSL服务器测试:https://www.ssllabs.com/ssltest/index.html进行测试

我只开启了TLSv1.2 TLSv1.3的支持,如果需要,你可以自己增加其他协议的支持

后话

人们的生活已经离不开网络,所以网络安全在现在和未来都至关重要,曾经很多站长都以HTTPS影响站点速度为由,又或说说SSL证书昂贵,拒绝配HTTPS,而随着技术的迭代升级,配置HTTPS + HTTPS2能提高网站速度,而SSL不仅可以免费获取,还可以使用命令自动获取自动更新,在我看来已经没有理由不配置HTTPS了,所以希望各位站长,都赶紧上车吧

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181005A0IN0C00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券