Реверсивный прокси на Nginx

Материал из Записки на полях
Перейти к навигации Перейти к поиску

Нюансы установки Ubuntu

В статье по установке Owncloud можно подсмотреть нюансы в установке Ubuntu 14.04 Установка OwnCloud на ubuntu 14.04

Установка Nginx

   sudo apt-get install nginx

Настройка Nginx

Файл /etc/ngins/proxy_params приводим к следующему виду

   vim /etc/nginx/proxy_params
   proxy_set_header Host $http_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;

Индивидуальные настройки для каждого сайта располагаются в директории sites-available.

При перенаправлении HTTP трафика

Пример файла revers_proxy.conf

   server {
       listen          192.168.1.1:80;
       server_name     site1.ru www.site1.ru;
       access_log      /var/log/nginx/log/site1_access.log;
       error_log       /var/log/nginx/log/site1_error.log;
       root            /usr/share/nginx/html;
       index           index.html index.htm;
       location / {
                       proxy_pass      http://192.168.1.2;
               }
       }

При перенаправлении HTTPS трафика

Пример файла revers_proxy.conf

   server {
       listen          192.168.1.1:443;
       server_name     cloud.lenair.ru;
       ssl                     on;
       ssl_protocols           SSLv3 TLSv1;
       ssl_certificate         /etc/nginx/ssl/cert.pem;
       ssl_certificate_key     /etc/nginx/ssl/cert.key;
       location / {
                       proxy_pass      http://192.168.1.2;
                       proxy_redirect          off;
                       proxy_set_header        X-Real-IP $remote_addr;
                       proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                       proxy_set_header        Host $http_host;
                       proxy_pass_header       Set-Cookie;
                       client_max_body_size    1G;
               }
       }

Можно так же параметру proxy_pass давать значение https://192.168.1.2 И необходимо создать сертификаты для Nginx

   mkdir /etc/nginx/ssl && cd /etc/nginx/ssl
   openssl req -new -x509 -days 2000 -nodes -out cert.pem -keyout cert.key
Особенность работы Nginx с ssl
Nginx игнорирует валидность подписи внутреннего ресурса на который он перенаправляет. В этом есть плюсы и минусы - хорошо то, что достаточно только один сертификат подписывать для корректной работы нескольких ресурсов, а плохо в плане безопасности, особенно если Вы перенаправляете трафик через неконтролируемую сеть.

Nginx настройка подробная инструкция. Nginx веб-сервер. подробная инструкция nginx настройка

Ниже Вы найдете полезные примеры использования nginx веб-сервера.

nginx для балансировки нагрузки /etc/nginx/sites-enabled

upstream название-серверов-для-php-обработки {
#
#Привязка клиента к серверу
#Часто бывает нужно, чтобы один и тот же клиент, начав делать запросы к какому-то определённому #серверу, не переключался на другие. Для этого в Nginx предусмотрена опция ip_hash. Если она #определена, сервер будет запоминать IP-хеши клиентов и стараться проксировать каждого из них на один #и тот же сервер.
#
ip_hash;
#
#список серверов
#
    server айпи:порт;
    server айпи:порт;
}

#
#обработка сайта с помощью серверов, указанных в upstream
#требуется указывать название после upstream в строку proxy_pass
#
server {
	listen   80;
	access_log /var/log/nginx/proxy.log;
	location / {
	proxy_pass http://название-сервера-для-php-обработки;
  }
}

Распределение нагрузки между веб-серверами (nginx балансировка с указание веса сервера). Насколько часто сервер будет использоваться.

upstream сервера {
#опция weight сообщает nginx кол-во запросов на один сервер
#в примере указано 3 запроса на сервер№1 и один запрос на сервер№2
#
  server сервер№1 weight=3;
#Без опции сервер будет принимать только один запрос
#балансировщик по очереди отправляет запросы#в зависимости от веса веб-сервера
#
  server сервер№2;
}

Автоотключение серверов при ошибках Если какой-то из upstream-серверов перестанет отвечать на запросы, то подключение к нему станет невозможным. Nginx в этом случае переключиться на использование следующего сервера однако каждый раз будет пытаться подключаться к неработающему серверу, растрачивая время. При помощи директивы max_fails параметра server можно определить максимально-допустимое количество неудачных попыток подключения к upstream-серверу, после чего тот будет считаться нерабочим и запросы к нему прекратятся. По умолчанию значение этого параметра равно единице, то есть после одной неудачной попытки Nginx на определённое время прекратит попытки новых подключений с нерабочему серверу. Это «определённое время» определяется значением опции fail_timeout, по умолчанию равным 10 секундам.

upstream сервера {
  server сервер№1 max_fails=3 fail_timeout=120;
  server сервер№2;
}

Резервные серверы Под понятием «резервный» в Nginx выступает сервер, который используется тогда, и только тогда, когда все «не резервные» upstream-серверы определены как нерабочие, т. е. не отвечающие на запросы. Резервные серверы отмечаются с помощью директивы backup:

upstream сервера {
  server сервер;
  server резервный-сервер backup;
}

Исключение сервера из списка обработки сайта. Если какой-то сервер по каким-то причинам вам необходимо отключить, чтобы Nginx не проксировал к нему клиентов.

upstream название-серверов {
    server айпи:порт;
#опция down выключает из цепочки сервер
    server айпи:порт down;
}

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

server {
    listen   80;
    server_name домен;
    access_log off;
 error_log off;
    location / {
	# remote HTTP server
        proxy_pass http://IP:Порт;
	proxy_redirect http://IP:Порт /;
	proxy_set_header Host $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Real-IP $remote_addr;
    proxy_connect_timeout 600;
    }
}

В этой схеме можно рассмотреть работу с кешом в Nginx. Воздаем папку для кеша и задаем размер кеша Nginx'a.

mkdir полный_адрес_до_папки

Настройка nginx.conf.

http {
...
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=all:128m;
...
}

Для работы кеша Nginx в этом примере должно быть 2 хоста. Меняем порт старого с 80 на любой другой, а на новом хосте задаем старый порт (тут будет работать кеш). Nginx кеширующий хост.

server {
        listen 80;

        location / {
                proxy_pass http://IP:порт_осн_хоста_не_кеша/;
                proxy_cache all;
                proxy_cache_valid any 1h;
        }
}

Обратный прокси. Перенаправляет данные с одного веб сервера на другой.

server {
  listen 192.168.0.1:80;
#access_log /var/log/nginx/proxy.log;
# раскомментировать для сохранения журнала
  location / {
    proxy_pass http://192.168.0.2;
  }
}

Аналогично, если передаем конкретные запросы (в примере изображения) на еще один сервер.

Любая страница в Nginx кеше будет храниться один час. Nginx создание нового хоста.

server {
# порт отличный от 80, который занял у нас кеш.
        listen 81;
...
}

Как не кешировать Cookies в Nginx?

location / {
                if ($http_cookie ~* ".+" ) {
                        set $do_not_cache 1;
                }
                proxy_cache_bypass $do_not_cache;
                proxy_pass http://IP_осн_хоста/;
                proxy_cache all;
                proxy_cache_valid any 1h;
        }

Nginx кеш для ошибок. Добавил новую строку в нашу location.

proxy_cache_valid 404 502 503 1m;

Кеш fastcgi через Nginx. В файле nginx.conf находим секцию http и добавляем строки. В примере максимальный размер кеша 100 Мб. Папку для кеша PHP создаем отдельно руками заранее.

fastcgi_cache_path /var/cache/fpm levels=1:2 keys_zone=fcgi:100m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Далее для всех рабочих страниц (ответ 200) мы ставим кеш на 60 минут.

location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        <b>fastcgi_cache fcgi;
        fastcgi_cache_valid 200 60m;</b>
    }

Хранение картинок на стороне клиента

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|pdf|ppt|txt|bmp|rtf|js)$
{
root /var/www/папка-с-сайтом/;
log_not_found off;
#выше перечисленные форматы хранятся 7 дней, после чего запрашиваются заново
expires 7d;
}

autoindex листинг каталога в nginx

#папка отображает содержимое в браузере
	location /forum/download/ {
		autoindex on;
	}

Перед запуском новой конфигурации желательно делать тест

Проверка работоспособности веб-сервера nginx

nginx -t

Результат теста:

> nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Максимальный размер загружаемого файла в nginx Пример для изменения на всех сайтах: Откройте файл

/etc/nginx/nginx.conf

добавьте следующую строчку в секцию "http"

client_max_body_size 100M;

Пример изменения размера загружаемого файла для одного домена.

server {
	listen   80;
# Здесь Ваши данные к ним мы добавим новую строку
# Добавляем новый размер для загружаемых файлов
client_max_body_size 100m;
# Ниже продолжение вашего конфига домена
}

Всех сохраняем и перезапускаем nginx. Примеры redirect nginx перенаправление страниц

   location ~* /Service2 {
            rewrite ^ http://demo.site.ru/Service2 permanent;
         }

nginx перенаправление страниц на домен

server {
	listen   80;
  rewrite ^(.*)$ http://forum.vkurske.org/index.php?board=145.0$1 permanent;
}

nginx принудительный редирект на https

server {
    server_name ...;
    rewrite ^(/somewhere/.*)$ https://$host$1 permanent;
    ...
}

nginx ограничение соединений Пример модуля лимитов. Документация.

Находим конфиг веб-сервера nginx - nginx.conf

/etc/nginx/nginx.conf
#Находит строку
http {

	##
	# Basic Settings
	##

#Добавляем ниже
limit_conn_zone $binary_remote_addr zone=addr:10m;

Редактируем конфиг сайта /etc/nginx/sites-enabled/ ваш сайт

server {
	listen   80;
# ...
# Добавляем строку

limit_conn addr 3;

# Ваш конфиг
}

Как перенаправить папку на новый домен? Для данного действия нам не требуется location, все сразу в server, смотрите пример ниже.

server {
# В примере из папки форума запросы будут направлены на новый домен
rewrite ^/forum/(.*) http://forum.vkurske.org/$1 permanent;
# Ваши правила
}

Проксирование запроса. Сервер делает запрос и возвращает сгенерированную страницу.

location /папка {
    proxy_pass http://адрес:порт;
}

Nginx запрет доступа к сайту по ip. Если Вы не хотите разрешать доступ к сайту с ip - нужно изменить хост в nginx.

Пример на Debian и Дебиан подобных дистрибутивах. В папке /etc/nginx/sites-enabled/ есть стандартный файл default, его можно отредактировать для реакции на запрос доступа к сайту по ip.

Находим строку listen 80 и добавляем к ней default. Цитировать listen 80 default; В примере при доступе к несуществующему файлу (ошибка 404) произойдет перенаправление на другую страницу. Цитировать

   error_page  404             forum.vkurske.org/...

Полный конфиг измененного файла.

server {
    listen       80 default;
    server_name  localhost;
limit_conn addr 7;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page  404             http://forum.vkurske.org/index.php?topic=1236;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

P.S. Спасибо Борису за вразумление.

Запрет доступа по IP. Разрешим доступ только через доменное имя:

if ($host !~ ^(host.com|www.host.com)$ ) {
return 444;
}

Данный кусок кода помещаем в секцию location Разрешаем только заданные методы обращения

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}

Запрет доступа к скрытым файлам. Это очень распространено, когда корень сервера или другие публичные каталоги имеют скрытые файлы, которые начинаются с точки (.) И, как правило, они не предназначены для пользователей сайта. Публичный каталог может содержать файлы системы контроля версий: .git, .svn; файлы IDE: .idea; .htaccess файлы. Настройки запещают доступ к скрытым файлам и отключают ведение логов:

location ~ /\. {
    access_log off;
    log_not_found off; 
    deny all;
}

Скрываем версию nginx. Для этого в файле nginx.conf перед client_max_body_size добавляем параметр server_tokens off;

...
keepalive_timeout  30;                                                      
send_timeout       900;
server_tokens      off;
server {
        listen       80;
	server_name     _;
...

Nginx режим перезапуска. Как добавить домен в Nginx без перезагрузки? Перезагрузка конфигурации Nginx. Изменения, сделанные в конфигурационном файле, не будут применены, пока команда перезагрузить конфигурацию не будет вручную отправлена nginx’у или он не будет перезапущен. Подробней о работе метода Для перезагрузки конфигурации Nginx:

nginx -s reload

Reload Nginx безопаснее, чем restart, потому что перед перезагрузкой старый процесс будет завершен, новый файл конфигурации обрабатывается и весь процесс прерывается, если есть какие-либо проблемы с этим.

С другой стороны, при restart Nginx вы можете столкнуться с ситуацией, в которой Nginx будет остановлен, а не запустится снова, из-за синтаксической ошибки.

Reload завершает старый процесс, так что при любой утечки памяти он должен быть очищен в любом случае. Мягкое завершение Nginx. Остановить процессы nginx с ожиданием окончания обслуживания текущих запросов рабочими процессами.

nginx -s quit

Цитировать Команда должна быть выполнена под тем же пользователем, под которым был запущен nginx. Оптимизация Nginx. Логи в Nginx. Основной лог лучше отключить для экономии дисковых операций, а лог ошибок лучше перевести в режим логирования только критических ситуаций.

access_log off;
error_log /var/log/nginx/error.log crit;

nginx поддомен в директорию сайта

server_name ~^(?.+)\.tech-g\.com$;
root /var/www_nginx/$sub;

Таким образом, когда вы добавляете каталог, к примеру, как mysite.com внутри вашего Nginx веб-каталога, посетители пришедшего к mysite.com.tech-g будут в конечном итоге видеть контент из каталога /var/www_nginx/mysite.com

Nginx кеш. Настройка http. open_file_cache - определяет максимальное количество файлов, информация о которых будет содержаться в кеше. open_file_cache_valid - определяет через какое время информация будет удалена из кеша. open_file_cache_min_uses - будет кешировать информацию о тех файлах, которые были использованы хотя бы 3 раза (в примере ниже). open_file_cache_errors - будет кешировать информацию об отсутствующих файлах.

http {
open_file_cache          max=10000 inactive=5m;
open_file_cache_valid    2m;
open_file_cache_min_uses 3;
open_file_cache_errors   on;
}

Как включить Gzip в Nginx? Обязательно нужно использовать сжатие, это значительно уменьшит трафик. В опцию нужно вписать все типы файлов, который будем сжимать. Проверить, включено ли сжатие, можно с помощью Gzip checker.

gzip on;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

Nginx время жизни соединения. Настройка. Для избежания повторного соединения клиента с сервером используем Keepalive. В примере до закрытия соединения проходит минутное ожидание, если бездействуем - соединение будет закрыто.

keepalive_timeout 60;

Максимальное количество keepalive запросов от одного клиента.

keepalive_requests 100;

Проблемы с медленными клиентами это медленная передача тела запроса от клиента к серверу и неожиданное закрытие клиентом соединений. Чтобы не плодить лишние запросы Nginx сбрасывает соединение клиентом, если тот перестал читать ответ.

reset_timedout_connection on;

Ждать 10 секунд тело запроса от клиента до сброса соединения.

client_body_timeout 10;

Клиент прекратил чтение ответа? Nginx через 2 секунды ожидания сбросит соединение.

send_timeout 2;

Nginx отдача статичный файлов. В конфиге nginx'a nginx.conf нам стоит обратить на наличие некоторый параметром в секции HTTP, по каждому из них по отдельности ниже. Как обычно работает передача файлов Системный вызов sendfile позволяет избежать излишнее копирование и обеспечить прямую передачу файла.

sendfile on;

Для Linux ОС будет полезно записать еще директиву tcp_nopush, которая благотворно влияет на sendfile через вывод данных полными пакетами. После того, как весь запрос обработан, TCP_CORK/TCP_NOPUSH выключается, что приводит в сбросу последнего неполного пакета.

tcp_nopush on;

Директива разрешает или запрещает использовать опцию TCP_NODELAY (при переходе соединения в состояние keep-alive). Перед переходом соединения в keepalive nginx выводит данные вызовами writev() достаточно большими порциями для заполнения пакета ("postpone_output 1460"), поэтому данные должны уходить без задержек и TCP_NODELAY не нужен. А вот с последним неполным пакетом может случится небольшая задержка, если соединение не закрывается. Для этого и нужно включить TCP_NODELAY:

tcp_nodelay on;

Эта опция позволяет включить прямое чтение без обращение в кеш операционной системы. Это полезно для больших файлов, поскольку операционный кеш для них малоэффективен. Опция позволяет задать минимальный размер для включения режима прямого чтения:

directio 10m;

Файлы более 10Мб Nginx будет читать с диска минуя операционный кеш.


Поскольку мы имеем дело со статическими файлами, и есть вероятность того, что один и тот же пользователь сможет несколько раз запросить один и тот же файл, следует включить клиентское кеширование. Это достигается установкой опции "expires max", которая отправит браузеру нужные заголовки:

expires max;

Nginx ограничение скорости отдачи. Это достаточно важная опция. Она позволяет ограничить скорость отдачи файлов. В том случае, если Вы отдаете потоковое видео, либо музыку, Вам следует установить ограничения на скорость отдачи. Это позволит сэкономить канал и обслужить больше клиентов:

limit_rate 196K;

Ограничиваем скорость отдачи до 196Кб/с

Эта опция работает только в рамках одного запроса, а не клиента. Если Вы хотите поставить ограничение на клиента, следует использовать переменную:

set $limit_rate 196K;

В Nginx также есть возможность установить порог отдачи, после которой ограничение войдет в силу. Также имеет смысл для потокового медиа (в этом случае первая указанная часть будет отдаваться без ограничений):

limit_rate_after 1m;

Ограничение скорости отдачи будет накладываться после 1Мб. Как настроить SSL Nginx? Установка SSL сертификата на Nginx Просмотреть весь код Если при обращении по http не проходит автоматическое перенаправление на HTTPs, то необходимо явно указать порт для SSL. Цитировать 400 Bad Request The plain HTTP request was sent to HTTPS port

listen 80;
# НЕ ТАК!
#listen 443;
ssl on;
# А ТАК
listen 443 ssl;

Как перенаправить в nginx HTTP -> HTTPs. Принудительно HTTP в HTTPs.

# force https-redirects
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
}


Проверка IP для клиента.

# Если адрес совпадает с 1.2.3.4 перенаправляем запрос
if ( $remote_addr ~* 1.2.3.4 ) {
    proxy_pass http://apachereadwrite;
}
if ( $remote_addr = 1.2.3.4 ) {
proxy_pass http://www.yourwebsite.com/otherpage.htm;
}

Перенаправление с использованием Nginx HttpAccessModule

if ($remote_addr = 1.2.3.4) {
rewrite ^ http://www.yourwebsite.com/otherpage.htm;
}

Перенапралвение с использование Nginx Geo модуля. Второй вариант мы должны сделать это с помощью модуля Nginx Geo. Этот модуль будет создавать переменные в зависимости от IP-адреса посетителя.

geo $bad_user {
default 0;
1.2.3.4/32 1;
}

server {
if ($bad_user) {
rewrite ^ http://www.yourwebsite.com/otherpage.html;
}


Заглушка для доступа по IP

vim /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name  IP_address;

    location / {
       root   /usr/share/nginx/html;
       index  index.html index.htm;
    }

И меняем index.html по своему вкусу. Теперь при заходе по IP адресу будет выдаваться эта страничка. Тоже самое делается для 443 порта. Можно сделать перенаправление на нужный сайт или выдать 404.

Настройка Apache

Будем считать, что Apache уже установлен и настроен (наш сайт работает во внутренней сети), если нет, то Вам надо на Установка и настройка Apache2

Если после настройки перенаправления посмотреть в логи Апача, то там все запросы будут идти с адреса Nginx. Чтобы это исправить, необходимо установить mod_rpaf. На данный момент последняя версия модуля libapache2-mod-rpaf в репозиториях 0.6-12. Требуемый функционал она поддерживает. На GitHub последняя версия 0.8.4, так что любители собирать из сорцов, велкам https://github.com/gnif/mod_rpaf/releases

Итак ставим:

   apt-get install install libapache2-mod-rpaf

И настраиваем его

   sudo vim /etc/apache2/mods-enabled/rpaf.conf

Должен выглядеть примерно так:

   <IfModule mod_rpaf.c>
       # Включаем модуль
     RPAFenable On
       # Приводит в порядок X-Host
     RPAFsethostname On
       # Адрес фронтенда (nginx)       
     RPAFproxy_ips 127.0.0.1 192.168.1.1
   </IfModule>

Перезагружаем Apache

   sudo service apache2 restart

На этом настройка закончена!