more DoS prevention: add packet_limit option to apply a hard limit to downstream packets per session
This commit is contained in:
parent
ee333473db
commit
bb63cb9994
7 changed files with 79 additions and 17 deletions
4
Changes
4
Changes
|
|
@ -1,10 +1,12 @@
|
||||||
* Fri Jan 7 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0
|
* Mon Jan 10 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0
|
||||||
- Add IPv6 support from Jonathan McDowell (work in progress).
|
- Add IPv6 support from Jonathan McDowell (work in progress).
|
||||||
- Add CHAP support from Jordan Hrycaj (work in progress).
|
- Add CHAP support from Jordan Hrycaj (work in progress).
|
||||||
- Sanity check that cluster_send_session is not called from a child
|
- Sanity check that cluster_send_session is not called from a child
|
||||||
process.
|
process.
|
||||||
- Throttle outgoing LASTSEEN packets to at most one per second for a
|
- Throttle outgoing LASTSEEN packets to at most one per second for a
|
||||||
given seq#.
|
given seq#.
|
||||||
|
- More DoS prevention: add packet_limit option to apply a hard limit
|
||||||
|
to downstream packets per session.
|
||||||
- Use bounds-checking lookup functions for string constants.
|
- Use bounds-checking lookup functions for string constants.
|
||||||
- Add enum for RADIUS codes.
|
- Add enum for RADIUS codes.
|
||||||
- Make "call_" prefix implict in CSTAT() macro.
|
- Make "call_" prefix implict in CSTAT() macro.
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,13 @@ Keep all pages mapped by the l2tpns process in memory.
|
||||||
Maximum number of host unreachable ICMP packets to send per second.
|
Maximum number of host unreachable ICMP packets to send per second.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
|
<LI><B>packet_limit</B> (int><BR>
|
||||||
|
Maximum number of packets of downstream traffic to be handled each
|
||||||
|
tenth of a second per session. If zero, no limit is applied (default:
|
||||||
|
0). Intended as a DoS prevention mechanism and not a general
|
||||||
|
throttling control (packets are dropped, not queued).
|
||||||
|
</LI>
|
||||||
|
|
||||||
<LI><B>cluster_address</B> (ip address)<BR>
|
<LI><B>cluster_address</B> (ip address)<BR>
|
||||||
Multicast cluster address (default: 239.192.13.13). See the section
|
Multicast cluster address (default: 239.192.13.13). See the section
|
||||||
on <A HREF="#Clustering">Clustering</A> for more information.
|
on <A HREF="#Clustering">Clustering</A> for more information.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.de Id
|
.de Id
|
||||||
.ds Dt \\$4 \\$5
|
.ds Dt \\$4 \\$5
|
||||||
..
|
..
|
||||||
.Id $Id: startup-config.5,v 1.3 2004/11/29 06:29:28 bodea Exp $
|
.Id $Id: startup-config.5,v 1.4 2005/01/10 07:17:37 bodea Exp $
|
||||||
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
startup\-config \- configuration file for l2tpns
|
startup\-config \- configuration file for l2tpns
|
||||||
|
|
@ -160,6 +160,12 @@ process in memory.
|
||||||
.B icmp_rate
|
.B icmp_rate
|
||||||
Maximum number of host unreachable ICMP packets to send per second.
|
Maximum number of host unreachable ICMP packets to send per second.
|
||||||
.TP
|
.TP
|
||||||
|
.B packet_limit
|
||||||
|
Maximum number of packets of downstream traffic to be handled each
|
||||||
|
tenth of a second per session. If zero, no limit is applied (default:
|
||||||
|
0). Intended as a DoS prevention mechanism and not a general
|
||||||
|
throttling control (packets are dropped, not queued).
|
||||||
|
.TP
|
||||||
.B cluster_address
|
.B cluster_address
|
||||||
Multicast cluster address (default: 239.192.13.13).
|
Multicast cluster address (default: 239.192.13.13).
|
||||||
.TP
|
.TP
|
||||||
|
|
|
||||||
17
cli.c
17
cli.c
|
|
@ -2,7 +2,7 @@
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_name = "$Name: $";
|
char const *cvs_name = "$Name: $";
|
||||||
char const *cvs_id_cli = "$Id: cli.c,v 1.45 2005/01/07 07:15:10 bodea Exp $";
|
char const *cvs_id_cli = "$Id: cli.c,v 1.46 2005/01/10 07:17:37 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -646,23 +646,24 @@ static int cmd_show_counters(struct cli_def *cli, char *command, char **argv, in
|
||||||
if (CLI_HELP_REQUESTED)
|
if (CLI_HELP_REQUESTED)
|
||||||
return CLI_HELP_NO_ARGS;
|
return CLI_HELP_NO_ARGS;
|
||||||
|
|
||||||
cli_print(cli, "%-10s %-8s %-10s %-8s", "Ethernet", "Bytes", "Packets", "Errors");
|
cli_print(cli, "%-10s %10s %8s %8s %8s", "Ethernet", "Bytes", "Packets", "Errors", "Dropped");
|
||||||
cli_print(cli, "%-10s %8u %8u %8u", "RX",
|
cli_print(cli, "%-10s %10u %8u %8u %8u", "RX",
|
||||||
GET_STAT(tun_rx_bytes),
|
GET_STAT(tun_rx_bytes),
|
||||||
GET_STAT(tun_rx_packets),
|
GET_STAT(tun_rx_packets),
|
||||||
GET_STAT(tun_rx_errors));
|
GET_STAT(tun_rx_errors),
|
||||||
cli_print(cli, "%-10s %8u %8u %8u", "TX",
|
GET_STAT(tun_rx_dropped));
|
||||||
|
cli_print(cli, "%-10s %10u %8u %8u", "TX",
|
||||||
GET_STAT(tun_tx_bytes),
|
GET_STAT(tun_tx_bytes),
|
||||||
GET_STAT(tun_tx_packets),
|
GET_STAT(tun_tx_packets),
|
||||||
GET_STAT(tun_tx_errors));
|
GET_STAT(tun_tx_errors));
|
||||||
cli_print(cli, "");
|
cli_print(cli, "");
|
||||||
|
|
||||||
cli_print(cli, "%-10s %-8s %-10s %-8s %-8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
|
cli_print(cli, "%-10s %10s %8s %8s %8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
|
||||||
cli_print(cli, "%-10s %8u %8u %8u", "RX",
|
cli_print(cli, "%-10s %10u %8u %8u", "RX",
|
||||||
GET_STAT(tunnel_rx_bytes),
|
GET_STAT(tunnel_rx_bytes),
|
||||||
GET_STAT(tunnel_rx_packets),
|
GET_STAT(tunnel_rx_packets),
|
||||||
GET_STAT(tunnel_rx_errors));
|
GET_STAT(tunnel_rx_errors));
|
||||||
cli_print(cli, "%-10s %8u %8u %8u %8u", "TX",
|
cli_print(cli, "%-10s %10u %8u %8u %8u", "TX",
|
||||||
GET_STAT(tunnel_tx_bytes),
|
GET_STAT(tunnel_tx_bytes),
|
||||||
GET_STAT(tunnel_tx_packets),
|
GET_STAT(tunnel_tx_packets),
|
||||||
GET_STAT(tunnel_tx_errors),
|
GET_STAT(tunnel_tx_errors),
|
||||||
|
|
|
||||||
44
l2tpns.c
44
l2tpns.c
|
|
@ -4,7 +4,7 @@
|
||||||
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.75 2005/01/07 07:18:33 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.76 2005/01/10 07:17:37 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -120,6 +120,7 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
|
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
|
||||||
CONFIG("lock_pages", lock_pages, BOOL),
|
CONFIG("lock_pages", lock_pages, BOOL),
|
||||||
CONFIG("icmp_rate", icmp_rate, INT),
|
CONFIG("icmp_rate", icmp_rate, INT),
|
||||||
|
CONFIG("packet_limit", max_packets, INT),
|
||||||
CONFIG("cluster_address", cluster_address, IPv4),
|
CONFIG("cluster_address", cluster_address, IPv4),
|
||||||
CONFIG("cluster_interface", cluster_interface, STRING),
|
CONFIG("cluster_interface", cluster_interface, STRING),
|
||||||
CONFIG("cluster_hb_interval", cluster_hb_interval, INT),
|
CONFIG("cluster_hb_interval", cluster_hb_interval, INT),
|
||||||
|
|
@ -784,13 +785,13 @@ static void processipout(uint8_t * buf, int len)
|
||||||
if (len < MIN_IP_SIZE)
|
if (len < MIN_IP_SIZE)
|
||||||
{
|
{
|
||||||
LOG(1, 0, 0, "Short IP, %d bytes\n", len);
|
LOG(1, 0, 0, "Short IP, %d bytes\n", len);
|
||||||
STAT(tunnel_tx_errors);
|
STAT(tun_rx_errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (len >= MAXETHER)
|
if (len >= MAXETHER)
|
||||||
{
|
{
|
||||||
LOG(1, 0, 0, "Oversize IP packet %d bytes\n", len);
|
LOG(1, 0, 0, "Oversize IP packet %d bytes\n", len);
|
||||||
STAT(tunnel_tx_errors);
|
STAT(tun_rx_errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -828,6 +829,43 @@ static void processipout(uint8_t * buf, int len)
|
||||||
t = session[s].tunnel;
|
t = session[s].tunnel;
|
||||||
sp = &session[s];
|
sp = &session[s];
|
||||||
|
|
||||||
|
// DoS prevention: enforce a maximum number of packets per 0.1s for a session
|
||||||
|
if (config->max_packets > 0)
|
||||||
|
{
|
||||||
|
if (sess_count[s].last_packet_out == TIME)
|
||||||
|
{
|
||||||
|
int max = config->max_packets;
|
||||||
|
|
||||||
|
// All packets for throttled sessions are handled by the
|
||||||
|
// master, so further limit by using the throttle rate.
|
||||||
|
// A bit of a kludge, since throttle rate is in kbps,
|
||||||
|
// but should still be generous given our average DSL
|
||||||
|
// packet size is 200 bytes: a limit of 28kbps equates
|
||||||
|
// to around 180 packets per second.
|
||||||
|
if (!config->cluster_iam_master && sp->throttle_out && sp->throttle_out < max)
|
||||||
|
max = sp->throttle_out;
|
||||||
|
|
||||||
|
if (++sess_count[s].packets_out > max)
|
||||||
|
{
|
||||||
|
sess_count[s].packets_dropped++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sess_count[s].packets_dropped)
|
||||||
|
{
|
||||||
|
INC_STAT(tun_rx_dropped, sess_count[s].packets_dropped);
|
||||||
|
LOG(2, s, t, "Possible DoS attack on %s (%s); dropped %u packets.",
|
||||||
|
fmtaddr(ip, 0), sp->user, sess_count[s].packets_dropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
sess_count[s].last_packet_out = TIME;
|
||||||
|
sess_count[s].packets_out = 1;
|
||||||
|
sess_count[s].packets_dropped = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// run access-list if any
|
// run access-list if any
|
||||||
if (session[s].filter_out && !ip_filter(buf, len, session[s].filter_out - 1))
|
if (session[s].filter_out && !ip_filter(buf, len, session[s].filter_out - 1))
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
12
l2tpns.h
12
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.51 2005/01/07 07:17:13 bodea Exp $
|
// $Id: l2tpns.h,v 1.52 2005/01/10 07:17:37 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -228,8 +228,14 @@ sessiont;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
// byte counters
|
||||||
uint32_t cin;
|
uint32_t cin;
|
||||||
uint32_t cout;
|
uint32_t cout;
|
||||||
|
|
||||||
|
// DoS prevention
|
||||||
|
clockt last_packet_out;
|
||||||
|
uint32_t packets_out;
|
||||||
|
uint32_t packets_dropped;
|
||||||
} sessioncountt;
|
} sessioncountt;
|
||||||
|
|
||||||
#define SESSIONPFC 1 // PFC negotiated flags
|
#define SESSIONPFC 1 // PFC negotiated flags
|
||||||
|
|
@ -333,6 +339,7 @@ struct Tstats
|
||||||
uint32_t tun_tx_bytes;
|
uint32_t tun_tx_bytes;
|
||||||
uint32_t tun_rx_errors;
|
uint32_t tun_rx_errors;
|
||||||
uint32_t tun_tx_errors;
|
uint32_t tun_tx_errors;
|
||||||
|
uint32_t tun_rx_dropped;
|
||||||
|
|
||||||
uint32_t tunnel_rx_packets;
|
uint32_t tunnel_rx_packets;
|
||||||
uint32_t tunnel_tx_packets;
|
uint32_t tunnel_tx_packets;
|
||||||
|
|
@ -470,7 +477,8 @@ typedef struct
|
||||||
int next_tbf; // Next HTB id available to use
|
int next_tbf; // Next HTB id available to use
|
||||||
int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling policy for this process.
|
int scheduler_fifo; // If the system has multiple CPUs, use FIFO scheduling policy for this process.
|
||||||
int lock_pages; // Lock pages into memory.
|
int lock_pages; // Lock pages into memory.
|
||||||
int icmp_rate; // Max number of ICMP unreachable per second to send>
|
int icmp_rate; // Max number of ICMP unreachable per second to send
|
||||||
|
int max_packets; // DoS prevention: per session limit of packets/0.1s
|
||||||
|
|
||||||
in_addr_t cluster_address; // Multicast address of cluster.
|
in_addr_t cluster_address; // Multicast address of cluster.
|
||||||
// Send to this address to have everyone hear.
|
// Send to this address to have everyone hear.
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,5 @@ rm -rf %{buildroot}
|
||||||
%attr(644,root,root) /usr/share/man/man[58]/*
|
%attr(644,root,root) /usr/share/man/man[58]/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Fri Jan 7 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0-1
|
* Mon Jan 10 2005 Brendan O'Dea <bod@optusnet.com.au> 2.1.0-1
|
||||||
- 2.1.0 release, see /usr/share/doc/l2tpns-2.1.0/Changes
|
- 2.1.0 release, see /usr/share/doc/l2tpns-2.1.0/Changes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue