关于每个软件包的nginx签名
总结
从1.9.11版本开始,Nginx可以使用动态模块。然而,存在一个限制条件即外部模块的二进制文件必须与Nginx的二进制文件签名相同,否则无法正常运行。这一限制条件一直存在至今。
从版本1.11.5开始,当进行./configure时,将支持–with-compat选项,并且启用此选项后,使用nginx官方分发的nginx在环境中就不再有问题了。然而,对于非官方的EPEL或Ubuntu的标准仓库等分发的nginx二进制文件,并不能一概而论,仍然需要自行分析二进制文件和nginx -V,并选择适当的configure选项进行构建,这种情况仍然持续存在。
在考虑简单的情况下,如果使用动态模块,则使用官方的Nginx二进制文件(或者自己构建Nginx)可能是最佳选择,但根据要求,可能需要使用其他二进制文件。
在这里,我想总结一下除了官方nginx二进制文件之外的nginx签名是什么样的,并简单说明一下应该添加哪些选项。
在閱讀本文章之前
在写这篇文章的时候,参考了Heartbeats的博客文章,对我很有帮助。我认为提前阅读一下会更加顺利。
-
- nginx-1.9.11で動的モジュールをサポート – インフラエンジニアway – Powered by HEARTBEATS
- nginxの動的モジュールの最新状況(2017年2月版) – インフラエンジニアway – Powered by HEARTBEATS
签名的查找方法
可以通过以下命令进行查询,正如 Heart Beats 所提到的该命令。
$ strings /usr/sbin/nginx | grep '^.,.,.,'
nginx的二进制文件位置可能会因环境而异。尤其是像OpenResty这样的非官方二进制文件通常会有不同的位置(例如/usr/local/openresty/nginx/sbin/nginx)。
各个二进制文件的签名列表
- 本項の内容は、適宜追加・更新をする場合があります。
亚马逊Linux 2环境
亚马逊Linux 2018环境中的Amazon Linux 1版本与CentOS 6兼容。
CentOS Linux 7.7.1908 (核心) 发行版环境
nginx-1.16.1-1.el7.x86_64.rpmepel8,4,8,0010111111010111001110111111111110
openresty-1.15.8.2-6.el7.x86_64.rpmopenresty8,4,8,0000111111010111001111111111111110
kong-2.0.1.el7.amd64.rpmkong8,4,8,0000111111010111001110111111110110Kongに含まれるnginxはOpenResty。バージョンも1.15.8.2。
Ubuntu 18.04.4 LTS(Bionic Beaver)环境
Windows version -> Windows版本
苹果操作系统的版本
为了适应目标signature,可以使用configure选项。
在nginx源码目录中执行以下命令来构建动态模块。假设在此过程中已经安装了必要的构建包。
$ ./configure --add-dynamic-module=<動的モジュールのソースのパスを指定>
$ make modules
随后,在相同的目录中的objs目录下会生成ngx_????.so文件,然后将其移动到适当的位置,以供nginx加载。
如果没有考虑任何事情,configure执行时的选项将由操作系统的设置和已安装的库等自动确定。将nginx二进制文件和动态模块的签名进行匹配,就是在检查configure的选项后进行调整的必要性。
顺便说一句,在我的工作环境中,如果使用上述命令而不添加任何选项进行构建,动态模块的签名将如下所示。尽管字符串有点长,在页面内进行搜索也可以发现与上述任何签名都不同。在这种情况下,与上述的任何nginx二进制文件结合使用都将无法运行,这将导致生成一种完全无用的动态模块的二进制文件。
8,4,8,0000111111010111001110101111000110
不仅限于nginx,一般来说,通过使用$ ./configure –help命令可以大致了解configure选项。正如Heartbeats先生在博客中所述,数字签名的序列是构建时使用的选项标志,可以从这里了解哪些选项是启用或禁用的。
最后,根据配置情况选择configure选项。但是,有一些选项不方便直接指定,在这种情况下,可以使用–with-cc-opt进行添加。
例如,要与kong-2.0.1.el7.amd64.rpm中包含的nginx二进制文件的签名相匹配,可以使用以下选项。
$ ./configure --add-dynamic-module=<動的モジュールのソースのパスを指定してね> \
--with-http_realip_module \
--with-http_ssl_module \
--with-cc-opt='-DNGX_HTTP_HEADERS'
更简单的方法(2020-09-20补充)
当在执行nginx命令时添加-V选项,将会显示该nginx编译时所使用的选项。虽然有点长,可能会超出右边的范围,不过我们还是直接粘贴试试(此处是在Mac上使用Homebrew安装的nginx进行尝试)。
$ nginx -V
nginx version: nginx/1.19.2
built by clang 11.0.3 (clang-1103.0.32.62)
built with OpenSSL 1.1.1g 21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.19.2 --sbin-path=/usr/local/Cellar/nginx/1.19.2/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-compat --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_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-ipv6 --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module
配置参数:复制粘贴后,执行./configure命令,就几乎可以确定地编译出与之相匹配的外部模块。
如果想在Shell脚本中获取信息,可能会变成这样。由于nginx -V显示的内容不是在标准输出而是在标准错误输出中输出,所以需要考虑这一点。
$ nginx -V 2>&1 > /dev/null | grep -E "^configure " | sed -E "s/^.+: //"
如果使用变量,就可以这样做。
$ NGINX_OPTION=$(nginx -V 2>&1 > /dev/null | grep -E "^configure " | sed -E "s/^.+: //")
$ ./configure --add-dynamic-module=<動的モジュールのソースのパスを指定してね> $NGINX_OPTION
完成后,您只需执行以下操作即可:首先,创建模块,然后适当地配置文件并添加到nginx配置中。之后,通过运行sudo nginx -t等命令进行语法检查,再通过sudo nginx -s reload等命令重新加载文件以完结。