Что есть: сервисы ssh, ftp(vsftp), dovecot и многое другое, но о нём позже.
За основу я брал уже используюмою мной схему по защите exim.
Топология:
Несколько серверов, шлюзы, на которых крутятся разные сервися, весь syslog стикается на один сервер
Для работы нам нужен будет MySQL. Основная логика сделана на процедурах и тригере(оракловци дали понять, что так проще).
Создаём таблици
Код: Выделить всё
CREATE TABLE hack_exp(
ip CHAR(15),
date_delete CHAR(19) DEFAULT NULL,
active INT(1) DEFAULT 0,
PRIMARY KEY (ip)
)
ENGINE = MEMORY;
CREATE TABLE hack_pass(
ip CHAR(15),
count INT(4) DEFAULT NULL,
host VARCHAR(20) DEFAULT NULL,
date_original CHAR(19) DEFAULT NULL,
date_insert CHAR(19) DEFAULT NULL,
date_last CHAR(19) DEFAULT NULL,
date_exp CHAR(19) DEFAULT NULL,
type CHAR(5) DEFAULT NULL,
PRIMARY KEY (ip)
)
ENGINE = MEMORY;
CREATE TABLE log_list(
log_string VARCHAR(255) DEFAULT NULL
)
ENGINE = MYISAM;
Код: Выделить всё
CREATE
TRIGGER ins_into_hack
AFTER INSERT
ON log_list
FOR EACH ROW
BEGIN
SET @t_str = new.log_string;
-- Время первого заноса в таблицу
SET @t_date_insert = NOW();
-- Время последнего заноса в таблицу
SET @t_date_last = NOW();
-- Интервал, за который идёт анализ
SET @t_date_expire = NOW() + INTERVAL 10 MINUTE;
-- Вызываем процедуру, парсящую строки логов
-- CALL deny_ip.string_parser(@t_str, @t_ip, @t_host, @t_date_original);
CALL deny_ip.case_type(@t_str, @t_ip, @t_host, @t_date_original, @t_type);
-- Заносим данные в таблицу колектор и, в случии нахождения ip, обновляем и добавляем очки
INSERT INTO deny_ip.hack_pass (ip, count, host, date_original, date_insert, date_last, date_exp, type) VALUES (@t_ip, 1, @t_host, @t_date_original, @t_date_insert, @t_date_last, @t_date_expire, @t_type)
ON DUPLICATE KEY
UPDATE
deny_ip.hack_pass.count = deny_ip.hack_pass.count + 1,
deny_ip.hack_pass.date_exp = @t_date_expire,
deny_ip.hack_pass.date_last = deny_ip.hack_pass.date_last;
-- Заносим данные в таблицу, из которой информацию черпает фаервол
-- Данные заносятся из таблици коллектора
-- coun >5 - это условие, при котором можно с увереностью сказать,
-- что вас или спамят или ддосят, интервал анализа - @date_expire
-- date_expire + INTERVAL 10 MINUTE интервал, сколько в фаерволе будет находится ip
INSERT IGNORE INTO deny_ip.hack_exp (ip, date_delete)
SELECT
ip, date_exp + INTERVAL 10 MINUTE
FROM
deny_ip.hack_pass
WHERE
count > 5;
-- Удаляем просроченные или записи из таблици коллектора
-- по времени оканчания срока жизни @date_expire
DELETE
FROM
deny_ip.hack_pass
WHERE
LEFT(date_exp, 16) < NOW();
-- Удаляем из таблици коллектора свои подсети
-- Надо будет переделать на свой whitelist, хранимый в мускуле
DELETE
FROM
deny_ip.hack_pass
WHERE
ip LIKE '10.4.%' OR ip LIKE '192.168.%' OR ip LIKE '217.112.%';
END
Код: Выделить всё
DELIMITER $$
--
-- Описание для процедуры case_type
--
CREATE PROCEDURE case_type(IN i VARCHAR(255), OUT o_ip CHAR(15), OUT o_host VARCHAR(55), OUT o_date CHAR(19), OUT o_type CHAR(5))
BEGIN
-- Опрделяем тип события
SELECT
CASE
WHEN (i LIKE '%lid user%') AND (i LIKE '%ssh%') THEN 'sshi'
WHEN (i LIKE '%POSS%') AND (i LIKE '%ssh%') THEN 'sshp'
WHEN (i LIKE '%Aborted login%') AND (i LIKE '%pop3-login%') THEN 'dovp'
END
INTO
@wer;
-- Вызываем соответствующую процедеру для события
CASE @wer
WHEN 'sshi' THEN
CALL deny_ip.ssh_invalid(i, o_ip, o_host, o_date, o_type);
WHEN 'sshp' THEN
CALL deny_ip.ssh_posible(i, o_ip, o_host, o_date, o_type);
WHEN 'dovp' THEN
CALL deny_ip.dovecot_pop3(i, o_ip, o_host, o_date, o_type);
END CASE;
END
$$
--
-- Описание для процедуры dovecot_pop3
--
CREATE PROCEDURE dovecot_pop3(IN in_str VARCHAR(255), OUT out_ip CHAR(15), OUT out_host VARCHAR(55), OUT out_date_orig CHAR(19), OUT out_type CHAR(5))
BEGIN
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'rip=', -1), ',', 1)
INTO
out_ip;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, ':', 3), ' ', -1)
INTO
out_host;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'dovecot:', 1), ' ', 3)
INTO
out_date_orig;
SET out_type = 'dovp';
END
$$
--
-- Описание для процедуры ssh_invalid
--
CREATE PROCEDURE ssh_invalid(IN in_str VARCHAR(255), OUT out_ip CHAR(15), OUT out_host VARCHAR(55), OUT out_date_orig CHAR(19), OUT out_type CHAR(5))
BEGIN
SELECT
SUBSTRING_INDEX(in_str, ' ', -1)
INTO
out_ip;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'sshd[', 1), ' ', -2)
INTO
out_host;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'sshd[', 1), ' ', 3)
INTO
out_date_orig;
-- SET out_ip = 'inv';
SET out_type = 'sshi';
END
$$
--
-- Описание для процедуры ssh_posible
--
CREATE PROCEDURE ssh_posible(IN in_str VARCHAR(255), OUT out_ip CHAR(15), OUT out_host VARCHAR(55), OUT out_date_orig CHAR(19), INOUT out_type CHAR(5))
BEGIN
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, "[", -1), ']', 1)
INTO
out_ip;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, "[", 1), ' ', -2), ' ', 1)
INTO
out_host;
SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'sshd[', 1), ' ', 3)
INTO
out_date_orig;
SET out_type = 'sshp';
END
$$
$$
Код: Выделить всё
[root@hqgw1:/scripts/deny]# cat ./add_ipfw_hack_pass.sh
#!/usr/local/bin/bash
/usr/local/bin/mysql --host=10.4.250.3 --password='pass'--user=deny_ip deny_ip --execute=' \
update deny_ip.hack_exp \
set active = 2 \
WHERE \
LEFT(date_delete, 16) < NOW() and active = 1; \
SELECT "ipfw table 101 add " asdf, ip FROM deny_ip.hack_exp \
WHERE \
active = 0; \
SELECT "ipfw table 101 delete " asdf, ip FROM deny_ip.hack_exp \
WHERE \
active = 2; \
UPDATE deny_ip.hack_exp \
SET active = 1 where active = 0; \
delete FROM deny_ip.hack_exp \
WHERE \
LEFT(date_delete, 16) < NOW() and active = 2;'| grep -v asdf>/tmp/pass_hack_ipfw_add_table_blacklist.sh
. /tmp/pass_hack_ipfw_add_table_blacklist.sh
rm /tmp/pass_hack_ipfw_add_table_blacklist.sh
Код: Выделить всё
${fwcmd} add 58 deny log ip from table\(101\) to any via ${ifwan}
Код: Выделить всё
# touch /var/log/all.log and chmod it to mode 600 before it will work
*.* /var/log/all.log
Код: Выделить всё
cat /scripts/deny/service.sh
#!/usr/local/bin/bash
msql="/usr/local/bin/mysql --user=deny_ip --password=deny_ip --database=deny_ip --host=10.4.250.3"
lf="/var/log/all.log"
cp ${lf} ${lf}.tmp
> ${lf}
cat ${lf}.tmp >> ${lf}.store
## insert into mysql
cat ${lf}.store|egrep -e "Invalid user|POSSIBLE BREAK-IN ATTEMPT|FAIL LOGIN|: Aborted login" | \
sed 's/"//g'|sed 's/^/INSERT INTO deny_ip.log_list (log_string) VALUES ("/g'|sed 's/$/");/g' | ${msql}
rm -f ${lf}.tmp
Расширение на новый функционал происходит путём написания процедуры
Код: Выделить всё
CREATE PROCEDURE deny_ip.string_parser(IN in_str VARCHAR(255), OUT out_ip CHAR(15), OUT out_host VARCHAR(55), OUT out_date_orig CHAR(19), OUT out_type CHAR(5))
BEGIN
-- в этой секции строка парсится на определение ip удалённого хоста
SELECT SUBSTRING_INDEX(in_str, ' ', -1) INTO out_ip;
-- в этой секции строка парсится на определение имени хоста, на который бомбят
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'sshd[', 1), ' ', -2) INTO out_host;
-- в этой секции строка парсится на определение времени события
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(in_str, 'sshd[', 1), ' ', 3) INTO out_date_orig;
-- в этой секции определяем тип события
SET out_type = 'pos';
END
Код: Выделить всё
WHEN (i LIKE '%lid user%') AND (i LIKE '%ssh%') THEN 'sshi'
Код: Выделить всё
WHEN 'sshi' THEN
CALL deny_ip.sshi(i, o_ip, o_host, o_date, o_type);