Вопрос или проблема
Вопрос
Как исключить несущественные¹ неудачные входы по SSH?
Контекст
Для общего информирования мне нравится иметь небольшие окна с системными журналами ошибок на каждом сервере GNU/Linux, который я администрирую. Раньше я делал это с помощью xconsole, но теперь использую xterm, выполняя journalctl -f
.
К сожалению, на машинах, где ssh
является необходимым сервисом, журнал journalctl
представляет собой постоянный поток беспорядка от злоумышленников, пытающихся зайти по SSH с помощью списков распространенных имен/паролей.² Я вижу неудачи, прокручивающиеся каждую секунду для аккаунтов, которые даже не существуют. Это затрудняет просмотр чего-либо другого в моем консольном журнале.
Решения?
Я не знаю systemd так хорошо, как должен, поэтому возможно, что есть элегантный и простой ответ, но я его еще не нашел.³ Любое решение приветствуется. Я подозреваю, что это будет связано с настройками pam, journalctl и/или grep -v
.
Мне нужно решение, которое все еще покажет мне попытки доступа к существующим аккаунтам. Однако, если это слишком сложно, я приму ответ, который скрывает все неудачные попытки входа.
Примеры Journalctl
Не показывать следующее:
12 дек 17:19:21 gaia sshd[10146]: pam_unix(sshd:auth): ошибка аутентификации; logname= uid=0 euid=0 tty=ssh ruser= rhost=139.59.90.40 user=root
12 дек 17:19:21 gaia sshd[10148]: Неверный пользователь git с 14.29.201.30
12 дек 17:19:21 gaia sshd[10148]: input_userauth_request: неверный пользователь git [preauth]
12 дек 17:19:21 gaia sshd[10148]: pam_unix(sshd:auth): проверьте пароль; пользователь неизвестен
12 дек 17:19:21 gaia sshd[10148]: pam_unix(sshd:auth): ошибка аутентификации; logname= uid=0 euid=0 tty=ssh ruser= rhost=14.29.201.30
12 дек 17:19:22 gaia sshd[10150]: Неверный пользователь molisoft с 5.135.152.97
12 дек 17:19:22 gaia sshd[10150]: input_userauth_request: неверный пользователь molisoft [preauth]
12 дек 17:19:22 gaia sshd[10150]: pam_unix(sshd:auth): проверьте пароль; пользователь неизвестен
12 дек 17:19:22 gaia sshd[10150]: pam_unix(sshd:auth): ошибка аутентификации; logname= uid=0 euid=0 tty=ssh ruser= rhost=5.135.152.97
12 дек 17:19:23 gaia sshd[10146]: Неудачный пароль для root с 139.59.90.40 порт 37752 ssh2
12 дек 17:19:23 gaia sshd[10146]: Получено отключение от 139.59.90.40: 11: До свидания [preauth]
12 дек 17:19:23 gaia sshd[10148]: Неудачный пароль для неверного пользователя git с 14.29.201.30 порт 41178 ssh2
12 дек 17:19:23 gaia sshd[10148]: Получено отключение от 14.29.201.30: 11: До свидания [preauth]
12 дек 17:19:24 gaia sshd[10150]: Неудачный пароль для неверного пользователя molisoft с 5.135.152.97 порт 50730 ssh2
12 дек 17:19:24 gaia sshd[10150]: Получено отключение от 5.135.152.97: 11: До свидания [preauth]
Но показывать действительные входы:
10 дек 08:56:16 gaia sshd[1414]: Принят публичный ключ для sophia с 24.22.130.192 порт 41610 ssh2: RSA 6b:5f:aa:9c:d8:33:65:2c:c4:0c:88:12:ec:9b:ff:51
10 дек 08:56:16 gaia sshd[1414]: pam_unix(sshd:session): сеанс открыт для пользователя sophia (uid=0)
10 дек 10:06:37 gaia sshd[1414]: pam_unix(sshd:session): сеанс закрыт для пользователя sophia
Также показывать неудачные попытки на действительных аккаунтах (кроме root):
12 дек 00:46:28 gaia sshd[30924]: pam_unix(sshd:auth): ошибка аутентификации; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.9.134 user=sophia
12 дек 00:46:30 gaia sshd[30924]: Неудачный пароль для sophia с 192.168.9.134 порт 55888 ssh2
12 дек 00:46:33 gaia sshd[30924]: Соединение закрыто аутентифицирующим пользователем sophia 192.168.9.134 порт 55888 [preauth]
И, конечно, любые сервисы, которые не sshd, должны отображаться.
10 дек 08:56:16 gaia systemd[1]: Запущен менеджер пользователей для UID 3237.
¹ Определяется как “имя пользователя не существует” или “имя пользователя – root”. Доступ по SSH для root отключен на моих машинах.
² Я использую fail2ban
. Это помогает, но попытки поступают с слишком многих IP адресов.
³ Например, journalctl позволяет использовать grep
, но не grep -v
для исключения определенных критериев.
Используйте
journalctl -f | awk -f filter.awk
с файлом filter.awk, содержащим
# убираем не sshd
$5 !~ /^sshd\[[0-9]*\]:$/ { print ; next }
# показываем ошибки аутентификации для действительных пользователей, кроме root
/authentication failure/ && $15 != "" && $15 != "user=root"
/Failed password for/ && !/invalid user/ && !/for root/
# показываем действительные входы
/Connection closed by authenticating user/
/Accepted publickey/
/pam_unix\(sshd:session):/
Ничего особенного. Если строка не sshd, то печатаем её и переходим к следующей. В противном случае выводим строки, которые соответствуют выражению. Я использовал GNU awk версии 5.0.1
Вы можете значительно сократить количество записей в журнале в /etc/ssh/sshd_config
следующим образом:
-
Отключив аутентификацию по паролю и разрешив только использование публичных ключей:
PasswordAuthentication no ChallengeResponseAuthentication no PermitRootLogin prohibit-password
-
Установив уровень
INFO
или ниже (INFO
является настройкой по умолчанию для sshd):LogLevel INFO
Единственное, что это пока не решает, это когда боты спама по входу не поддерживают ваши методы обмена ключами; тогда вы получаете, например:
Невозможно провести обмен с 203.0.113.1 порт 40442: не найдено подходящего метода обмена ключами. Их предложение: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
Я пока не нашел способ избавиться от этой проблемы.
Вы можете фильтровать журналы перед тем, как они будут добавлены в системный журнал systemd, с помощью опции LogFilterPatterns
. Это требует версии systemd 253 или выше.
Опция LogFilterPatterns
может быть указана несколько раз. Каждая содержит регулярное выражение и должна начинаться с ~
, чтобы указать, что соответствующие журналы должны быть исключены.
Создайте файл /etc/systemd/system/ssh.service.d/logfilter.conf
со следующим содержимым:
[Service]
LogFilterPatterns=~Invalid user .+ from .+ port [0-9]+$
LogFilterPatterns=~Disconnected from invalid user .+ \[preauth\]$
LogFilterPatterns=~Connection closed by invalid user .+ \[preauth\]$
LogFilterPatterns=~Received disconnect from .+: Bye Bye \[preauth\]$
Затем выполните sudo systemctl daemon-reload
.
Ответ или решение
Скрытие неудачных попыток SSH для несуществующих пользователей является важной задачей для администраторов, стремящихся поддерживать порядок в журнале событий и снижать уровень "шумов" от брутфорс-атак. Вот несколько решений, которые помогут вам добиться этого.
1. Фильтрация журналов с помощью awk
Создайте скрипт, который будет фильтровать ненужные записи. В терминале запустите команду:
journalctl -f | awk -f filter.awk
Создайте файл filter.awk
со следующим содержимым:
# Убираем все, кроме записей sshd
$5 !~ /^sshd\[[0-9]*\]:$/ { print ; next }
# Показываем ошибки аутентификации для допустимых пользователей кроме root
/authentication failure/ && $15 != "" && $15 != "user=root"
/Failed password for/ && !/invalid user/ && !/for root/
# Показываем успешные входы
/Connection closed by authenticating user/
/Accepted publickey/
/pam_unix\(sshd:session):/
2. Настройки SSH для уменьшения шума
Чтобы существенно сократить количество записей в журналах, вы можете изменить настройки SSH в файле /etc/ssh/sshd_config
:
-
Отключите аутентификацию по паролю и используйте только ключи:
PasswordAuthentication no ChallengeResponseAuthentication no PermitRootLogin prohibit-password
-
Установите уровень логирования на
INFO
или ниже:LogLevel INFO
Такие изменения уменьшат количество записей от несуществующих пользователей.
3. Фильтрация журналов перед записью в систему
Если у вас установлена система systemd
версии 253 или выше, вы можете использовать параметры фильтрации логов. Создайте файл конфигурации /etc/systemd/system/ssh.service.d/logfilter.conf
со следующим содержимым:
[Service]
LogFilterPatterns=~Invalid user .+ from .+ port [0-9]+$
LogFilterPatterns=~Disconnected from invalid user .+ \[preauth\]$
LogFilterPatterns=~Connection closed by invalid user .+ \[preauth\]$
LogFilterPatterns=~Received disconnect from .+: Bye Bye \[preauth\]$
После этого выполните команду:
sudo systemctl daemon-reload
4. Использование fail2ban
Хотя вы уже используете fail2ban
, это очень полезный инструмент для блокировки IP-адресов, осуществляющих множественные неудачные попытки входа. Убедитесь, что ваши настройки соответствуют требованиям.
Заключение
С помощью вышеперечисленных методов вы сможете значительно уменьшить количество несущественных записей в журналах, сохранив при этом важные данные о попытках доступа к существующим аккаунтам. Правильная конфигурация позволит вам сосредоточиться на действительно значимых событиях и повысить уровень безопасности ваших систем.