mirror of https://github.com/acanas/swad-core.git
Version 18.40
This commit is contained in:
parent
c62e46d617
commit
3c4dc97d5b
14
sql/swad.sql
14
sql/swad.sql
|
@ -522,9 +522,19 @@ CREATE TABLE IF NOT EXISTS files (
|
|||
INDEX(ZoneUsrCod),
|
||||
INDEX(PublisherUsrCod));
|
||||
--
|
||||
-- Table firewall: stores the most recent IPs in order to mitigate denial of service attacks
|
||||
-- Table firewall_banned: stores the banned IPs in order to mitigate denial of service attacks
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS firewall (
|
||||
CREATE TABLE IF NOT EXISTS firewall_banned (
|
||||
IP CHAR(15) NOT NULL,
|
||||
BanTime DATETIME NOT NULL,
|
||||
UnbanTime DATETIME NOT NULL,
|
||||
INDEX(IP,UnbanTime),
|
||||
INDEX(BanTime),
|
||||
INDEX(UnbanTime));
|
||||
--
|
||||
-- Table firewall_log: stores the most recent IPs in order to mitigate denial of service attacks
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS firewall_log (
|
||||
ClickTime DATETIME NOT NULL,
|
||||
IP CHAR(15) NOT NULL,
|
||||
INDEX(ClickTime),
|
||||
|
|
|
@ -335,9 +335,6 @@ Buenos d
|
|||
// TODO: Que la opción por defecto en "Permitir que los profesores vean este examen" la configuren los profesores en cada asignatura"
|
||||
// TODO: URGENTE: Bego del Pino, una columna en resultados de test que indique los descriptores de ese examen
|
||||
|
||||
// TODO: Pedro Villar Castro:
|
||||
// Al asignar un TFG a alumnos, no escribir el DNI del alumno, sino escogerlo de una lista de entre los alumnos inscritos en la asignatura.
|
||||
|
||||
// TODO: Cuando se muestre un usuario duplicado, que SWAD calcule automáticamente sus cifras no calculadas sin tener que pulsar en Calcular
|
||||
|
||||
// TODO: Miguel Damas Hermoso sugiere poder editar texto enriquecido (Markdown) en las preguntas de tipo test
|
||||
|
@ -361,6 +358,15 @@ Buenos d
|
|||
|
||||
// TODO: Tabla de asistencia con símbolos tip ok como entidades HTML
|
||||
|
||||
// TODO: Pedro Villar Castro:
|
||||
// Al asignar un TFG a alumnos, no escribir el DNI del alumno, sino escogerlo de una lista de entre los alumnos inscritos en la asignatura.
|
||||
|
||||
// TODO: Pedro Villar Castro:
|
||||
// Bloquear individualmente la edición con una casilla de configuración para cada TFG, sólo el profesor de la asignatura (Perico) podría bloquear/desbloquear
|
||||
// Que haya una opción general que los bloquee todos y que los desbloquee todos
|
||||
// Para bloquear/desbloquear se usará un icono candado
|
||||
// Para preasignado/no preasignado usar otro icono (usuario/usuario tachado, por ej.)
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -380,11 +386,16 @@ En OpenSWAD:
|
|||
ps2pdf source.ps destination.pdf
|
||||
*/
|
||||
|
||||
#define Log_PLATFORM_VERSION "SWAD 18.39 (2019-02-13)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 18.40 (2019-02-13)"
|
||||
#define CSS_FILE "swad18.33.css"
|
||||
#define JS_FILE "swad18.32.1.js"
|
||||
/*
|
||||
Version 18.39: Feb 13, 2019 New module swad_firewall to mitigate mitigate DoS attacks. (239101 lines)
|
||||
Version 18.40: Feb 13, 2019 New table for banned IPs to mitigate DoS attacks. (239198 lines)
|
||||
2 changes necessary in database:
|
||||
RENAME TABLE firewall TO firewall_log;
|
||||
CREATE TABLE IF NOT EXISTS firewall_banned (IP CHAR(15) NOT NULL,BanTime DATETIME NOT NULL,UnbanTime DATETIME NOT NULL,INDEX(IP,UnbanTime),INDEX(BanTime),INDEX(UnbanTime));
|
||||
|
||||
Version 18.39: Feb 13, 2019 New module swad_firewall to mitigate DoS attacks. (239101 lines)
|
||||
1 change necessary in database:
|
||||
CREATE TABLE IF NOT EXISTS firewall (ClickTime DATETIME NOT NULL,IP CHAR(15) NOT NULL,INDEX(ClickTime),INDEX(IP));
|
||||
|
||||
|
|
|
@ -1149,9 +1149,29 @@ mysql> DESCRIBE files;
|
|||
"INDEX(ZoneUsrCod),"
|
||||
"INDEX(PublisherUsrCod))");
|
||||
|
||||
/***** Table firewall *****/
|
||||
/***** Table firewall_banned *****/
|
||||
/*
|
||||
mysql> DESCRIBE firewall;
|
||||
mysql> DESCRIBE firewall_banned;
|
||||
+-----------+----------+------+-----+---------+-------+
|
||||
| Field | Type | Null | Key | Default | Extra |
|
||||
+-----------+----------+------+-----+---------+-------+
|
||||
| IP | char(15) | NO | MUL | NULL | |
|
||||
| BanTime | datetime | NO | MUL | NULL | |
|
||||
| UnbanTime | datetime | NO | MUL | NULL | |
|
||||
+-----------+----------+------+-----+---------+-------+
|
||||
3 rows in set (0.00 sec)
|
||||
*/
|
||||
DB_CreateTable ("CREATE TABLE IF NOT EXISTS firewall_banned ("
|
||||
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP
|
||||
"BanTime DATETIME NOT NULL,"
|
||||
"UnbanTime DATETIME NOT NULL,"
|
||||
"INDEX(IP,UnbanTime),"
|
||||
"INDEX(BanTime),"
|
||||
"INDEX(UnbanTime));");
|
||||
|
||||
/***** Table firewall_log *****/
|
||||
/*
|
||||
mysql> DESCRIBE firewall_log;
|
||||
+-----------+----------+------+-----+---------+-------+
|
||||
| Field | Type | Null | Key | Default | Extra |
|
||||
+-----------+----------+------+-----+---------+-------+
|
||||
|
@ -1160,7 +1180,7 @@ mysql> DESCRIBE firewall;
|
|||
+-----------+----------+------+-----+---------+-------+
|
||||
2 rows in set (0.00 sec)
|
||||
*/
|
||||
DB_CreateTable ("CREATE TABLE IF NOT EXISTS firewall ("
|
||||
DB_CreateTable ("CREATE TABLE IF NOT EXISTS firewall_log ("
|
||||
"ClickTime DATETIME NOT NULL,"
|
||||
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP
|
||||
"INDEX(ClickTime),"
|
||||
|
|
|
@ -38,9 +38,14 @@ 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)(10UL)) // Check clicks in the last 10 seconds
|
||||
#define Fw_MAX_CLICKS_IN_INTERVAL 30 // Maximum of 30 clicks allowed in 10 seconds
|
||||
|
||||
#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
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -51,6 +56,8 @@ extern struct Globals Gbl;
|
|||
/***************************** Internal prototypes ***************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void FW_BanIP (void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Log access into firewall *************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -58,13 +65,67 @@ extern struct Globals Gbl;
|
|||
void FW_LogAccess (void)
|
||||
{
|
||||
/***** Log access in firewall recent log *****/
|
||||
DB_QueryINSERT ("can not log access into firewall",
|
||||
"INSERT INTO firewall (ClickTime,IP) VALUES (NOW(),'%s')",
|
||||
DB_QueryINSERT ("can not log access into firewall_log",
|
||||
"INSERT INTO firewall_log"
|
||||
" (ClickTime,IP)"
|
||||
" VALUES"
|
||||
" (NOW(),'%s')",
|
||||
Gbl.IP);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Log access into firewall *************************/
|
||||
/********************** Remove old clicks from firewall **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void FW_PurgeFirewall (void)
|
||||
{
|
||||
/***** Remove old clicks *****/
|
||||
DB_QueryDELETE ("can not purge firewall log",
|
||||
"DELETE LOW_PRIORITY FROM firewall_log"
|
||||
" WHERE ClickTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
|
||||
(unsigned long) Fw_TIME_TO_DELETE_OLD_CLICKS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** Check if IP is banned ***************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void FW_CheckFirewallAndExitIfBanned (void)
|
||||
{
|
||||
unsigned long NumCurrentBans;
|
||||
|
||||
/***** Get number of current bans from database *****/
|
||||
NumCurrentBans = DB_QueryCOUNT ("can not check firewall log",
|
||||
"SELECT COUNT(*) FROM firewall_banned"
|
||||
" WHERE IP='%s' AND UnbanTime>NOW()",
|
||||
Gbl.IP);
|
||||
|
||||
/***** Exit with status 403 if banned *****/
|
||||
/* RFC 6585 suggests "429 Too Many Requests", according to
|
||||
https://stackoverflow.com/questions/7447283/proper-http-status-to-return-for-hacking-attempts
|
||||
https://tools.ietf.org/html/rfc2616#section-10.4.4 */
|
||||
if (NumCurrentBans)
|
||||
{
|
||||
/* Return status 403 Forbidden */
|
||||
fprintf (stdout,"Content-Type: text/html; charset=windows-1252\n"
|
||||
"Status: 403\r\n\r\n"
|
||||
"<html>"
|
||||
"<head>"
|
||||
"<title>Forbidden</title>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<h1>You are banned temporarily</h1>"
|
||||
"</body>"
|
||||
"</html>\n");
|
||||
|
||||
/* Close database connection and exit */
|
||||
DB_CloseDBConnection ();
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************** Check if too many connections from this IP *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void FW_CheckFirewallAndExitIfTooManyRequests (void)
|
||||
|
@ -72,8 +133,8 @@ void FW_CheckFirewallAndExitIfTooManyRequests (void)
|
|||
unsigned long NumClicks;
|
||||
|
||||
/***** Get number of clicks from database *****/
|
||||
NumClicks = DB_QueryCOUNT ("can not check firewall",
|
||||
"SELECT COUNT(*) FROM firewall"
|
||||
NumClicks = DB_QueryCOUNT ("can not check firewall log",
|
||||
"SELECT COUNT(*) FROM firewall_log"
|
||||
" WHERE IP='%s'"
|
||||
" AND ClickTime>FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
|
||||
Gbl.IP,
|
||||
|
@ -85,9 +146,12 @@ void FW_CheckFirewallAndExitIfTooManyRequests (void)
|
|||
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429 */
|
||||
if (NumClicks > Fw_MAX_CLICKS_IN_INTERVAL)
|
||||
{
|
||||
/* Ban this IP */
|
||||
FW_BanIP ();
|
||||
|
||||
/* Return status 429 Too Many Requests */
|
||||
fprintf (stdout,"Content-Type: text/html; charset=windows-1252\n"
|
||||
"Retry-After: 3600\n"
|
||||
"Retry-After: %lu\n"
|
||||
"Status: 429\r\n\r\n"
|
||||
"<html>"
|
||||
"<head>"
|
||||
|
@ -96,7 +160,8 @@ void FW_CheckFirewallAndExitIfTooManyRequests (void)
|
|||
"<body>"
|
||||
"<h1>Please stop that</h1>"
|
||||
"</body>"
|
||||
"</html>\n");
|
||||
"</html>\n",
|
||||
(unsigned long) Fw_TIME_BANNED);
|
||||
|
||||
/* Close database connection and exit */
|
||||
DB_CloseDBConnection ();
|
||||
|
@ -105,14 +170,16 @@ void FW_CheckFirewallAndExitIfTooManyRequests (void)
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Remove old clicks from firewall **********************/
|
||||
/********************************* Ban an IP *********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void FW_PurgeFirewall (void)
|
||||
static void FW_BanIP (void)
|
||||
{
|
||||
/***** Remove old clicks *****/
|
||||
DB_QueryDELETE ("can not purge firewall",
|
||||
"DELETE LOW_PRIORITY FROM firewall"
|
||||
" WHERE ClickTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
|
||||
Fw_TIME_TO_DELETE_OLD_CLICKS);
|
||||
/***** Insert IP into table of banned IPs *****/
|
||||
DB_QueryINSERT ("can not ban IP",
|
||||
"INSERT INTO firewall_banned"
|
||||
" (IP,BanTime,UnbanTime)"
|
||||
" VALUES"
|
||||
" ('%s',NOW(),FROM_UNIXTIME(UNIX_TIMESTAMP()+%lu))",
|
||||
Gbl.IP,(unsigned long) Fw_TIME_BANNED);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
void FW_LogAccess (void);
|
||||
void FW_CheckFirewallAndExitIfTooManyRequests (void);
|
||||
void FW_PurgeFirewall (void);
|
||||
|
||||
void FW_CheckFirewallAndExitIfBanned (void);
|
||||
void FW_CheckFirewallAndExitIfTooManyRequests (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -112,6 +112,7 @@ int main (void)
|
|||
Par_GetMainParameters ();
|
||||
|
||||
/***** Mitigate DoS attacks *****/
|
||||
FW_CheckFirewallAndExitIfBanned ();
|
||||
FW_LogAccess ();
|
||||
FW_CheckFirewallAndExitIfTooManyRequests ();
|
||||
|
||||
|
|
Loading…
Reference in New Issue