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
# 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
# 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"
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
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
...
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
....
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;
...
}
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;
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
# 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/;
}
}
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
# 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
# chmod -R o-rwx /etc/nginx