
لقد أنشأنا مؤخرًا وحدة نمطية ديناميكية لـ Nginx ، وعندما أصبح كل شيء جاهزًا ، اتضح أن وحدتنا غير متوافقة مع Nginx ، والذي تم تثبيته بالفعل على الخادم. لم نتمكن من إيجاد حل جاهز للمشكلة وبدأنا في محاربته بمفردنا. لقد قضينا الكثير من الوقت ، لكننا حصلنا على تجربة جديدة ، والأهم من ذلك ، حل عملي. الذي أود أن أشارك.
لنبدأ بوصف عملية تجميع الوحدة الديناميكية باستخدام المثال https://github.com/vozlt/nginx-module-vts . وبعد ذلك سوف نظهر الخطأ الذي يحدث وماذا نفعل به.
إدخال البيانات:
دبيان 9 OS
Nginx v1.10.3 من مستودع دبيان القياسي. إخراج nginx -V
:
nginx version: nginx/1.10.3 built with OpenSSL 1.1.0k 28 May 2019 (running with OpenSSL 1.1.1c 28 May 2019) TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-DhOtPd/nginx-1.10.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --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-pcre-jit --with-ipv6 --with-http_ssl_module - -with-http_stub_status_module --with-http_realip_mod ule --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-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-DhOtPd/nginx-1.10.3/debian/modules/nginx-auth-pam --add-dynamic-module=/build/nginx-DhOtPd/nginx-1.10.3/debian/modules/nginx-dav-ext-module --add-dynamic-module=/build/nginx-DhOtPd/nginx-1.10.3/debian/modules/nginx-echo --add-dynamic-module=/build/nginx-DhOtPd/nginx-1.10.3/debian/modules/nginx-upstream-fair --add-dynamic-module=/build/nginx-DhOtPd/nginx -1.10.3/debian/modules/ngx_http_substitutions_filter_module
يحتوي إخراج هذا الأمر على معلومات ضرورية لإنشاء وحدات نمطية ديناميكية ، أي كل ما يتم كتابته بعد configure arguments:
وقبل أول --add-dynamic-module
، وهي:
--with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-DhOtPd/nginx-1.10.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --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-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_mod ule --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-mail=dynamic --with-mail_ssl_module
لذلك ، ننتقل إلى تجميع الوحدة:
- للتجميع ، من المريح استخدام حاوية الإرساء حتى لا تشوش النظام الرئيسي ، واتخاذ ديبيان: 9 صورة كأساس ، لتوفير الراحة لنسخ الوحدة النمطية الجاهزة من الحاوية ، يمكنك تحديد حجم. سيظهر الأمر لبدء الحاوية في هذه الحالة:
docker run --rm -it -v /tmp/nginx_module:/nginx_module debian:9 bash
- بعد بدء تشغيل الحاوية ، قم بتثبيت الحزم اللازمة. يرجى ملاحظة أنه يتم تحديد الحزم وفقًا لإخراج الأمر nginx -V ، لذلك قد لا تحتاج إلى بعض المكتبات. في أي حال ، سوف يحذرك البرنامج النصي للتكوين من غياب التبعيات:
apt update apt install git make gcc autoconf wget libpcre3-dev libpcre++-dev zlib1g-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev
حزمة libssl-dev مفقودة من هذه القائمة ، نظرًا لأن nginx المثبت على الخادم مبني على الإصدار 1.1.0k من OpenSSL ، وفي وقت كتابة هذا التقرير ، عند تثبيت حزمة libssl-dev من المستودع ، كان إصدار OpenSSL فيه هو 1.1.0l بالفعل. لذلك ، يجب تنزيل التعليمات البرمجية المصدر OpenSSL للإصدار الصحيح بشكل منفصل.
cd /usr/local/src/ wget http://nginx.org/download/nginx-1.10.3.tar.gz wget https://www.openssl.org/source/old/1.1.0/openssl-1.1.0k.tar.gz git clone git://github.com/vozlt/nginx-module-vts.git tar xvfz nginx-1.10.3.tar.gz tar xzvf openssl-1.1.0k.tar.gz cd nginx-1.10.3
- أنت الآن جاهز لتشغيل البرنامج النصي للتكوين. كمعلمات البرنامج النصي ، نشير إلى جميع المعلمات من إخراج الأمر nginx -V ، الذي كتبته في بداية المقال. نضيف أيضًا المعلمة -add-dynamic-module لإنشاء الوحدة النمطية nginx-module-vts وتحديد المسار إلى الدليل باستخدام ملفات مصدر OpenSSL من خلال --with-openssl. الأمر النهائي سيبدو كما يلي:
./configure --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-DhOtPd/nginx-1.10.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --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-pcre-jit --with-ipv6 --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-mail=dynamic --with-mail_ssl_module --with-openssl=../openssl-1.1.0k/ --add-dynamic-module=../nginx-module-vts/
- بعد انتهاء البرنامج النصي
configure
، نبدأ في تجميع الوحدات النمطية ؛ لسنا بحاجة إلى جمع كل nginx
:
make modules
لاحظ أن هذا الأمر متاح فقط مع إصدار nginx
1.9.13.
- بعد اكتمال عملية التجميع ، انسخ الملف الناتج الناتج إلى
volume
، والذي تم تحميله عند بدء تشغيل الحاوية:
cp objs/ngx_http_vhost_traffic_status_module.so /nginx_module/
- بعد ذلك ، نضع الملف على الخادم الهدف ، في هذه الحالة ، يوجد الدليل الذي يحتوي على الوحدات النمطية على المسار
/usr/share/nginx/modules
. لتمكين الوحدة النمطية في nginx
نقوم بإنشاء الملف /etc/nginx/modules-enabled/mod-http-vhost-traffic-status.conf
بالمحتويات التالية:
load_module modules/ngx_http_vhost_traffic_status_module.so;
وقم بإنشاء رابط رمزي لهذا الملف في الدليل /etc/nginx/modules-enabled
.
بعد الانتهاء من العمل ، نسمي الأمر nginx -t
و ... حصلنا على الخطأ:
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_vhost_traffic_status_module.so" is not binary compatible in /etc/nginx/modules-enabled/50-mod-http-vhost-traffic-status.conf:1
وهنا ، عادة ، هناك بعض الحيرة ، لأن الإصدار المصدر وإصدار nginx
المثبت على الخادم متماثلان ، إصدارات OpenSSL أيضًا ، يتم أيضًا نسخ معلمات البرنامج النصي configure
بالكامل. إذن ما هي الصفقة؟
لفهم هذه المشكلة ، كان علي أن أفهم كيف يتحقق nginx إذا كانت الوحدة الديناميكية مناسبة لها. الكود الموجود في مصادر nginx
في ملف src/core/ngx_module.h
( https://github.com/nginx/nginx/blob/master/src/core/ngx_module.h ) هو المسؤول عن هذا الفحص. يوجد عدد من عمليات التحقق في هذا الملف ، في هذه الحالة 34 ، يتم خلالها تعيين nginx لمتغيرات النموذج NGX_MODULE_SIGNATURE_0
(1،2،3 ، إلخ.)
القيم 1 أو 0. التالي هو المتغير NGX_MODULE_SIGNATURE
الذي يجمع نتائج جميع الشيكات في سطر واحد. وفقًا لذلك ، تكمن المشكلة في أن سلسلة توقيع الوحدة الجديدة لا تتطابق مع سلسلة توقيع nginx الموجودة. للتحقق من قيم سلاسل التوقيع ، يمكنك استخدام الأوامر التالية:
- خط توقيع الوحدة التي تم إنشاؤها:
strings /usr/share/nginx/modules/ngx_http_vhost_traffic_status_module.so| fgrep '8,4,8' 8,4,8,000011111101011111111111110110111
- سطر توقيع الملف الثنائي
nginx
المثبت على الخادم:
strings /usr/sbin/nginx| fgrep '8,4,8' 8,4,8,000011111101011111111111110111111
عند مقارنة هذه الخطوط بالعين المجردة ، من الواضح أنه في سطر توقيع الوحدة النمطية ، تحول المتغير الرابع من النهاية إلى 0 ، بينما يحتوي nginx
على 1. لفهم ما هو مفقود بالضبط في الوحدة النمطية ، تحتاج إلى الرجوع إلى ملف src/core/ngx_module.h
والعثور على المتغير الرابع من النهاية ، يبدو مثل هذا:
#if (NGX_HTTP_REALIP) #define NGX_MODULE_SIGNATURE_29 "1" #else #define NGX_MODULE_SIGNATURE_29 "0" #endif #if (NGX_HTTP_HEADERS) #define NGX_MODULE_SIGNATURE_30 "1" #else #define NGX_MODULE_SIGNATURE_30 "0" #endif #if (NGX_HTTP_DAV) #define NGX_MODULE_SIGNATURE_31 "1" #else #define NGX_MODULE_SIGNATURE_31 "0" #endif #if (NGX_HTTP_CACHE) #define NGX_MODULE_SIGNATURE_32 "1" #else #define NGX_MODULE_SIGNATURE_32 "0" #endif #if (NGX_HTTP_UPSTREAM_ZONE) #define NGX_MODULE_SIGNATURE_33 "1" #else #define NGX_MODULE_SIGNATURE_33 "0" #endif #define NGX_MODULE_SIGNATURE
نحن مهتمون بالمتغير NGX_HTTP_HEADERS
، عند إنشاء nginx
كان 1 ، وعند إنشاء الوحدة النمطية 0. لكي تتمكن الوحدة النمطية من NGX_HTTP_HEADERS
باستخدام NGX_HTTP_HEADERS
تحتاج إلى ضبط ملف التكوين في الدليل باستخدام الكود المصدري للوحدة النمطية عن طريق إضافة السطر have=NGX_HTTP_HEADERS . auto/have
have=NGX_HTTP_HEADERS . auto/have
في بداية ملف config.
التالي هو بداية ملف التكوين بعد إجراء التغييرات:
ngx_addon_name=ngx_http_vhost_traffic_status_module have=NGX_STAT_STUB . auto/have have=NGX_HTTP_HEADERS . auto/have ...
بعد ذلك ، قم make clean
، ثم أعد تشغيل configure
make modules
. بعد تجميع الوحدة ، نتحقق من سلسلة توقيعها ونرى الآن أنها تطابق سلسلة nginx
:
$ strings /usr/sbin/nginx| fgrep '8,4,8' 8,4,8,000011111101011111111111110111111 $ strings /usr/share/nginx/modules/ngx_http_vhost_traffic_status_module.so | fgrep '8,4,8' 8,4,8,000011111101011111111111110111111
بعد ذلك ، تتصل الوحدة النمطية دون أي مشاكل ويمكنك جمع إحصاءات متقدمة مع nginx
.
في حالتك ، ربما سيبدو خط التوقيع مختلفًا ، وكذلك المتغيرات المسؤولة عن كل موضع في هذا السطر. ومع ذلك ، الآن يمكنك أن تفهم بالضبط ما هو الخطأ في تجميع الوحدة النمطية وإصلاح المشكلة.
آمل أن توفر هذه المقالة لشخص ما بضع ساعات من الوقت ، لأنني شخصياً واجهت عدة مرات مشكلة أن الوحدة لا تتناسب مع nginx
، كنتيجة لذلك ، كقاعدة عامة ، قمت بحل هذا من خلال التجميع الكامل لـ nginx
مع الوحدة النمطية الصحيحة.
اقرأ أيضًا مقالات أخرى على مدونتنا: