Защита ssh от брутфорса. Блокирование IP при подборе паролей

Если у вас есть сервер, на котором должна быть возможность подключения по ssh из интернета, значит всегда будут желающие подобрать пароль (brute force) для входа. Как бороться с такими «переборщиками»?

Лучше всего сделать авторизацию по ключу. Можно поменять порт (поможет, но не от всех желающих). А что делать, если нужно использовать стандартный порт и авторизацию по паролю?

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

PermitRootLogin no

Далее, вы должны ограничить число пользователей у которых есть доступ к ssh.

AllowUsers user1 user2 user3

Эти настройки вы должны изменить или добавить в конфигурационном файле ssh /etc/ssh/sshd_config и перезапустить демон sshd.

Теперь в вашем /var/log/messages будет полно записей типа:

Oct 15 18:13:59 myserver sshd[7790]: Failed password for invalid user root from 212.83
.130.87 port 56520 ssh2

Можно избавиться и от этих назойливых попыток взлома. Достаточно установить и настроить одну из программ Fail2ban или DenyHosts. Они будут анализировать содержимое журнала /var/log/messages и особо ретивых брутфорсеров блокировать при помощи firewall.

Но мы лёгких путей не ищем! У меня на сервере нет python, необходимого для работы этих программ, да и блокировки при помощи файервола мне не нравятся.

Сделаем на perl простенький блокировщик с использованием /etc/hosts.deny. Он будет постоянно следить за сообщениями syslog, поступающими от sshd, анализировать их. Если с какого-то ip-адреса будет более 5 попыток входа «нелегальным» пользователем, этот ip будет добавлен в /etc/hosts.deny, а это значит демон tcpd заблокирует доступ с этого ip к sshd.

Для начала определимся где будет находиться наш блокировщик. Например в /root/bin/deny-hosts/.

mkdir /root/bin/deny-hosts

Создаём файл для списка заблокированных ip.

touch /etc/hosts.sshd.deny

В /etc/hosts.deny добавим такую строчку:

sshd : /etc/hosts.sshd.deny

Взаимодействие syslog и нашей программы организуем через именованные каналы (named pipe). Создаем канал:

mknod /root/bin/deny-hosts/auth.info p
chmod 600 /root/bin/deny-hosts/auth.info

И настроим syslog так чтобы сообщения от sshd попадали в этот канал. Добавим в /etc/syslog.conf такую строчку:

auth.info;mail.none             |/root/bin/deny-hosts/auth.info

Теперь в /root/bin/deny-hosts/ создадим deny-hosts.pl такого содержания:

#!/usr/bin/perl

use Sys::Syslog;

$from = "admin\@myserver.com";
$to = "admin\@myserver.com";
%ban;
%banned;

openlog("deny-hosts", "ndelay,pid", "local0");
open (FIFO, "/root/bin/deny-hosts/auth.info");

syslog(LOG_INFO, "started");

while (1) {
    while (<FIFO>) {
	$str = $_;
	if ($str=~/Failed password for invalid user .+ (.+) port/) {
	    if(!$ban{$1}) {
		$ban{$1}=1;
	    } else {
		$ban{$1}++;
	    }
	    foreach $key (keys %ban) {
		if($ban{$key}>5 && $key) {
		    if (!$banned{$key}) {
			open (BL, '>>/etc/hosts.sshd.deny');
			print BL $key,"\n";
			close(BL);
			smtp_send($key);
			syslog(LOG_INFO, "IP banned: $key");
		    }
		    delete($ban{$key});
		    $banned{$key} = 1;
		}
	    }
	}
    }
    smtp_send("syslog restarted");
    sleep 5;
}

syslog(LOG_INFO, "exited");

close (FIFO);
closelog();

sub smtp_send {
    my $body = $_[0];

    my $time = time();
    my ($sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,my $isdst) = localtime($time);
    my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d ", ($year+1900), ($mon+1), $mday, $hour, $min, $sec);

    if (open (SENDMAIL, "|/usr/sbin/sendmail -t")) {
        print SENDMAIL "From: $from\n";
        print SENDMAIL "To: $to\n";
        print SENDMAIL "Subject: IP banned $now\n\n";
        print SENDMAIL "$body";
        close (SENDMAIL);
    }
}

Следует заменить в коде email-адреса с которого будут отправляться и на который будут приходить сообщения о заблокированных ip-адресах (в 5 и 6 строках кода).

Дайте права на запуск:

chmod 755 /root/bin/deny-hosts/deny-hosts.pl

Можно запускать скрипт вручную, а можно написать такой вот скрипт запуска/перезапуска:

#!/bin/sh

killall deny-hosts.pl
/root/bin/deny-hosts/deny-hosts.pl &

И запускать его автоматически при старте системы.

Поделиться в FacebookДобавить в TwitterДобавить в Telegram

Комментарии

  1. (#)   Андрій:

    Привіт. А можна якесь роз’яснення щодо «можно написать такой вот скрипт запуска/перезапуска»? де цей скрипт має знаходитись? як налаштувать його увімкнення\активність?


  2. (#)   Дмитрий:

    Ви можете покласти його де вам зручно, а викликати як зазвичай, з /etc/rc.d/rc.local
    Це якщо у вас стара сиcтема ще без systemd

    Якщо в вашій системі вже використовується systemd то відповідні скрипти знайдете тут https://github.com/dshovchko/deny-hosts-pl (Але в такому разі я раджу встановити Fail2ban)


Оставить комментарий

Ответ на Защита ssh от брутфорса. Блокирование IP при подборе паролей