在 CentOS 7 上使用支持 chacha20 加密算法的 Nginx


一、前言

由于我的云主机不支持 AES-NI,所以很有必要使用 chacha20 加密算法。

但 CentOS 7 自带的 OpenSSL 库版本过低(1.0.2),不支持 chacha20 加密算法。

并且 EPEL 源里的 Nginx 是动态链接到系统自带 OpenSSL 库的,还不能使用别的版本的 OpenSSL 库。

所以就只能自己动手编译 Nginx 咯。编译的时候只需指定静态链接到新版本 OpenSSL 库即可。

说明
• 由于各人的系统环境各不相同,所以无法保证一次就能编译成功。如果编译出现错误,建议使用 Docker 搭建一个全新的系统环境再进行编译,具体方法这里就不赘述了。


二、软件版本

  • 操作系统:CentOS 7.7.1908
  • Nginx:1.16.1
  • OpenSSL:1.1.1d

三、准备工作

3.1 安装必要的软件包

执行以下命令:

yum -y install epel-release && \
yum -y update && \
yum -y groupinstall 'Development Tools' && \
yum -y install gd-devel GeoIP-devel gperftools libxml2-devel libxslt-devel pcre-devel perl-devel perl-ExtUtils-Embed tar wget

3.2 创建临时目录并进入

说明
• 该目录用于暂时存放编译所需的各种文件及源码,在编译完成后可自行删除。

执行以下命令:

mkdir /tmp/build && cd /tmp/build

3.3 下载 Nginx 源码包

执行以下命令:

wget http://nginx.org/download/nginx-1.16.1.tar.gz && \
tar -xf nginx-1.16.1.tar.gz

3.4 下载 OpenSSL 源码包

执行以下命令:

wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz && \
tar -xf openssl-1.1.1d.tar.gz

四、编译及安装 Nginx

4.1 编译 Nginx

执行以下命令:

cd nginx-1.16.1 && \
./configure --prefix=/usr/share/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 --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --with-openssl=../openssl-1.1.1d --with-openssl-opt='enable-tls1_3' --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --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_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' && \
make

说明
• 这里的编译参数与 EPEL 源上的 Nginx 几乎完全相同,使用时无需修改路径或增加额外配置。

4.2 安装 Nginx

⚠️ 注意
• 安装之前请先卸载使用 yum 安装的 Nginx(请备份配置文件),以免日后造成依赖问题或者被覆盖。

执行以下命令:

make install

4.3 安装服务文件

执行以下命令:

cat << EOF > /lib/systemd/system/nginx.service

以下内容直接粘贴到命令行窗口中按回车即可。

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running \`nginx -t\` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

然后再执行以下命令让服务文件生效:

systemctl daemon-reload

4.4 创建 Nginx 专用群组及账户

执行以下命令:

groupadd nginx && \
useradd -g nginx nginx -d /var/lib/nginx -s /sbin/nologin

4.5 创建 Nginx 临时目录

执行以下命令:

mkdir -p /var/lib/nginx/tmp

五、chacha20 加密算法的配置

这里简单讲一下配置方法,不做过多介绍。

ssl_ciphers 配置项中加入 ECDHE-ECDSA-CHACHA20-POLY1305(用于 ECC 证书)和 ECDHE-RSA-CHACHA20-POLY1305 这两个加密算法即可让 Nginx 支持 chacha20 加密算法。

发表评论

电子邮件地址不会被公开。