【进阶】在 Ubuntu 21.10 操作系统下自编译 Nginx 及编译时所需参数详解。
Nginx
Nginx(发音同“engine X”)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。该软件由俄罗斯程序员伊戈尔·赛索耶夫开发并于2004年首次公开发布。2011年成立同名公司以提供支持服务。2019年3月11日,Nginx公司被F5网络公司以6.7亿美元收购。
安装与配置 nginx
这并非是本文的重点,简单的入门级配置教程请查看本站文章Nginx搭建web服务器。
如果还没有使用过 Nginx ,甚至从未听说过 Nginx ,请务必按照上面的文章先搭建一个简单的 Nginx Web 服务。本文是进阶操作,完全不建议新手尝试。
nginx 的编译
自行编译 nginx 的好处是显而易见的:可以针对自己的业务优化性能和软件大小、能够随心所欲的以模块的形式添加功能。
编译 Nginx
作者采用 Ubuntu 21.10 Server 作为基础操作系统,架构为x86_64
及arm64
,使用的镜像源分别为 中国科学技术大学开源软件镜像 和 华为开源镜像站 ;本文创作日期及更新日期请看文章标题下方标示;本文创作时 nginx stable 版本为nginx-1.20.2
,Mainline 版本为 nginx-1.21.6
,本文将仅操作 Stable 版本。
安装依赖
1 2 3 4 5 6 7
| sudo apt install libxml2-dev build-essential openssl libssl-dev make curl \ libcurl4-gnutls-dev libjpeg-dev libpng-dev libtool-bin bison zlib1g-dev \ libpcre3 libpcre3-dev libssl-dev libxslt1-dev libgeoip-dev \ libgoogle-perftools-dev libperl-dev libtool libxml2-dev build-essential \ openssl libssl-dev make curl libcurl4-gnutls-dev libjpeg-dev libpng-dev \ libtool-bin bison zlib1g-dev libpcre3 libpcre3-dev libssl-dev libxslt1-dev \ libgeoip-dev libgoogle-perftools-dev libperl-dev libtool libgd-dev
|
以上依赖并非需要全部安装,如果不需要 Nginx 中的某些功能可以自行搜索后移除。
注意:如果在编译之前系统已经安装了来自 Linux 软件源的 Nginx 版本,则建议提前卸载并附带purge
(删除配置文件)参数以确保编译过程不会和原有版本冲突。
取得源码
到 nginx: download 页面确定你需要下载的版本。其中Mainline version
是主线版本,通常会有更多的新功能,但与此同时不稳定性和遇到bug的可能性也会提高;Stable version
是稳定版本,通常是通过了用户和社区的验证后认为比较稳定,适用于生产环境的版本;Legacy versions
是历史版本。
本文编写时Stable版本为1.20.2
,并以此为例。
1 2 3 4
| wget https://nginx.org/download/nginx-1.20.2.tar.gz
tar -zxvf nginx-1.20.2.tar.gz
|
目录结构
名称 | 类型 | 用途 |
---|
auto | DIR | 编译时需要的文件、相关lib库、对操作系统的判断等, 辅助./configure命令执行的辅助文件 |
conf | DIR | nginx编译安装后的默认配置文件或者示例文件, 安装时会拷贝到安装的文件夹里面 |
contrib | DIR | 方便用vim编辑nginx的配置文件时候,颜色突出显示, 可以将该目录拷贝到自己的~/.vim目录下面 |
html | DIR | 编译安装的默认的2个标准web页面, 安装后会自动拷贝到nginx的安装目录下的html下 |
man | DIR | nginx命令的帮助文档, linux上可以使用man命令查看帮助 |
objs | DIR | 编译生成的中间文件和编译完成的二进制文件 |
src | DIR | nginx的源码文件 |
CHANGES | — | 英语版版本日志 |
CHANGES.ru | — | 版本日志的俄语版 |
configure | — | 编译安装前的预备执行文件 |
LICENSE | — | 许可文件 |
README | — | Readme |
Makefile | — | 执行预备执行文件后自动生成的编译脚本 |
编译
Nginx 编译前需要先进行配置生成 Makefile ,有关配置参数的问题下面会说。
1
| ./configure --prefix=/usr/share/nginx --with-http_ssl_module
|
完成后即可开始编译
1 2 3 4
| sudo make
sudo make install
|
源码修改
这个的用途基本上是伪装服务端,使得其他人在查看你的站点时无法获知具体的服务器类型和版本。
查看服务器后端程序和版本;
1 2 3 4 5 6 7 8
| root@lxn-testbench-v33:~ HTTP/1.1 302 Found Server: Tengine Date: Sat, 18 Jun 2022 12:47:07 GMT Content-Type: text/html Content-Length: 258 Connection: keep-alive Location: http://www.taobao.com/
|
需要修改的有两个文件:
src/http/ngx_http_header_filter_module.c
:
1 2 3
| static u_char ngx_http_server_string[] = "Server: nginx" CRLF; static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
|
修改为:
1 2 3
| static u_char ngx_http_server_string[] = "Server: myserver" CRLF; static u_char ngx_http_server_full_string[] = "Server: myserver/2.2.2" CRLF; static u_char ngx_http_server_build_string[] = "Server: myserver/2.2.2" CRLF;
|
src/core/nginx.h
:
1 2 3
| #define nginx_version 1022000 #define NGINX_VERSION "1.22.0" #define NGINX_VER "nginx/" NGINX_VERSION
|
修改为:
1 2 3 4 5
| #define nginx_version 2002002 #define NGINX_VERSION "2.2.2" #define NGINX_VER "myserver/" NGINX_VERSION
#define NGINX_VAR "myserver"
|
重新编译即可。
编译参数详解
理论上来说 Nginx 没有必选参数,所有参数都是可选的,基本上只添加--prefix
参数即可,但不选任何参数就毫无意义了。
Nginx 的核心功能包括 HTTP 、 Mail 和 Stream ,本文将以核心功能为区分解析 Nginx 的编译参数。
可能仅介绍一些核心参数,对于非核心参数请查看 Nginx 官方文档。
基础路径类
参数 | 示例值 | 说明 |
---|
--prefix=<path> | /etc/nginx | Nginx 安装的根路径, 所有其它路径类参数都要依赖该选项 |
--sbin-path=<path> | /usr/sbin/nginx | Nginx 二进制文件路径, 不指定则使用<prefix>/sbin/nginx |
--conf-path=<path> | /etc/nginx/nginx.conf | 配置文件默认路径, 不指定则需要在运行时附带-c 参数 |
--error-log-path=<path> | /var/log/nginx/error.log | 错误日志路径, 可以被配置文件中的配置项覆盖掉 |
--pid-path=<path> | /var/run/nginx.pid | Nginx 主进程 PID 写入位置 |
--user=<user> | nginx | Worker 进程运行的用户 |
--group=<group> | nginx | Worker 进程运行的组 |
--modules-path=<path> | /usr/lib/nginx/modules | Nginx 模块路径 |
--lock-path=<path> | /var/run/nginx.lock | Lock文件位置 |
--http-log-path | /var/log/nginx/access.log | HTTP 访问日志位置 |
HTTP 功能类
参数 | 说明 |
---|
--with-http_ssl_module | 启用SSL支持 |
--with-http_v2_module | 启用HTTP2支持 |
--with-http_realip_module | 当Nginx服务器在反向代理后面的时候, 该模块可让 Nginx 知晓真正的用户IP |
--with-http_addition_module | 过滤相应前后的文本 |
--with-http_image_filter_module | 转换 JPEG、GIF、PNG 和 WebP 格式图像 该模块可被编译为动态模块 |
--with-http_sub_module | 可以替换指定的字符串来修改响应数据 |
--with-http_dav_module | 开启 WebDAV 协议 |
--with-http_flv_module | 对 Flash 启用服务端支持 |
--with-http_mp4_module | 对 MP4 文件启用服务端支持 |
--with-http_gunzip_module | 对不支持 gzip 编码方法的客户端解压缩
Content-Encoding:gzip 的响应。 可以存储压缩数据以节省空间并降低 I/O 成本 |
--with-http_gzip_static_module | 发送以 .gz 结尾的预压缩文件替代普通文件 |
--with-http_auth_request_module | 基于子请求结果实现客户端授权 |
--with-http_random_index_module | 随机选择目录中的文件作为索引文件展示 |
--with-http_secure_link_module | 用于检查请求链接的真实性, 保护资源免受未经授权的访问, 并限制链接有效时长。 |
--with-http_degradation_module | 用于当主机剩余内存较低时,用户请求访问, Nginx会对某些请求返回204或444的响应码 |
--with-http_slice_module | 将请求切片并返回 |
--with-http_stub_status_module | 提供对基本状态信息的访问的支持 |
— | — |
--without-http | 禁用 HTTP 功能 |
--without-http-cache | 禁用 HTTP 缓存功能 |
邮件类
参数 | 说明 |
---|
--with-mail | 启用邮件功能 该模块可被编译为动态模块 |
--with-mail_ssl_module | 对邮件功能启用SSL |
--without-mail_pop3_module | 禁用POP3 |
--without-mail_imap_module | 禁用IMAP |
--without-mail_smtp_module | 禁用SMTP |
Stream
略
其他参数
参数 | 说明 |
---|
--with-google_perftools_module | 可以使用 Google 性能工具 对 nginx 的 worker 进程进行分析 |
--with-compat | 启用动态模块兼容性 |
--with-file-aio | 启用异步IO |
--with-threads | 启用线程池功能 |
--with-cpu-opt=<cpu> | 为特定的CPU执行编译操作 有效的值:pentium,pentiumpro,pentium3,pentium4,athlon,opteron,sparc32,sparc64,ppc64。 |
--with-openssl=<openssl_path> | 指定OpenSSL的源码目录 |
模块配置示例
http_random_index_module
1 2 3
| location / { random_index on; }
|
http_stub_status_module
1 2 3
| location = /basic_status { stub_status; }
|
其他附加模块
ngx_brotli
Brotli 是基于LZ77算法的一个现代变体、霍夫曼编码和二阶上下文建模。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。其中的编码器被部分改写以提高压缩比,编码器和解码器都提高了速度,流式API已被改进,增加更多压缩质量级别。
与常见的通用压缩算法不同,Brotli使用一个预定义的120千字节字典。该字典包含超过13000个常用单词、短语和其他子字符串,这些来自一个文本和HTML文档的大型语料库。预定义的算法可以提升较小文件的压缩密度。
使用Brotli替换Deflate来对文本文件压缩通常可以增加20%的压缩密度,而压缩与解压缩速度则大致不变。
- 下载源码
1 2 3
| cd /usr/local/src/ git clone https://github.com/google/ngx_brotli cd ngx_brotli && git submodule update --init
|
- 重新编译 Nginx
编译时只需要在原有的编译参数后面添加--add-module=/usr/local/src/ngx_brotli
。
示例如下:
1
| ./configure --prefix=/usr/share/nginx --with-http_ssl_module --add-module=/usr/local/src/ngx_brotli
|
- 检查是否安装成功
输出中有ngx_brotli
字样即为成功。
- 修改配置文件
1 2 3 4
| #Brotli Compression brotli on; # switch brotli_comp_level 6; # level 1-11 brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
|
其中brotli_comp_level
值为压缩比,1 压缩比最小,处理速度最快,11 压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。
默认配置参数
这里提供一些软件源中安装的 Nginx 的默认的编译参数
Ubuntu21.10 | 1.18.0 | amd64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| root@lxnchan-testbench-vm13:~/nginx nginx version: nginx/1.18.0 (Ubuntu) built with OpenSSL 1.1.1l 24 Aug 2021 TLS SNI support enabled configure arguments: --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-compat --with-debug --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 \ --add-dynamic-module=/build/nginx-jEeuM0/nginx-1.18.0/debian/modules/http-geoip2 \ --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module \ --with-http_sub_module \ --with-cc-opt='-g -O2 -ffile-prefix-map=/build/nginx-jEeuM0/nginx-1.18.0=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' \ --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -Wl,-z,relro -Wl,-z,now -fPIC'
|
Ubuntu20.04 | 1.20.2 | arm64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| root@lxnchan-testbench-qemu2:~ nginx version: nginx/1.20.2 built by gcc 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) built with OpenSSL 1.1.1 11 Sep 2018 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx \ --modules-path=/usr/lib/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-compat --with-file-aio --with-threads \ --with-http_addition_module --with-http_auth_request_module --with-http_dav_module \ --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module \ --with-http_mp4_module --with-http_random_index_module --with-http_realip_module \ --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module \ --with-http_stub_status_module --with-http_sub_module --with-http_v2_module \ --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module \ --with-stream_ssl_module --with-stream_ssl_preread_module \ --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.20.2/debian/debuild-base/nginx-1.20.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \ --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
|
CentOS7.5 | 1.12.2 | arm64
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
| [root@ecs-01 ~] nginx version: nginx/1.12.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --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 \ --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' \ --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
|
参考资料
排名不分先后。