背景信息
Tengine是由阿里云团队开发并开源的一款高性能、可扩展的Web服务器和反向代理服务器,它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine已对铜锁/Tongsuo(原名BabaSSL)进行适配,并增加了对NTLS(National TLS,也称国密TLS)相关能力的支持。对于有使用国密算法进行安全通信协议需求的用户,可以直接使用Tengine+Tongsuo的组合。
本文使用Tengine+Tongsuo组合实现SM2/RSA双证书模式,在Tengine部署SM2/RSA双SSL证书, 当用户使用360浏览器、奇安信浏览器、红莲花浏览器等国密浏览器访问时,自动采用国密算法HTTPS加密; 当用户使用Chrome、Firefox、IE、Safari等不支持国密算法的通用浏览器访问时, 自动采用RSA算法HTTPS加密,自适应兼容所有浏览器及移动终端。
1. 环境准备
1.1 下载Tongsuo
cd /usr/local/src
# 下载Tongsuo
wget -c https://github.com/Tongsuo-Project/Tongsuo/archive/refs/tags/8.4.0.tar.gz
# 解压Tongsuo源码
tar zxf 8.4.0.tar.gz
1.2 下载Tengine
# 下载Tengine
wget -c https://github.com/alibaba/tengine/archive/refs/tags/3.1.0.tar.gz
# 解压Tengine源码
tar zxf 3.1.0.tar.gz
1.3 安装依赖
# CentOS 系统 [麒麟/Redhat]
yum install -y wget gcc gcc-c++ make pcre pcre-devel gzip zlib-devel
# Ubuntu 系统
apt install g++ libpcre3 libpcre3-dev openssl libssl-dev zlib1g zlib1g-dev -y
2. 编译安装Tengine
cd /usr/local/src/tengine-3.1.0
# 配置
./configure --prefix=/usr/local/tengine \
--with-openssl=/usr/local/src/Tongsuo-8.4.0 \
--with-openssl-opt="enable-ntls" --with-http_ssl_module \
--with-http_stub_status_module --with-http_v2_module \
--with-http_realip_module --with-http_sub_module \
--with-http_flv_module --with-http_mp4_module \
--with-http_random_index_module --with-http_gzip_static_module \
--add-module=modules/ngx_tongsuo_ntls \
--add-module=modules/ngx_http_upstream_session_sticky_module \
--add-module=modules/ngx_http_upstream_check_module
# 编译
make -j
# 安装
make install
--prefix=/usr/local/tengine:指定Tengine安装目录为/usr/local/tengine,您可以指定其他目录。
--add-module=modules/ngx_tongsuo_ntls:加载Tongsuo NTLS。Tengine 2.4.1之前的版本需将ngx_tongsuo_ntls替换为ngx_openssl_ntls。
--with-openssl=/usr/local/src/Tongsuo-8.4.0 :OpenSSL替换为Tongsuo以实现SM2。/usr/local/src/Tongsuo-8.4.0 需替换为实际Tongsuo源码解压路径。
--add-module=modules/ngx_http_upstream_session_sticky_module :负载均衡模块,通过cookie实现客户端与后端服务器的会话保持。
--add-module=modules/ngx_http_upstream_check_module :提供主动式后端服务器健康检查的功能。
3. Tengine 配置
cd /usr/local/tengine/conf
# 备份模式配置文件
mv nginx.conf nging.conf.bak0
# 编辑生成新的配置文件[根据应用部署模式(单机/多节点)选择配置]
vi /usr/local/tengine/conf/nginx.conf
3.1 应用单机配置[nginx.conf]
worker_processes auto;
worker_rlimit_nofile 20960;
error_log logs/error.log crit;
events {
worker_connections 4096;
multi_accept on;
accept_mutex on;
accept_mutex_delay 500ms;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
include mime.types;
default_type application/octet-stream;
keepalive_timeout 300;
client_max_body_size 10240M;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 3;
gzip_types text/xml text/plain text/css text/javascript application/x-javascript application/javascript application/xml;
gzip_disable "MSIE [1-6].";
server {
listen 443 ssl;
server_name oa.test.cc;
enable_ntls on;
# 配置国密算法签名证书
ssl_sign_certificate cert/sm2.test.cc.sig.crt.pem;
ssl_sign_certificate_key cert/sm2.test.cc.sig.key.pem;
# 配置国密算法加密证书
ssl_enc_certificate cert/sm2.test.cc.enc.crt.pem;
ssl_enc_certificate_key cert/sm2.test.cc.enc.key.pem;
# 配置RSA算法证书
ssl_certificate cert/rsa.test.cc.crt.pem;
ssl_certificate_key cert/rsa.test.cc.key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
# 配置加密套件# ssl_ciphers HIGH: !aNULL: !MD5;
ssl_ciphers ECC-SM2-SM4-CBC-SM3:ECC-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!RC4:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 如正式配置,可使用此段location;
location / {
# 应用服务地址
proxy_pass http://192.168.159.151:8088;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# http访问配置为非80端口,需要删除
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}
# 如测试证书,可启用此段location(取消行前注释即可);
# location / {
# root html;
# index index.html index.htm;
# }
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 需模块ngx_http_upstream_check_module支持,浏览器访问 http://IP:PORT/status [可选]
location /status {
check_status;
access_log off;
#allow SOME.IP.ADD.RESS;
#deny all;
}
}
# 配置80端口默认转发至443端口
server {
listen 80;
return 301 https://$host$request_uri;
}
}
3.2 应用负载配置[nginx.conf]
worker_processes auto;
worker_rlimit_nofile 20960;
error_log logs/error.log crit;
events {
worker_connections 4096;
multi_accept on;
accept_mutex on;
accept_mutex_delay 500ms;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
include mime.types;
default_type application/octet-stream;
keepalive_timeout 300;
client_max_body_size 10240M;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 3;
gzip_types text/xml text/plain text/css text/javascript application/x-javascript application/javascript application/xml;
gzip_disable "MSIE [1-6].";
upstream apps_cluster{
session_sticky;
# 负载多个应用服务地址
server 192.168.159.151:8088;
server 192.168.159.152:8088;
server 192.168.159.153:8088;
# 需模块ngx_http_upstream_check_module支持
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_keepalive_requests 100;
}
server {
listen 443 ssl;
server_name app.test.cc;
enable_ntls on;
# 配置国密算法签名证书
ssl_sign_certificate cert/sm2.test.cc.sig.crt.pem;
ssl_sign_certificate_key cert/sm2.test.cc.sig.key.pem;
# 配置国密算法加密证书
ssl_enc_certificate cert/sm2.test.cc.enc.crt.pem;
ssl_enc_certificate_key cert/sm2.test.cc.enc.key.pem;
# 配置RSA算法证书
ssl_certificate cert/rsa.test.cc.crt.pem;
ssl_certificate_key cert/rsa.test.cc.key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
# 配置加密套件# ssl_ciphers HIGH: !aNULL: !MD5;
ssl_ciphers ECC-SM2-SM4-CBC-SM3:ECC-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!RC4:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://apps_cluster;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# http访问配置为非80端口,需要删除
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 需模块ngx_http_upstream_check_module支持,浏览器访问 http://IP:PORT/status [可选]
location /status {
check_status;
access_log off;
#allow SOME.IP.ADD.RESS;
#deny all;
}
}
# 配置80端口默认转发至443端口
server {
listen 80;
return 301 https://$host$request_uri;
}
}
3.3 服务控制
vi /usr/lib/systemd/system/nginx.service
nginx.service 文件内容
[Unit]
Description=Tengine Web Server
Documentation=https://tengine.taobao.org/documentation_cn.html
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
# User=nginx
# Group=nginx
Type=forking
PIDFile=/usr/local/tengine/logs/nginx.pid
ExecStart=/usr/local/tengine/sbin/nginx -p /usr/local/tengine -c /usr/local/tengine/conf/nginx.conf
ExecReload=/usr/local/tengine/sbin/nginx -p /usr/local/tengine -s reload
ExecStop=/usr/local/tengine/sbin/nginx -p /usr/local/tengine -s stop
LimitNOFILE=infinity
PrivateTmp=true
Restart=on-failure
RestartPreventExitStatus=1
RestartSec=3
[Install]
WantedBy=multi-user.target
# 设置开机启动并立即启动服务
systemctl enable --now nginx.service
# 服务重启
systemctl restart nginx.service
# 服务状态
systemctl status nginx.service
3.4 防护墙策略
# firewalld
# 默认端口时,可添加http或https服务
firewall-cmd --permanent --zone=public --add-service=http --add-service=https
# 非默认端口时使用指定端口
firewall-cmd --permanent --zone=public --add-port=8080/tcp --add-port=8443/tcp
# 立即生效
firewall-cmd --reload复制
4. 附
国密浏览器下载:
密信浏览器:www.mesigndoc.com/zh-cn/brows…
360安全浏览器:browser.360.net/gmzb.html?s…
奇安信可信浏览器:www.qianxin.com/ctp/gmbrows…