mirror of https://github.com/acanas/swad-core.git
Version 21.4: Sep 15, 2021 New module swad_firewall_database for database queries related to firewall.
This commit is contained in:
parent
9d25990134
commit
26eddc4534
5
Makefile
5
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 \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <stdlib.h> // 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 ClickTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
|
||||
(unsigned long) Fw_TIME_TO_DELETE_OLD_CLICKS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** Check if IP is banned ***************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -100,13 +61,7 @@ void Fir_CheckFirewallAndExitIfBanned (void)
|
|||
unsigned NumCurrentBans;
|
||||
|
||||
/***** Get number of current bans from database *****/
|
||||
NumCurrentBans = (unsigned)
|
||||
DB_QueryCOUNT ("can not check firewall log",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM fir_banned"
|
||||
" WHERE IP='%s'"
|
||||
" AND UnbanTime>NOW()",
|
||||
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,"<html>"
|
||||
"<head>"
|
||||
"<title>%s</title>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<h1>%s</h1>"
|
||||
"</body>"
|
||||
"<head>"
|
||||
"<title>%s</title>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<h1>%s</h1>"
|
||||
"</body>"
|
||||
"</html>\n",
|
||||
Title,H1);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <stdlib.h> // 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 ClickTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
|
||||
(unsigned long) Fw_TIME_TO_DELETE_OLD_CLICKS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************************* Ban an IP *********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Fir_DB_BanIP (void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Get number of current bans from database ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Fir_DB_GetNumBansIP (void)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QueryCOUNT ("can not check firewall log",
|
||||
"SELECT COUNT(*)"
|
||||
" FROM fir_banned"
|
||||
" WHERE IP='%s'"
|
||||
" AND UnbanTime>NOW()",
|
||||
Gbl.IP);
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* 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
|
|
@ -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))
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue