diff mbox series

firewall3: add udp/icmp flood protection

Message ID 1604500804-26604-1-git-send-email-maksym.kovalchuck-ext@sagemcom.com
State Changes Requested
Delegated to: Petr Štetiar
Headers show
Series firewall3: add udp/icmp flood protection | expand

Commit Message

Maksym Kovalchuck Nov. 4, 2020, 2:40 p.m. UTC
Signed-off-by: Maksym Kovalchuck <maksym.kovalchuck-ext@sagemcom.com>
---
 defaults.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 options.h  | 14 +++++++++++---
 2 files changed, 65 insertions(+), 3 deletions(-)

Comments

Petr Štetiar Dec. 22, 2020, 10:55 a.m. UTC | #1
Maksym Kovalchuck <monkeyukraine@gmail.com> [2020-11-04 15:40:04]:

Please add proper commit description, see openwrt.org/submitting-patches for
details

> Signed-off-by: Maksym Kovalchuck <maksym.kovalchuck-ext@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;
diff mbox series

Patch

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;