Nginx 配合 BoringSSL 进行编译,并且启用 chacha20-poly1305 加密教程

2015-03-05 11:13:21 +08:00
 xiaolvmu
这是一篇很特殊的教程。对于大多数网站来说,OpenSSL 足够稳定和兼容。因此 ChaCha20-Poly1305 系(以下简称CP)加密似乎是不必要的。
但是,ChaCha20-Poly1305 加密在 ARM 平台上有着先天的优势。

根据测试,在许多移动设备上,ChaCha20-Poly1305 加密的速度是 AES 的3倍还多。这样,网站在移动设备上的体验将会更好。虽然这种优化很难感受到,远没有 fcgi_cache/pagespeed 之类明显,不过为了信仰,还是要试一试。

一:方案的选择。

1:至今 OpenSSL 还没能在生产环境中支持 ChaCha20-Poly1305 加密。
在一个特殊的分支中,OpenSSL 添加了对这种加密的支持,叫做 the 1.0.2-aead branch。不过依然不建议使用。
你可以参考的资料:
https://www.onwebsecurity.com/cryptography/openssl
2:我们的选择主要是 LibreSSL(OpenBSD 创建的 OpenSSL 分支) 和 BoringSSL(Google 创建的 OpenSSL 分支)。
你可以参考的资料:
https://boringssl.googlesource.com/boringssl/
http://m.slashdot.org/story/203641
http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/
3:关于 Web 服务器。
在 Apache HTTP Server 下,BoringSSL 和 LibreSSL 会导致 mod_ssl 出错,只有用 nginx 对其进行反代才有可能实现。而反代对资源消耗太大,因此,我们在方案中直接弃用 Apache,使用 Nginx。注意,以下所有的资料都针对 Nginx HTTPS Webserver。
4:LibreSSL or BoringSSL?
就在前天,LibreSSL 的 2.1.4 版本发布了。
实现这套加密时,我最开始选择的加密库是 LibreSSL,因为资料非常齐全。但是我仅仅编译成功了 LibreSSL 2.1.1 版本,在高于 2.1.1 的版本中,存在一个特殊的编译问题,经过我的测试,2.1.2/2.1.3 版本都不能和 Nginx 1.7.10 一起编译成功。因为 2.1.4 刚刚出来,我还没有测试,大家可以试一试。
LibreSSL 的 2.1.4 更新日志:
http://undeadly.org/cgi?action=article&sid=20150304092744
2.1.2 编译问题的相关讨论:
https://github.com/libressl-portable/portable/issues/51
最终,我选择 BoringSSL 作为解决方案。
5:为什么不采用 LibreSSL?
在 LibreSSL 2.1.2 所有以前的版本中均存在一个可导致拒绝服务攻击的漏洞。
ssllabs.com 中,使用 LibreSSL 2.1.2 以下版本时,会有一个特殊的警告。
This server doesn't support TLS_Fallback_SCSV.
这方面的讨论非常多,你可以参考的资料:
https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01
(虽然这一篇我看不懂。。。)
而 LibreSSL 2.1.2 和 2.1.3 版本会导致无法 make nginx,而且没有方便的解决方案/patch。
因此我们不再考虑 LibreSSL。


二:BoringSSL 的编译
花了这么多篇幅讲述方案的选择,再写编译就很明了了:
1:使用的软件包
稍后用到
Nginx Mainline 1.7.10:
http://nginx.org/en/download.html
或者 wget http://nginx.org/download/nginx-1.7.10.tar.gz

BoringSSL 源码
git clone https://boringssl.googlesource.com/boringssl
2:假定的目录
/boring
--boringssl
--nginx-1.7.10.tar.gz
3:处理链接搜索路径:
cd /boring/boringssl
sed -i \
-e 's:-ggdb -std=c89:-std=c89 -march=sandybridge -O2 -pipe -fdiagnostics-color=always:' \
-e 's:-ggdb -std=c++0x:-std=c++0x -march=sandybridge -O2 -pipe -fdiagnostics-color=always:' \
-e '/^add_subdirectory(ssl\/test)/d' \
-e '/^add_subdirectory(tool)/d' \
CMakeLists.txt

这些命令来自 Github @wmark install.sh。在我执行的时候,只sed了后3行,似乎没有问题,不过建议大家全部执行。
https://gist.github.com/wmark/d208d82c6424810f1b7c
使用这个 install.sh 也是不错的办法,不过centos 7 x64失败了,只有手动来了。
4:开始编译 BoringSSL
先安装 CMake,在这里找 releases
https://github.com/Kitware/CMake

cd /boring/boringssl
mkdir build &&cd build
cmake ../ && make
cd ..
5:处理加密库,使它兼容 OpenSSL
cd /boring/boringssl
mkdir -p .openssl/lib
ln -s include /boring/boringssl/.openssl/
#
注意!在这一步中,链接到的目录最好是绝对路径,不然容易在进入时出现
Too many levels of symbolic links
#
cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
#注意,如果你在编译时没有输出 libssl.a/libcrypto.a,说明编译错误了
#


三:Nginx 的编译

Nginx 不支持动态so库,所有的模块必须编译时一起编译进去。
1:分享一下我的 nginx config参数:
[root@default ~]# /etc/sbin/nginx -V
TLS SNI support enabled
configure arguments: --prefix=/etc --user=nginx --group=nginx --with-openssl=../boringssl --with-ld-opt=-lrt --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-pcre --add-module=../ngx_cache_purge-2.3 --add-module=/boring/ngx_pagespeed-1.9.32.3-beta

我额外使用了 cache purge 和 pagespeed 模块。
Frickle 的 ngx_cache_purge 模块:
https://github.com/FRiCKLE/ngx_cache_purge
Google 的 ngx_pagespeed 模块:
https://github.com/pagespeed/ngx_pagespeed
找到 release,解压即可,add-module 的路径必须是绝对路径。

注意:ngx_pagespeed 需要 psol
cd /path/to/pagespeed/module
wget https://dl.google.com/dl/page-speed/psol/1.9.32.3.tar.gz
tar -xzvf 1.9.32.3.tar.gz # expands to psol/

发现扯远了-_-||继续说 boringSSL
--with-openssl=../boringssl --with-ld-opt=-lrt --with-http_ssl_module
这是必要的编译参数。

2:开始编译
注意!这时需要先更新 ssl.h 的文件时间,防止被 nginx 重新编译导致 make nginx 失败。
cd /boring/boringssl/.openssl/include/openssl
touch ssl.h
cd /boring/nginx-1.7.10
make

3:安装 nginx
make upgrade

四:Nginx 的配置

server {} 字段

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers CHACHA20:AES128:AES256:GCM:!DH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;add_header Strict-Transport-Security max-age=31536000;ssl_prefer_server_ciphers on;

PS:BoringSSL 默认禁用 SSLv3。

五:其他的 nginx 安全配置

1:HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
可以多配置几个:
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

2:SPDY 3.1 的实现
listen 443 ssl default spdy
add_header Alternate-Protocol 443:npn-spdy/3.1;

3:完美向前保密(PFS)
openssl dhparam -rand - 2048 >> /path/to/my-key.crt
#这需要比较长的时间。
2048 位还是不错的选择,我在生成的时候选择了 4096 位,后悔了。。
#

4:对于使用 StartSSL 证书的同学
http://www.startssl.com/certs/class1/sha2/pem/
也有 sha2 加密的哦(>﹏<)

#configuration
ssl_dhparam /etc/conf/dh4096.pem

六:我想说的

安全性是一个永恒的话题。
安全性会牺牲很多东西,例如兼容性,例如加载网页的速度。
不要太过于追求安全性,而我们,需要在安全性和易用性之间,做出一个较好的权衡。

10526 次点击
所在节点    分享发现
11 条回复
xiaolvmu
2015-03-05 11:14:27 +08:00
V2EX 太酷炫了,引用 Github 链接竟然直接出来 Showcase(>﹏<)
0x1e240
2015-03-05 14:48:32 +08:00
简直炫酷,继续Apache
😯
xiaolvmu
2015-03-05 17:48:55 +08:00
额……
其实 Apache 有的,Nginx 大多都有,实在找不出来用 Apache 的理由……
mafuyu
2015-03-05 23:00:24 +08:00
简直是炫酷,默默地继续用LibreSSL来实现CP...
(副音轨:CP根本就只能拿来卖萌用么 (╯°Д°)╯︵ ┻━┻)
xiaolvmu
2015-03-06 00:21:35 +08:00
哈哈~每天坚持卖萌(>﹏<)
lhbc
2015-03-06 02:49:28 +08:00
futursolo
2015-03-07 11:11:07 +08:00
Nginx支持动态库,用--with-openssl=shared就OK,只不过那样就没办法使用自定义的SSL库了。
LibreSSL2.1.2及2.1.3需要给Nginx打Patch才可用。2.1.4就恢复正常了,而且集成了SSL_Fallback_SCSV,测试也可以拿到A+了。
xiaolvmu
2015-04-03 10:52:23 +08:00
终于放假了~
话说,有的 gcc 不支持 sandybridge 这个 march,如果 sed 的时候选择 sandybridge 不起作用,就用
march=native,需要 gcc 4.2 以上。
xiaolvmu
2015-04-03 10:53:31 +08:00
话说 libressl 发布 2.1.6 了,他们刷版本号好疯狂,刚编译完2.1.5。。
xiaolvmu
2015-04-03 10:58:04 +08:00
新动态:
新版本1.7.11的 nginx,编译 boringssl 出错了......
找了下,在nginx源码的 /src/event/openssl.c 的 1900 行附近有一个 SSL_R_BLOCK_CIPHER_PAD_IS_WRONG ,去掉就可以编译了。可是不知道这有什么影响。
windydays
2015-05-14 18:03:55 +08:00
之前做了一个nginx+openssl+chacha20-poly1305的配置,可以看:
https://blog.helong.info/blog/2015/05/08/https-config-optimize-in-nginx/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/174625

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX