自己编译Nginx启用ALPN和chacha20

     2016/6/28更新:根据测试,chacha20在pc上面的加解密性能并不能令人满意,所以,完成两天的测试后,本站SSL的加密方式仍然改回AES。PC的cpu由于有AES指令集加持,处理AES加解密的速度还是非常有保证的。另外,firefox的最新版本也提供了chacha20的支持。如果需要像google一样,根据平台更换加密算法,需要使用BoringSSL的等价加密组功能,具体请自行搜索。

================================================
      一般来说,安装nginx我都喜欢从官方源安装预编译版本,简单省事,功能齐全。但是自从chrome升级到51版本,我发现博客的http2不见了,谷歌加百度搜索了半天才发现,从51版本开始,开启http2需要服务端支持ALPN(Application Layer Protocol Negotiation,应用层协议协商),然而ALPN又依赖openssl 1.0.2,这对于偏爱centos6的我来说,简直很黄很暴力(系统自带openssl 1.0.1)。

      没办法,只有动手编译nginx了。网上找到的都是ubuntu的教程,用在centos上面需要稍作修改。这里采用nginx 1.10.1 stable version和LibreSSL,用LiberSSL替代openssl的主要原因是可以它启用chacha20加密,从而在移动设备上获得更好的性能。openssl对于chacha20的支持还停留在试验版本呢!

      废话不多说,下面上编译过程。系统环境centos 6.8 x86_64。

      首先,安装epel源,然后安装编译需要的依赖环境。

yum install epel-release
yum install gcc automake autoconf libtool make
yum install gcc gcc-c++
yum install libxslt-devel gd-devel GeoIP-devel

  
      环境安装好之后,如果你需要编译rewrite功能,还要下载pcre组件的源码,下载之后解压好就行,不用编译,nginx编译的时候会自动去处理它。

mkdir -p /root/nginx-source/pcre
cd /root/nginx-source/pcre
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.38.tar.gz
tar -zxvf pcre-8.38.tar.gz

      现在获取并编译LibreSSL,注意编译完了不要去执行make install,不然他会替换掉系统的openssl,容易引发莫名其妙的问题。

mkdir -p /root/nginx-source/libressl
cd /root/nginx-source/libressl
wget http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.4.1.tar.gz
tar -zxvf libressl-2.4.1.tar.gz

cd libressl-2.4.1
./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 ../../../

        要编译gzip支持的话,需要zlib的源码,但是centos6自带这个库,nginx在编译的时候会自己去调用。这样就不用去折腾这个依赖了。

        现在可以获取nginx的源码并且编译了,这里编译的配置我直接从官方源抄了一波,去掉了perl支持,注意编译环境是64位系统,32位系统的话,部分路径可能会不同。

       最后,configure完了之后一定要先执行touch下ssl.h再开始编译,避免nginx在编译过程中对LibreSSL进行第二次编译。

cd /root/nginx-source
wget http://nginx.org/download/nginx-1.10.1.tar.gz
tar -zxvf nginx-1.10.1.tar.gz
cd nginx-1.10.1
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/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-http_geoip_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='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-openssl=/root/nginx-source/libressl/libressl-2.4.1 --with-pcre=/root/nginx-source/pcre/pcre-8.38 --with-ld-opt=-lrt
#!!!!注意下面的touch命令必须执行,路径要写对!!!!
touch /root/nginx-source/libressl/libressl-2.4.1/.openssl/include/openssl/ssl.h
make

       如果编译顺利完成,下一步就可以准备安装了。我的系统里面是安装了预编译版本的。按照老陈的说法,直接执行make install 可以替换原来的版本。当然,你也可以先执行yum remove nginx,卸载掉原来的版本,再全新安装。需要注意的是,卸载前请备份好/etc/nginx目录下面的所有配置文件,卸载可能造成部分配置文件丢失!

      对于全新安装的童鞋,如果需要用servic 和 chkconfig 命令来控制nginx,必须设置init脚本。这里的脚本来源于nginx官网的wiki。

wget -O /etc/init.d/nginx https://raw.githubusercontent.com/MikeMiao/centos-lnmp/master/git/nginx_init.sh
chmod +x /etc/init.d/nginx
service nginx start
chkconfig nginx on

       执行下nginx -V,查看输出信息

nginx version: nginx/1.10.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
built with LibreSSL 2.4.1
TLS SNI support enabled

      要开启chacha20,把你nginx配置文件的ssl_cipher修改成下面的形式:

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

      最后执行下测试,chacha20有了,http2也回来了。当然由于chacha20的兼容性问题,目前只有chrome和安卓5.0+系统的浏览器可以协商成功,对于不兼容chacha20算法的浏览器,nginx会默认去协商兼容性更好的AES。

     chacha20 h2

参考资料:
https://sunflyer.cn/archives/406
https://www.futures.moe/writings/chacha20-poly1305.htm
https://imququ.com/post/enable-alpn-asap.html

发表评论

邮箱地址不会被公开。 必填项已用*标注