The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Hедостатки ssh (ssh flood security)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: ssh, flood, security,  (найти похожие документы)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _ From : Solar Designer 2:5020/400 27 Nov 98 00:59:24 Subj : Hедостатки ssh ________________________________________________________________________________ From: Solar Designer <[email protected]> Solar Designer <[email protected]> wrote: > Именно поэтому я и говорю, что задача нетривиальная. Также, поэтому я > говорю насчет поддержки в ядре (SYN flood'ы -- это его дело). Короче, > тут просто надо начать пробовать, я лучше не буду много рассуждать. Вот и попробовал. Все получается как надо. Единственный недостаток -- не удается послать RST сразу -- 3-way handshake происходит вообще до accept(2). Впрочем, никаких опасных последствий от этого не вижу. А так, на 2.0.36 с SYN cookies, даже при DAEMON_SYN_LIMIT=1 (см. пример ниже) все живет без проблем. Проверялось под одновременным SYN и connect() флудом, и нормально пропускало и обрабатывало соединение с другого адреса. Можно будет в таком стиле (только аккуратнее, чем в примере) делать и для SSH и для xinetd. #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define DAEMON_PORT 9999 #define DAEMON_SYN_LIMIT 1 #define DAEMON_SOURCE_LIMIT 2 #define DAEMON_TOTAL_LIMIT 3 struct source { struct in_addr addr; int pid; }; int total; struct source source[DAEMON_TOTAL_LIMIT]; int ptr, found; void pexit(char *s) { perror(s); exit(1); } void handle_connection(int sock) { char c; if (read(sock, &c, 1) == 1) write(sock, &c, 1); } void handle_child() { int status, pid; int i; if ((pid = wait(&status)) > 0) { total--; for (i = 0; i < DAEMON_TOTAL_LIMIT; i++) if (source[i].pid == pid) { source[i].addr.s_addr = 0; source[i].pid = 0; break; } if (i == DAEMON_TOTAL_LIMIT) found = 0; } signal(SIGCHLD, handle_child); } int main() { int sock, new; int true = 1; struct sockaddr_in addr; int addrlen; int i, n; if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) pexit("socket"); if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(true))) pexit("setsockopt"); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(DAEMON_PORT); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) pexit("bind"); if (listen(sock, DAEMON_SYN_LIMIT)) pexit("listen"); signal(SIGCHLD, handle_child); total = 0; memset(source, 0, sizeof(source)); while (1) { addrlen = sizeof(addr); new = accept(sock, (struct sockaddr *)&addr, &addrlen); if (new < 0) { if (errno != EINTR) perror("accept"); continue; } printf("Connection from %s\n", inet_ntoa(addr.sin_addr)); if (total >= DAEMON_TOTAL_LIMIT) goto reject; n = 0; for (i = 0; i < DAEMON_TOTAL_LIMIT; i++) if (source[i].addr.s_addr == addr.sin_addr.s_addr) n++; if (n >= DAEMON_SOURCE_LIMIT) goto reject; ptr = 0; while (source[ptr].pid && ptr < DAEMON_TOTAL_LIMIT - 1) ptr++; found = 1; switch ((source[ptr].pid = fork())) { case -1: perror("fork"); break; case 0: handle_connection(new); exit(0); default: total++; source[ptr].addr = addr.sin_addr; if (!found) { source[ptr].addr.s_addr = 0; source[ptr].pid = 0; } } reject: if (close(new)) pexit("close"); } return 0; } -- /sd --- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру