From 26eddc4534d3a5a12c4d7620c5551942778db83a Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 15 Sep 2021 08:14:09 +0200 Subject: [PATCH] Version 21.4: Sep 15, 2021 New module swad_firewall_database for database queries related to firewall. --- Makefile | 5 +- swad_changelog.h | 3 +- swad_firewall.c | 88 ++++------------------------ swad_firewall.h | 14 ++++- swad_firewall_database.c | 122 +++++++++++++++++++++++++++++++++++++++ swad_firewall_database.h | 45 +++++++++++++++ swad_layout.c | 4 +- swad_main.c | 1 + 8 files changed, 196 insertions(+), 86 deletions(-) create mode 100644 swad_firewall_database.c create mode 100644 swad_firewall_database.h diff --git a/Makefile b/Makefile index 973bd230..5088ec55 100644 --- a/Makefile +++ b/Makefile @@ -48,8 +48,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \ swad_exam_database.o swad_exam_log.o swad_exam_print.o \ swad_exam_result.o swad_exam_session.o swad_exam_set.o \ swad_figure.o swad_figure_cache.o swad_figure_database.o swad_file.o \ - swad_file_extension.o swad_file_MIME.o swad_firewall.o swad_follow.o \ - swad_follow_database.o swad_form.o swad_forum.o \ + swad_file_extension.o swad_file_MIME.o swad_firewall.o \ + swad_firewall_database.o swad_follow.o swad_follow_database.o \ + swad_form.o swad_forum.o \ swad_game.o swad_global.o swad_group.o swad_group_database.o \ swad_help.o swad_hierarchy.o swad_hierarchy_config.o swad_holiday.o \ swad_HTML.o \ diff --git a/swad_changelog.h b/swad_changelog.h index 0a76fef4..6ae81d37 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.3.1 (2021-09-15)" +#define Log_PLATFORM_VERSION "SWAD 21.4 (2021-09-15)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.4: Sep 15, 2021 New module swad_firewall_database for database queries related to firewall. (315286 lines) Version 21.3.1: Sep 15, 2021 Queries moved to module swad_browser_database. (315201 lines) Version 21.3: Sep 15, 2021 New module swad_notification_database for database queries related to notifications. (315211 lines) Version 21.2.2: Sep 14, 2021 Queries moved to module swad_browser_database. (315051 lines) diff --git a/swad_firewall.c b/swad_firewall.c index fb66129e..66849396 100644 --- a/swad_firewall.c +++ b/swad_firewall.c @@ -28,6 +28,8 @@ #include // For exit #include "swad_database.h" +#include "swad_firewall.h" +#include "swad_firewall_database.h" #include "swad_global.h" /*****************************************************************************/ @@ -40,17 +42,6 @@ extern struct Globals Gbl; /***************************** Private constants *****************************/ /*****************************************************************************/ -/* The maximum number of clicks in the interval - should be large enough to prevent an IP from being banned - due to automatic refresh when the user is viewing the last clicks. */ -#define Fw_CHECK_INTERVAL ((time_t)(30UL)) // Check clicks in the last 30 seconds -#define Fw_MAX_CLICKS_IN_INTERVAL 150 // Maximum of 150 clicks allowed in 30 seconds - // (5 clicks/s sustained for 30 s) - -#define Fw_TIME_BANNED ((time_t)(60UL*60UL)) // Ban IP for 1 hour - -#define Fw_TIME_TO_DELETE_OLD_CLICKS Fw_CHECK_INTERVAL // Remove clicks older than these seconds - /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ @@ -59,38 +50,8 @@ extern struct Globals Gbl; /****************************** Private prototypes ***************************/ /*****************************************************************************/ -static void Fir_DB_BanIP (void); - static void Fir_WriteHTML (const char *Title,const char *H1); -/*****************************************************************************/ -/************************** Log access into firewall *************************/ -/*****************************************************************************/ - -void Fir_DB_LogAccess (void) - { - /***** Log access in firewall recent log *****/ - DB_QueryINSERT ("can not log access into firewall_log", - "INSERT INTO fir_log" - " (ClickTime,IP)" - " VALUES" - " (NOW(),'%s')", - Gbl.IP); - } - -/*****************************************************************************/ -/********************** Remove old clicks from firewall **********************/ -/*****************************************************************************/ - -void Fir_DB_PurgeFirewall (void) - { - /***** Remove old clicks *****/ - DB_QueryDELETE ("can not purge firewall log", - "DELETE LOW_PRIORITY FROM fir_log" - " WHERE ClickTimeNOW()", - Gbl.IP); + NumCurrentBans = Fir_DB_GetNumBansIP (); /***** Exit with status 403 if banned *****/ /* RFC 6585 suggests "403 Forbidden", according to @@ -134,14 +89,7 @@ void Fir_CheckFirewallAndExitIfTooManyRequests (void) unsigned NumClicks; /***** Get number of clicks from database *****/ - NumClicks = (unsigned) - DB_QueryCOUNT ("can not check firewall log", - "SELECT COUNT(*)" - " FROM fir_log" - " WHERE IP='%s'" - " AND ClickTime>FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)", - Gbl.IP, - Fw_CHECK_INTERVAL); + NumClicks = Fir_DB_GetNumClicksFromLog (); /***** Exit with status 429 if too many connections *****/ /* RFC 6585 suggests "429 Too Many Requests", according to @@ -169,31 +117,15 @@ void Fir_CheckFirewallAndExitIfTooManyRequests (void) /********************************* Ban an IP *********************************/ /*****************************************************************************/ -static void Fir_DB_BanIP (void) - { - /***** Insert IP into table of banned IPs *****/ - DB_QueryINSERT ("can not ban IP", - "INSERT INTO fir_banned" - " (IP,BanTime,UnbanTime)" - " VALUES" - " ('%s',NOW(),FROM_UNIXTIME(UNIX_TIMESTAMP()+%lu))", - Gbl.IP, - (unsigned long) Fw_TIME_BANNED); - } - -/*****************************************************************************/ -/********************************* Ban an IP *********************************/ -/*****************************************************************************/ - static void Fir_WriteHTML (const char *Title,const char *H1) { fprintf (stdout,"" - "" - "%s" - "" - "" - "

%s

" - "" + "" + "%s" + "" + "" + "

%s

" + "" "\n", Title,H1); } diff --git a/swad_firewall.h b/swad_firewall.h index da946de2..5c6bdfa0 100644 --- a/swad_firewall.h +++ b/swad_firewall.h @@ -31,13 +31,21 @@ /************************** Public types and constants ***********************/ /*****************************************************************************/ +/* The maximum number of clicks in the interval + should be large enough to prevent an IP from being banned + due to automatic refresh when the user is viewing the last clicks. */ +#define Fw_CHECK_INTERVAL ((time_t)(30UL)) // Check clicks in the last 30 seconds +#define Fw_MAX_CLICKS_IN_INTERVAL 150 // Maximum of 150 clicks allowed in 30 seconds + // (5 clicks/s sustained for 30 s) + +#define Fw_TIME_BANNED ((time_t)(60UL*60UL)) // Ban IP for 1 hour + +#define Fw_TIME_TO_DELETE_OLD_CLICKS Fw_CHECK_INTERVAL // Remove clicks older than these seconds + /*****************************************************************************/ /***************************** Public prototypes *****************************/ /*****************************************************************************/ -void Fir_DB_LogAccess (void); -void Fir_DB_PurgeFirewall (void); - void Fir_CheckFirewallAndExitIfBanned (void); void Fir_CheckFirewallAndExitIfTooManyRequests (void); diff --git a/swad_firewall_database.c b/swad_firewall_database.c new file mode 100644 index 00000000..4dc63495 --- /dev/null +++ b/swad_firewall_database.c @@ -0,0 +1,122 @@ +// swad_firewall_database.c: firewall to mitigate denial of service attacks, operations with database + +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2021 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include // For exit + +#include "swad_database.h" +#include "swad_firewall.h" +#include "swad_global.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Private types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Private prototypes ***************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/********************* Log access into firewall recent log *******************/ +/*****************************************************************************/ + +void Fir_DB_LogAccess (void) + { + DB_QueryINSERT ("can not log access into firewall_log", + "INSERT INTO fir_log" + " (ClickTime,IP)" + " VALUES" + " (NOW(),'%s')", + Gbl.IP); + } + +/*****************************************************************************/ +/********************* Get number of clicks from database ********************/ +/*****************************************************************************/ + +unsigned Fir_DB_GetNumClicksFromLog (void) + { + return (unsigned) + DB_QueryCOUNT ("can not check firewall log", + "SELECT COUNT(*)" + " FROM fir_log" + " WHERE IP='%s'" + " AND ClickTime>FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)", + Gbl.IP, + Fw_CHECK_INTERVAL); + } + +/*****************************************************************************/ +/********************** Remove old clicks from firewall **********************/ +/*****************************************************************************/ + +void Fir_DB_PurgeFirewallLog (void) + { + DB_QueryDELETE ("can not purge firewall log", + "DELETE LOW_PRIORITY FROM fir_log" + " WHERE ClickTimeNOW()", + Gbl.IP); + } diff --git a/swad_firewall_database.h b/swad_firewall_database.h new file mode 100644 index 00000000..9dfbfa68 --- /dev/null +++ b/swad_firewall_database.h @@ -0,0 +1,45 @@ +// swad_firewall_database.h: firewall to mitigate denial of service attacks, operations with database + +#ifndef _SWAD_FW_DB +#define _SWAD_FW_DB +/* + SWAD (Shared Workspace At a Distance in Spanish), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2021 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************************** Public types and constants ***********************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +void Fir_DB_LogAccess (void); +unsigned Fir_DB_GetNumClicksFromLog (void); +void Fir_DB_PurgeFirewallLog (void); + +void Fir_DB_BanIP (void); +unsigned Fir_DB_GetNumBansIP (void); + +#endif diff --git a/swad_layout.c b/swad_layout.c index f86d9707..9188ca2f 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -41,7 +41,7 @@ #include "swad_database.h" #include "swad_error.h" #include "swad_exam_session.h" -#include "swad_firewall.h" +#include "swad_firewall_database.h" #include "swad_follow.h" #include "swad_form.h" #include "swad_global.h" @@ -1437,7 +1437,7 @@ void Lay_RefreshNotifsAndConnected (void) if (!(Gbl.PID % 11)) Ntf_SendPendingNotifByEMailToAllUsrs (); // Send pending notifications by email else if (!(Gbl.PID % 19)) - Fir_DB_PurgeFirewall (); // Remove old clicks from firewall + Fir_DB_PurgeFirewallLog (); // Remove old clicks from firewall else if (!(Gbl.PID % 23)) Fil_RemoveOldTmpFiles (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC ,Cfg_TIME_TO_DELETE_BROWSER_TMP_FILES ,false); // Remove the oldest temporary public directories used for downloading else if (!(Gbl.PID % 101)) diff --git a/swad_main.c b/swad_main.c index 48468618..03d7cce4 100644 --- a/swad_main.c +++ b/swad_main.c @@ -37,6 +37,7 @@ #include "swad_database.h" #include "swad_error.h" #include "swad_firewall.h" +#include "swad_firewall_database.h" #include "swad_global.h" #include "swad_hierarchy.h" #include "swad_hierarchy_level.h"