配置 nginx 前向保密及 rtmp 模块

简述

随着 Firefox、Chrome 等主流浏览器对 HTTP 协议标记为不安全,Let’s Encrypt 使得 SSL 证书的取得变得便宜快捷,启用 HTTPS 对传输数据进行加密成为了当今每个网站不可或缺的一部分。然而,nginx 的默认配置参数使用的加密协议版本和加密方式有弱加密的情况,启用前向保密(Forward Secrecy)可以增强加密效果,增大攻击难度。在此,我给出我的配置过程和策略。

安装 nginx

您可以使用任意包管理系统安装 nginx,例如在 openSUSE 下直接使用 zypper in nginx 即可安装。发行版所提供的软件版本一般适合大多数用于的需求,它按照该发行版所广泛使用的默认依赖关系对其进行编译打包,不会破坏依赖关系。

openSUSE 所提供的 nginx 启用了多个扩展,其中就包含有 nginx-rtmp-module,为后续配置 rtmp 服务器提供支持。

配置 nginx 并启用前向保密

配置 nginx

您可以直接编辑 /etc/nginx/nginx.conf,由于 openSUSE 的 nginx 使用了 vhosts.d,这里的配置将作为其默认模板。我按照默认的 nginx.conf 添加了以下选项:

使用用户 nginx,线程数配置为 auto 让程序自动选择最佳:

user nginx;
worker_processes auto;

设置默认字符集为 utf-8(http),启用 gzip 压缩:

charset utf-8;
gzip on;

启用前向保密

TLS 1.3 默认不启用,启用并限制 SSL 协议版本为 TLSv1.2、TLSv1.3,使用安全的加密方式:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

对于以上加密方式的选取,可以参考 Mozilla SSL 配置生成器

优先选取服务器配置的加密方式:

ssl_prefer_server_ciphers on;

启用 OCSP 装订(OCSP Stapling,TLS 证书状态查询扩展)使得网页浏览器免去发送验证请求:

ssl_stapling on;
ssl_stapling_verify on;

为此我们还需在 nginx 中配置 DNS 解析服务器:

resolver 8.8.8.8 8.8.4.4;

配置 SSL 会话超时、缓存时间,禁用 ssl_session_tickets

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

使用 dhparam.pemDH 参数,用于 DH 密钥交换):

ssl_dhparam dhparam.pem;

命令行生成 /etc/nginx/dhparam.pem

openssl dhparam -out dhparam.pem 2048

完成

完成编辑后的 nginx.conf 如下所示:

nginx.confnginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
user nginx;
worker_processes auto;

events {
worker_connections 1024;
use epoll;
}

http {
include mime.types;
default_type application/octet-stream;

charset utf-8;
sendfile on;
keepalive_timeout 60;
gzip on;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_dhparam dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4;

include vhosts.d/*.conf;
}

vhosts.d 中的单个站点设置

例如,我们要为本站点 www.groverchou.com 进行配置,我们新建 groverchou.com.conf 使用以下配置:

groverchou.com.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80;
listen [::]:80;
server_name www.groverchou.com;

return 301 https://www.groverchou.com$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.groverchou.com;

ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_trusted_certificate /path/to/chain.pem;

root /srv/www/www.groverchou.com;
}

由于有特殊需求,我在这里并没有设置 HSTS。

重启 nginx

systemctl restart nginx

测试配置效果

前往 SSL Labs 输入你的网站地址进行测试,例如本网站的测试结果在这里

配置 rtmp 模块

首先我们需要在 nginx.confevents 块之前添加:

load_module lib64/nginx/modules/ngx_rtmp_module.so;

后在 nginx.conf 的尾部添加:

1
2
3
4
5
6
7
8
9
10
11
rtmp_auto_push on;

rtmp {
server {
listen 1935;

application live {
live on;
}
}
}

这将启用多线程并在默认端口 1935 上监听,使用:

rtmp://address/live

作为推流地址及拉流地址,若推流密钥设置,则拉流地址变为:

rtmp://address/live/<key>

若要使用其统计页面,可使用以下配置作为模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 80;
listen [::]:80;
server_name _;

root /srv/www/default;

location /rtmp {
rtmp_stat all;
rtmp_stat_stylesheet rtmp.xsl;

add_header Refresh "3; $request_uri";
}

location /rtmp.xsl {
alias /usr/share/doc/packages/nginx/nginx-rtmp-module-1.2.1/stat.xsl;
}
}

这里使用 stat.xsl 的位置是打包时放置的,最好复制到一个固定的地方以免更新时消失。