Зачем нужен Nginx?
Это веб-сервер, предназначенный в основном для отдачи статики (для того чтобы разгрузить бекенд) и использования в качестве фронтендов. Apache при этом можно использовать в качестве бэкенда для генерации динамического контента.
Так же Nginx можно использовать в режиме FastCGI, при этом Apache вам не понадобится. Однако при этом режиме у PHP наблюдается ряд проблем, поэтому на помощь приходит php-fpm!
Однако мы сегодня поговорим о совместной установке с Apache, а не в режиме FastCGI. Более того, по задаче у нас эти веб-сервера будут находится на одном сервере, поэтому выделим для Nginx — 80, а для Apache — 88 порт!
Apache (см. схему)
Установка Apache и Nginx
Ставим Apache:
FreeBSD:
cd /usr/ports/www/apache2
make config
make install clean
Debian:
Установка Apache
apt-get install apache2
[+mod_rewrite]
a2enmod rewrite
При этом буду установлены так же пакеты:
Если этого не произошло, то необходимо установить их самостоятельно:
sudo apt-get install openssl openssl-blacklist ssl-cert
Создание сертификатов для SSL
Создание ключа
Первым делом необходимо создать приватный ключ (private key):
$ openssl genrsa -des3 -out adminunix.ru.key 2048
Generating RSA private key, 2048 bit long modulus
............................................+++
.....................................+++
e is 65537 (0x10001)
Enter pass phrase for adminunix.ru.key:
Verifying - Enter pass phrase for adminunix.ru.key:
При создании ключа необходимо указать ключевую фразу (и запомнить ее).
Создание подписанного сертификата
После того, как сгенерирован ключ, можно создавать самоподписанный сертификат (CSR — Certificate Signing Reques):
$ openssl req -new -key adminunix.ru.key -out adminunix.ru.csr
Enter pass phrase for adminunix.ru.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Russia
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:adminunix.ru
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Email Address []:ssl@lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Удаление пароля из ключа
Неприятной особенностью ключа с паролем является то, что Apache или nginx будет регулярно спрашивать пароль при старте. Очевидно, что это не очень удобно (если только кто-то не находится постоянно рядом на случай перезагрузки или аварийной остановки). Для удаления ключа из пароля необходимо выполнить следующее:
$ cp adminunix.ru.key adminunix.ru.key.orig
$ openssl rsa -in adminunix.ru.key.orig -out adminunix.ru.key
Enter pass phrase for adminunix.ru.key.orig: <пароль-который-указывался-при-создании-adminunix.ru.key>
writing RSA key
Генерация SSL сертификата
Далее, создаем сам SSL сертификат:
$ openssl x509 -req -days 365 -in adminunix.ru.csr -signkey adminunix.ru.key -out adminunix.ru.crt
Signature ok
subject=/C=RU/ST=Russia/O=adminunix.ru/CN=lists.adminunix.rulists.adminunix.rulists.adminunix.ru/emailAddress=ssl@lists.adminunix.rulists.adminunix.rulists.adminunix.ru
Getting Private key
Теперь есть все, что необходимо для создания SSL-соединений.
Правильное расположение SSL сертификатов
Заключительным шагом в создании SSL сертификата будет распределение полученных файлов в соответствующие директории. Во-первых, копируем сам сертификат:
$ sudo cp adminunix.ru.crt /etc/ssl/certs/
Во-вторых, копируем ключ:
$ sudo cp adminunix.ru.key /etc/ssl/private/
И в-третьих, удаляем, все то, что было создано в текущей директории:
$ rm adminunix.ru.crt adminunix.ru.key adminunix.ru.csr adminunix.ru.key.orig
Ставим Nginx:
FreeBSD:
cd /usr/ports/www/nginx
make config
make install clean
Debian:
apt-get install nginx
Конфиги -> /etc/nginx
Настройка Nginx
Отредактируем файл /usr/local/etc/nginx/nginx.conf
# пользователь и группа от которого запускается процесс
user www-data;
# кол-во рабочих процессов. Обычно равно кол-ву ядер на машине
worker_processes 2;
# Лог для ошибок
error_log logs/error.log;
events {
# максимум рабочих соединений
worker_connections 1024;
# Метод обработки соединений
# kqueue — эффективный метод, используемый во FreeBSD
# Подробнее [urlspan]http://sysoev.ru/nginx/docs/events.html[/urlspan]
use kqueue;
}
http {
# Подключаем таблицу mime
include mime.types;
# mime-тип по умолчанию
default_type application/octet-stream;
# Формат лог файла
#log_format main '$remote_addr - $remote_user [$time_local] $request '
# '"$status" $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# Лог доступа всего веб-сервера
#access_log logs/access.log main;
# Директива задаёт таймаут при чтении заголовка запроса клиента
client_header_timeout 3m;
# Директива задаёт таймаут при чтении тела запроса клиента
client_body_timeout 3m;
# Директива задаёт таймаут при передаче ответа клиенту
send_timeout 3m;
# Директива задаёт таймаут, в течение которого keep-alive соединение с клиентом не будет закрыто со стороны сервера
keepalive_timeout 2m;
# Директива разрешает или запрещает использовать sendfile()
sendfile on;
# Директива разрешает или запрещает использовать опции TCP_NOPUSH во FreeBSD
#tcp_nopush on;
# Директива задаёт размер буфера для чтения заголовка запроса клиента
#client_header_buffer_size 1k;
# Директива задаёт максимальное число и размер буферов для чтения большого заголовка запроса клиента
#large_client_header_buffers 4 4k;
# Настройки сжатия
gzip on;
gzip_disable "msie6";
ssi on;
gzip_comp_level 3;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Модуль позволяет описывать группы серверов, которые могут использоваться
# в директивах proxy_pass и fastcgi_pass. upstream backend {
# Директива задаёт имя и параметры сервера. Обратите внимание, мы будем
# использовать имя "backend" в директиве proxy_pass server 127.0.0.1:88; } server {
# Слушать 80 порт listen 80;
# Использовать следующие хосты server_name adminunix.ru www.adminunix.ru;
# Кодировка #
charset koi8-r;
# Лог доступа для конкретного виртуального хоста
#access_log logs/host.access.log main;
# Максимальный размер тела запроса клиента client_max_body_size 101M;
# Разруливаем статику и динамку, смотрите описание ниже в этой статье! location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ { root /home/adminunix/adminunix.ru; } location ~ /.ht { deny all; } #Секция описывает параметры, по которым фронтенд обменивается с бекендом,
#такие, как адресабекенда, параметры прямого редиректа, парарметры передачи заголовков,
#максимальный размер принимаемых файлов и пр.
}
}
Создаем файл конфигурации proxy.conf:
$ sudo mcedit /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 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
Настройка виртуального хоста в Nginx
Создаем файл виртуального хоста:
$ sudo mcedit /etc/nginx/sites-available/adminunix.ru.vhost
Файл следующего вида:
upstream backend {
# Адрес back-end'a
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.adminunix.ru adminunix.ru;
access_log /home/site/adminunix.ru/logs/nginx_access.log;
error_log /home/site/adminunix.ru/logs/nginx_error.log;
# Перенаправление на back-end
location / {
proxy_pass http://backend;
include /etc/nginx/proxy.conf;
}
# Статическиое наполнение отдает сам nginx
# back-end этим заниматься не должен
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
root /home/site/adminunix.ru/static/;
}
}
Создание виртуальных хостов в Nginx
Создаем описание двух виртуальных хостов:
$ sudo touch /etc/nginx/sites-available/adminunix.ru.vhost
$ sudo touch /etc/nginx/sites-available/lists.adminunix.ru-ssl.vhost
Создаем необходимые директории двух виртуальных хостов:
$ sudo mkdir -p /usr/local/hosting/www/adminunix.ru/logs
$ sudo mkdir -p /usr/local/hosting/www/adminunix.ru/apache
# создаем html файл, который будет отражаться при обращении к "http://adminunix.ru"
$ sudo touch /usr/local/hosting/www/adminunix.ru-1/index.html
$ sudo mkdir -p /usr/local/hosting/www/lists.adminunix.ru/logs
$ sudo mkdir -p /usr/local/hosting/www/lists.adminunix.ru/apache
# создаем html файл, который будет отражаться при обращении к "http(s)://lists.adminunix.ru"
$ sudo touch /usr/local/hosting/www/lists.adminunix.ru/index.html
$ sudo chown www-data:www-data -R /usr/local/hosting/www/
Настройка стандартного виртуального хоста в Nginx
Файл настройки должен иметь следующий вид:
#$ sudo cat /etc/nginx/sites-available/adminunix.ru.vhost
upstream backend {
# Адрес back-end'a
server 127.0.0.1:8080;
}
server {
listen 80;
server_name adminunix.ru;
access_log /usr/local/hosting/www/adminunix.ru/logs/nginx_access.log;
error_log /usr/local/hosting/www/adminunix.ru/logs/nginx_error.log;
# Перенаправление на back-end
location / {
proxy_pass http://backend;
include /etc/nginx/proxy.conf;
}
# ...
}
Настройка виртуального хоста в Nginx с поддержкой SSL
Файл настройки должен иметь следующий вид:
#$ sudo cat /etc/nginx/sites-available/listen.adminunix-ssl.vhost
upstream backend1 {
# Адрес back-end'a
server 127.0.0.1:8080;
}
server {
listen 80;
server_name lists.adminunix.ru;
access_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_access.log;
error_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_error.log;
# Перенаправление на back-end
location / {
proxy_pass http://backend1;
include /etc/nginx/proxy.conf;
}
# ...
}
server {
listen 443;
server_name lists.adminunix.ru;
ssl on;
ssl_certificate /etc/ssl/certs/lists.adminunix.ru.crt;
ssl_certificate_key /etc/ssl/private/lists.adminunix.ru.key;
access_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_ssl_access.log;
error_log /usr/local/hosting/www/lists.adminunix.ru/logs/nginx_ssl_error.log;
# Перенаправление на back-end
location / {
proxy_pass http://backend1;
include /etc/nginx/proxy.conf;
}
# ...
}
В отличие от конфигурации для adminunix.ru тут уже появляется описание для 443 порта. Идея проста — ssl-соединение создает nginx, а вот данные по этому соединению передает уже apache.
Включение хостов и перезапуск Nginx
После того, как настройки сделаны, необходимо сделать виртуальные хосты достпными и перезапустить nginx:
$ sudo ln -s /etc/nginx/sites-available/adminunix.ru.vhost /etc/nginx/sites-enabled/adminunix.ru
$ sudo ln -s /etc/nginx/sites-available/adminunix.ru-ssl.vhost /etc/nginx/sites-enabled/adminunix.ru-ssl.vhost
$ sudo /etc/init.d/nginx restart
Создание виртуальных хостов в Apache
Так как ssl-соединениями занимается nginx, то apache остается всего лишь работать на не стандартном порту (например, 8080) и обрабатывает входящие содинения. Создаем файлы виртуальных хостов Apache:
#$ sudo cat /etc/apache2/sites-available/adminunix.ru.vhost
<VirtualHost *:8080>
# Осн. настройки домена
ServerAdmin admin@adminunix.ru
ServerName adminunix.ru
DocumentRoot /usr/local/hosting/www/adminunix.ru/
<Directory /usr/local/hosting/www/adminunix.r/>
Order deny,allow
Allow from all
</Directory>
ErrorLog /usr/local/hosting/www/adminunix.ru/logs/apache_error.log
CustomLog /usr/local/hosting/www/adminunix.ru/logs/apache_access.log combined
# Остальные настройки
# ...
</VirtualHost>
Второй хост:
#$ sudo cat /etc/apache2/sites-available/lists.adminunix.ru
<VirtualHost *:8080>
# Осн. настройки домена
ServerAdmin admin@lists.adminunix.ru
ServerName lists.adminunix.ru
DocumentRoot /usr/local/hosting/www/lists.adminunix.ru/
<Directory /usr/local/hosting/www/lists.adminunix.ru/>
Order deny,allow
Allow from all
</Directory>
ErrorLog /usr/local/hosting/www/lists.adminunix.ru/logs/apache_error.log
CustomLog /usr/local/hosting/www/lists.adminunix.ru/logs/apache_access.log combined
# Остальные настройки
# ...
</VirtualHost>
Далее, необходимо включить хосты и перегрузить apache:
$ sudo a2ensite adminunix.ru
$ sudo a2ensite lists.adminunix.ru
$ sudo /etc/init.d/apache2 restart
Проверка SSL соединения
Чтобы проверить корректность настройки SSL достаточно открыть в браузере https://lists.adminunix.ru/. Так как используется самоподписанный сертификат, то браузер, вероятнее всего, выдаст предупреждение, что подлинность сервера не может быть проверена, и предоставит возможность просмотреть сертификат. В случае, если текущий домен не совпадает с тем, что указан «Common Name», может быть выдано еще одно предупреждение.
Самоподписанных сертификтов как правило хватает для административных зон на сайтах. При использовании коммерческих сертификатов никаких предупреждений выдаваться не будет.
Для более тонкой настройки SSL или для решения проблем в TLS/SSL-соединениях следует пользоваться набором утилит openssl. Например:
$ openssl s_client -connect lists.adminunix.rulists.adminunix.rulists.adminunix.ru:443
После конфигурации необходимо перезагрузить Nginx
/usr/local/etc/rc.d/nginx restart
Nginx: Отдаем статику
С помощью этих правил разруливаем запросы на отдачу статику и динамического контента
# Следующие расширения файлов (jpg, jpeg, gif, png, ico, css, bmp, swf и js) отдаются напрямую, без участия Apache.
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js)$ {
root /home/adminunix/adminunix.ru;
}
# htaccess и htpasswd не отдаем
location ~ /.ht {
deny all;
}
# Все остальное разруливает бекенд (Apache)
location / {
# Адрес бекенда. Параметры бекенда перечислили в директиве "upstream" (см. выше в статье)
proxy_pass http://backend/;
# Заголовок Host
proxy_set_header Host $host;
# Заголовок X-Real-IP
proxy_set_header X-Real-IP $remote_addr;
# Заголовок X-Forwarded-For
proxy_set_header X-Forwarded-For $remote_addr;
# Директива задаёт таймаут для соединения с проксированным сервером, сек
proxy_connect_timeout 120;
# Директива задаёт таймаут при передаче запроса проксированному серверу, сек
proxy_send_timeout 120;
# Директива задаёт таймаут при чтении ответа проксированного сервера, сек
proxy_read_timeout 180;
}
Настройка Apache
Редактируем файл /usr/local/etc/apache2/httpd.conf
# Меняем порт с 80 на 88
Listen 88
Тоже самое делаем и в httpd-vhosts.conf для ваших хостов.
Если у вас появляется следующая ошибка:
> [warn] (2) No such file or directory:
> Failed to enable the ‘httpready’ Accept Filter
то вам следует подгрузить модуль
# kldload accf_http
Установка и настройка RPAF или даешь верный REMOTE_ADDR!
Так как у нас появился в цепи дополнительный элемент в виде фронтенд-сервера, то теперь в REMOTE_ADDR у нас не пользовательский IP, а IP-адрес фронтенд-сервера (на котором расположен Nginx). Поэтому на помощь приходит RPAF, он берет тело заголовка X-Forwarded-For, присланного от фронтенда и формирует на бекенде из него REMOTE_ADDR.
Таким образом заголовок REMOTE_ADDR снова имеет пользовательский IP!
Устанавливаем модуль RPAF
FreeBSD
cd /usr/ports/www/mod_rpaf2
make install clean
Debian
apt-get install libapache2-mod-rpaf
a2enmod rpaf
mod_rpaf2 - для apache2, а для первого индейца надо mod_rpaf
Настраиваем RPAF, редактируем httpd.conf, добавляем в конец файла:
# Включаем модуль
RPAFenable On
# Доводит до ума X-Host
RPAFsethostname On
# Адрес фронтенда (nginx)
RPAFproxy_ips 82.146.61.55 127.0.0.1
# Имя отправляемого заголовка
RPAFheader X-Forwarded-For
или
RPAFheader X-Real-IP
После конфигурации необходимо перезагрузить Apache
apachectl restart
Debian
/etc/init.d/apache2 restart
/etc/init.d/nginx restart
Ну вот вроде и все, смотрите ниже дополнительную литературу и задавайте вопросы в камменты!
Полезные материалы по Nginx
[urlspan]Полезные ссылки[/urlspan]
[urlspan]Пример конфигурации nginx[/urlspan]
Настройка виртуальных серверов
Отличная статья с Хабра: [urlspan]Тюнинг nginx[/urlspan]