在Nginx启用Chacha20和ALPN

博客启用HTTPS也应该有一年多了,最近闲的无聊的时候F12发现自己网站的HTTP2没了(博客服务器一直是用的Nginx的mainline版本),寻思咋回事儿的时候发现谷歌从Chrome 51开始强行要求ALPN(Application Layer Protocol Negotiation,应用层协议协商)才能开HTTP2。然而搜遍谷歌给出的结果是OpenSSL 1.0.2才支持ALPN,这就搞得Server端用Ubuntu 14.04的我比较尴尬了(1.0.1版)。 当时我心里第一反应是WQNMLGB的OpenSSL……CHACHA20在实验版本才有就算了,ALPN支持也这么坑。。。。。(只是吐槽,不带恶意,毕竟这东西在开源世界还是帮了不少忙的。) 然后思来想去,反正14.04上的OpenSSL已经这个鬼样子了,我还是自己动手编译支持吧,顺便把Chacha20丢进去。 那么问题来了:ALPN和CHACHA20好处都有啥?说对了就给他 首先,上面提到了,ALPN对后面版本的Chrome来说是开启HTTP2协议的必要条件。HTTP2对比Http 1.1做出了比较多的改动,比如Server Push,服务端根据客户端的请求推测他后面会请求的资源,然后一并推送给客户端,这样一来可以减少客户端请求次数。其次,头部压缩减少了传输体积,优化传输效率。 其次,对于CHACHA20加密,CHACHA20是一种流加密方式,并且旨在提供256位高强度的加密,对移动设备的兼容性更好(毕竟PC上有AES-NI指令集可以处理AES加密,然而手机上面并没有)。之前有一篇测试曾对比过三星移动设备使用AES和CHACHA20加密的速度的对比,在同样大小的密文解密情况下,CHACHA20的效率是AES的4倍左右。 所以说了这么多,开工开工。 (对于使用Ubuntu/Debian的同学,如果不想看下文的话,可以参考这份脚本—》链接) 由于OpenSSL目前生产环境还不支持CHACHA20,因此使用LibreSSL替代。 先下载LibreSSL,这里使用2.4.1版本,然后make:

wget http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.4.1.tar.gz -O libressl.tar.gz
tar zxf libressl.tar.gz
cd libressl*

./configure –prefix=/usr LDFLAGS=-lrt
make

mkdir -p .openssl/lib
cp crypto/.libs/libcrypto.a ssl/.libs/libssl.a .openssl/lib
cd .openssl && ln -s ../include ./
cd lib && strip -g libssl.a && strip -g libcrypto.a
cd ../../../

至于为啥不install,毕竟你系统里面还有其他需求OpenSSL的,万一install完出问题那就不好说了。 然后下载Nginx,这里我使用1.10.1的源代码。configure的配置来自于Nginx官方源的配置,但是去掉了GeoIP和Perl支持。 在配置之前,为了保证configure的完整性,避免报错,你可能需要安装下面几个东西:

apt-get update
apt-get install libxslt1-dev libxml2-dev zlib1g-dev libpcre3-dev libgd-dev -y –force-yes

然后configure

tar zxf nginx.tar.gz

cd nginx*

./configure –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx.pid –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-http_ssl_module –with-http_realip_module –with-http_addition_module –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_stub_status_module –with-http_auth_request_module –with-http_xslt_module=dynamic –with-http_image_filter_module=dynamic –with-threads –with-stream –with-stream_ssl_module –with-http_slice_module –with-mail –with-mail_ssl_module –with-file-aio –with-ipv6 –with-http_v2_module –with-cc-opt=’-g -O2 -fstack-protector –param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2’ –with-ld-opt=’-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,–as-needed’ –with-openssl=《LibreSSL的绝对路径,比如/opt/nginx/libressl-2.4.1》 –with-ld-opt=”-lrt”

touch下Header File,避免被Nginx 重新编译,然后make

touch /opt/nginx/libressl-2.4.1/.openssl/include/openssl/ssl.h
make

接下来,是make install 还是继续其他的操作,取决在你自己了。对于之前已经安装过的同学,执行make install的话会替换掉之前你安装的版本。因此这步请注意下选择。 我这里是make install替换原版本。 然后,如果你是全新安装,你需要把这份文件丢到/etc/init.d里面,然后执行下面的语句,以确保Nginx开机自动运行

sudo ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

wget https://raw.githubusercontent.com/sunflyer/EasyUbuntu/master/nginx.init -O /etc/init.d/nginx

sudo chmod +x /etc/init.d/nginx #安装启动脚本

sudo update-rc.d -f nginx defaults #设置开机自启动

最后运行 nginx -V看看?

nginx version: nginx/1.10.1
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
built with LibreSSL 2.4.1
TLS SNI support enabled

修改你的ssl_cipher配置为下述:(这个是CloudFlare的SSL配置)

EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5:!MEDIUM:!LOW

然后测试下连接。 chacha chacha2 至此大功告成。