firewall3: add udp/icmp flood protection

Maksym Kovalchuck monkeyukraine at gmail.com
Wed Nov 4 09:40:04 EST 2020


Signed-off-by: Maksym Kovalchuck <maksym.kovalchuck-ext at sagemcom.com>
---
 defaults.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 options.h  | 14 +++++++++++---
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/defaults.c b/defaults.c
index f03765c..a8c9d4d 100644
--- a/defaults.c
+++ b/defaults.c
@@ -28,6 +28,8 @@ static const struct fw3_chain_spec default_chains[] = {
 	C(ANY, FILTER, CUSTOM_CHAINS, "output_rule"),
 	C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_rule"),
 	C(ANY, FILTER, SYN_FLOOD,     "syn_flood"),
+	C(ANY, FILTER, UDP_FLOOD,     "udp_flood"),
+	C(ANY, FILTER, ICMP_FLOOD,    "icmp_flood"),
 
 	C(V4,  NAT,    CUSTOM_CHAINS, "prerouting_rule"),
 	C(V4,  NAT,    CUSTOM_CHAINS, "postrouting_rule"),
@@ -49,6 +51,14 @@ const struct fw3_option fw3_flag_opts[] = {
 	FW3_OPT("synflood_rate",       limit,    defaults, syn_flood_rate),
 	FW3_OPT("synflood_burst",      int,      defaults, syn_flood_rate.burst),
 
+	FW3_OPT("udpflood_protect",    bool,     defaults, udp_flood),
+	FW3_OPT("udpflood_rate",       limit,    defaults, udp_flood_rate),
+	FW3_OPT("udpflood_burst",      int,      defaults, udp_flood_rate.burst),
+
+	FW3_OPT("icmpflood_protect",   bool,     defaults, icmp_flood),
+	FW3_OPT("icmpflood_rate",      limit,    defaults, icmp_flood_rate),
+	FW3_OPT("icmpflood_burst",     int,      defaults, icmp_flood_rate.burst),
+
 	FW3_OPT("tcp_syncookies",      bool,     defaults, tcp_syncookies),
 	FW3_OPT("tcp_ecn",             int,      defaults, tcp_ecn),
 	FW3_OPT("tcp_window_scaling",  bool,     defaults, tcp_window_scaling),
@@ -144,6 +154,10 @@ fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
 	defs->any_reject_code      = FW3_REJECT_CODE_PORT_UNREACH;
 	defs->syn_flood_rate.rate  = 25;
 	defs->syn_flood_rate.burst = 50;
+	defs->udp_flood_rate.rate  = 50;
+	defs->udp_flood_rate.burst = 50;
+	defs->icmp_flood_rate.rate  = 10;
+	defs->icmp_flood_rate.burst = 1;
 	defs->tcp_syncookies       = true;
 	defs->tcp_window_scaling   = true;
 	defs->custom_chains        = true;
@@ -201,6 +215,12 @@ fw3_print_default_chains(struct fw3_ipt_handle *handle, struct fw3_state *state,
 	if (defs->syn_flood)
 		set(defs->flags, handle->family, FW3_FLAG_SYN_FLOOD);
 
+	if (defs->udp_flood)
+	        set(defs->flags, handle->family, FW3_FLAG_UDP_FLOOD);
+
+	if (defs->icmp_flood)
+	        set(defs->flags, handle->family, FW3_FLAG_ICMP_FLOOD);
+
 	for (c = default_chains; c->format; c++)
 	{
 		/* don't touch user chains on selective stop */
@@ -231,6 +251,8 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
 	struct fw3_defaults *defs = &state->defaults;
 	struct fw3_device lodev = { .set = true };
 	struct fw3_protocol tcp = { .protocol = 6 };
+	struct fw3_protocol udp = { .protocol = 17 };
+	struct fw3_protocol icmp = { .protocol = 1 };
 	struct fw3_ipt_rule *r;
 
 	const char *chains[] = {
@@ -309,6 +331,38 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
 			fw3_ipt_rule_append(r, "INPUT");
 		}
 
+		if (defs->udp_flood)
+		{
+			r = fw3_ipt_rule_create(handle, &udp, NULL, NULL, NULL, NULL);
+			fw3_ipt_rule_limit(r, &defs->udp_flood_rate);
+			fw3_ipt_rule_target(r, "RETURN");
+			fw3_ipt_rule_append(r, "udp_flood");
+
+			r = fw3_ipt_rule_new(handle);
+			fw3_ipt_rule_target(r, "DROP");
+			fw3_ipt_rule_append(r, "udp_flood");
+
+			r = fw3_ipt_rule_create(handle, &udp, NULL, NULL, NULL, NULL);
+			fw3_ipt_rule_target(r, "udp_flood");
+			fw3_ipt_rule_append(r, "INPUT");
+		}
+
+		if (defs->icmp_flood)
+		{
+			r = fw3_ipt_rule_create(handle, &icmp, NULL, NULL, NULL, NULL);
+			fw3_ipt_rule_limit(r, &defs->icmp_flood_rate);
+			fw3_ipt_rule_target(r, "RETURN");
+			fw3_ipt_rule_append(r, "icmp_flood");
+
+			r = fw3_ipt_rule_new(handle);
+			fw3_ipt_rule_target(r, "DROP");
+			fw3_ipt_rule_append(r, "icmp_flood");
+
+			r = fw3_ipt_rule_create(handle, &icmp, NULL, NULL, NULL, NULL);
+			fw3_ipt_rule_target(r, "icmp_flood");
+			fw3_ipt_rule_append(r, "INPUT");
+		}
+
 		r = fw3_ipt_rule_create(handle, &tcp, NULL, NULL, NULL, NULL);
 		fw3_ipt_rule_target(r, "REJECT");
 		fw3_ipt_rule_addarg(r, false, "--reject-with", get_reject_code(handle->family, defs->tcp_reject_code));
diff --git a/options.h b/options.h
index cffc01c..7679d0e 100644
--- a/options.h
+++ b/options.h
@@ -82,9 +82,11 @@ enum fw3_flag
 	FW3_FLAG_SRC_DROP      = 18,
 	FW3_FLAG_CUSTOM_CHAINS = 19,
 	FW3_FLAG_SYN_FLOOD     = 20,
-	FW3_FLAG_MTU_FIX       = 21,
-	FW3_FLAG_DROP_INVALID  = 22,
-	FW3_FLAG_HOTPLUG       = 23,
+	FW3_FLAG_UDP_FLOOD     = 21,
+	FW3_FLAG_ICMP_FLOOD    = 22,
+	FW3_FLAG_MTU_FIX       = 23,
+	FW3_FLAG_DROP_INVALID  = 24,
+	FW3_FLAG_HOTPLUG       = 25,
 
 	__FW3_FLAG_MAX
 };
@@ -299,6 +301,12 @@ struct fw3_defaults
 	bool syn_flood;
 	struct fw3_limit syn_flood_rate;
 
+	bool udp_flood;
+	struct fw3_limit udp_flood_rate;
+
+	bool icmp_flood;
+	struct fw3_limit icmp_flood_rate;
+
 	bool tcp_syncookies;
 	int tcp_ecn;
 	bool tcp_window_scaling;
-- 
2.7.4




More information about the openwrt-devel mailing list