Найти в Дзене
Andrey N

Работа с сервером (VPS/VDS) ч. 3

Оглавление

Защита SSH от Brute-force attack (брутфорс) на любом порту

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

Сейчас самое время перейти к защите от Brute-force attack

Brute-force (брутфорс) он же «метод Грубой силы» — это хакерская атака путем полного перебора (подбора) пароля. Вручную, естественно, этим никто заниматься не будет – создаются бот-сети (botnet), которые в автоматическом режиме, 24 часа в сутки 7 дней в неделю 365 дней в году, сканируют целые сегменты IP-адресов и при получении отклика начинают данную атаку. Перебирать, суммарно, по 5 млн. паролей в сутки для ботнета совсем не проблема.

СКОРЕЕ ВСЕГО ВАШ СЕРВЕР УЖЕ ПОД АТАКОЙ!

Вероятно возник вопрос: Зачем я то им нужен? У меня и красть там нечего, по большому счёту.

Дело в том, что красть то у нас, по большому счёту, никто ничего не собирается.

Цель атаки: Заразить (зомбировать) наш сервер/компьютер - сделать его частью ботнета, а далее уже только фантазия брутфорсера решит как этим воспользоваться. Наш сервер, будучи зомби, может брутфорсить другие сервера для расширения ботнета или, скажем, быть атакующей машиной при DDoS-атаке (кстати, услуга DDoS-атаки сайта/сервера какого-нибудь конкурента стоит очень не дешево, но эта услуга востребована).

Если Вы читали первую и вторую части данной инструкции, тогда на данном этапе у Вас уже настроено соединение по SSH-ключам и отключен вход по паролям и, в принципе, Вам уже не страшен брутфорс так как вход по паролям отключен и подбирать нечего, НО…

Атака брутфорс всё равно продолжается и создаёт некую нагрузку на ваш сервер, пусть и не большую, но создаёт и в данной части инструкции мы настроим защиту от брутфорс и сведём нагрузку к нулю, в отличие от той же защиты с помощью File2Ban, которая, так или иначе, даёт нагрузку примерно в 5%.

Ну что, давайте приступим?!

Примечание: Данная настройка оттестирована на ОС Ubuntu 20.04, на других ОС команды могут немного отличаться.

Сначала, если есть желание, можно убедиться в том, что наш сервер действительно атакуют.

Проверьте свой сервер введя одну из команд (из под пользователя «root»):

grep -a "Failed password" /var/log/auth.log

либо:

egrep -a "Failed|Failure" /var/log/auth.log

Вероятнее всего, если еще не настроен Fifewall (контроль и фильтрация проходящего сетевого трафика в соответствии с заданными правилами), мы увидим приличный список неудачных попыток входа по логину и паролю, по разным портам:

Список попыток неудачного ввода логина и пароля по разным портам
Список попыток неудачного ввода логина и пароля по разным портам

Впечатляюще, не правда ли?

Вот именно поэтому я всегда рекомендую сначала позаботиться о защите с помощью SSH-ключей, потом отключить возможность входа по паролю, потом настроить Firewall для защиты от Brute-force attack

Ну собственно, переходим к самой настройке защиты:

Первым делом я бы рекомендовал произвести обновления репозиториев и обновление системы, команды следующие:

❗️ Делать обновление или нет - это каждый решает самостоятельно.

❗️ Дальнейшие действия продолжаем делать под пользователем «root».

Обновление репозиториев - вводим команду и нажимаем «Enter»:

apt update

Ждём окончания обновления репозиториев:

Обновление репозиториев завершено
Обновление репозиториев завершено

Обновление системы - вводим команду и нажимаем «Enter»:

apt full-upgrade

Конфликтующие пакеты могут быть удалены, а новые, дополнительные - установлены.

Система сообщает о том, что будет установлено и что обновлено и задаст вопрос - желаем ли мы продолжить:

Система ожидает подтверждения или отказа установки обновлений
Система ожидает подтверждения или отказа установки обновлений

Для подтверждения нажимаем клавишу «y» и нажимаем «Enter»

Ожидаем и при появлении такого или подобного окна (если появится)и выбираем пункт отмеченный по умолчанию - нажимаем «Enter»:

Выбираем пункт отмеченный по умолчанию
Выбираем пункт отмеченный по умолчанию

После завершения обновлений (обновление занимает некоторое время) система будет ожидать ввода команд:

Обновления завершены и система ожидает дальнейших команд
Обновления завершены и система ожидает дальнейших команд

Приступим к самой настройке Firewall

Подсистема «iptables» и «netfilter» встроены в ядро, но вот набор утилит для управления всем этим не всегда поставляется вместе с системой.

Для установки утилиты в Ubuntu , нужно ввести команду и нажать «Enter»:

apt install iptables

Если попросит ввести пароль - вводим пароль текущего пользователя

В моем случае система сообщила о том, что у меня уже установлены последние обновления «iptables»:

Окно после установки набора утилит iptables
Окно после установки набора утилит iptables

Далее, введя эту команду, можно увидеть список всех имеющихся у нас правил с номерами (не забываем нажимать «Enter» после ввода каждой команды):

iptables -L -n --line-numbers

В моем случае система отобразила 3 раздела правил и все они пустые:

Списки правил Firewall пустые
Списки правил Firewall пустые

Запоминаем, визуально, какие правила у нас на текущий момент (если они есть, но на скриншоте выше список пуст).

Примечание: Вы не можете просто так отключить iptables остановив сервис обновления правил iptables через systemd или даже удалив набор утилит для настройки. Подсистема работает на уровне ядра и не зависит от того, что там у вас установлено. Поэтому если сделаете что-то не так, то нужно будет очистить правила. Для этого нужно ввести команду:

sudo iptables -F

Создаем правила (вставляем блоки целиком, по очереди):

iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name SSH --hashlimit-htable-expire 60000 -j ACCEPT

Нажимаем «Enter»

iptables -A INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,RST,ACK SYN -j DROP

Нажимаем «Enter»

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

Нажимаем «Enter»

Проверяем добавились правила или нет - вводим команду и нажимаем «Enter»:

iptables -L -n --line-numbers

Видим, что теперь добавлено 3 правила (номера пометил на скриншоте):

Правила Firewall добавились
Правила Firewall добавились

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

❗️ ВНИМАНИЕ: На хостерах First Bite, MskHost (если выявите других хостеров - дайте знать) замечено то, что после выполнения ниже описанных действий правила не подгружаются. Для Вас решение немного другое - в принципе, должно сработает на всех хостерах, поэтому сами решайте как реализовать подгрузку правил:

Блок для хостеров у которых правила не подгружаются сервисом:

--------------------

Установить пакет сохранения:

apt install iptables-persistent

В процессе установки на оба вопроса ответить Yes.

Сохранить текущие правила:

service netfilter-persistent save

❗️ ВСЁ! При следующей загрузке сохраненные правила подгрузятся как положено.

--------------------

Конец блока

Далее информация для тех кто решил создать сервис подгружающий правила (работает не на всех хостерах, но на Hetzner, Digital Ocean работает нормально).

❗️ Оба варианта делать не нужно, если сделали один и он работает - другой делать не нужно

Вот только перед сохранением файла iptables.rules в директорию iptables - нужно создать эту директорию.

Вводим команду и нажимаем «Enter»:

mkdir /etc/iptables

Команду создания директории ввели:

Система ожидает следующей команды - ошибки нет
Система ожидает следующей команды - ошибки нет

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

Сохраняем введенные правила в файл, команда:

iptables-save > /etc/iptables/iptables.rules

Примечание: в разных дистрибутивах команда отличается, данная команда для Ubuntu.

Настройки сохранены - ошибки нет
Настройки сохранены - ошибки нет

На всякий случай проверим есть ли правила в сохраненном файле (продолжаем работать под пользователем «root») - вводим команду:

cat /etc/iptables/iptables.rules

Появляется вот такое окно:

Правила Firewall сохранены в файле
Правила Firewall сохранены в файле

На скриншоте выше мы видим, что добавленные нами правила сохранились файле.

Путь к файлу и название самого файла, с правилами, можно указать любыми (в пределах папки «etc»), но я люблю порядок и поэтому выбрал путь и название файла именно такими: /etc/iptables/iptables.rules

Описание самих правил:

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

Третье правило разрешает доступ к серверу по ssh.

Все самое интересное (военная тайна) кроется в первом и втором правилах:

Первое правило разрешает две попытки соединения на 22-й порт в течение часа, после чего начнёт срабатывать второе правило. Срок действия хэш-таблицы с IP-адресами – 60 секунд, после которых можно повторить попытку.

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

Если не принимать попыток соединения (входа) до истечения таймера (в данном случае это 1 минута) информация о наших попытках потухнет и можно будет снова повторить две попытки входа, но, если, не дожидаясь истечения таймера произвести попытку соединения с сервером пакет будет убит, а таймер начнет новый отсчет 60000 миллисекунд и так до бесконечности.

Таким образом, если вы «Нетерпеливый брутфорсер» и будете тупо долбить порт после блокировки, то вы с каждой попыткой будете продлевать свой бан! Иными словами: забаните себя навечно!

При действии этих правил в: /proc/net/ipt_hashlimit будет создаваться файл с именем, заданным параметром –hashlimit-name (в нашем случае это ssh ).

После второй попытки подключения туда попадает информация:

55 ХХ.ХХ.ХХ.ХХ:0->0.0.0.0:0 11533000 230400000 115000000

первое число — кол-во оставшихся секунд, можно смотреть как оно равномерно тикает

Таким образом решены две проблемы:

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

Что делать, если вы вдруг с нескольких попыток не смогли ввести пароль?

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

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

Создаем сервис подгрузки правил Firewall (вставляем блок целиком):

cat >> /etc/systemd/system/iptables-rules-restore.service <<EOF
[Unit]
Description = Apply iptables rules
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'iptables-restore < /etc/iptables/iptables.rules'
[Install]
WantedBy=network-pre.target
EOF

Нажимаем «Enter»

Видим что команда принялась - ошибок не выдало:

Команда принята (ошибок нет) и система ожидает следующую команду
Команда принята (ошибок нет) и система ожидает следующую команду

Даём права на исполнение файла:

chmod +x /etc/systemd/system/iptables-rules-restore.service

Нажимаем «Enter»

Подключаем сервис :

systemctl enable iptables-rules-restore.service

Нажимаем «Enter»

Обновляем конфигурацию всех служб:

systemctl daemon-reload

Нажимаем «Enter»

Запускаем сервис подгрузки правил Firewall :

systemctl start iptables-rules-restore.service

Нажимаем «Enter»

Вот, собственно, и всё!

❗️ Правила Firewall созданы и при перезагрузке сервера будут загружаться как сервис.

Давайте проверим загружаются ли правила, автоматически, при перезагрузке сервера, для этого нам поможет священный «reboot» (перезагрузка) нашего сервера.

Существует два способа перезагрузки сервера: «Через панель управления в личном кабинете на сайте хостера» и «Командой в консоли».

Сейчас мы воспользуемся командой в консоли, вводим команду:

reboot

Нажимаем «Enter»

и еще 1-2 раза «Enter»

«Перезагрузка» процесс НЕ мгновенный - ожидаем буквально несколько секунд и система запросит у нас ввод пароля от SSH-ключа.

После перезагрузки нашего сервера вводим команду (если требуется - подтверждаем паролем):

iptables -L -n --line-numbers

отображение списка всех имеющихся у нас правил с номерами

После ввода команды появится вот такое окно и если в нем присутствуют правила (изначально правил не было) значит все в порядке:

Правила Firewall подгрузились после перезагрузки
Правила Firewall подгрузились после перезагрузки

❗️ ВСЁ! При следующей загрузке сохраненные правила подгрузятся как положено.

Я полагаю, что Вам не терпится проверить то, как работает данная защита?!

Ну что же, давайте проверим.

Закрываем окно консоли и открываем снова (Вы это уже умеете):

Default Settings - Настройки по умолчанию
Default Settings - Настройки по умолчанию

Выставляем настройки по умолчанию (Default Settings) и вводим IP-адрес сервера.

Далее нажимаем «Соединиться»

Вводим логин - например: «root» и нажимаем «Enter»

Появляется вот такое окно с ошибкой:

Окно консоли с ошибкой так как вход по паролям запрещен
Окно консоли с ошибкой так как вход по паролям запрещен

Мы видим ошибку так как при настройке SSH-ключей мы отключили вход по паролям пользователей.

Закрываем окна и пробуем подключиться снова (Default Settings) - вводим логин и опять точно такая же ошибка как на скриншоте выше.

Опять закрываем и пробуем подключиться еще раз и что мы видим?

Система перестала запрашивать логин
Система перестала запрашивать логин

Система даже логин, у нас, не запрашивает!

Поздравляю, с этого моменты мы в БАНе - сервер перестал принимать пакеты с нашего IP-адреса и теперь мы будем долбится в закрытые двери (если бы мы были брутфорсером и пытались подобрать пароль) .

Иными словами: брутфорсер смог предпринять ДВЕ попытки подбора логина и ни одной пароля, после чего попал в БАН и все последующие его попытки будут убиты (ни один пакет сервер не примет), а таймер будет продлеваться на 60 секунд после каждой попытки (вечный бан).

Чтобы сервер начал принимать пакеты от нашего IP-адреса - нужно не пытаться с ним соединиться в течение 60 сек, если не меняли настройку «hashlimit-htable-expire 60000».

(120000 - это 2 минуты, 180000 - это 3 минуты и т.д).

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

Если какие-то моменты были не понятны - не стесняйтесь сообщить мне об этом и я буду редактировать эту инструкцию.

А сейчас, желающие установить и настроить ноду блокчейна Idena (майнинг криптовалюты iDNA) как сервис, чтобы нода запускалась автоматически при загрузке/перезагрузке сервера - переходите по ссылке к следующей инструкции:

Установка ноды IDENA на сервер (VPS/VDS) как сервис

Пожертвования и благодарность:

Яндекс (Ю.Money): https://sobe.ru/na/nuzhdy_Andrey_N

IDNA: 0x5d69be52a201f9d0a2f3ec49060112811a63e4d1