Документация по ОС FreeBSD Четверг, 25.04.2024, 21:46
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Apache

Полный тюнинг движка: Делаем из nginx непробиваемый Web-сервер [2010]
Выделенный 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

Далее открой файл nginx.conf и впиши в него следующие строки:

# 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 <abuse> persist
  block in quick from <abuse>
  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 <abusive_ips> 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, SourceForge.net, vkontakte.ru, megashara.com, Либрусек и Taba.ru. Грамотная архитектура, основанная на мультиплексировании соединений с помощью системных вызовов select, epoll (Linux), kqueue (FreeBSD) и механизме управления памятью на основе пулов (небольших буферов от 1 до 16 Кб), позволяет nginx не проседать даже под очень высокими нагрузками, выдерживая свыше 10000 одновременных соединений (так называемая проблема C10K). Изначально написан Игорем Сысоевым для компании Rambler и открыт в 2004 году под BSD-подобной лицензией.


Источник: http://www.xakep.ru/post/54168/default.asp
Категория: Apache | Добавил: oleg (11.12.2010) | Автор: Евгений Зобнин
Просмотров: 1358 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024