Рубрики
Защита и безопасность

Спам-боты, postfix и fail2ban

На моём сервере Postfix работает в качестве сервера исходящей почты, то есть только отправляет почту с сайтов. Естественно, открыт 25-ый порт. Но большую часть времени туда долбятся носом всякие боты, пытающиеся воспользоваться сервером, как открытым релеем. :) Естественно, у них ничего не получается, ибо настроены правила. Но логи засоряют.

Спам-боты, postfix и fail2ban

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

Apr  8 21:15:20 omega postfix/smtpd[3075]: connect from unknown[189.158.233.139] Apr  8 21:15:21 omega postfix/smtpd[3075]: lost connection after UNKNOWN from unknown[189.158.233.139] Apr  8 21:15:21 omega postfix/smtpd[3075]: disconnect from unknown[189.158.233.139] Apr  8 21:16:00 omega postfix/smtpd[3075]: warning: hostname dsl-189-158-233-139-dyn.prod-infinitum.com.mx does not resolve to address 189.158.233.139: Name or service not known

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

Прежде всего откройте конфигурационный файл фильтра для Postfix. Он находится в каталоге /etc/fail2ban/filter.d/postfix.conf. Найдите параметр failregex и с новой строки допишите следующее регулярное выражение:

^%(__prefix_line)sdisconnect from S+[]

Сохраните файл. Теперь проверьте регулярку командой:

fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/postfix.conf

У меня в итоге выдало 100500 ip-адресов, в том числе и по стандартному правилу. :)

Последний шаг: откройте главный файл настроек — /etc/fail2ban/jail.conf. Найдите директиву [postfix] и включите фильтр.

enabled  = true

Перезапустите Fail2ban. На этом всё.

Рубрики
Защита и безопасность

Ограничение доступа к wp-login по ip в nginx

В последнее время fail2ban перестал нормально защищать от брутфорса на wordpress потому, что ip во всяком запросе уникальный и блокировать каждый адрес бессмысленно.

Ограничение доступа к wp-login по ip в nginx

Раз такая ерунда, решил ограничить доступ к файлу wp-login.php по ip. Здесь есть один нюанс: для прописанного в конфигурационном файле nginx локейшена (location) нужно добавить обработчик скриптов, при использовании php-fpm.

В итоге, конструкция выглядит так:

server{ ... location ~* wp-login.php$ { allow 127.0.0.1; deny all; try_files $uri =404; fastcgi_pass unix:/run/php-www.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name; fastcgi_ignore_client_abort off; fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com"; fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/"; } ... }

Теперь ботам выдаётся ошибка 403 вместо страницы авторизации. Только этот метод не слишком универсален — если на сайте есть регистрация пользователей, применить его не получится.

Но если вы — единственный пользователь, то можно подключить фантазию, и вместо доступа по ip сделать доступ по user-agent, по паролю…

Рубрики
Защита и безопасность

Простое отслеживание изменений файлов

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

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

Чтобы подсчитать контрольные суммы файлов, например, в папке /etc, воспользуемся комбинацией команд find и sha256sum:

# find /etc -type f | xargs sha256sum > file.txt

Флаг -type f указывает программе find искать только файлы (для папок вычислить контрольную сумму нельзя), а file.txt — это имя файла, куда будут записаны хэш-суммы всех найденных файлов.

Если необходимо подсчитать контрольную сумму только для определённых файлов, php, например, то следует указать флаг -name *.php (маска файлов * обязательно экранируется обратным слэшем):

# find www -type f -name *.php | xargs sha256sum > file.txt

Также можно вычислить контрольную сумму для конкретного файла:

# sha256sum backup.tar.gz > file.txt

А теперь сравним полученные хэш-суммы с хэш-суммами файлов:

# sha256sum -c file.txt

И если контрольная сумма конкретного файла совпадает с имеющейся в file.txt, то этот файл не был изменён с момента последней проверки. О целостности говорит метка ЦЕЛ напротив файла.

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

А помимо sha256 можно использовать любой другой алгоритм: md5, sha512, sha1, sha384.

Рубрики
Основы Debian

Как подключить Backports в Debian?

Если вы пользуетесь стабильным выпуском дистрибутива Debian, то знаете, что в нём присутствуют пакеты только определённой версии. Например, php 5.6. И, пока не будет обновлён сам дистрибутив в этой ветке, вы не сможете установить более свежую версию ПО…

Как подключить Backports в Debian?

…До тех пор, пока не подключите дополнительный, но официальный репозиторий пакетов backports. Он предоставляет более новые версии определённых пакетов. Например, если в стандартном репозитории располагается nginx версии 1.6.2, то из backports вы можете установить версию 1.9.10, включающую в себя множество необходимых улучшений.

Чтобы добавить этот репозиторий, необходимо в каталоге /etc/apt/sources.list.d/ создать файл backports.list и прописать там единственную строку:

deb http://ftp.ru.debian.org/debian jessie-backports main

Или любое другое ближайшее к вашему серверу зеркало.

Всё это дело можно выполнить одной командой:

echo -e "deb http://packages.dotdeb.org jessie allndeb-src http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list

Затем обновить список доступных пакетов: aptitude update.

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

aptitude install -t jessie-backports packagename

Где, вместо «packagename», нужно указать имя пакета.

Обновление уже установленных пакетов из ветки stable на ветку jessie-backports производится той же самой командой.

Конфликты с другими репозиториями

Конфликт может возникнуть, например, при использовании репозитория dotdeb. В моём случае, понадобилась установка только php7. Но при полном обновлении командой aptitude upgrade из репозитория dotdeb тянется nginx другой версии.

Всё было бы неплохо, если бы не факт, что nginx в dotdeb собран без поддержки openssl 1.0.2h. А это нужно для работы ALPN.

Выход из этой ситуации следующий: для пакетов из dotdeb, которые не требуется обновлять, следует понизить приоритет. Создаём файл dotdeb в каталоге /etc/apt/preferenses.d/ и прописываем туда содержимое:

Package: nginx* Pin: origin packages.dotdeb.org Pin-Priority: -10

В примере — nginx. Но его можно заменить на имя другого пакета.

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

Рубрики
Мониторинг

Iptraf: интерактивный мониторинг сети

Нашёл удобную программку для просмотра текущей нагрузки на сеть. Называется iptraf. Самое интересное для меня в этой программе — детализированная нагрузка по конкретному интерфейсу с указанием исходящего и входящего трафика, количества пакетов, и т.д.

Iptraf: интерактивный мониторинг сети

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

Такой график можно просмотреть, напечатав в консоли команду iptraf -d eth0. Eth0 соответствует имени сетевого интерфейса, полный список которых выводится на экран командой ifconfig.

Имеется монитор TCP/UDP трафика, отображающий текущие соединения. Вызывается командой iptraf -s eth0.

Iptraf доступен в репозиториях Debian.

aptitude install iptraf
Рубрики
Защита и безопасность

Использование nginx http_referer_module для защиты админки сайта от брутфорса

Читая документацию веб-сервера nginx, наткнулся на интересный модуль под названием http referer module. Он позволяет блокировать доступ к сайту, либо его разделам, если в запросе отсутствует корректный заголовок referer.

Использование nginx http_referer_module для защиты админки сайта от брутфорса

Этот модуль можно применить для защиты админки любого сайта от брутфорса. Например, сайт работает на вордпресс, но блокировка доступа по ip будет неуместной, если на сайте есть зарегистрированные пользователи. Им же тоже надо аутентифицироваться, а собирать их ip — занятие бессмысленное. :)

Принцип работы прост: на сайте выводим ссылку на страницу входа wp-login.php, а в конфигурационном файле nginx задаём проверку запросов к wp-login.php и /wp-admin/ на наличие адреса нашего сайта в заголовке реферер.

Прежде всего создаём выделенный локейшн для нужных страниц. Например, так:

server{ ... location ~* (wp-login.php|wp-admin(.*))$ {  try_files $uri =404;  fastcgi_pass unix:/run/php-www.sock;  location ~ .php$ {   include fastcgi_params;   fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;   fastcgi_ignore_client_abort off;   fastcgi_param PHP_VALUE "sendmail_path=/usr/sbin/sendmail -t -i -fmail@example.com";   fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/example.com/:/var/save_path/:/var/tmp_dir/";  } } ... }

Как видим, тут указаны ещё и параметры обработки php скриптов (иначе указанные в локейшн скрипты не будут работать).

Конфигурацию модуля можно прописать сразу после location ~* (wp-login.php|wp-admin(.*))$ {.

Первая строка:

valid_referers server_names

Она указывает, что корректным полем referer должен считаться домен сайта.

А также прописываем проверочное условие. Если поле referer некорректно, сервер отобразит ошибку 403 (доступ запрещён).

if ($invalid_referer) {     return 403; }

В итоге конфигурация будет выглядеть так:

server{ ... location ~* (wp-login.php|wp-admin(.*))$ { valid_referers server_names if ($invalid_referer) {     return 403; } (параметры fastcgi) } ... }

Напоследок на сайте добавляем ссылку на страницу входа (wp-login.php или что-то там ещё). Если посетитель кликает по этой ссылке, то получает форму авторизации. Но если бот будет стучаться напрямую к этому файлу, то получит ошибку доступа.

Да, стоит отметить, что заголовок referer можно подделать. Но лично мне боты с корректно заполненным полем referer попадались очень редко и банились по ip. :) Так что этот метод может быть вполне уместен.

Рубрики
Защита и безопасность

Как скрыть факт использования nginx на сервере

Однажды я прочитал статью где речь шла о том, что можно скрыть факт использования nginx на сервере.

Как скрыть факт использования nginx на сервере

Для этого требуется отредактировать исходный код модуля ngx_http_header_filter_module и изменить строки

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

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

Однако, существует и более простой метод, не требующий вообще никаких особых действий, типа редактирования исходников и перекомпиляции.

Для этого нам понадобится установить пакет nginx-extras из репозитория Debian. Этот пакет содержит в себе модуль HttpHeadersMore.

# aptitude install nginx-extras

Если у вас уже был установлен nginx-full, aptitude предложит удалить этот пакет, поскольку он не может использоваться совместно с extras.

После установки пакета, открываем файл /etc/nginx/nginx.conf и в секции http прописываем строку:

more_set_headers "Server: Apache";

И там же не забываем указать это (на всякий случай, если не сделали ранее):

server_tokens off;

И перезапускаем nginx. Вместо Apache можно подставить что-то своё. Либо замаскировать под другой веб-сервер. Простор для фантазии, в общем. :)

Собственно, вопрос: а зачем нам это всё делать? Маскируя nginx под другой сервер, мы усложняем хакерам работу. Ведь им нужно понять, на чём работает сайт, чтобы выяснить, как можно использовать уязвимости веб-сервера. Называя сервер по-другому, мы даём злоумышленнику уникальную возможность бесконечно долго подбирать уязвимость, например, к IIS вместо nginx. :)

Рубрики
Защита и безопасность

Базовая настройка iptables

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

Базовая настройка iptables

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

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

Как и все статьи на сайте, эта инструкция написана на основе личного опыта, а-ля «я делаю так», кто-то другой иначе.

Содержание статьи:

  • 1 Установка необходимых компонентов
  • 2 Редактирование правил для ip версии 4

Установка необходимых компонентов

И так, в системе уже присутствует главный из списка необходимых инструмент — iptables. Но этого недостаточно. Также понадобятся фильтр tarpit и iptables-persistent, чтобы загружать правила при старте системы.

# aptitude install iptables-persistent xtables-addons-dkms

Во время установки persistent будет задано два вопроса о сохранении текущих правил. Можно ответить «Да» и тогда в папке /etc/iptables/rules/ будут созданы нужные файлы с правилами, которые мы отредактируем.

Редактирование правил для ip версии 4

Открываем файл /etc/iptables/rules.v4 в любимом редакторе. Вы увидите строки, устанавливающие политику по-умолчанию для цепочек. Во всех значениях она будет иметь значение accept. Для цепочки FORWARD устанавливаем политику DROP. Мы же не роутер и не компьютер, перенаправляющий трафик куда-то ещё. :) Остальное не меняем.

*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] COMMIT

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

-A INPUT -i lo -j ACCEPT

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

-A INPUT -m state --state RELATED,ESTABLISHED -p all -j ACCEPT

Теперь необходимо добавить правило, разрешающее установку новых входящих соединений к определённым сервисам. У меня это web-сервер и почтовый, а также ssh.

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

Сюда можно добавлять и другие порты, разделяя запятой. Расширение multiport позволяет указать несколько портов, чтобы не плодить почти одинаковые правила для каждого отдельно. ;)

-A INPUT -m state --state NEW -p tcp -m multiport --dport 22,25,80,443 -j ACCEPT

Если у вас на сервере только один сервис, для которого нужно открыть один порт, то правило будет таким:

-A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT

Также вам может понадобиться открыть какие-то udp порты. Отличие от вышеприведённых правил будет только в том, что вместо -p tcp следует указать -p udp.

А при добавлении следующего правила пригодится фильтр tarpit, который мы установили с пакетом xtables-addon-dkms. Если кратко, то он создаёт ловушку для входящих соединений, не отсылая ничего в ответ, но удерживая соединение, что тратит ресурсы подключившегося клиента, но не сервера. Подробнее о tarpit можно узнать на сайте OpenNET. А пока добавляем правило для всех остальных входящих соединений.

-A INPUT -p tcp -m tcp -j TARPIT

Важно иметь в виду, что ловушка работает только с tcp. Подобным образом можно реализовать бан по ip на уровне iptables, вместо стандартного drop. К сожалению, для udp он не пригоден. Поэтому запрещаем все остальные входящие udp — пакеты, для которых не создали исключения ранее.

-A INPUT -p udp -j DROP

И принимаемся за icmp. Здесь в качестве типа icmp можно указать как код, так и эквивалентное ему название. У меня — код. :)

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

-A INPUT -p icmp --icmp-type 0 -j ACCEPT

Затем входящие icmp — сообщения о недоступности адресата.

-A INPUT -p icmp --icmp-type 3 -j ACCEPT

И входящие эхо-запросы, если кто-то пингует наш сервер.

-A INPUT -p icmp --icmp-type 8 -j ACCEPT

А также сообщение об истечении времени действия пакета.

-A INPUT -p icmp --icmp-type 11 -j ACCEPT

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

Теперь принимаемся за создание правил для исходящих icmp сообщений. Эти правила выглядят похожими, но цепочкой будет уже OUTPUT. Поэтому описывать их нет смысла.

-A OUTPUT -p icmp --icmp-type 0 -j ACCEPT -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT -A OUTPUT -p icmp --icmp-type 11 -j ACCEPT -A OUTPUT -p icmp --icmp-type 12 -j ACCEPT

Кроме двенадцатого. Оно разрешает отправку сообщения о неверном параметре (ошибка в IP-заголовке или отсутствует необходимая опция).

Все остальные исходящие ICMP запрещаем, чтобы сервер не сболтнул лишнего.

-A OUTPUT -p icmp -j DROP

На этом всё. Сохраняем файл /etc/iptables/rules.v4, активируем правила командой:

cat /etc/iptables/rules.v4 | iptables-restore -c
Рубрики
Защита и безопасность

Доступ к серверу по ssh только для определённой группы

SSH позволяет ограничивать доступ к серверу только для пользователей, состоящих в определённой группе. Не являясь её членами, другие пользователи не смогут зайти на сервер по ssh. Это удобная возможность выдавать права доступа только тем пользователям, кому это действительно необходимо.

Доступ к серверу по ssh только для определённой группы

В начале необходимо создать группу, члены которой будут авторизованы для работы с ssh. Такой GID группы указывается для того, чтобы не портить равенство UID/GID для новых, создаваемых в системе пользователей.

# addgroup --gid 9999 whocanusessh

Затем в конфигурационном файле /etc/ssh/sshd_config прописываем параметр.

AllowGroups whocanusessh

После чего в обязательном порядке добавляем root в эту группу:

# adduser root whocanusessh

Если этого не сделать, то и root не сможет зайти на сервер по этому протоколу.

Напоследок перезапускаем ssh командой service ssh restart.

Как это работает. Например, для редактирования файлов сайта example.com по sftp необходимо выдать доступ пользователю webmaster. Добавляем его в группу, аналогично добавлению root. Выполняем необходимые операции.

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

# deluser webmaster whocanusessh

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

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

Рубрики
Защита и безопасность

OCSP stapling на nginx с сертификатом StartSSL

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

OCSP stapling на nginx с сертификатом StartSSL

OCSP stapling позволяет веб-серверу прикреплять OCSP-ответы от сервера издателя сертификата. Что положительно сказывается на скорости работы. Ведь браузеру уже не нужно подключаться непосредственно к серверу издателя.

В общем, для включения степлинга на nginx понадобится корневой сертификат издателя. Актуальный корневой сертификат StartSSL его можно скачать здесь: startssl.com/root. При этом, необходимо сначала авторизоваться в личном кабинете.

Но можно скачать и напрямую:

wget https://startssl.com/certs/ca.crt -O /etc/nginx/ssl/ca-startssl.crt

Далее в конфиге сайта с сертификатом от StartSSL (или в глобальном конфигурационном файле сервера, если все сайты имеют сертификат от StartSSL) прописываем параметр, включающий степлинг:

ssl_stapling on;

Затем параметр, указывающий на корневой сертификат, который мы скачали ранее:

ssl_trusted_certificate /etc/nginx/ssl/ca-startssl.crt;

Или даже можем указать путь к корневому сертификату, который поставляется вместе с пакетом openssl:

ssl_trusted_certificate /etc/ssl/certs/StartCom_Certification_Authority.pem;

И, самое главное, — глубина проверки цепочки сертификатов. По-умолчанию этот параметр равен 1.

ssl_verify_depth 3;

У startssl минимальная глубина — 3. Здесь проверяется корневой сертификат, промежуточный сертификат StartCom Class 1 DV Server CA и, непосредственно, сертификат вашего сайта. Без этого степлинг работать не будет.

Также во многих статьях рекомендуется указывать параметр resolver для определения IP серверов OCSP. Но у меня заработало и без него. Не забываем перезапустить nginx после изменений файлов. ;)

Проверить работу степлинга можно на сайтах: https://www.digicert.com/help/ и https://ssllabs.com.