Настройка конфигурации nginx на хостинге. Защищай важные каталоги от посторонних. Создание виртуального сервера

Более 50% трафика во всем мире обслуживает технология связки Apache и Nginx – веб сервера, которые имеют открытый исходный код. Nginx исполняет функцию фронтэнда, Apache – бэкэнда . Nginx первым принимает запросы пользователей и выдает по ним необходимый контент – изображения, файлы, скрипты. Тяжелый Apache в свою очередь не имеет с этим дело, а обрабатывает динамику. Nginx проксирует запросы и возвращает ответы . Данная связка отлично подходит для больших сайтов, которые посещают много пользователей. Для маленьких сайтов данная связка не даст роста производительности. Apache и Nginx снижает нагрузку на сервер в общем, благодаря тому, что Nginx обрабатывает статический контент, а Apache динамический.

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

Функциональный и быстрый Nginx был выпущен в 2004 году и после этого релиза начал набирать свою популярность. Благодаря своей легкости и масштабируемости хорошо работает на любом оборудовании. Nginx используют в двух направлениях: как веб сервер или как прокси.

Что делает Nginx в качестве веб сервера?

  • автоматически создает кэш дескрипторы и списки файлов, обслуживает индексные файлы и статические запросы;
  • ускоряет отказоустойчивость, проксирование и рапределение нагрузки;
  • кэширует при FastCGI и ускоряет проксирование;
  • поддерживает SSL;
  • поддерживает Perl;
  • имеет филтры и модульность;
  • аунтифецирует HTTP и фильтрирует SSL.

В качестве прокси Nginx:

  • полное обеспечение StartTLS и SSL;
  • легкость аутентификации (USER/PASS, LOGIN);
  • использует внешний HTTP-сервер для перенаправления на POP3/IMAP-бэкенд.

Как видим, Nginx выполняет множество функций, при этом не перегружая систему. По официальным данным, технологию используют более 56 млн. сайтов во всем мире (к примеру, Rambler, Yandex, Mail, Begun, WordPress.com, vk.com, Facebook, Rutracker.org), но по популярности Nginx уступает Apache. Почему же так популярен Apache?

Веб сервер Apache – кросплатформенное программное обеспечение, которое было создано в 1995 году. Благодаря большой документации и хорошей интеграции с сторонним ПО, Apache получил огромное распространение. Поддерживает следущие ОС – Linux, BSD, Mac OS, Microsoft Windows, Novell NetWare, BeOS. .

Преимущества веб сервера Apache:

  • поддержка языков программирования PHP, Python, Ruby, Perl, ASP, Tcl ;
  • легкость в подключении внешних модулей;
  • поддержка технологий CGI и FastCGI ;
  • наличие механизмов, которые обеспечивают безопасноть и разграничение к доступу данных;
  • возможность использовать СУБД для аутентификации пользователей;
  • гибкая и надежная конфигурация системы;
  • подходит для приложений, которым нужна мощная криптографическая защита данных ;
  • возможность создания пользовательских директорий для веб-сайта;
  • возможность настройки виртуальных хостов , с помощью которых на одном физическом сервере можно создать несколько виртуальных;
  • ведет протоколы того, что происходит на вашем сервере;
  • активная обратная связь с разработчиками и своевременное решения возникших ошибок в ПО.

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

Хотите обезопасить работу PHP на сервере? Об этом более подробно .

После ознакомления с плюсами и минусами Apache и Nginx, Вы можете выбрать полезное решения для своего сайта в зависимости от целей, которые преследуете. Но возможно Вам понадобится именно связка Apache+Nginx для достижения наилучшего результата. Например, часто используют Nginx перед Apache в качестве реверс прокси. Такая комбинация позволяет обрабатывать много конкурентных запросов и сортирует их. Те запросы, которые не под силу Nginx отправляются к Apache, тем самым снижается нагрузка на последний. Отказоустойчивость в таком случае увеличивается. Перед выбором веб сервера нужно провести обязательные тесты на производительность и возможности каждого решения.

Обо всех технологиях, которые поддерживает хостинг HyperHost, более подробно по .

Данная статья была предоставлена для общего ознакомления с возможностями связки веб серверов Apache и Nginx. Еще больше информации в .

Если понадобится наша помощь, обращайтесь!

Мы будем рады ответить на все интересующие вас вопросы по настройке веб серверов. Также у нас Вы всегда можете с бесплатным администрированием. Вся ли техническая поддержка хостеров одинакова? Об особенностях бесплатного и платного администрирования в специальной .

17249 раз(а) 10 Сегодня просмотрено раз(а)

14 августа 2009 в 19:29

Настройка nginx

  • Nginx

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

Неплохой начальной точкой для настройки nginx является конфиг, который идёт в комплекте с дистрибутивом, но очень многие возможности этого сервера в нём даже не упоминаются. Значительно более подробный пример есть на сайте Игоря Сысоева: sysoev.ru/nginx/docs/example.html . Однако, давайте лучше попробуем собрать с нуля свой конфиг, с бриджем и поэтессами. :)

Начнём с общих настроек. Сначала укажем пользователя, от имени которого будет работать nginx (от рута работать плохо, все знают:))

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

Worker_processes 2;

Уточним, куда писать логи ошибок. Потом, для отдельных виртуальных серверов, этот параметр можно переопределить, так что в этот лог будут сыпаться только «глобальные» ошибки, например, связанные со стартом сервера.

Error_log /spool/logs/nginx/nginx.error_log notice; # уровень уведомлений "notice", конечно, можно менять

Теперь идёт очень интересная секция «events». В ней можно задать максимальное количество соединений, которые одновременно будет обрабатывать один процесс-воркер, и метод, который будет использоваться для получения асинхронных уведомлений о событиях в ОС. Конечно же, можно выбрать только те методы, которые доступны на вашей ОС и были включены при компиляции.

Эти параметры могут оказать значительное влияние на производительность вашего сервера. Их надо подбирать индивидуально, в зависимости от ОС и железа. Я могу привести только несколько общих правил.

Модули работы с событиями:
- select и poll обычно медленнее и довольно сильно нагружают процессор, зато доступны практически везде, и работают практически всегда;
- kqueue и epoll - более эффективны, но доступны только во FreeBSD и Linux 2.6, соответственно;
- rtsig - довольно эффективный метод, и поддерживается даже очень старыми линуксами, но может вызывать проблемы при большом числе подключений;
- /dev/poll - насколько мне известно, работает в несколько более экзотических системах, типа соляриса, и в нём довольно эффективен;

Параметр worker_connections:
- Общее максимальное количество обслуживаемых клиентов будет равно worker_processes * worker_connections;
- Иногда могут сработать в положительную сторону даже самые экстремальные значения, вроде 128 процессов, по 128 коннектов на процесс, или 1 процесса, но с параметром worker_connections=16384. В последнем случае, впрочем, скорее всего понадобится тюнить ОС.

Events {
worker_connections 2048;
use kqueue; # У нас BSD:)
}

Следующая секция - самая большая, и содержит самое интересное. Это описание виртуальных серверов, и некоторых параметров, общих для них всех. Я опущу стандартные настройки, которые есть в каждом конфиге, типа путей к логам.

Http {
# Весь код ниже будет внутри этой секции %)
# ...
}

Внутри этой секции могут находиться несколько довольно интересных параметров.

Системный вызов sendfile появился в Linux относительно недавно. Он позволяет отправить данные в сеть, минуя этап их копирования в адресное пространство приложения. Во многих случаях это существенно повышает производительность сервера, так что параметр sendfile лучше всегда включать.

Параметр keepalive_timeout отвечает за максимальное время поддержания keepalive-соединения, в случае, если пользователь по нему ничего не запрашивает. Обдумайте, как именно на вашем сайте посылаются запросы, и исправьте этот параметр. Для сайтов, активно использующих AJAX, соединение лучше держать подольше, для статических страничек, которые пользователи будут долго читать, соединение лучше разрывать пораньше. Учтите, что поддерживая неактивное keepalive-соединение, вы занимаете коннекшн, который мог бы использоваться по-другому. :)

Keepalive_timeout 15;

Отдельно стоит выделить настройки проксирования nginx. Чаще всего, nginx используется именно как сервер-прокси, соответственно они имеют довольно большое значение. В частности, размер буфера для проксируемых запросов имеет смысл устанавливать не менее, чем ожидаемый размер ответа от сервера-бэкенда. При медленных (или, наоборот, очень быстрых) бэкендах, имеет смысл изменить таймауты ожидания ответа от бэкенда. Помните, чем больше эти таймауты, тем дольше будут ждать ответа ваши пользователе, при тормозах бэкенда.

Proxy_buffers 8 64k;
proxy_intercept_errors on;
proxy_connect_timeout 1s;
proxy_read_timeout 3s;
proxy_send_timeout 3s;

Небольшой трюк. В случае, если nginx обслуживает более чем один виртуальный хост, имеет смысл создать «виртуальный хост по-умолчанию», который будет обрабатывать запросы в тех случаях, когда сервер не сможет найти другой альтернативы по заголовку Host в запросе клиента.

# default virtual host
server {
listen 80 default;
server_name localhost;
deny all;
}

Далее может следовать одна (или несколько) секций «server». В каждой из них описывается виртуальный хост (чаще всего, name-based). Для владельцев множества сайтов на одном хостинге, или для хостеров здесь может быть что-то, типа директивы

Include /spool/users/nginx/*.conf;

Остальные, скорее всего опишут свой виртуальный хост прямо в основном конфиге.

Server {
listen 80;

# Обратите внимание, в директиве server_name можно указать несколько имён одновременно.
server_name myserver.ru myserver.com;
access_log /spool/logs/nginx/myserver.access_log timed;
error_log /spool/logs/nginx/myserver.error_log warn;
# ...

Установим кодировку для отдачи по-умолчанию.

Charset utf-8;

И скажем, что мы не хотим принимать от клиентов запросы, длиной более чем 1 мегабайт.

Client_max_body_size 1m;

Включим для сервера SSI и попросим для SSI-переменных резервировать не более 1 килобайта.

Ssi on;
ssi_value_length 1024;

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

Здравствуй, уважаемый пользователь Хабрахабра. Мое повествование будет о том, как подготовить почву для локальной веб-разработки проектов в операционной системе Ubuntu 16.04.1 LTS.

В данной статье хочется развеять и разъяснить возможные трудности связанные с установкой и настройкой ПО, которое требуется для современной веб-разработки, с которыми возможно сталкиваются начинающие разработчики и не только.

Технологии которые будут использованы в статье: nginx, php-fpm.

Перед началом повествования, хочу отметить, что я проделывал все эти действия на «голой» системе.
Я буду работать с пакетным менеджером aptitude. Так же рекомендую обновить индекс пакетов и сами пакеты перед установкой ПО. В статье мы проделаем эти действия вместе.

Поехали!

Установка пакетного менеджера aptitude , обновление индекса и пакетов

Устанавливаем:

Sudo apt install aptitude
Обновляем индекс.

Sudo aptitude update
Обновляем пакеты (команда обновит все пакеты, для которых есть новые версии, если потребуется удаление пакетов, то оно будет выполнено).

Sudo aptitude full-upgrade

Установка и настройка nginx (версия >= 1.10.0)

Устанавливаем.

Sudo aptitude install nginx
Запускаем.

Sudo service nginx start
Проверяем версию, чтобы убедиться что не установили старую, то есть ниже 1.10.0.

Установку и запуск произвели, теперь пойдем в каталог туда куда установлен наш nginx и посмотрим на его структуру. Каталог nginx находится по такому пути:

Cd /etc/nginx/
Посмотреть содержимое директории можно командой ls, с флагами -la будет удобнее просматривать содержимое каталога (в действительности эту команду с конкретными флагами можно описать детальнее и вернее, но у нас сегодня другая тема).

Ls -la
Наc интересуют в данный момент два каталога, которые вы видите на скриншоте. Это каталоги sites-available и sites-enabled.

Давайте перейдем в каталог sites-available и начнем конфигурировать наш виртуальный хост (сайт).

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

Важное отступление

В случае установки nginx «с нуля», именно «с нуля», так как при удалении nginx командой
sudo apt-get remove nginx или sudo apt remove nginx конфигурационные файлы остаются и если вы вдруг будете не понимать, почему nginx не работает и захотите его переустановить (обычно к такому прибегают начинающие пользователи Linux), то и после переустановки он не будет корректно работать, из-за того что в старых конфигурационных файлах (они не удаляются после удаления командой remove) прописаны неверные настройки, их придется удалить, либо настроить верно, только тогда nginx заработает.

Рекомендую удалять командой sudo apt-get purge nginx или sudo apt purge nginx . Если вы используете пакетный менеджер aptitude, то команда sudo aptitude purge nginx удаляет пакет полностью со всеми зависимостями и конфигурационными файлами.


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

Ls -la

Создадим свой конфигурационный файл, который будет соответствовать названию домена нашего локального сайта (или реального, если уже знаете его название). Это удобно, в будущем, когда будет много конфигурационных файлов, то это избавит вас от путаницы в них. У меня этот файл будет называться project.local.

Sudo touch project.local
Посмотрим что получилось.

Теперь откроем его в редакторе, я открою его в nano.

Sudo nano project.local
Видим что он у нас пустой. Теперь перейдем к формированию нашего файла. Нужно привести конфигурацию к такому виду, как написано ниже. Я опишу только жизненно важные директивы этого файла, описывать остальное не буду, так как это не является на данный момент важным, все-таки у нас тема базовой настройки. Этих настроек с «горкой» хватит для разработки проектов локально, не только мелких, но и довольно крупных. В следующих статьях опишу отдельно каждые использованные директивы (именно так называются строки, например server_name) этого файла.

Смотрите комментарии прям в конфигурационном файле.

Server { listen 80; # порт, прослушивающий nginx server_name project.local; # доменное имя, относящиеся к текущему виртуальному хосту root /home/stavanger/code/project.local; # каталог в котором лежит проект, путь к точке входа index index.php; # add_header Access-Control-Allow-Origin *; # serve static files directly location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { access_log off; expires max; log_not_found off; } location / { # add_header Access-Control-Allow-Origin *; try_files $uri $uri/ /index.php?$query_string; } location ~* \.php$ { try_files $uri = 404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; # подключаем сокет php-fpm fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.ht { deny all; } }
Сохраняем файл. Теперь нам надо проверить, нет ли в нем ошибок. Сделать мы это можем командой.

Sudo nginx -t
Если видим такую информацию как на скриншоте, значит у нас все верно, может продолжать настройку. Если вы получаете какие-либо ошибки, стоит перепроверить конфигурационный файл.

Теперь нам надо активировать конфигурационный файл, в каталоге /etc/nginx/sites-enabled/ необходимо создать симлинк (символическая ссылка). Если у вас nginx был установлен «с нуля», то в этом каталоге есть симлинк на файл default, про который рассказывалось выше, его можно удалить, если он вам не требуется. Переходим в нужный каталог.

Cd /etc/nginx/sites-enabled/
Теперь мы в нужном каталоге. Давайте создадим наш симлинк. Для создания используется команда ln с флагом -s, далее мы укажем путь до нашего конфига project.local.

Sudo ln -s /etc/nginx/sites-available/project.local
Посмотрим на наш созданный симлинк.

Чтобы убедиться что мы делаем еще все верно опять запустим команду.

Файл hosts

Этот файл находится по пути /etc/hosts. Наличие в нем записей, позволяет запускать nginx с использованием в качестве домена localhost. В этом файле можно присваивать альтернативные псевдонимы, например для нашего проекта project.local, мы присвоим домен project.local.

Открываем файл в редакторе nano.

Sudo nano /etc/hosts
У вас в этом файле будет и другая информация, просто игнорируйте ее. Вам всего лишь нужно добавить строку как на моем скриншоте.

Установка php-fpm (>=7.0)

sudo aptitude install php-fpm
Проверяем установленную версию, на всякий случай, хотя в Ubuntu 16.04.1 в репозиториях лежит именно 7.0 версия.

Php-fpm7.0 -v

Убеждаемся что все ок. Стартуем php-fpm.

Sudo service php7.0-fpm start
Если будете править конфиги, то не забывайте рестартовать демон. Это делает так. Но нам это не потребуется.

Sudo service php7.0-fpm restart
На этом установка и настройка php-fpm закончена. Правда, это все. Это не магия, путь до сокета php-fpm у нас уже был прописан в конфигурационном файле. Конечно, вам могут понадобиться какие-либо расширения php для разработки личных проектов, но их вы можете поставить по мере того как они будут требоваться.

Теперь пойдем для в каталог с нашим проектом, у меня он лежит по такому пути.

Cd /home/stavanger/code/project.local
Поднимемся на каталог выше и сделаем права 777 (то есть мы будем делать полные права каталогу с нашим проектом project.local). В будущем это избавим нас от лишних проблем.

Cd .. sudo chmod -R 777 project.local
На этом настройка ПО завершена, давайте создадим тестовый файл в нашем рабочем каталоге project.local и убедимся что все работает. Я создам файл index.php с таким содержанием.

Идем в браузер и видим что у нас все прекрасно работает! Интерпретатор php в том числе.

С уважением к читателям, Stavanger.

Выделенный Web-сервер на основе nginx – отличный способ повышения производительности Web-сайтов. В скорости обработки статического контента ему просто нет равных: он легко выдерживает несколько тысяч одновременных соединений и может быть легко оптимизирован и подогнан под любую конфигурацию. Однако? выступая в качестве фронт-энда для Apache, nginx оказывается наиболее уязвимым местом всей Web-инфраструктуры, поэтому безопасности nginx необходимо уделить особое внимание.

Эта статья – своего рода ликбез, или, если хочешь, резюме всех техник повышения безопасности nginx. В ней не будет теории, описания основ настройки Web-сервера и прочей воды. Вместо этого ты получишь исчерпывающий практический материал, описывающий все основные шаги, которые необходимо проделать для того, чтобы получить по-настоящему защищенный Web-сервер.

Установка

Пакет nginx доступен в прекомпилированном виде для любого дистрибутива. Однако собрав сервер самостоятельно, ты сможешь сделать его более компактным и надежным, а также получишь возможность изменить строку приветствия Web-сервера, чтобы отбить несмышленых скрипт-кидди.

Измени строку приветствия Web-сервера

Скачай исходники nginx, открой файл src/http/ngx_http_header_filter_module.c и найди следующие две строки:

static char ngx_http_server_string = "Server: nginx" CRLF;
static char ngx_http_server_full_string = "Server: " NGINX_VER CRLF;

Замени их на что-то вроде этого:

static char ngx_http_server_string = "Server: ][ Web Server" CRLF;
static char ngx_http_server_full_string = "Server: ][ Web Server" CRLF;

Удали все неиспользуемые тобой nginx-модули

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

Выполни сборку с помощью следующих команд:

# ./configure --without-http_autoindex_module --without-http_ssi_module
# make
# make install

Так ты получишь nginx с заранее отключенными (и в большинстве случаев бесполезными) модулями SSI (Server Side Includes) и Autoindex. Чтобы узнать, какие модули можно безболезненно выбросить из Web-сервера, запусти скрипт configure с флагом ‘-help’.

Препарируем nginx.conf

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

Отключи показ версии сервера на всех ошибочных страницах

Добавь в файл nginx.conf строку “server_tokens off”. Это заставит nginx скрывать информацию о типе и версии Web-сервера на страницах, генерируемых в ответ на ошибочный запрос клиента.

Настрой защиту от срыва стека

Добавь в секцию server следующие строки:

# vi /etc/nginx/nginx.conf

# Максимальный размер буфера для хранения тела запроса клиента
client_body_buffer_size 1K;
# Максимальный размер буфера для хранения заголовков запроса клиента
client_header_buffer_size 1k;
# Максимальный размер тела запроса клиента, прописанный в поле Content-Length заголовка. Если сервер должен поддерживать загрузку файлов, это значение необходимо увеличить
client_max_body_size 1k;
# Количество и размер буферов для чтения большого заголовка запроса клиента
large_client_header_buffers 2 1k;

Обрати внимание на директиву large_client_header_buffers. По умолчанию, для хранения строки URI nginx выделяет четыре буфера, размер каждого из которых равен размеру страницы памяти (для x86 это 4 Кб). Буферы освобождаются каждый раз, когда по окончанию обработки запроса соединение переходит в состояние keep-alive. Два буфера по 1 Кб могут хранить URI длиной только 2 Кб, что позволяет бороться с ботами и DoS-атаками.

Для повышения производительности добавь следующие строки:

# vi /etc/nginx/nginx.conf

# Таймаут при чтении тела запроса клиента
client_body_timeout 10;
# Таймаут при чтении заголовка запроса клиента
client_header_timeout 10;
# Таймаут, по истечению которого keep-alive соединение с клиентом не будет закрыто со стороны сервера
keepalive_timeout 5 5;
# Таймаут при передаче ответа клиенту
send_timeout 10;

Контролируй количество одновременных соединений

Для защиты Web-сервера от перегрузки и попыток осуществить DoS-атаку добавь в конфиг следующие строки:

# vi /etc/nginx/nginx.conf

# Описываем зону (slimits), в которой будут храниться состояния сессий. Зона размером 1 Мб может хранить около 32000 состояний, мы устанавливаем ее размер равным 5 Мб
limit_zone slimits $binary_remote_addr 5m;
# Задаем максимальное количество одновременных соединений для одной сессии. По сути, это число задает максимальное количество соединений с одного IP
limit_conn slimits 5;

Первая директива должна находиться в секции HTTP, вторая – в секции location. Когда количество соединений выйдет за пределы лимитов, клиент получит сообщение «Service unavailable» с кодом 503.

Разреши коннекты только к своему домену

Взломщики могут использовать ботов для сканирования подсетей и поиска уязвимых Web-серверов. Обычно боты просто перебирают диапазоны IP-адресов в поисках открытых 80 портов и посылают запрос HEAD для получения информации о веб-сервере (или главной странице). Ты можешь легко предотвратить такой скан, запретив обращение к серверу по IP-адресу (добавить в подсекцию location):

# vi /etc/nginx/nginx.conf

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

Ограничь количество доступных методов обращения к Web-серверу

Некоторые боты используют различные методы обращения к серверу для попытки определения его типа и/или проникновения, однако в документе RFC 2616 четко сказано, что Web-сервер не обязан реализовывать их все, и неподдерживаемые методы могут просто не обрабатываться. Сегодня используемыми остаются только методы GET (запрос документа), HEAD (запрос заголовков сервера) и POST (запрос на публикацию документа), поэтому все остальные можно безболезненно отключить с помощью помещения следующих строк в секцию server конфигурационного файла:

# vi /etc/nginx/nginx.conf

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

Отшивай ботов

Другой способ блокирования ботов, сканеров и прочей нечисти основан на определении типа клиента (user-agent). Он не слишком эффективен, потому как большинство ботов косят под вполне легитимные браузеры, но в ряде случаев остается полезным:

# vi /etc/nginx/nginx.conf

# Блокируем менеджеры загрузки
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;
}
# Блокируем некоторые типы ботов
if ($http_user_agent ~* msnbot|scrapbot) {
return 403;
}

Блокируй Referrer-спам

Если твой сайт публикует Web-логи в общедоступном виде, ты легко можешь стать жертвой Referrer-спама (когда спам-боты обращаются к твоему серверу, указывая в заголовке referrer – адрес рекламируемого сайта). Такой вид спама может легко испортить SEO-рейтинги интернет-страницы, поэтому его необходимо блокировать в обязательном порядке. Один из способов сделать это – занести наиболее частые слова, встречающиеся в адресах рекламируемых сайтов, в черный список.

# vi /etc/nginx/nginx.conf

# Секция server
if ($http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen))
{
return 403;
}

Блокируй хотлинк

Хотлинк – это включение в страницу изображения (или иного контента) с другого сайта. По сути, это воровство, потому как изображение, на которое ты потратил не один час своего свободного времени, не только свободно используется другими, но и создает нагрузку на твой Web-сервер, не приводя на него посетителей. Для борьбы с хотлинками достаточно сделать так, чтобы изображения отдавались клиенту только в том случае, если он запросил их, уже находясь на сайте (другими словами, заголовок referrer-запроса должен содержать имя твоего сайта). Добавь в секцию server конфигурационного файла nginx.conf следующие строки (host.com – это адрес твоего сайта):

# vi /etc/nginx/nginx.conf

location /images/ {
valid_referers none blocked www.host.com host.com;
if ($invalid_referer) {
return 403;
}
}

В качестве альтернативы ты можешь настроить сервер на отдачу специального баннера с сообщением о воровстве вместо запрашиваемого изображения. Для этого замени строку «return 403» на строку:

rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.host.com/banned.jpg last

Защищай важные каталоги от посторонних

Как и любой другой Web-сервер, nginx позволяет регулировать доступ к каталогам на основе IP-адресов и паролей. Эту возможность можно использовать для закрытия некоторых частей сайта от посторонних глаз. Например, для отрезания URI от внешнего мира:

# vi /etc/nginx/nginx.conf

location /uploads/ {
# Разрешаем доступ только машинам локальной сети
allow 192.168.1.0/24;
# Отшиваем всех остальных
deny all;
}

Теперь к документам каталога uploads будут иметь доступ только пользователи локальной сети. Для установки пароля придется проделать более сложные действия. Сначала необходимо создать приватный для nginx-файл паролей и добавить в него необходимых пользователей (в качестве примера добавим пользователя admin):

# mkdir /etc/nginx/.htpasswd
# htpasswd -c /etc/nginx/.htpasswd/passwd admin

# vi /etc/nginx/nginx.conf

location /admin/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd/passwd;
}

Новых пользователей можно добавить с помощью следующей команды:

# htpasswd -s /etc/nginx/.htpasswd/passwd пользователь

Используй SSL

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

Для настройки SSL-шифрования средствами nginx достаточно выполнить несколько простых шагов. Сначала ты должен создать сертификат с помощью следующей последовательности команд:

# cd /etc/nginx
# openssl genrsa -des3 -out server.key 1024
# openssl req -new -key server.key -out server.csr
# cp server.key server.key.org
# openssl rsa -in server.key.org -out server.key
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Затем описать сертификат в конфигурационном файле nginx:

# vi /etc/nginx/nginx.conf

server {
server_name host.com;
listen 443;
ssl on;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
access_log /etc/nginx/logs/ssl.access.log;
error_log /etc/nginx/logs/ssl.error.log;
}

После этого можно перезагрузить Web-сервер:

# /etc/init.d/nginx reload

Естественно, без поддержки со стороны самого Web-сайта это делать бессмысленно.

Другие способы

Установи правильные значения системных переменных

Открой файл /etc/sysctl.conf и помести в него следующие строки:

# vi /etc/sysctl.conf

# Защита от smurf-атак
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Защита от неправильных ICMP-сообщений
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Защита от SYN-флуда
net.ipv4.tcp_syncookies = 1
# Запрещаем маршрутизацию от источника
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Защита от спуфинга
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Мы не маршрутизатор
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Включаем ExecShield
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# Расширяем диапазон доступных портов
net.ipv4.ip_local_port_range = 2000 65000
# Увеличиваем максимальный размер TCP-буферов
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1

Размести корневой каталог Web-сервера на выделенном разделе

Поместив корневой каталог Web-сервера в выделенный раздел и запретив на нем размещение любых исполняемых файлов и файлов-устройств, ты обезопасишь остальную часть системы от тех, кто сможет получить доступ к корню Web-сервера. При этом запись в файле /etc/fstab должна иметь примерно такой вид:

/dev/sda5 /nginx ext4 defaults,nosuid,noexec,nodev 1 2

Помести nginx в chroot/jail-окружение

Любая современная *nix-система позволяет запереть приложение в изолированной среде исполнения. В Linux для этого можно использовать технологии KVM, Xen, OpenVZ и VServer, во FreeBSD – Jail, в Solaris – Zones. Если ни одна из этих технологий не доступна, ты можешь поместить nginx в классический chroot, который хоть и намного более хрупок, но большинство взломщиков остановить сможет.

Установи правила SELinux для защиты nginx

Хорошей альтернативой изолированным средам исполнения являются локальные системы обнаружения и предотвращения вторжений, такие как SELinux или AppArmor. Будучи правильно настроенными, они смогут предотвратить попытки взлома Web-сервера. По дефолту ни одна из них не настроена для работы в связке с nginx, однако в рамках проекта SELinuxNginx (http://sf.net/projects/selinuxnginx/) были созданы правила для SELinux, которые может использовать любой желающий. Остается только скачать и установить:

# tar -zxvf se-ngix_1_0_10.tar.gz
# cd se-ngix_1_0_10/nginx
# make
# /usr/sbin/semodule -i nginx.pp

Настрой брандмауэр

Обычно nginx устанавливают на выделенных машинах, готовых к высокой нагрузке, поэтому зачастую он остается единственным сетевым сервисом, работающим на сервере. Чтобы обезопасить сервер, достаточно создать совсем небольшой набор правил, которые будут открывать 80, 110 и 143-й порты (если, конечно, nginx должен работать еще и как IMAP/POP3-прокси) и закрывать от внешнего мира все остальное.

Ограничь количество соединений с помощью брандмауэра

Для не слишком нагруженного Web-сайта хорошей идеей будет ограничить количество попыток соединений с одного IP-адреса в минуту. Это сможет уберечь тебя от некоторых типов DoS-атак и брутфорса. В Linux это можно сделать с помощью стандартного iptables/netfilter-модуля state:

# iptables -A INPUT -p tcp --dport 80 -i eth0 \
-m state --state NEW -m recent --set
# iptables -A INPUT -p tcp --dport 80 -i eth0 \
-m state --state NEW -m recent --update \
--seconds 60 --hitcount 15 -j DROP

Правила урезают лимит на количество подключений с одного IP в минуту до 15. То же можно сделать и с помощью pf:

# vi /etc/pf.conf

webserver_ip="1.1.1.1"
table persist
block in quick from
pass in on $ext_if proto tcp to $webserver_ip \
port www flags S/SA keep state \
(max-src-conn 100, max-src-conn-rate 15/60, \
overload flush)

Кроме лимита на количество последовательных подключений (15 в минуту), данное правило устанавливает дополнительный лимит на количество одновременных подключений равный 100.

Настрой PHP

Если ты используешь nginx в связке с PHP, не забудь настроить и его. Вот как должен выглядеть конфигурационный файл /etc/php/php.ini защищенного сервера:

# vi /etc/php/php.ini

# Отключаем опасные функции
disable_functions = phpinfo, system, mail, exec
# Максимальное время исполнения скрипта
max_execution_time = 30
# Максимальное время, которое может потратить скрипт на обработку данных запроса
max_input_time = 60
# Максимальное количество памяти, выделяемое каждому скрипту
memory_limit = 8M
# Максимальный размер данных, отсылаемых скрипту с помощью метода POST
post_max_size = 8M
# Максимальный размер загружаемых файлов
upload_max_filesize = 2M
# Не показывать ошибки PHP-скриптов пользователям
display_errors = Off
# Включаем Safe Mode
safe_mode = On
# Включаем SQL Safe Mode
sql.safe_mode = On
# Позволяем выполнять внешние команды только в этом каталоге
safe_mode_exec_dir = /путь/к/защищенному/каталогу
# Защищаемся от утечки информации о PHP
expose_php = Off
# Ведем логи
log_errors = On
# Запрещаем открытие удаленных файлов
allow_url_fopen = Off

Выводы

Применив описанные в статье рекомендации, ты получишь гораздо более защищенный Web-сервер. Но имей в виду, что не все техники подойдут к твоей конфигурации. Например, защита от брутфорса, основанная на урезании размеров буферов, выделяемых nginx под обработку запросов клиентов, может привести к падению производительности, а в некоторых случаях и к сбоям в обработке запросов. Ограничение на количество подключений нанесет сильный удар по производительности даже средненагруженного Web-сайта, но принесет пользу, если страница имеет низкий поток посетителей. Всегда проверяй, как внесенные тобой изменения повлияли на производительность и общую работоспособность Web-страницы.

О герое дня

Nginx – один самых производительных и популярных Web-серверов в мире. Согласно данным Netcraft, он используется для поддержки более чем 12 миллионов Web-сайтов по всему миру, включая таких мастодонтов как Rambler, Yandex, Begun, WordPress.com , Wrike, vkontakte.ru , megashara.com , Либрусек и Taba.ru. Грамотная архитектура, основанная на мультиплексировании соединений с помощью системных вызовов select, epoll (Linux), kqueue (FreeBSD) и механизме управления памятью на основе пулов (небольших буферов от 1 до 16 Кб), позволяет nginx не проседать даже под очень высокими нагрузками, выдерживая свыше 10000 одновременных соединений (так называемая проблема C10K). Изначально написан Игорем Сысоевым для компании Rambler и открыт в 2004 году под BSD-подобной лицензией.

Вконтакте

На данный момент самую большую популярность набрали два веб-сервера. Это Apache и Ngnix. У каждого из них есть свои плюсы и минусы. Apache был разработан еще в 1995 году и при его разработке учитывались не все возможные потребности пользователей, он потребляет много памяти и ресурсов системы, зато он прост в настройке. Nginx был разработан чуть позже в 2002 году уже учитывая ошибки Apache и ориентируясь на максимальную производительность.

Мы не будем подробно вникать в плюсы и минусы этих обоих веб-серверов. У каждого из них своя область применения. В этой инструкции будет рассмотрена установка Nginx Ubuntu 16.04. Хотя я буду говорить об Ubuntu 16.04, все действия подойдут и для других дистрибутивов. Настройка Nginx везде одинакова, только команда установки отличается.

Первым делом нужно установить сам веб-сервер в систему. Программа есть в официальных репозиториях, но ее версия уже немного устарела, поэтому если хотите самую новую версию, нужно добавить PPA:

sudo apt-add-repository ppa:nginx/stable

Сейчас в официальных репозиториях доступна версия 1.10.0, а в стабильной PPA уже доступна 1.10.1. Если для вас версия не нужна можно обойтись и без PPA. Дальше обновите списки пакетов из репозиториев:

И устанавливаем ngnix:

sudo apt install nginx

После того как установка сервера Nginx будет завершена добавим программу в автозагрузку, чтобы она запускалась автоматически:

sudo systemctl enable nginx

Если вы уже сейчас откроете браузер, то увидите работающий nginx, но нам предстоит его еще настроить.

Настройка Nginx Ubuntu

Настройка Nginx Ubuntu намного сложнее чем Apache. Здесь мы не будем рассматривать все опции и возможности программы, а поговорим только об основном. Есть различные конфигурации, в которых Nginx используется в качестве прокси сервера, а основной сервер Apache, но нас это интересовать не будет. Нам нужна установка Nginx как самостоятельного веб-сервера.

Настройки Nginx сильно отличаются здесь есть только один основной файл конфигурации и файлы для виртуальных хостов. Настройка из каждой директории, как в Apache не поддерживается.

  • /etc/nginx/nginx.conf - главный файл конфигурации
  • /etc/nginx/sites-available/* - файлы конфигурации для виртуальных хостов, проще говоря для каждого сайта.
  • /etc/nginx/sites-enabled/* - файлы конфигурации активированных сайтов.

На самом деле файлы конфигурации для виртуальных хостов читаются только из директории sites-enabled, но здесь содержаться ссылки на sites-available. Такая система была придумана, чтобы дать возможность отключать на время те или иные сайты, не стирая их конфигурацию. Все остальные файлы содержат только объявления переменных и стандартные настройки, которые изменять не нужно. Что же касается nginx.conf, то в него включаются все файлы из sites-enables, а поэтому они могут содержать все точно такие же инструкции. А теперь давайте рассмотрим главный файл конфигурации:

sudo vi /etc/nginx/nginx.conf

Как видите файл разделен на секции. Общая структура такова:

глобальные опции
events {}
http{
server {
location{}
}
server {}
}
mail {}

  • глобальные опции отвечают за работу всей программы.
  • events - эта секция содержит настройки для работы с сетью.
  • http - содержит настройки веб-сервера. Должна содержать секцию servier для тонкой настройки каждого сайта.
  • server - в этой секции содержится настройка каждого размещенного на веб-сервере сайта.
  • location - секция location может находиться только внутри секции server и содержит настройки только для определенного запроса.
  • mail - содержит настройки почтового прокси.

Перед тем как перейти к опциям, нужно сказать еще пару слов о синтаксисе строки в конфигурационном файле. Он выглядит вот так:

параметр значение дополнительное_значение... ;

Строка должна обязательно заканчиваться ";", а все открытые скобки { должны быть закрыты.

Теперь, когда вы немного изучили глобальную структуру, можно переходить к рассмотрению самих параметров. Глобальных опций не так уж много:

  • user - пользователь, от имени которого будет работать программа.
  • worker_processes - устанавливает сколько процессов нужно запускать для параллелизации работы программы, нужно запускать не больше процессов, чем у вас есть ядер. Можно установить параметр auto и тогда программа определит это число сама.
  • pid = файл pid программы.
  • worker_rlimit_nofile - указывает максимальное количество файлов, которые может открыть программа. Рассчитывается как worker_processes * worker_connections* 2.

С глобальными опциями закончили, их было не так много и они не такие интереснее. Куда интереснее в плане оптимизации опции с секции events:

  • worker_connections - количество соединений, которые программа может обрабатывать одновременно на одном процессе. Если умножить worker_process на этот параметр, то мы получим максимальное количество пользователей, которые могут подключиться к серверу одновременно. Рекомендуется устанавливать значение от 1024 до 4048.
  • multi_accept - разрешить принимать много подключений одновременно, установите параметр on или off.
  • use - способ работы с сетевым стеком. По умолчанию используется poll, но для Linux эффективнее использовать epoll.
  • sendfile - использовать метод отправки данных sendfile. Значение on.
  • tcp_nodelay, tcp_nopush - отправлять заголовки и начало файла одним пакетом. Значение on.
  • keepalive_timeout - таймаут ожидания, перед тем как keepalive соединение будет разорвано, по умолчанию 65, но можно уменьшить до 10 секунд.
  • keepalive_requests - максимальное количество keepalive соединений от одного клиента, рекомендовано 100.
  • reset_timedout_connection - разрывать соединения после таймаута. Значение on.
  • open_file_cache - кэшировать информацию об открытых файлах. Строчка настройки выглядит вот так: open_file_cache max=200000 inactive=20s; max - максимальное количество файлов в кэше, время кэширования.
  • open_file_cache_valid - указывает по истечении какого времени нужно удалить информацию из кэша. Например: open_file_cache_valid 30s;
  • open_file_cache_min_uses - кэшировать информацию о файлах, которые были открыты как минимум указанное количество раз.
  • open_file_cache_errors - кэшировать информацию об отсутствующих файлах, значение on.

Основные параметры рассмотрели. Эти настройки помогут вам получить большую производительность от nginx. Секцию server и location мы рассмотрим в настройке виртуальных хостов.

Настройка сжатия Gzip

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

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

  • gzip_min_length - минимальная длина страницы в байтах, при которой нужно использовать сжатие, например, 1000 (1 кб)
  • gzip_proxied - нужно ли сжимать проксированые запросы, any говорит, что нужно сжимать все.
  • gzip_types - типы файлов, которые нужно сжимать, например: text/plain application/xml application/x-javascript text/javascript text/css text/json;
  • gzip_disable "msie6" - в IE 6 сжатие не поддерживается, поэтому отключаем.
  • gzip_comp_level - уровень сжатия, доступны варианты от 1 до 10. 1 - минимальное, 10 - максимальное сжатие.

Настройка виртуальных хостов

Как вы знаете, на сервере может размещаться несколько сайтов. Все запросы приходят на ip сервера, а nginx уже определяет на основе домена какой контент нужно выдать. Для того чтобы nginx знал что к какому домену относится нужно настроить виртуальные хосты. Каждый хост принято размещать в отдельном файле. Настройка хоста находится в секции server, но поскольку все файлы из sites-enabled импортируются в секцию http, то логика структуры конфигурационного файла не нарушается.

Рассмотрим пример настройки:

vi /etc/nginx/sites-enabled/сайт.conf

  • listen 80 - указывает, что нужно ожидать подключения на порту 80, может также содержать опцию default-server , которая означает, что этот домен будет открывается если домен не был задан в запросе.
  • root /var/www/html - директория, в которой находятся файлы сайта.
  • index index.html - страница, которая будет открываться по умолчанию.
  • server_name - доменное имя сайта.
  • access_log - файл для записи лога запросов к серверу, может использоваться как глобально в секции http, так и для определенного типа файлов в location.
  • error_log - лог ошибок веб-сервера, может принимать дополнительный параметр, указывающий подробность лога. warn - максимум, crit - только критические ошибки.

Это все основные настройки виртуального хоста, после них он уже будет работать. Но тут есть еще секция location, которая позволяет настроить поведение сервера для определенных директорий и файлов. Синтаксис location такой:

location адрес {}

В качестве адреса может использоваться как прямой запрос относительно корня сервера, так и регулярные выражения. Для использования регулярных выражений перед ним ставится символ "~". Примеры рассмотрим ниже, а пока рассмотрим возможные директивы:

  • allow - разрешить доступ к местоположению для пользователей, all - всех, также можно указать ip или подсеть.
  • deny - запретить доступ к местоположению, all - для всех.
  • try-files - пытается открыть файлы в определенном порядке, открывает первый обнаруженный файл. Например, такая конструкция: $uri $uri/index.html $uri.html =404; сначала пытается открыть $uri, затем index.html, если не найден $uri.html, и аж потом, если ни одного из предложных файлов не существует, выдает ошибку 404.
  • expires - задает время кэширования браузером отданного элемента, например, 1d - один день, 2h - два часа, 30s - 30 секунд.

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

Не выполнять логирование для favicon:

location = /favicon.ico {
log_not_found off;
access_log off;
}

Запретить доступ к файлам, начинающимся с точки:

location ~ /\. {
deny all;
}

Кэшировать обычные файлы на 90 дней:

location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires 90d;