ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)

Как обезопасить свой стек LEMP в Linux

LEMP устанавливается на Linux, (EngineX) NGINX, MariaDB (или MySQL) и PHP. Благодаря своей гибкости и простоте, NGINX эффективно отдает данные.

На этом уроке, мы попытаемся на практических примерах (плохих и хороших), пройти через шаги для правильного обеспечения безопасности вашего веб-сервера Linux.

Так что же такое понятие безопасности? Часто можно услышать ИТ – инженеры говорят  “Наша сеть защищена” или “Наши серверы находятся в безопасности” , однако, эти предложения, которые широко используются технически не правильно, так как во многих книгах и публикациях вы можете обнаружить, что  безопасность как термин не является статическое значение, а степень.

Материал из Википедии определение является:

“Безопасность является степень сопротивления, или защита от вреда. Это относится к любой уязвимой и/или ценного актива, такие как личность, жилище, общины, пункта, нации или организации “.

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

“Самый безопасный сервер является тот , который выключен.” .

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

Целевая аудитория

Прежде чем идти дальше, мы должны отметить, что это руководство предназначено для опытных пользователей со знанием установки и настройки стека LEMP. Будем считать, что вы (читатель) уже имеет соответствующие знания для работы с операционной системой Linux. Это руководство не для начинающих. Многие другие связанные с этим вопросы связаны с этим руководством, такие как установка стека LEMP, установка сертификатов SSL, настройка аутентификации открытого ключа и многие другие находятся вне рамок данного руководства.

Предпосылки

Самостоятельное обеспечение безопасности Linux

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

Несмотря на это, существует ряд мер предосторожности, которые следует учитывать, что поможет иметь еще более безопасную систему.

Всегда иметь последнюю версию программного обеспечения и обновления безопасности

Это уже предположили, однако, мы считаем, что должно быть упомянуто ради полноты данного руководства. Независимо от того, что вы делаете, если ваша система не обновлена, настоящие и старые уязвимости не будут использоваться, и ваш сервер будет в конечном итоге быть под угрозой, а не людьми, а автоматизированных роботов, которые сканируют для этих уязвимостей. Хакеры даже не понимают, что ваш сервер был взломан, его сценарий сделает это за него. Вы должны всегда держать свою систему обновляется. Это означает любое программное обеспечение и приложение, которое находится на вашем сервере, и любой веб – сайт (CMS), работающий на нем. Если у вас есть WordPress работающим как веб – сайт, он должен обновляться, как только новая версия будет выпущена.

Обеспечение удаленного входа в систему

  1. Очевидное – корневой пароль должен быть очень длинным и сильные комбинации букв, цифр и символов.
  2. Изменение SSH порт по умолчанию (22) на произвольный порт.
  3. Удаленные корневые логины должны быть деактивированы.
  4.  Следует использовать открытый ключ механизма аутентификации вместо пароля входа в систему.
  5. Во время выполнения указанных выше следует использовать стандартные учетные записи пользователей Linux. Этим пользователям должна быть предоставлена ​​возможность эскалации привилегий суперпользователя.

Например:

Мы установим наш корневой пароль, чтобы что-то вроде `j7LAaW#zLWrjs!PHE^jk`

Если это основная Linux (CentOS) в установке следует использовать sudo в первую очередь.

# yum install sudo

 

Создание стандартного пользователя:

# useradd -d /home/adminjohn adminjohn
# passwd adminjohn

 

Изменение привилегий adminjohn к возможности повышения привилегий суперпользователя:

# visudo

 

В конце файла найти ту часть, где пишется:

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)   ALL

 

И убедитесь, что линия раскомментирована.

Теперь добавьте нашего adminjohn в качестве члена группы whell.

# usermod -a -G wheel adminjohn

 

Отредактируйте файл /etc/ssh/sshd_config и установите следующие параметры:

 

 

# vim /etc/ssh/sshd_config

Port 29862
PermitRootLogin no

 

С помощью этих параметров, удаленные корневые логины запрещены, однако, наш пользователь adminjohn сможет войти в систему с помощью SSH, а затем он может переключиться на корень, используя команды, sudo su -  если это необходимо.

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

Брандмауэр Linux

В большинстве систем Linux сегодня используют либо IPTables или Firewalld как брандмауэр. Ключевым понятием здесь нужно понять, как правило, если мы хотим, чтобы наш брандмауэр, был эффективным, то мы должны реализовать так называемое deny all with exceptions policy.

Например: если ваш сервер обслуживает только веб – сайт WordPress, то любой брандмауэр на месте должен позволять доступ только к портам 80 (HTTP), 443 (HTTPS) и 22 (SSH) или любой другой порт, который вы открыли. В нашем примере, мы должны обеспечить доступ к 80, 443 и 29862. Мы можем, однако, в дальнейшем расширения нашего использования и также открыть порт 25, если мы хотим отправлять электронную почту с нашего сайта. Если мы не уверены, мы всегда можем использовать команду netstat -tulnp для того, чтобы проверить все активные порты на нашем сервере и решить, что следует и не следует использовать.

Отключение неиспользуемых служб

Для того, чтобы сделать еще один шаг, на любом сервере Linux, всегда должны отключить все неиспользуемые услуги/приложения, так как это будет в значительной степени ограничивать поверхность атаки сервера. Чем больше услуг вы добавляете, тем больше вы увеличиваете поверхность атаки сервера, и тем более уязвимы для атак становится. Современные реализации Linux как CentOS 7 и Ubuntu 16, использование Systemd в качестве инициализации демона. Услуги, которым необходим доступ к сети могут быть легко идентифицированы с командой netstat -tulnp.

В приведенном ниже примере, мы можем видеть, что наша система (CentOS 7) запускает dovecot, postfix (master), sshd, vsftpd и nginx.

# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN 444/dovecot
tcp 0 0 0.0.0.0:995 0.0.0.0:* LISTEN 444/dovecot
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 442/master
tcp 0 0 0.0.0.0:29862 0.0.0.0:* LISTEN 30430/sshd
tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN 444/dovecot
tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN 444/dovecot
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 241/nginx: master p
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 119/vsftpd
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 442/master

 

Если мы решим, что нам не нужно dovecot, можно отключить ее с помощью:

## Be carefull not to disable anything essential
systemctl stop dovecot
systemctl disable dovecot

 

Последнее отключает dovecot от запуска в следующий раз, когда наша система будет перезагружена.

Обеспечение безопасности NGINX

NGINX должен работать как не суперпользователь

Установка NGINX по умолчанию устанавливает его процесс работающим либо как nginx or www-data в качестве пользователя. Если случайно сервер работает как корень, то его можно изменить, установив соответствующую директиву в файле /etc/nginx/nginx.conf.

user nginx;

 

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

Обычные разрешения web root являются 755 для каталогов и 644 для файлов.

Скрыть номер версии Nginx

Номера версий часто используются хакерами для использования уже существующие уязвимости.

Поместите это в HTTP блока /etc/nginx/nginx.conf:

# vim /etc/nginx/nginx.conf
server_tokens off;

Заставьте работать с помощью HTTPS

Если вы стремитесь к высокому уровню безопасности сайта вы всегда должны стандартизировать имена URL и заставить пользователей использовать HTTPS. Обычно разработчики будут ставить заголовки в их сайт WordPress, однако, правильный способ сделать это из самого NGNIX.

В приведенном ниже примере, у нас есть два блока сервера. Первый из них только цель состоит в том, чтобы захватить стандартные запросы HTTP и перенаправляет их на запросы HTTPS.

server {
    listen 80;
    server_name yoursite.ru www.yoursite.ru;
    return 301 https://yoursite.ru$request_uri;
}

 

server {
    listen 443;
    server_name yoursite.ru www.yoursite.ru;
    ssl_protocols TLSv1.1 TLSv1.2;
    # [...]
}

 

Ограничение HTTPS для TLSv1.1 и TLSv1.2

Обратитесь к предыдущему примеру. В блоке сервера SSL, директива ssl_protocls четко определяет протоколы, которые должны быть разрешены. Более либеральный подход должен был включать TLSv1 , а также:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Пересылка неконтролируемых запросов на PHP

Многие онлайн руководства по настройке NGINX с PHP содержат разделы, как этот:

location ~* \.php$ {
    fastcgi_pass backend;
    # [...]
}

 

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

Например, если запрос сделан для /yoursite.ru/wp-content/uploads/1232.jpg/file.php, которого не существует, но если /yoursite.ru/wp-content/uploads/1232.jpg выполняется, то интерпретатор PHP будет обрабатывать //yoursite.ru/wp-content/uploads/1232.jpg вместо этого. Если он содержит встроенный PHP – код, этот код будет выполнен соответствующим образом. Ты знаешь что это значит? Если у вас есть сайт на WordPress, который позволяет пользователю загружать изображения, злоумышленник может легко загрузить вредоносный файл, замаскированный как образ и поставить под угрозу ваш сайт.

Есть несколько решений для этого, как в конфигурации Nginx, так и в самом PHP (смотрите ниже на защиты PHP).

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

В приведенном ниже примере наш сервер будет обрабатывать только файлы с именами index.php, site.php и cms.php.

location ~* (index.php|site.php|cms.php)\.php$ {
    fastcgi_pass backend;
    # [...]
}

 

Другой подход заключается в использовании директивы try_files. В приведенном ниже примере, если предоставленный файл не существует, NGINX выдаст ошибку 404.

location ~* \.php$ {
    try_files $uri =404;
    fastcgi_pass backend;
    # [...]
}

 

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

location /uploads {
    location ~ \.php$ {return 403;}
    # [...]
}

 

Обеспечение безопасности MySQL / MariaDB

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

Для тех из вас, которые уже имеют функционирующие серверы и не хотят, чтобы запускались сценарий, проверьте файл /etc/my.cnf и убедитесь, что у вас установленное значение bind-address = 127.0.0.1 и не закомментировано.

Другой также очень безопасный механизм использовать одного пользователя/базы данных для каждого сайта. Много сайтов там используют MySQL пользователя для подключения корневого веб-сайта с базой данных. Привилегированный пользователь по умолчанию имеет доступ к любой другой базе данных. Это означает, что любая обнаруженная уязвимость на одном сайте, потенциально могут быть использована для злоумышленника, чтобы получить доступ ко всем базам данных.

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

Обеспечение безопасности PHP

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

Типы атак PHP

SQL-инъекция

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

XSS – Cross Site Scripting

От этих типов уязвимостей трудно защититься. Опять же, разработчики из наиболее часто используемых CMS платформ, таких как WordPress, Joomla, Drupal и т.д. очень осторожны и убедитесь, что их код правильно написан и регулярно защищен. Большинство мер безопасности в отношении этих и любых других видов атак могут быть реализованы с помощью главного конфигурационного файла PHP. Подробнее об этом позже.

Подделками запросов Cross-Site – CSRF

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

Настройка php.ini

Остановить обработку PHP, если файл не найден

Убедитесь , что cgi.fix_pathinfo = 0 фактически установлен в 0 в php.ini. Это приводит к тому, PHP интерпретатор только проверит заданный литеральный путь и остановит обработку, если файл не найден.

Отключение опасных функций PHP

Гибкость PHP включает в себя множество функций, по умолчанию, которые могут быть использованы или неправильно в зависимости от того, что кто-то хочет сделать. Например, для более продвинутых конфигураций, PHP позволяет для удаленных файлов выполняться, где файлы могут быть удаленно выполненны с другого сервера. Хотя это может звучать весело, это также уязвимость системы безопасности, где злоумышленник может открыть и выполнить любой файл на удаленном сервере. Это может позволить им также загружать вредоносные файлы. Удаленное выполнение файла должно быть отключено из файла конфигурации PHP.

disable_functions =exec,eval,phpinfo,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Ограничение загрузки файлов

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

file_uploads = Off

 

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

file_uploads = On
upload_max_filesize = 1M

Установить размер POST в разумное значение

Метод POST используется, когда пользователь должен отправить некоторые данные на сервер/веб-приложение, и как таковые потенциально могут быть использованы для злонамеренного использования, как DoS-атаки, например. Это также включает в себя отправку больших файлов на сервер. Однако этот метод также является неотъемлемой частью любого веб-приложения, так что лучший способ защитить себя, чтобы ограничить его значение и установить его на что-то более разумное. Если вы не используете загрузку файлов, то его значение может быть установлено на что-то вроде 4 КБ или меньше.

post_max_size = 1K

 

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

Ограничение PHP утечки информации

Устанавливая   expose_php = Off, можно просто скрыть информацию, какой PHP установлен на сервере. Это, по сути, скрыть подпись, что PHP удаляется из заголовка веб – сервера. В документации говорится, что PHP оставляет это значение в ON и не является уязвимостью. Тем не менее, никто не может отрицать тот факт, что чем меньше информации вы предоставляете в внешний мир, тем более безопасным будет ваш сервер.

Ограничение максимального времени выполнения PHP скрипта

Установите следующие значения в вашем файле php.ini. Позже они могут быть адаптированы в соответствии с более конкретными потребностями.

# set in seconds
max_execution_time = 30
max_input_time = 30
memory_limit = 40M

 

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

  1. Устанавливает максимальное время до 30 секунд, скрипт может работать, прежде чем он завершается синтаксическим анализатором (PHP).
  2. Устанавливает максимальное время до 30 секунд, скрипт может разобрать входные данные, как POST и GET.
  3. Устанавливает максимальный объем памяти до 40 МБ, значение, которое скрипту позволино выделить.

Во многих конфигурациях PHP, значение memory_limit устанавливается равным -1, что хорошо в развитии, но в противном случае плохой выбор.

Отключение неиспользуемых модулей PHP

Модули PHP являются большими, так как они позволяют и активируют определенные функциональные возможности для вашего веб-приложения. Наиболее распространенным примером этого является модуль PDO_MySQL PHP, который позволяет PHP для доступа к базам данных MySQL. Все эти модули, однако, могут потенциально привести с собой собственные недостатки и уязвимости, и если они не используются, они могут быть отключены или удалены. С помощью команды php -m можно увидеть все установленные PHP модули. Отключение неиспользуемых модулей снижает поверхность PHP атаки. В идеале, PHP должен быть переустановлен и перекомпилирован используя только необходимые модули. Тем не менее, если вы чувствуете, что переделка всего этого слишком затянется, то вы можете просто отключить их, просто раскомментировав свою линию в php.ini или переименовывание их конфигурационного файла, /etc/php.d/module_name.ini во что – то подобное  /etc/php.d/module_name.ini.disabled.

Как обезопасить свой стек LEMP

Вывод

Сам сервер Linux по своей природе является очень безопасной операционной системой. Это не считается для любой небрежности, поэтому стандартные меры безопасности должны всегда быть реализовано на практике. Прямые корневые логины не рекомендуется, и открытый ключ аутентификации рекомендуется всегда.

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

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

Exit mobile version