mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-02 08:42:48 +00:00
Add a 'verrevpath' option that verifies the interface that a packet
comes in on is the same interface that we would route out of to get to the packet's source address. Essentially automates an anti-spoofing check using the information in the routing table. Experimental. The usage and rule format for the feature may still be subject to change.
This commit is contained in:
parent
1fe8a56688
commit
010dabb047
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112250
@ -1115,6 +1115,22 @@ Match all TCP or UDP packets sent by or received for a
|
||||
A
|
||||
.Ar user
|
||||
may be matched by name or identification number.
|
||||
.It Cm verrevpath
|
||||
For incoming packets,
|
||||
a routing table lookup is done on the packet's source address.
|
||||
If the interface on which the packet entered the system matches the
|
||||
outgoing interface for the route,
|
||||
the packet matches.
|
||||
If the interfaces do not match up,
|
||||
the packet does not match.
|
||||
All outgoing packets or packets with no incoming interface match.
|
||||
.Pp
|
||||
The name and functionality of the option is intentionally similar to
|
||||
the Cisco IOS command:
|
||||
.Pp
|
||||
.Dl ip verify unicast reverse-path
|
||||
.Pp
|
||||
This option can be used to make anti-spoofing rules.
|
||||
.El
|
||||
.Sh SETS OF RULES
|
||||
Each rule belongs to one of 32 different
|
||||
@ -1818,6 +1834,18 @@ The
|
||||
.Nm ipfw1
|
||||
syntax would require a separate rule for each IP in the above
|
||||
example.
|
||||
.Pp
|
||||
The
|
||||
.Cm verrevpath
|
||||
option could be used to do automated anti-spoofing by adding the
|
||||
following to the top of a ruleset:
|
||||
.Pp
|
||||
.Dl "ipfw add deny ip from any to any not verrevpath in"
|
||||
.Pp
|
||||
This rule drops all incoming packets that appear to be coming to the
|
||||
sytem on the wrong interface. For example, a packet with a source
|
||||
address belonging to a host on a protected internal network would be
|
||||
dropped if it tried to enter the system from an external interface.
|
||||
.Ss DYNAMIC RULES
|
||||
In order to protect a site from flood attacks involving fake
|
||||
TCP packets, it is safer to use dynamic rules:
|
||||
|
@ -224,6 +224,7 @@ enum tokens {
|
||||
TOK_ICMPTYPES,
|
||||
TOK_MAC,
|
||||
TOK_MACTYPE,
|
||||
TOK_VERREVPATH,
|
||||
|
||||
TOK_PLR,
|
||||
TOK_NOERROR,
|
||||
@ -333,6 +334,7 @@ struct _s_x rule_options[] = {
|
||||
{ "MAC", TOK_MAC },
|
||||
{ "mac", TOK_MAC },
|
||||
{ "mac-type", TOK_MACTYPE },
|
||||
{ "verrevpath", TOK_VERREVPATH },
|
||||
|
||||
{ "not", TOK_NOT }, /* pseudo option */
|
||||
{ "!", /* escape ? */ TOK_NOT }, /* pseudo option */
|
||||
@ -1162,6 +1164,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
}
|
||||
break;
|
||||
|
||||
case O_VERREVPATH:
|
||||
printf(" verrevpath");
|
||||
break;
|
||||
|
||||
case O_KEEP_STATE:
|
||||
printf(" keep-state");
|
||||
break;
|
||||
@ -3160,6 +3166,10 @@ add(int ac, char *av[])
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_VERREVPATH:
|
||||
fill_cmd(cmd, O_VERREVPATH, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s);
|
||||
}
|
||||
|
@ -89,6 +89,8 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
O_ICMPTYPE, /* u32 = icmp bitmap */
|
||||
O_TCPOPTS, /* arg1 = 2*u8 bitmap */
|
||||
|
||||
O_VERREVPATH, /* none */
|
||||
|
||||
O_PROBE_STATE, /* none */
|
||||
O_KEEP_STATE, /* none */
|
||||
O_LIMIT, /* ipfw_insn_limit */
|
||||
|
@ -402,6 +402,48 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
|
||||
return(0); /* no match, fail ... */
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'verrevpath' option checks that the interface that an IP packet
|
||||
* arrives on is the same interface that traffic destined for the
|
||||
* packet's source address would be routed out of. This is a measure
|
||||
* to block forged packets. This is also commonly known as "anti-spoofing"
|
||||
* or Unicast Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The
|
||||
* name of the knob is purposely reminisent of the Cisco IOS command,
|
||||
*
|
||||
* ip verify unicast reverse-path
|
||||
*
|
||||
* which implements the same functionality. But note that syntax is
|
||||
* misleading. The check may be performed on all IP packets whether unicast,
|
||||
* multicast, or broadcast.
|
||||
*/
|
||||
static int
|
||||
verify_rev_path(struct in_addr src, struct ifnet *ifp)
|
||||
{
|
||||
static struct route ro;
|
||||
struct sockaddr_in *dst;
|
||||
|
||||
dst = (struct sockaddr_in *)&(ro.ro_dst);
|
||||
|
||||
/* Check if we've cached the route from the previous call. */
|
||||
if (src.s_addr != dst->sin_addr.s_addr) {
|
||||
ro.ro_rt = NULL;
|
||||
|
||||
bzero(dst, sizeof(*dst));
|
||||
dst->sin_family = AF_INET;
|
||||
dst->sin_len = sizeof(*dst);
|
||||
dst->sin_addr = src;
|
||||
|
||||
rtalloc_ign(&ro, RTF_CLONING|RTF_PRCLONING);
|
||||
}
|
||||
|
||||
if ((ro.ro_rt == NULL) || (ifp == NULL) ||
|
||||
(ro.ro_rt->rt_ifp->if_index != ifp->if_index))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static u_int64_t norule_counter; /* counter for ipfw_log(NULL...) */
|
||||
|
||||
#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
|
||||
@ -1755,6 +1797,13 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
|
||||
break;
|
||||
|
||||
case O_VERREVPATH:
|
||||
/* Outgoing packets automatically pass/match */
|
||||
match = ((oif != NULL) ||
|
||||
(m->m_pkthdr.rcvif == NULL) ||
|
||||
verify_rev_path(src_ip, m->m_pkthdr.rcvif));
|
||||
break;
|
||||
|
||||
/*
|
||||
* The second set of opcodes represents 'actions',
|
||||
* i.e. the terminal part of a rule once the packet
|
||||
@ -2322,6 +2371,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
case O_TCPFLAGS:
|
||||
case O_TCPOPTS:
|
||||
case O_ESTAB:
|
||||
case O_VERREVPATH:
|
||||
if (cmdlen != F_INSN_SIZE(ipfw_insn))
|
||||
goto bad_size;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user