mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-12 01:26:48 +08:00
Added points in KKDCP connections to prevent DoS attacks.
This commit is contained in:
+2
-2
@@ -55,7 +55,7 @@ auth = "plain[passwd=./sample.passwd]"
|
|||||||
# system calls allowed to a worker process, in order to reduce damage from a
|
# system calls allowed to a worker process, in order to reduce damage from a
|
||||||
# bug in the worker process. It is available on Linux systems at a performance cost.
|
# bug in the worker process. It is available on Linux systems at a performance cost.
|
||||||
# The performance cost is roughly 2% overhead at transfer time (tested on a Linux 3.17.8).
|
# The performance cost is roughly 2% overhead at transfer time (tested on a Linux 3.17.8).
|
||||||
isolate-workers = true
|
#isolate-workers = true
|
||||||
|
|
||||||
# A banner to be displayed on clients
|
# A banner to be displayed on clients
|
||||||
#banner = "Welcome"
|
#banner = "Welcome"
|
||||||
@@ -216,7 +216,7 @@ min-reauth-time = 300
|
|||||||
# Banning clients in ocserv works with a point system. IP addresses
|
# Banning clients in ocserv works with a point system. IP addresses
|
||||||
# that get a score over that configured number are banned for
|
# that get a score over that configured number are banned for
|
||||||
# min-reauth-time seconds. A wrong password attempt is 10 points,
|
# min-reauth-time seconds. A wrong password attempt is 10 points,
|
||||||
# a connection is 1 point.
|
# a KKDCP POST is 1 point, and a connection is 1 point.
|
||||||
#
|
#
|
||||||
# Set to zero to disable.
|
# Set to zero to disable.
|
||||||
max-ban-score = 50
|
max-ban-score = 50
|
||||||
|
|||||||
+8
-5
@@ -137,6 +137,13 @@ message session_info_msg
|
|||||||
optional string dtls_compr = 5;
|
optional string dtls_compr = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* WORKER_BAN_IP: sent from worker to main */
|
||||||
|
message ban_ip_msg
|
||||||
|
{
|
||||||
|
required string ip = 1;
|
||||||
|
required uint32 score = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Messages to and from the security module */
|
/* Messages to and from the security module */
|
||||||
|
|
||||||
@@ -257,8 +264,4 @@ message sec_auth_session_reply_msg
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SEC_BAN_IP: sent from sec-mod to main */
|
/* SEC_BAN_IP: sent from sec-mod to main */
|
||||||
message sec_auth_ban_ip
|
/* same as: ban_ip_msg */
|
||||||
{
|
|
||||||
required string ip = 1;
|
|
||||||
required uint32 score = 2;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#include <cookies.h>
|
#include <cookies.h>
|
||||||
#include <tun.h>
|
#include <tun.h>
|
||||||
#include <main.h>
|
#include <main.h>
|
||||||
|
#include <main-ban.h>
|
||||||
#include <ccan/list/list.h>
|
#include <ccan/list/list.h>
|
||||||
|
|
||||||
int set_tun_mtu(main_server_st * s, struct proc_st *proc, unsigned mtu)
|
int set_tun_mtu(main_server_st * s, struct proc_st *proc, unsigned mtu)
|
||||||
@@ -505,6 +506,21 @@ int handle_commands(main_server_st * s, struct proc_st *proc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case CMD_BAN_IP:{
|
||||||
|
BanIpMsg *tmsg;
|
||||||
|
|
||||||
|
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
|
||||||
|
if (tmsg == NULL) {
|
||||||
|
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
|
||||||
|
ret = ERR_BAD_COMMAND;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
add_ip_to_ban_list(s, tmsg->ip, tmsg->score);
|
||||||
|
|
||||||
|
ban_ip_msg__free_unpacked(tmsg, &pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case CMD_TUN_MTU:{
|
case CMD_TUN_MTU:{
|
||||||
TunMtuMsg *tmsg;
|
TunMtuMsg *tmsg;
|
||||||
|
|
||||||
|
|||||||
@@ -112,9 +112,9 @@ int handle_sec_mod_commands(main_server_st * s)
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SM_CMD_AUTH_BAN_IP:{
|
case SM_CMD_AUTH_BAN_IP:{
|
||||||
SecAuthBanIp *tmsg;
|
BanIpMsg *tmsg;
|
||||||
|
|
||||||
tmsg = sec_auth_ban_ip__unpack(&pa, raw_len, raw);
|
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
|
||||||
if (tmsg == NULL) {
|
if (tmsg == NULL) {
|
||||||
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
|
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
|
||||||
ret = ERR_BAD_COMMAND;
|
ret = ERR_BAD_COMMAND;
|
||||||
@@ -122,7 +122,7 @@ int handle_sec_mod_commands(main_server_st * s)
|
|||||||
}
|
}
|
||||||
add_ip_to_ban_list(s, tmsg->ip, tmsg->score);
|
add_ip_to_ban_list(s, tmsg->ip, tmsg->score);
|
||||||
|
|
||||||
sec_auth_ban_ip__free_unpacked(tmsg, &pa);
|
ban_ip_msg__free_unpacked(tmsg, &pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
+2
-2
@@ -130,7 +130,7 @@ An example configuration file follows.
|
|||||||
# system calls allowed to a worker process, in order to reduce damage from a
|
# system calls allowed to a worker process, in order to reduce damage from a
|
||||||
# bug in the worker process. It is available on Linux systems at a performance cost.
|
# bug in the worker process. It is available on Linux systems at a performance cost.
|
||||||
# The performance cost is roughly 2% overhead at transfer time (tested on a Linux 3.17.8).
|
# The performance cost is roughly 2% overhead at transfer time (tested on a Linux 3.17.8).
|
||||||
#isolate-workers = true
|
isolate-workers = true
|
||||||
|
|
||||||
# A banner to be displayed on clients
|
# A banner to be displayed on clients
|
||||||
#banner = "Welcome"
|
#banner = "Welcome"
|
||||||
@@ -291,7 +291,7 @@ min-reauth-time = 120
|
|||||||
# Banning clients in ocserv works with a point system. IP addresses
|
# Banning clients in ocserv works with a point system. IP addresses
|
||||||
# that get a score over that configured number are banned for
|
# that get a score over that configured number are banned for
|
||||||
# min-reauth-time seconds. A wrong password attempt is 10 points,
|
# min-reauth-time seconds. A wrong password attempt is 10 points,
|
||||||
# a connection is 1 point.
|
# a KKDCP POST is 1 point, and a connection is 1 point.
|
||||||
#
|
#
|
||||||
# Set to zero to disable.
|
# Set to zero to disable.
|
||||||
max-ban-score = 50
|
max-ban-score = 50
|
||||||
|
|||||||
+3
-3
@@ -77,7 +77,7 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, void *pool, const char *ip, unsign
|
|||||||
{
|
{
|
||||||
void *lpool;
|
void *lpool;
|
||||||
int ret, e;
|
int ret, e;
|
||||||
SecAuthBanIp msg = SEC_AUTH_BAN_IP__INIT;
|
BanIpMsg msg = BAN_IP_MSG__INIT;
|
||||||
|
|
||||||
msg.ip = (char*)ip;
|
msg.ip = (char*)ip;
|
||||||
msg.score = points;
|
msg.score = points;
|
||||||
@@ -88,8 +88,8 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, void *pool, const char *ip, unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = send_msg(lpool, sec->cmd_fd, SM_CMD_AUTH_BAN_IP, &msg,
|
ret = send_msg(lpool, sec->cmd_fd, SM_CMD_AUTH_BAN_IP, &msg,
|
||||||
(pack_size_func) sec_auth_ban_ip__get_packed_size,
|
(pack_size_func) ban_ip_msg__get_packed_size,
|
||||||
(pack_func) sec_auth_ban_ip__pack);
|
(pack_func) ban_ip_msg__pack);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
e = errno;
|
e = errno;
|
||||||
seclog(sec, LOG_WARNING, "error in sending BAN IP message: %s", strerror(e));
|
seclog(sec, LOG_WARNING, "error in sending BAN IP message: %s", strerror(e));
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
#define PASSWORD_POINTS 10
|
#define PASSWORD_POINTS 10
|
||||||
#define CONNECT_POINTS 1
|
#define CONNECT_POINTS 1
|
||||||
|
#define KKDCP_POINTS 1
|
||||||
#define DEFAULT_MAX_BAN_SCORE (MAX_PASSWORD_TRIES*PASSWORD_POINTS)
|
#define DEFAULT_MAX_BAN_SCORE (MAX_PASSWORD_TRIES*PASSWORD_POINTS)
|
||||||
#define DEFAULT_BAN_RESET_TIME 300
|
#define DEFAULT_BAN_RESET_TIME 300
|
||||||
|
|
||||||
@@ -143,6 +144,7 @@ typedef enum {
|
|||||||
CMD_TERMINATE = 12,
|
CMD_TERMINATE = 12,
|
||||||
CMD_SESSION_INFO = 13,
|
CMD_SESSION_INFO = 13,
|
||||||
CMD_CLI_STATS = 15,
|
CMD_CLI_STATS = 15,
|
||||||
|
CMD_BAN_IP = 16,
|
||||||
|
|
||||||
/* from worker to sec-mod */
|
/* from worker to sec-mod */
|
||||||
SM_CMD_AUTH_INIT = 120,
|
SM_CMD_AUTH_INIT = 120,
|
||||||
|
|||||||
@@ -30,6 +30,33 @@
|
|||||||
|
|
||||||
#ifdef HAVE_GSSAPI
|
#ifdef HAVE_GSSAPI
|
||||||
|
|
||||||
|
static
|
||||||
|
void worker_add_score_to_ip(worker_st *ws, const char *ip, unsigned points)
|
||||||
|
{
|
||||||
|
void *lpool;
|
||||||
|
int ret, e;
|
||||||
|
BanIpMsg msg = BAN_IP_MSG__INIT;
|
||||||
|
|
||||||
|
msg.ip = (char*)ip;
|
||||||
|
msg.score = points;
|
||||||
|
|
||||||
|
lpool = talloc_new(ws);
|
||||||
|
if (lpool == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = send_msg(lpool, ws->cmd_fd, CMD_BAN_IP, &msg,
|
||||||
|
(pack_size_func) ban_ip_msg__get_packed_size,
|
||||||
|
(pack_func) ban_ip_msg__pack);
|
||||||
|
if (ret < 0) {
|
||||||
|
e = errno;
|
||||||
|
oclog(ws, LOG_WARNING, "error in sending BAN IP message: %s", strerror(e));
|
||||||
|
}
|
||||||
|
talloc_free(lpool);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int der_decode(const uint8_t *der, unsigned der_size, uint8_t *out, unsigned *out_size,
|
int der_decode(const uint8_t *der, unsigned der_size, uint8_t *out, unsigned *out_size,
|
||||||
char *realm, unsigned realm_size, int *error)
|
char *realm, unsigned realm_size, int *error)
|
||||||
{
|
{
|
||||||
@@ -140,6 +167,9 @@ int post_kkdcp_handler(worker_st *ws, unsigned http_ver)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (human_addr2((void*)&ws->remote_addr, ws->remote_addr_len, realm, sizeof(realm), 0) != NULL)
|
||||||
|
worker_add_score_to_ip(ws, realm, KKDCP_POINTS);
|
||||||
|
|
||||||
oclog(ws, LOG_HTTP_DEBUG, "HTTP processing kkdcp framed request: %u bytes", (unsigned)req->body_length);
|
oclog(ws, LOG_HTTP_DEBUG, "HTTP processing kkdcp framed request: %u bytes", (unsigned)req->body_length);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user