Сборка nginx: CentOS 6.8, документы и грабли

от автора

Недолюбливаю пакеты redhat. Они небезопасны: любой пакет можно изучить заранее; они не дают должного контроля, в отличие от сборки, поэтому предпочитаю последнюю. Однако есть в пакетах и кое-что хорошее, о чём скажу ниже. Кажется, собрал из исходников сервер – «молодец», статья зачем?
Документация пока упускает существенные детали, а статьи с рекомендациями, как лучше, во-первых, разрознены и, как правило, не цельны, а во-вторых отсылают к далёким источникам, тогда как на самом деле всё под рукой. Я предлагаю решение. Вместе с тем, покажу несколько удобных, на мой взгляд, вспомогательных функций bash для сборки как таковой. Кроме того, сборочный скрипт будет «из коробки» прятать версию и имя сервера, делая это, конечно же, на уровне исходников, а не директивы server_tokens, так что не нужно никакой коммерческой подписки. Интересно?

Начну с документации. Конечно же, соответствующие правки будут предложены сообществу nginx. Вот такой скрипт у нас получится, если ей верить:

#!/bin/bash wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz tar -zxf pcre-8.39.tar.gz cd pcre-8.39 ./configure make sudo make install  wget http://zlib.net/zlib-1.2.8.tar.gz tar -zxf zlib-1.2.8.tar.gz cd zlib-1.2.8 ./configure make sudo make install  wget http://www.openssl.org/source/openssl-1.0.2f.tar.gz tar -zxf openssl-1.0.2f.tar.gz cd openssl-1.0.2f

Конфигуратор OpenSSL на самом деле называется config, а здесь:

./configure darwin64-x86_64-cc --prefix=/usr make sudo make install  wget http://nginx.org/download/nginx-1.10.2.tar.gz tar zxf nginx-1.10.2.tar.gz cd nginx-1.10.2  ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-pcre=../pcre-8.39 --with-zlib=../zlib-1.2.8 --with-http_ssl_module --with-stream --with-mail=dynamic --add-module=/usr/build/nginx-rtmp-module --add-dynamic-module=/usr/build/3party_module  make sudo make install sudo nginx

Во-первых, мне не нравится рутина: скачать исходники, распаковать, перейти в их папку. В несколько команд. Предлагаю пригодную в подавляющем большинстве случаев функцию bash, работающую с 7z и ещё одной функцией, возвращающей корень архива.

#!/bin/bash set -x sudo yum -y install p7zip wget tidy util-linux openssl-devel

Возвращает корень архива:

arroot () { 7z l "$1" | grep '^[0-9][0-9][0-9][0-9]' | head -n1  | gawk '{print $NF}' }

Распаковывает архивы и переходит к исходникам. При желании домашняя директория меняется на /usr/local/src:

gotosrc () { cd "$HOME" echo "$1" > /var/tmp/gawk.temp arname=$(gawk -F/ '{print $NF}' /var/tmp/gawk.temp)  	if ! test -f "$arname"; then { 	wget -P "$PWD" "$1" 	} 	fi  7z x "$arname"  	if test -f $(arroot "$arname"); then { 	7z x $(arroot "$arname") 	srcfold=$( arroot $(arroot "$arname") ) 	} else { 	srcfold=$( arroot "$arname" ) 	}  	fi  cd "$srcfold"; ls -la }

Короткая обёртка установки прав выполнения configure:

setconfex () { 	if ! test -x configure; then { 	sudo chmod +x configure 	} 	fi }

Дальше – инструкции make. В них часто забывают о параметрe make -jn, n – число рабочих процессов; работает не всегда, но в многоядерной современности значительно ускоряет make. Для использования узнаём число ядер процессора:

getnumcores () { echo $(( $(lscpu -p=core | wc -l) - 4  )) } # ... make -j$(getnumcores); sudo make -j$(getnumcores) install

Она же пригодится для конфигурирования директивы количества рабочих процессов nginx.
А эта функция возвращает ссылку на новейший архив исходников стабильной ветки с официального сайта:

getlatestlink_nginx () { # tidy нужен для удобной работы grep curl "http://nginx.org/en/download.html" | tidy -imc | grep "/download/nginx" | gawk -F'"' '{print $2}' > /var/tmp/temp.file.gawk branchnum=$( head -n1 /var/tmp/temp.file.gawk | gawk -F'.' '{print $2}' )  	if [ "$(( $branchnum % 2 ))" = "1" ]; then { 	latestlink="https://nginx.org"$( grep "$(($branchnum - 1))" /var/tmp/temp.file.gawk | head -n1 ) 	echo "$latestlink" 	}  	fi }

Почему не git clone? Архивы проще, надёжней, да и github всегда предлагает zip-архив.

gotosrc $( getlatestlink_nginx )

Теперь, когда мы скачали и собрали зависимости (ссылка на весь код) и оказались в исходниках nginx, можно прятать его версию, просто оставив запрошенные этой функцией строки пустыми:

hidengxver () { read -r -p "Your own http_server_string for safety: " http_server_string first_string="static char ngx_http_server_string\[\] = \"Server: nginx\" CRLF;" second_string="static char ngx_http_server_string\[\] = \"$http_server_string\" CRLF;" sed -ire "s/$first_string/$second_string/g" src/http/ngx_http_header_filter_module.c 	 read -r -p "Your own NGINX_VER const: " nginx_ver third_string="\#define NGINX\_VER          \"nginx\/\" NGINX\_VERSION" forth_string="\#define NGINX\_VER          \"$nginx_ver\" NGINX\_VERSION" sed -ire "s/$third_string/$forth_string/g" src/core/nginx.h 	 real_nginx_version=$( grep '#define NGINX_VERSION' src/core/nginx.h | gawk -F'"' '{print $2}' ) read -r -p "Your own NGINX_VERSION const: " new_nginx_version fifth_string="\#define NGINX\_VERSION      \"$real_nginx_version\"" sixth_string="\#define NGINX\_VERSION      \"$new_nginx_version\"" sed -ire "s/$fifth_string/$sixth_string/g" src/core/nginx.h  }

Ловкость sed и никакой коммерции. Команда nginx вряд ли скажет спасибо, но я благодарю её за красивый структурированный код и пользователя StackOverflow Martin M. за его пост – основу функции.
И самое интересное. Что хорошо в пакетах? Конечно же, дополнительные скрипты. И если без команды service nginx start и подобных можно обойтись, то без ротации логов… Сами понимаете. Напишем распаковывающую пакет функцию и разложим нужные файлы по местам.

gotorpm () { cd "$HOME" echo "$1" > /var/tmp/gawk.temp rpmname=$(gawk -F/ '{print $NF}' /var/tmp/gawk.temp)  	if ! test -f "$rpmname"; then { 	wget -P "$PWD" "$1" 	} 	fi  7z x "$rpmname" rpmname_size=${#rpmname} rpmfold=${rpmname:0:($rpmname_size-4)} mkdir "$rpmfold"; mv "$rpmfold"".cpio" "$rpmfold" cd "$rpmfold" 7z x "$rpmfold"".cpio" ls -la }

Дублирование кода – зло и можно лучше, но функция ясна и делает дело.
Обращаю внимание: пакетные файлы рассчитаны на префикс /usr, с которым при установке из исходников образуется бардак, потому оставим /usr/local/nginx и заменим пару строк в пакете до копирования в систему:

modify_nginx_init () { first_init_string="NGINX\=\/usr\/sbin\/nginx" second_init_string="NGINX\=\/usr\/local\/nginx\/sbin\/nginx" sudo sed -ire "s/$first_init_string/$second_init_string/g" etc/sysconfig/nginx  third_init_string="nginx\=\${NGINX\-\/usr\/sbin\/nginx}" forth_init_string="nginx\=\${NGINX\-\/usr\/local\/nginx\/sbin\/nginx}" sudo sed -ire "s/$third_init_string/$forth_init_string/g" etc/rc.d/init.d/nginx }

Лично мне при знакомстве с Линукс и командами user{add,mod.del} чисто психологически не хватило ещё двух:

userlist () { sudo gawk -F: '{print $1}' /etc/passwd | sort -g }  userex () { 	if [ "$( userlist | grep "$1" )" = "$1"  ]; then { 	return 0  	}  	else {  	return 1  	}  	fi }

И, наконец, функция установки с учётом изложенного:

install_nginx () { nginx_install_prefix="/usr/local/nginx" #install pcre gotosrc "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz" setconfex ./configure --prefix=$nginx_install_prefix make -j$(getnumcores) sudo make -j$(getnumcores) install #instaall zlib gotosrc "http://zlib.net/zlib-1.2.8.tar.gz" setconfex ./configure --prefix=$nginx_install_prefix make -j$(getnumcores) sudo make -j$(getnumcores) install #install nginx gotosrc $(getlatestlink_nginx) setconfex hidengxver

Параметры configure из пакета с небольшими изменениями:

./configure --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-http_ssl_module --with-http_realip_module --with-http_addition_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_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-ipv6 --with-pcre=../pcre-8.39 --with-zlib=../zlib-1.2.8 make -j$(getnumcores); sudo make -j$(getnumcores) install  gotorpm "https://nginx.org/packages/centos/6/x86_64/RPMS/nginx-1.10.2-1.el6.ngx.x86_64.rpm"  modify_nginx_init sudo cp etc/sysconfig/nginx /etc/sysconfig/nginx sudo cp etc/logrotate.d/nginx /etc/logrotate.d/nginx sudo cp etc/rc.d/init.d/nginx /etc/rc.d/init.d/nginx

Да, сервер при запуске жалуется на отсутствие одной из папок, несмотря на её указание конфигуратору. Исправляем:

if ! test -d /var/cache/nginx/client_temp; then { sudo mkdir -p /var/cache/nginx/client_temp } fi

Конфигуратором не создаётся пользователь nginx, делаем сами:

if ! userex "nginx"; then { sudo useradd --home-dir /var/cache/nginx "nginx" } fi

Добавляем сервис:

sudo chmod +x /etc/rc.d/init.d/nginx sudo chkconfig --add nginx

Если есть другая копия и она не остановлена или мертва:

if [ -z "$( sudo service nginx status | grep "stopped"  )" ]; then { sudo service nginx stop } fi sudo service nginx start; sudo chkconfig nginx on sudo service nginx status

Чтобы Engine X не послал на Forbidden:

sudo chown -R "nginx" "$nginx_install_prefix""/html" curl localhost }  install_nginx

Ещё раз полный код.
Спасибо за внимание. Конструктивная критика, предложения и замечания приветствуются.
ссылка на оригинал статьи https://habrahabr.ru/post/315098/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *