Настройка прокси NGINX
Apache и Nginx — это два самых популярных и наиболее часто используемых веб-серверов с открытым исходным кодом. Оба веб-сервера имеют свои преимущества и недостатки, вы можете ознакомиться с ними более подробно в статье Nginx vs Apache. Было бы отлично объединить эти программы, чтобы получить преимущества обоих и свести к минимуму недостатки. Это вполне возможно. Для этого достаточно использовать Nginx в качестве прокси для Apache, такая практика очень распространена среди системных администраторов.
В этой статье мы рассмотрим как выполняется настройка прокси Nginx, а также поговорим как заставить эту связку правильно обрабатывать HTTPS запросы и передадим управление статическими файлами Nginx.
КАК ЭТО БУДЕТ РАБОТАТЬ?
Допустим, у нас есть несколько доменов example.com, sample.org, test.io. Первые два будут обрабатываться Apache, последний только Nginx. Все запросы будут поступать к Nginx, который работает на порту 80, если это запрос к одному из доменов Apache и он требует работы PHP, тогда он будет передан веб-серверу Apache, который работает на порту 8080.
Если же это запрос статического файла, то мы будем обрабатывать его тут же с помощью Nginx для увеличения производительности. Что касается поддержки SSL, то мы собираемся использовать модуль mod_pref чтобы заменить все необходимые заголовки для нормальной работы связки. Начнем с настройки Apache.
НАСТРОЙКА APACHE ДЛЯ РАБОТЫ ПРОКСИ
Мы не будем подробно рассматривать как настроить Apache в вашей системе, все это уже описано в статье настройка Apache, сегодня же мы остановимся на настройках, необходимых для работы прокси.
Мы будем использовать Apache с интерпретатором PHP, установленным в виде модуля php-fpm. Это обеспечит лучшую общую производительность системы. Сначала установим все нужные пакеты:
sudo apt install apache2 libapache2-mod-fastcgi php-fpm
Поскольку нам нужно, чтобы Apache работал на порту 8080 нужно изменить конфигурационные файлы веб-сервера:
sudo vi /etc/apache2/ports.conf
Listen 8080
Замените значение строки Listen с 80 на 8080, затем сохраните изменения в файле. Далее изменим порт для веб-сайта по умолчанию:
sudo vi /etc/apache2/sites-available/000-default.conf
<VirtualHost *:8080>
Точно так же замените значение порта с 80 на 8080. Затем сохраните изменения и перезапустите веб-сервер:
sudo systemctl reload apache2
Теперь вы можете проверить на каком порту будет ожидать соединений Apache, если все было сделано правильно, то это будет 8080:
sudo netstat -tlpn
Чтобы показать настройку прокси Nginx более наглядно, создадим один виртуальный хост (домен). Сначала создадим каталог для нашего хоста:
sudo mkdir /var/www/test.com/
Затем файлы index.html и phpinfo.php:
echo "<h1 style='color: green;'>Test com</h1>" | sudo tee /var/www/test.com/index.html
Затем настроим файлы конфигурации виртуальных хостов для каждого из доменов:
sudo vi /etc/apache2/sites-available/test.com.conf
<VirtualHost *:8080>
ServerName test.com
ServerAlias www.test.com
DocumentRoot /var/www/test.com
<Directory /var/www/test.com>
AllowOverride All
</Directory>
</VirtualHost>
Обратите внимание на порт, тут тоже нужно указать 8080. Для тестирования работы php нам понадобится скрипт с вызовом функции:
echo "<?php phpinfo(); ?>" | sudo tee /var/www/test.com/phpinfo.php
Осталось включить конфигурацию для только что созданного сайта и перезапустить веб-сервер:
sudo a2ensite test.com
sudo apachectl -t
sudo systemctl reload apache2
НАСТРОЙКА APACHE ДЛЯ PHP-FPM
По умолчанию в Apache используется модуль mod-php для выполнения php скриптов. Сначала необходимо его отключить:
sudo a2dismod php7.0
Затем мы настроим работу mod_fastcgi с помощью модуля mod_actions, для этого нужно его активировать:
sudo a2enmod actions
Затем создадим конфигурационный файл fastcgi.conf:
sudo vi /etc/apache2/mods-available/fastcgi.conf
<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
#FastCgiWrapper /usr/lib/apache2/suexec
FastCgiIpcDir /var/lib/apache2/fastcgi
AddType application/x-httpd-fastphp .php
Action application/x-httpd-fastphp /php-fcgi
Alias /php-fcgi /usr/lib/cgi-bin/php-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php-fcgi -socket /run/php/php7.0-fpm.sock -pass-header Authorization
<Directory /usr/lib/cgi-bin>
Require all granted
</Directory>
</IfModule>
Сохраните изменения, активируйте модуль и проверьте конфигурацию веб-сервера:
sudo a2enmod fastcgi
sudo apachectl -t
Вы увидите сообщение, что с синтаксисом конфигурационных файлов все хорошо. Если программа выдаст сообщение Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1, его можно игнорировать. Далее перезапустите Apache:
sudo systemctl restart apache2
ПРОВЕРКА РАБОТЫ APACHE
Добавьте свои домены в файл hosts, если они не зарегистрированы и доступны только с локальной машины:
sudo vi /etc/hosts
127.0.0.1 test.com
Затем откройте сайт в браузере, чтобы убедится, в том что все работает:
НАСТРОЙКА ПРОКСИ NGINX
Теперь, когда Apache полностью готов к работе в качестве веб-сервера, перейдем к настройке прокси сервера Nginx, мы можем заняться настройкой самого Nginx. Как я уже сказал, мы будем перенаправлять все динамические запросы к Apache, чтобы пользователь смог получить поддержку файлов htaccess и другие преимущества, а статические файлы будем обрабатывать в Nginx.
Сначала установите Nginx, если вы этого еще не сделали:
sudo apt install nginx
Дальше создадим виртуальный хост Nginx с несколькими доменами, с помощью которого и будет выполняться проксирование Nginx:
sudo vi /etc/nginx/sites-available/apache
server {
listen 80;
server_name test.com www.test.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Для использования nginx в качестве прокси мы передаем в команде proxy_pass адрес и порт веб-сервера, а в заголовках передаем те значения, которые будут нужны Apache для правильного формирования документа. Сохраните файл и активируйте его:
sudo ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache
Затем проверьте конфигурацию и перезапустите Nginx:
sudo nginx -t
sudo systemctl reload nginx
Теперь вы можете проверить работу вашего сайта в браузере, если вы откроете скрипт phpinfo, то увидите, что он был обработан с помощью Apache, но возвращен Nginx.
Как вы могли убедится, теперь применяется nginx в качестве прокси. Теперь можно закрыть прямой доступ к Apache из сети с помощью iptables:
sudo iptables -I INPUT -p tcp --dport 8080 ! -s your_server_ip -j REJECT --reject-with tcp-reset
НАСТРОЙКА ПРАВИЛЬНОЙ РАБОТЫ SSL
Дальше рассмотрим как выполняется настройка https прокси Nginx. Как я уже сказал, для правильной работы SSL нам понадобится модуль Apache mod_rpaf. Он устанавливает заголовки и переменные таким образом, чтобы прокси мог без проблем использовать https. Его можно установить из официальных репозиториев:
sudo apt install libapache2-mod-rpaf
Затем создайте конфигурационный файл для этого модуля:
sudo vi /etc/apache2/mods-available/rpaf.conf
<IfModule mod_rpaf.c>
RPAFEnable On
RPAFHeader X-Real-Ip
RPAFProxyIPs ваш_внешний_ip_адрес
RPAFSetHostName On
</IfModule>
Строка RPAFProxyIPs задает IP адрес вашего прокси. После завершения настройки активируйте модуль:
sudo a2enmod rpaf
Осталось перезапустить Apache:
sudo systemctl reload apache2
Дальше нам нужно создать наши сертификаты с помощью OpenSSL:
sudo mkdir /etc/nginx/ssl/
sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/test.com-key.pem -out /etc/nginx/ssl/test.com-cert.pem -days 3650 -nodes
А файл виртуальных хостов с поддержкой SSL теперь будет выглядеть во так:
sudo nano /etc/nginx/sites-available/apache
server {
listen 80;
listen 443 ssl;
server_name test.com www.test.com;
ssl on;
ssl_certificate /etc/nginx/ssl/test.io-cert.pem;
ssl_certificate_key /etc/nginx/ssl/test.io-key.pem;
location / {
proxy_pass http://your_server_ip:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Сохраните файл конфигурации и перезапустите Nginx:
nginx -t
$ sudo systemctl restart nginx
Теперь вы можете открыть наш домен в браузере по HTTS и убедится что прокси отлично работает. Обратите внимание, что если вы используете самоподписанный сертификат, то вам придется добавить его в исключения браузера:
Поддержка защищенного протокола включена и SERVER_PORT имеет значение 443, все работает прозрачно, как бы проксирование nginx не осуществляется, а мы направляем запросы непосредственно к Apache.
СТАТИЧЕСКИЕ ФАЙЛЫ ЧЕРЕЗ NGINX
Чтобы уменьшить нагрузку на Apache мы можем обрабатывать все статические файлы в Nginx, как правило, это очень сильно увеличивает выдерживаемую нагрузку, поскольку Nginx способен работать быстрее с большим количеством подключений и занимать меньше ресурсов.
Нам нужно добавить несколько строк в /etc/nginx/sites-available/apache
server {
listen 80;
listen 443 ssl;
server_name test.com www.test.com;
ssl on;
ssl_certificate /etc/nginx/ssl/test.com-cert.pem;
ssl_certificate_key /etc/nginx/ssl/test.com-key.pem;
root /var/www/test.com;
index index.php index.htm index.html;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ /\. {
deny all;
}
}
Мы устанавливаем корень сайта в /var/www/test.com, и пытаемся отдать оттуда все статические файлы, а файлы с расширением .php будем обрабатывать в Apache. Также дополнительно мы закрываем доступ ко всем скрытым файлам.
Теперь откройте несколько раз сайт в браузере, динамические страницы phpinfo.php и статическую index.html, а затем посмотрите в лог файл, где вы обнаружите что Apache обрабатывает только динамику:
cat /var/log/apache2/other_vhosts_access.log
Теперь проксирование Nginx работает так же как и на большинстве серверов интернета.
В этой статье мы рассмотрели как выполняется настройка прокси Nginx, а точнее, как использовать nginx как прокси для Apache. Для новичков эти настройки могут показаться сложными, но если разобраться, то все обязательно получится. Если у вас остались вопросы, спрашивайте в комментариях.