Недолюбливаю пакеты 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
Спасибо за внимание. Конструктивная критика, предложения и замечания приветствуются.
Автор: stranger777