配置一个好用的nginx


写在最前的

本页所有内容基于以下环境部署:

  • 操作系统:Ubuntu 20.04.2 LTS
  • 系统内核:GNU/Linux 5.4.0-52-generic x86_64
  • nginx版本:1.18.0

安装 Nginx 服务器

下文命令均以 Ubuntu 20.04.2 LTS 为例,请检查你的 如你正使用过于老旧的 Ubuntu(如:Ubuntu 16.04)或其他发行版或软件包管理器,请酌情更改到适当的命令。
注:以下两种安装方式二选一即可。

通过软件源安装

使用 Ubuntu 官方源 :

1
apt update && apt install nginx-full -y

通过源码编译安装

这里只演示相对基本的 Nginx 编译安装方式,并为其启用了 HTTP/2 支持、添加了 OpenSSL 库使其支持 TLS 连接、添加了 ngx_brotli 模块使其支持 Brotli 压缩。如你需要更多自定义,可参看其官方文档。

安装依赖与组件

这里默认操作用户为 root,操作目录为/usr/src。
注:本网站未采用以下操作,具体操作尚未测试

安装编译依赖
1
apt install build-essential git libpcre3 libpcre3-dev zlib1g-dev -y
获取必要组件

首先定位到源码目录

1
cd /usr/src

获取 Nginx(截至 2021 年 2 月 16 日,Nginx 的主线版本为 1.19.6)

1
2
3
4
5
6
7
8
9
wget https://nginx.org/download/nginx-1.19.6.tar.gz
tar -xzf nginx-1.19.6.tar.gz && rm nginx-1.19.6.tar.gz
# 获取 OpenSSL
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1i.tar.gz
tar -xzf OpenSSL_1_1_1i.tar.gz && rm OpenSSL_1_1_1i.tar.gz
mv openssl* openssl
# 获取 ngx_brotli 模块
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli && git submodule update --init --recursive && cd ..

修改 Server: nginx 字段
为了个性化标识(好看),你可以修改 Nginx 默认发送的 HTTP 响应头中的 Server: nginx 字段为其他值,只需修改以下文件:

  • src/core/nginx.h
    1
    #define NGINX_VER          "nginx/" NGINX_VERSION
  • src/http/ngx_http_header_filter_module.c
    1
    static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
  • src/http/ngx_http_special_response.c
    1
    static u_char ngx_http_error_tail[] = "<hr><center>nginx</center>" CRLF
  • src/http/v2/ngx_http_v2_filter_module.c
    1
    2
    3
    4
    5
    static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7"; #这里是经 hpack 编码后的字段,你可以使用 https://yuankan.co/tools/hpack 提供的工具进行编码
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
    "http2 output header: \"server: nginx\"");
    }
    pos = ngx_http_v2_write_header_str("server", "nginx");

开始编译并安装

1
2
3
cd nginx-1.19.6
./configure --with-openssl=../openssl --with-http_ssl_module --with-http_v2_module --add-module=../ngx_brotli
make && make install

为 Nginx 添加动态模块

这里以 ngx_brotli 模块为例,演示如何在已安装 Nginx 的情况下,为其动态地添加模块。

添加 ngx_brotli 模块(例)

如你是通过官方软件源安装的 Nginx,可以照做
如你是参考上文自行编译的 Nginx,可以忽略此节,因为上文已添加了此模块

1
2
3
cd /usr/src
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli && git submodule update --init --recursive && cd ..

获取软件包源码

添加下载源

编辑 /etc/apt/sources.list 添加或启用来自软件源的源码包

1
vim /etc/apt/sources.list

如你使用官方软件源,需要添加以下行或删除其所在行的注释符#
(或者把所有带deb-src前的#删掉也可以)

1
2
deb-src http://archive.ubuntu.com/ubuntu eoan main restricted
deb-src http://archive.ubuntu.com/ubuntu eoan-updates main restricted
下载软件包源码
1
2
apt update && apt install build-essential cmake git libgd-dev libgeoip-dev libxslt-dev -y
apt source nginx-full

获取当前编译参数

使用nginx -V命令获取当前 Nginx 的编译参数,以下为示例:

1
2
3
4
5
root@feilongproject:/usr/src# nginx -V
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f 31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-5J5hor/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-subs-filter --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-geoip2

可以把像/build/nginx-5J5hor这种无用的删去

编译 ngx_brotli 模块

进入 Nginx 源码目录并执行以下命令:

1
2
3
4
5
cd nginx-1.18.0
./configure --add-dynamic-module=../ngx_brotli \
#这里粘贴上文获取的当前 Nginx 的编译参数
--with-cc-opt='-g -O2 -fdebug-prefix-map=/usr/src/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module
make modules

注意:有可能编译时会出错,试着可以加一下 --with-openssl=../openssl

加载 ngx_brotli 模块

执行make modules命令后,将在当前目录下的 objs 文件夹中生成ngx_http_brotli_filter_module.songx_http_brotli_static_module.so两个文件,将其复制出来即可。

1
2
cp objs/ngx_http_brotli_filter_module.so /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so
cp objs/ngx_http_brotli_static_module.so /usr/lib/nginx/modules/ngx_http_brotli_static_module.so

完成以上操作后,在 Nginx 配置文件的 Main 区中添加以下内容后重启 Nginx。

1
2
load_module /usr/lib/nginx/module/ngx_http_brotli_filter_module.so;
load_module /usr/lib/nginx/module/ngx_http_brotli_static_module.so;

有关load_module参数的相关信息可参见其官方文档

修改 Nginx 配置项

下文展示的配置可以正常实现的前提为:你从软件源安装了 nginx-full 软件包并已添加 ngx_brotli 模块、已获得 SSL 证书(推荐泛域名)。我使用的相对模块化的加载方式为不同的功能区进行了划分,如果你也喜欢这样,可以照做。

全局配置

Nginx 配置文件位于/etc/nginx/nginx.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#运行 Nginx 的用户(需要确保有足够的权限)
user www-root;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;

include /etc/nginx/modules-enabled/*.conf;

#加载编译的 ngx_brotli 模块
load_module /usr/lib/nginx/module/ngx_http_brotli_filter_module.so;
load_module /usr/lib/nginx/module/ngx_http_brotli_static_module.so;

events {
accept_mutex off;
multi_accept on;
use epoll;
worker_connections 65535;
}

http {
include /etc/nginx/mime.types;

client_header_buffer_size 4k;
default_type application/octet-stream;
keepalive_timeout 300s 300s;#你可以酌情降低此数值
keepalive_requests 65535;
send_timeout 10s;
sendfile on;
tcp_nodelay on;
tcp_nopush on;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
server_name_in_redirect off;
ssl_buffer_size 4k;
#支持的 TLS 协议
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384;#本站仅支持现代的、更安全的浏览器
#支持的 TLS 版本
ssl_protocols TLSv1.2 TLSv1.3;#本站仅支持现代的、更安全的浏览器
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_session_timeout 1d;#你可以酌情降低此数值
#OCSP Stapling 参数,与下文站点配置中的 ssl_trusted_certificate 参数相关联
ssl_stapling on;
ssl_stapling_verify on;

#这里关闭了详细的访问日志,如需要可重新开启
access_log off;
error_log /var/log/nginx/error.log;

brotli on;
brotli_buffers 32 4k;
brotli_comp_level 11;
brotli_min_length 32;
brotli_static on;
brotli_types text/css text/javascript text/mathml text/plain text/x-component text/xml text/vnd.wap.wml application/x-httpd-php image/svg+xml image/x-icon application/javascript application/x-javascript application/json application/xml application/atom+xml application/rss+xml application/xhtml+xml application/xspf+xml font/opentype application/x-font-ttf application/font-woff application/font-woff2 application/msword application/rtf application/x-cocoa application/x-makeself application/x-perl application/x-pilot application/x-tcl application/x-x509-ca-cert application/vnd.ms-excel application/vnd.ms-fontobject application/vnd.google-earth.kml+xml application/vnd.google-earth.kmz image/vnd.microsoft.icon;
brotli_window 1m;

gzip on;
gzip_buffers 32 4k;
gzip_comp_level 9;
gzip_disable "msie6";
gzip_http_version 1.1;
gzip_min_length 32;
gzip_proxied off;
gzip_static on;
gzip_types text/css text/javascript text/mathml text/plain text/x-component text/xml text/vnd.wap.wml application/x-httpd-php image/svg+xml image/x-icon application/javascript application/x-javascript application/json application/xml application/atom+xml application/rss+xml application/xhtml+xml application/xspf+xml font/opentype application/x-font-ttf application/font-woff application/font-woff2 application/msword application/rtf application/x-cocoa application/x-makeself application/x-perl application/x-pilot application/x-tcl application/x-x509-ca-cert application/vnd.ms-excel application/vnd.ms-fontobject application/vnd.google-earth.kml+xml application/vnd.google-earth.kmz image/vnd.microsoft.icon;
gzip_vary on;

open_file_cache_errors on;
open_file_cache max=65535 inactive=30s;
open_file_cache_min_uses 2;
open_file_cache_valid 30s;

#这里引用外部的站点配置
include /etc/nginx/sites/*.conf;
}

站点配置

因我有数个不同功能的子域名,所以为了方便及减小配置文件大小,我将 HTTP/HTTPS 的共用配置与站点的个体功能实现部分的配置进行了分离,

这里假设我有一www.example.com域名及数个子域,所有站点配置文件均存在于/etc/nginx/sites/目录中,以下是配置示例。

HTTPS 全局配置

1
2
3
4
#创建新文件:/etc/nginx/sites/https.cf
ssl_certificate /etc/nginx/ca/ssl_fullchain.crt;
ssl_certificate_key /etc/nginx/ca/ssl.key;
ssl_trusted_certificate /etc/nginx/ca/ssl_fullchain.crt;

子域配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#创建新文件:/etc/nginx/sites/example.com.conf
server {
listen 80;
listen 80 default;
listen 443 ssl http2 default;
server_name example.com;
server_name _;#当直接通过 ip 访问时进行转发
include /etc/nginx/sites/https.cf;

#屏蔽一些无意义的蜘蛛
if ($http_user_agent ~* "AdIdxBot|AhrefsBot|Bytespider|coccocbot|DotBot|EasouSpider|ia_archiver|iaskspider|MBCrawler|MJ12bot|MSNot-media|Semrush|Teoma|YandexBot|YisouSpider|^$") {
return 444;
}

location / {
root /var/www;
index index.html;
}
}

结语

以上。互联网技术变化得往往非常迅猛,这意味着本文具有较高的时效性,望参考之时多加考量。


← Prev [Pixiv] 真·反代P站 | 你好,世界! Next →
生活不易,给点打赏可好?
支付宝 | Alipay
微信 | WeChat