UMGUM.COM (лучше) 

Nginx + Apache ( Инсталляция и настрока Nginx и Apache. )

26 марта 2010  (обновлено 31 января 2015)

OS: Linux Debian Lenny/Squeeze.
Application: Nginx.

Устанавливаем Nginx из набора пакетов:

# aptitude install nginx

Получаем что-то вроде версии 0.6-0.7. Древнее, по сравнению с размещённой на сайте разработчика (стабильная версия уже за единичку перевалила). Однако, для работы среднестатистического web-сервера этого хватает - не будем усложнять себе жизнь сопровождением собранного из исходных кодов программного обеспечения.

После установки из пакетов Nginx не сможет стартовать, обнаружив занятым порт #80. Нам предстоит выставить его "front-end", убрав работающий пока в этой роли Apache на другой, локальный порт.


Для начала заведем для Ngnix отдельного пользователя, от имени которого он будет работать в системе:

# groupadd www-nginx
# useradd --home-dir /var/lib/nginx --shell /bin/false --gid www-nginx www-nginx

Сразу припоминаем, что доступ в директории ресурсов пользователей у нас жёстко ограничен. Для того, чтобы наш Nginx мог обратится к нужным ресурсам необходимо ввести пользователя "www-nginx" в группы владельцев ресурсов, которым разрешён доступ на чтение:

# usermod --append --groups ug1000 www-nginx
# usermod --append --groups ug1001 www-nginx

Доработаем конфигурацию Apache2 до той, в которой он будет корректно отрабатывать в связке с прозрачным "прокси" Nginx.

Для начала установим модуль, предоставляющий Apache2 принимать от "прокси" реальный IP-адрес обращающегося клиента, с учётом того, что он замаскирован включённой нами прослойкой из "прозрачного прокси". Суть в том, что модуль позволяет Apache2 использовать заголовок X-Forwarded-for, передаваемый с запросом, в качестве значения заголовка несущего реальный IP удалённого клиента (припоминаем, что IP удалённого клиента в запросе у нас занят IP "прозрачного прокси"):

# aptitude install libapache2-mod-rpaf

Приводим конфигурационный файл "/etc/apache2/mods-available/rpaf.conf" к следующему виду:

RPAFenable On            # включаем механизм
RPAFsethostname On       # включаем передачу заголовка X-Host
RPAFproxy_ips 127.0.0.1  # указываем адрес "front-end"

Пройдемся по конфигурационным файлам Apache2 и везде, где есть указание на то, какие интерфейсы и порты прослушиваются, укажем "127.0.0.1:8080". Как минимум это конфигурационные файлы "/etc/apache2/ports.conf" и "/etc/apache2/sites-available/*". Например, для файла "/etc/apache2/ports.conf" это будет:

NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080

А для "/etc/apache2/sites-available/u1000.local":

<VirtualHost 127.0.0.1:8080>
  ServerName u1000.local
  ServerAlias www.u1000.local
...

Для того, чтобы в журнальных файлах Apache2 фиксировался реальный IP удалённого клиента, а не IP "прокси", заменяем в описании формата вывода журналируемой информации переменную "%h" на "%{X-Forwarded-For}i" (как, впрочем, и рекомендовано разработчиками Apache2). Вывод после этого должен выглядеть так:

# cat /etc/apache2/apache2.conf

....
LogFormat "%v:%p %{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O" common
....

Перезапустим Apache2:

# /etc/init.d/apache2 restart

Теперь "back-end" не будет отвечать на запросы извне и будет заниматься только отработкой тяжеловесных запросов отработки динамики.

Проверим, переключился Apache на прослушивание заданного порта или нет:

# netstat -apn | grep tcp | grep apache2

tcp  0  0 127.0.0.1:8080  0.0.0.0:*  LISTEN  6231/apache2

Перейдем к конфигурированию Nginx.

Общая конфигурация Nginx находится в файле "/etc/nginx/nginx.conf"; настройки сайтов описываются в файлах, располагающихся в папке "/etc/nginx/sites-available".

Изменим ряд директив общего конфигурационного файла "/etc/nginx/nginx.conf":

# указываем пользователя (и его группу), от чьего имени запускается Nginx
user www-nginx www-nginx;
...
# количество запускаемых рабочих процессов для простоты приравняем к количеству процессорных ядер на нашем сервере
worker_processes    8;
...
http {
....
    # описание параметров регламентирующих работу Nginx с доменными именами, необходимо выставлять величину превышающую количество обслуживаемых доменных имён
    server_names_hash_max_size    712;
    server_names_hash_bucket_size    712;

    # Задаём таймаут побольше для чтения заголовка запроса клиента (по умолчанию: 60s)
    client_header_timeout  2m;
    #
    # Задаём таймаут побольше для чтения тела запроса клиента (по умолчанию: 60s)
    client_body_timeout    3m;
    #
    # Задаём таймаут побольше для передачи ответа клиенту (по умолчанию: 60s)
    send_timeout           3m;
....
    # запрещаем сообщать версию Nginx в ответе клиенту
    server_tokens off;
....
    # описание параметров работы сжатия трафика и перечень типов файлов подвергаемых сжатию
    gzip  on;
    gzip_comp_level 3;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
...
}

Создаем конфигурационный файл описания механизма "прозрачного проксирования" на "back-end" для последующего включения в конфигурации виртуальных хостов:

# touch /etc/nginx/proxy.conf

Приводим его к следующему виду:

proxy_redirect              off;
proxy_set_header            Host $host;
proxy_set_header            X-Real-IP $remote_addr;
proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size        22m;
client_body_buffer_size     128k;
proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
proxy_buffer_size           8k;
proxy_buffers               8 32k;
proxy_busy_buffers_size     64k;
proxy_temp_file_write_size  64k;

Создаем файлы конфигурации виртуальных хостов, поддерживаемых нами:

# touch /etc/nginx/sites-available/u1000.local
# touch /etc/nginx/sites-available/u1001.local

Приводим их примерно к следующему виду:

server {
    listen *:80;
    server_name u1000.local
                www.u1000.local;
    # Указываем кодировку отдаваемых страниц
    charset utf-8;
    access_log /var/www/u1000/log/nginx.access.log;
    error_log /var/www/u1000/log/nginx.error.log;
    # запрещаем отдавать кому бы то ни было файлы .htaccess и .htpasswd
    location ~* /\.ht {
        deny  all;
    }
    # Перенаправление на сервер "back-end"
    location / {
        proxy_pass    http://127.0.0.1:8080/;
        include       /etc/nginx/proxy.conf;
    }
    # Статическое наполнение у нас отдает сам Nginx из директорий ресурсов пользователей в соответствии с указанными типами файлов
    location ~* \.(css|gif|jpeg|jpg|js|txt|png|tif|tiff|ico|jng|bmp|doc|pdf|rtf|xls|ppt|rar|rpm|swf|xpi|zip|tgz|gz|bz2|tar|bin|exe|dll|deb|dmg|iso|img|msi|msp|msm|mid|midi|mp3|mpeg|mpg|mov|flv|asx|asf|wmv|avi)$ {
        root /var/www/u1000/www/;
    }
}

Казалось бы, зачем прописывать модули перенаправления трафика между "front-end" и "back-end" в каждом описании виртуального хоста, если они однотипны? Можно вынести их в общее описание конфигурации Nginx, но тогда у нас не будет типового подхода к возможности индивидуальной настройки разделения трафика. Например, не исключено, что для избранных хостов в Apache2 указаны нетипичные расширения для исполняемых файлов и мы хотели бы их не отдавать напрямую клиенту.

Указываем символическими ссылками Nginx на доступные конфигурации виртуальных хостов для загрузки:

# ln -s /etc/nginx/sites-available/u1000 /etc/nginx/sites-enabled/u1000
# ln -s /etc/nginx/sites-available/u1001 /etc/nginx/sites-enabled/u1001

Удаляем ссылку на конфигурацию виртуально хоста "по умолчанию":

# rm /etc/nginx/sites-enabled/default

Перезапускаем Nginx:

# /etc/init.d/nginx restart

Удостоверимся в том, что Nginx работает, прослушивая заданный порт:

# netstat -apn | grep tcp | grep nginx

tcp  0  0 0.0.0.0:80  0.0.0.0:*  LISTEN  6339/nginx

По завершению конфигурирования Nginx закрываем от постороннего взгляда директорию конфигурации:

# chown -R root:root /etc/nginx
# chmod -R o-rwx /etc/nginx


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )