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

Документация пока упускает существенные детали, а статьи с рекомендациями, как лучше, во-первых, разрознены и, как правило, не цельны, а во-вторых отсылают к далёким источникам, тогда как на самом деле всё под рукой. Я предлагаю решение. Вместе с тем, покажу несколько удобных, на мой взгляд, вспомогательных функций bash для сборки как таковой. Интересно?

Начну с документации. Конечно же, соответствующие правки будут предложены сообществу 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 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 
}

И самое интересное. Что хорошо в пакетах? Конечно же, дополнительные скрипты. И если без команды 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

Ещё раз полный код.

Спасибо за внимание. Конструктивная критика, предложения и замечания приветствуются.
Поделиться с друзьями
-->

Комментарии (17)


  1. aik
    12.11.2016 17:25
    +1

    небезопасны: любой пакет можно изучить заранее

    Вроде как возможность покопаться в программах обычно в плюс к безопасности засчитывалась среди сторонников опенсорса?


    1. stranger777
      12.11.2016 17:54
      -2

      Конечно. Но у медали как минимум две стороны, одна из них такая.


      1. dmitry_ch
        13.11.2016 00:04
        +2

        А в чем проблема-то? Как раз то, что кто-то может увидеть, что в пакете, дает карты в руки как злобным дядкам, так и добрым админам.

        И что там можно «изучить заранее»?


  1. AlexMal
    12.11.2016 17:54

    Выражением

    Недолюбливаю пакеты redhat.

    Можно сразу же задать большей части семейства RedHat, негативный настрой на прочтение статьи.


    1. stranger777
      12.11.2016 17:54
      -2

      Понимаю.


  1. RPG18
    12.11.2016 18:06
    +10

    make
    sudo make install
    sudo nginx

    Дикость, когда все можно собрать из src.rpm Собираем RPM-пакет для CentOS 6.4 x64


    1. stranger777
      12.11.2016 19:13
      -2

      Можно и так. На мой взгляд nginx.spec переусложнён, разобраться в нём труднее. И по сути это тот же bash, только с секциями, чуть другим синтаксисом, обёртка. Если заглянуть в spec-файлы, там легко можно встретить всё тот же make. Вот такой отрывок есть в nginx.spec:

      %build
      ./configure %{COMMON_CONFIGURE_ARGS} \
      --with-cc-opt="%{WITH_CC_OPT}" \
      %{?perlldopts} \
      --with-debug
      make %{?_smp_mflags}


      1. zirf
        12.11.2016 20:04

        Да, но это же редактируемый элемент в конце, тот же rpm. Более того, пакеты лучше собирать на платформе эксплуатации, собранный из src.rpm на Intel подвисал на некоторых AMD. Пакет удобен установил/убрал, в первую очередь.


  1. nikitasius
    12.11.2016 18:09
    +2

    Мне, на дебиане, не ясен смысл этой статьи… каких море. Этакая солянка из "как собрать nginx из сурцов" и "как сделать ротацию логов".


    Поменяли версию nginx? Так ее просто можно скрыть в конфиге. Раз начали ковырять исходники, где другие примеры, в виде увеличения длины файлов при листинге директории (кто юзает nginx для вывода папок на файлопомойке).


    Ну и… ./configure blablabla следом make и или make install или нудный кошерный checkinstall, который nginx'у не въелся, никто не отменял. Я каждый раз скачиваю исходники с оффсайта и собираю с нужными мне плагинами тремя командами.


    1. stranger777
      12.11.2016 19:23
      -3

      Да, статей море. Эта — лишь систематизация. Директива в конфиге прячет версию не совсем так, как хотелось бы, это легко сравнить.

      Раз начали ковырять исходники, где другие примеры, в виде увеличения длины файлов при листинге директории (кто юзает nginx для вывода папок на файлопомойке)
      Если найду время, посмотрю в эту сторону. Спасибо.
      К сожалению, checkinstall — сапожник без сапог. Вы не найдёте на его официальном сайте его собственного пакета, собранного им же. Это меня очень, очень смущает.


  1. sunnybear
    12.11.2016 21:37

    Если добавлять HTTP/2, то там немного сложнее исходники править для замены версии nginx :)


  1. n-name
    12.11.2016 22:36
    +2

    Недолюбливаю пакеты redhat. Они небезопасны: любой пакет можно изучить заранее

    .deb пакеты нельзя изучить заранее?

    Присоединяюсь к мнению собирать из src.rpm


  1. prefrontalCortex
    12.11.2016 22:49
    +4

    Как только люди не извращаются, лишь бы Gentoo не использовать :)
    Если серьёзно, вы бы, перед тем как в паблик выкладывать, прошлись бы по своему скрипту линтом для шелла, вот этим, например.


  1. VBart
    13.11.2016 02:00
    +4

    Ловкость sed и никакой коммерции. Команда nginx вряд ли скажет спасибо

    Заголовок ответа Server: nginx — это минимальная благодарность, которую пользователь может выразить разработчикам. Эти заголовки влияют на статистику серверов на рынке, которую таким образом агрегируют некоторые профильные ресурсы. Данная статистика, среди прочего, вносит вклад в отношение инвесторов к нам, дадут ли нам ещё денег и сколько, чтобы дальше разрабатывать и поддерживать nginx, либо придется идти искать другую работу.


    Хотите скрыть заголовок Server и поддержать разработку — купите NGINX Plus, там есть такая опция. А писать скрипты, подменяющие название продукта, и рассказывать об этом на весь мир — я лично считаю, что тем самым вы наиболее красноречиво выражаете свое отношение к его создателям.


    Что же касается безопасности, то данная практика называется "Security through obscurity" и в профессиональной среде считается порочной. При необходимости тип сервера легко узнается по косвенным признакам.


    1. VBart
      13.11.2016 02:15
      +4

      Про безопасность: забавно, что автор при этом в своем скрипте скачивает zlib и pcre по незащищенному каналу и даже не пытается хоть как-то верифицировать скачанное. Т.е. он с удовольствием готов запустить себе троян на сервер, но зато подменяет заголовок и собирает сам, ибо пакеты же по его мнению "небезопасны". Прекрасно.


  1. CentALT
    13.11.2016 08:57
    +2

    В 2016 году за советы собирать пакеты в RPM Based дистрибутивах с помощью configure; make; make install; надо отрубать руки.

    Документации по SPEC файлам куча, rpmbuild, mock. Что может быть проще.

    Причины побудившие Вас это сделать смешны и противоречивы. Вы пишите «небезопасны: любой пакет можно изучить заранее». Представьте ситуацию, Вас уволили (с Вашим подходом к системному администрированию шансы на то, что Вы будите работать в серьезной конторе минимальны) и Вам на смену пришел адекватный администратор, как ему узнать, что Вы навертели в системе какие параметры и какие изменения Вы внесли в пакет?

    За подмену заголовков ответа, отрубать вторую руку.


    1. istui
      13.11.2016 11:03

      Хорошо, а где для CentOS можно взять актуальные версии OpenSSL и nginx в нужной конфигурации? (Я не вступаю в спор, а спрашиваю — ваш ник дает основания предположить, что вы имеете отношение к CentALT-репозиторию).

      Интересует nginx+geoip+http2
      CentOS 6.x или 7.x

      Или может быть есть мануал, как автоматически настроить скачиваение сорцов-компиляцию-сборку нужных пакетов, и создать свой репозиторий?