Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jan 2010 03:27:13 +0900
From:      Hajimu UMEMOTO <ume@freebsd.org>
To:        David Horn <dhorn2000@gmail.com>
Cc:        freebsd-net@freebsd.org, freebsd-current@freebsd.org, freebsd-ipfw@freebsd.org
Subject:   Re: Unified rc.firewall ipfw me/me6 issue
Message-ID:  <yge8wc5u872.wl%ume@mahoroba.org>
In-Reply-To: <25ff90d61001021736p7b695197q104f4a7769b51b71@mail.gmail.com>
References:  <25ff90d60912162320y286e37a0ufeb64397716d8c18@mail.gmail.com> <ygek4wmyp3j.wl%ume@mahoroba.org> <25ff90d60912180612y2b1f64fbw34b4d7f648762087@mail.gmail.com> <yged42c4770.wl%ume@mahoroba.org> <25ff90d61001021736p7b695197q104f4a7769b51b71@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Mon_Jan_11_03:27:13_2010-1
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

>>>>> On Sat, 2 Jan 2010 20:36:45 -0500
>>>>> David Horn <dhorn2000@gmail.com> said:

> dhorn2000> Yes, "me" matching either ipv4/ipv6 would certainly simplify t=
he default
> dhorn2000> rc.firewall flow.
>
> Here is my proposed patch.  With this patch, 'me' matches to both IPv4
> and IPv6, and 'me4' is added for matching to only IPv4.

dhorn2000> The patch for me4/me6 works perfect in my testing to date.   I g=
uess
dhorn2000> we would need to convince a larger audience to get consensus on
dhorn2000> changing the behavior for "me" token from just ipv4 to both ipv4=
/ipv6,
dhorn2000> but I personally think it is the right direction.

Thank you for testing.
I've added current@ and net@ to Cc:.
It makes the IPv4/IPv6 dual stack rule definitely simpler that 'me'
matches to both IPv4 and IPv6.  I think it is desired feature.
However, I'm not sure we actually need 'me4'.  So, I split my previous
patch into two patches.  The 1st patch makes 'me' matches to both IPv4
and IPv6.  The 2nd patch adds 'me4'.
If there is no objection, I'll commit the 1st patch.  If someone want
'me4', I'll commit the 2nd patch.
And, the 3rd patch is for rc.firewall.

dhorn2000> ipfw(8) man page already shows:

dhorn2000> me      matches any IP address configured on an interface in the
dhorn2000>                      system.

dhorn2000> me6     matches any IPv6 address configured on an interface in
dhorn2000>                      the system.  The address list is evaluated =
at the time
dhorn2000>                      the packet is analysed.

I wish to believe this description about 'me' is correct.  But, I'm
not sure whether it is a feature or not.  It might be that someone
forgot to change it at the time when an IPv6 support was added to
IPFW.

Sincerely,

--Multipart_Mon_Jan_11_03:27:13_2010-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="ipfw-me-unify.diff"
Content-Transfer-Encoding: 7bit

Index: sys/netinet/ipfw/ip_fw2.c
diff -u -p sys/netinet/ipfw/ip_fw2.c.orig sys/netinet/ipfw/ip_fw2.c
--- sys/netinet/ipfw/ip_fw2.c.orig	2010-01-05 04:01:22.000000000 +0900
+++ sys/netinet/ipfw/ip_fw2.c	2010-01-08 12:30:31.039834764 +0900
@@ -1390,7 +1390,14 @@ do {								\
 
 					INADDR_TO_IFP(src_ip, tif);
 					match = (tif != NULL);
+					break;
 				}
+				/* FALLTHROUGH */
+#ifdef INET6
+			case O_IP6_SRC_ME:
+				match = is_ipv6 &&
+				    search_ip6_addr_net(&args->f_id.src_ip6);
+#endif
 				break;
 
 			case O_IP_DST_SET:
@@ -1423,7 +1430,14 @@ do {								\
 
 					INADDR_TO_IFP(dst_ip, tif);
 					match = (tif != NULL);
+					break;
 				}
+				/* FALLTHROUGH */
+#ifdef INET6
+			case O_IP6_DST_ME:
+				match = is_ipv6 &&
+				    search_ip6_addr_net(&args->f_id.dst_ip6);
+#endif
 				break;
 
 			case O_IP_SRCPORT:
@@ -1691,14 +1705,6 @@ do {								\
 				}
 				break;
 
-			case O_IP6_SRC_ME:
-				match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
-				break;
-
-			case O_IP6_DST_ME:
-				match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
-				break;
-
 			case O_FLOW6ID:
 				match = is_ipv6 &&
 				    flow6id_match(args->f_id.flow_id6,

--Multipart_Mon_Jan_11_03:27:13_2010-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="ipfw-me4.diff"
Content-Transfer-Encoding: 7bit

Index: sbin/ipfw/ipfw.8
diff -u sbin/ipfw/ipfw.8.orig sbin/ipfw/ipfw.8
--- sbin/ipfw/ipfw.8.orig	2009-12-15 18:46:27.000000000 +0900
+++ sbin/ipfw/ipfw.8	2010-01-08 12:33:36.117724529 +0900
@@ -1003,7 +1003,7 @@
 its use is discouraged.
 .It Ar addr : Oo Cm not Oc Bro
 .Bl -tag -width indent
-.Cm any | me | me6 |
+.Cm any | me | me4 | me6 |
 .Cm table Ns Pq Ar number Ns Op , Ns Ar value
 .Ar | addr-list | addr-set
 .Brc
@@ -1011,6 +1011,8 @@
 matches any IP address.
 .It Cm me
 matches any IP address configured on an interface in the system.
+.It Cm me4
+matches any IPv4 address configured on an interface in the system.
 .It Cm me6
 matches any IPv6 address configured on an interface in the system.
 The address list is evaluated at the time the packet is
Index: sbin/ipfw/ipfw2.c
diff -u -p sbin/ipfw/ipfw2.c.orig sbin/ipfw/ipfw2.c
--- sbin/ipfw/ipfw2.c.orig	2009-12-15 18:46:27.000000000 +0900
+++ sbin/ipfw/ipfw2.c	2010-01-08 12:33:36.037713520 +0900
@@ -768,6 +768,10 @@ print_ip(ipfw_insn_ip *cmd, char const *
 		printf("me");
 		return;
 	}
+	if (cmd->o.opcode == O_IP4_SRC_ME || cmd->o.opcode == O_IP4_DST_ME) {
+		printf("me4");
+		return;
+	}
 	if (cmd->o.opcode == O_IP_SRC_LOOKUP ||
 	    cmd->o.opcode == O_IP_DST_LOOKUP) {
 		printf("table(%u", ((ipfw_insn *)cmd)->arg1);
@@ -1187,6 +1191,7 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 		case O_IP_SRC_LOOKUP:
 		case O_IP_SRC_MASK:
 		case O_IP_SRC_ME:
+		case O_IP4_SRC_ME:
 		case O_IP_SRC_SET:
 			show_prerequisites(&flags, HAVE_PROTO, 0);
 			if (!(flags & HAVE_SRCIP))
@@ -1202,6 +1207,7 @@ show_ipfw(struct ip_fw *rule, int pcwidt
 		case O_IP_DST_LOOKUP:
 		case O_IP_DST_MASK:
 		case O_IP_DST_ME:
+		case O_IP4_DST_ME:
 		case O_IP_DST_SET:
 			show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);
 			if (!(flags & HAVE_DSTIP))
@@ -1972,6 +1978,12 @@ fill_ip(ipfw_insn_ip *cmd, char *av)
 		return;
 	}
 
+	if (strcmp(av, "me4") == 0) {
+		cmd->o.opcode = O_IP4_DST_ME;
+		cmd->o.len |= F_INSN_SIZE(ipfw_insn);
+		return;
+	}
+
 	if (strncmp(av, "table(", 6) == 0) {
 		char *p = strchr(av + 6, ',');
 
@@ -2478,6 +2490,8 @@ add_srcip(ipfw_insn *cmd, char *av)
 		cmd->opcode = O_IP_SRC_SET;
 	else if (cmd->opcode == O_IP_DST_LOOKUP)		/* table */
 		cmd->opcode = O_IP_SRC_LOOKUP;
+	else if (cmd->opcode == O_IP4_DST_ME)			/* me4 */
+		cmd->opcode = O_IP4_SRC_ME;
 	else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn))		/* me */
 		cmd->opcode = O_IP_SRC_ME;
 	else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32))	/* one IP */
@@ -2495,6 +2509,8 @@ add_dstip(ipfw_insn *cmd, char *av)
 		;
 	else if (cmd->opcode == O_IP_DST_LOOKUP)		/* table */
 		;
+	else if (cmd->opcode == O_IP4_DST_ME)			/* me4 */
+		;
 	else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn))		/* me */
 		cmd->opcode = O_IP_DST_ME;
 	else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32))	/* one IP */
@@ -2534,7 +2550,7 @@ add_src(ipfw_insn *cmd, char *av, u_char
 		ret = add_srcip6(cmd, av);
 	/* XXX: should check for IPv4, not !IPv6 */
 	if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
-	    !inet_pton(AF_INET6, host, &a)))
+	    strcmp(av, "me4") == 0 || !inet_pton(AF_INET6, host, &a)))
 		ret = add_srcip(cmd, av);
 	if (ret == NULL && strcmp(av, "any") != 0)
 		ret = cmd;
@@ -2560,7 +2576,7 @@ add_dst(ipfw_insn *cmd, char *av, u_char
 		ret = add_dstip6(cmd, av);
 	/* XXX: should check for IPv4, not !IPv6 */
 	if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 ||
-	    !inet_pton(AF_INET6, host, &a)))
+	    strcmp(av, "me4") == 0 || !inet_pton(AF_INET6, host, &a)))
 		ret = add_dstip(cmd, av);
 	if (ret == NULL && strcmp(av, "any") != 0)
 		ret = cmd;
Index: sys/netinet/ip_fw.h
diff -u sys/netinet/ip_fw.h.orig sys/netinet/ip_fw.h
--- sys/netinet/ip_fw.h.orig	2009-12-23 04:01:47.000000000 +0900
+++ sys/netinet/ip_fw.h	2010-01-08 12:33:36.157742465 +0900
@@ -166,6 +166,8 @@
 	O_ALTQ,			/* u32 = altq classif. qid	*/
 	O_DIVERTED,		/* arg1=bitmap (1:loop, 2:out)	*/
 	O_TCPDATALEN,		/* arg1 = tcp data len		*/
+	O_IP4_SRC_ME,		/* none				*/
+	O_IP4_DST_ME,		/* none				*/
 	O_IP6_SRC,		/* address without mask		*/
 	O_IP6_SRC_ME,		/* my addresses			*/
 	O_IP6_SRC_MASK,		/* address with the mask	*/
Index: sys/netinet/ipfw/ip_fw2.c
diff -u -p sys/netinet/ipfw/ip_fw2.c.orig sys/netinet/ipfw/ip_fw2.c
--- sys/netinet/ipfw/ip_fw2.c.orig	2010-01-08 12:30:31.039834764 +0900
+++ sys/netinet/ipfw/ip_fw2.c	2010-01-08 12:38:30.778824466 +0900
@@ -1385,6 +1385,7 @@ do {								\
 				break;
 
 			case O_IP_SRC_ME:
+			case O_IP4_SRC_ME:
 				if (is_ipv4) {
 					struct ifnet *tif;
 
@@ -1392,6 +1393,8 @@ do {								\
 					match = (tif != NULL);
 					break;
 				}
+				if (cmd->opcode == O_IP4_SRC_ME)
+					break;
 				/* FALLTHROUGH */
 #ifdef INET6
 			case O_IP6_SRC_ME:
@@ -1425,6 +1428,7 @@ do {								\
 				break;
 
 			case O_IP_DST_ME:
+			case O_IP4_DST_ME:
 				if (is_ipv4) {
 					struct ifnet *tif;
 
@@ -1432,6 +1436,8 @@ do {								\
 					match = (tif != NULL);
 					break;
 				}
+				if (cmd->opcode == O_IP4_DST_ME)
+					break;
 				/* FALLTHROUGH */
 #ifdef INET6
 			case O_IP6_DST_ME:
Index: sys/netinet/ipfw/ip_fw_sockopt.c
diff -u -p sys/netinet/ipfw/ip_fw_sockopt.c.orig sys/netinet/ipfw/ip_fw_sockopt.c
--- sys/netinet/ipfw/ip_fw_sockopt.c.orig	2010-01-07 19:08:05.000000000 +0900
+++ sys/netinet/ipfw/ip_fw_sockopt.c	2010-01-08 12:33:36.237826387 +0900
@@ -529,6 +529,8 @@ check_ipfw_struct(struct ip_fw *rule, in
 		case O_VERSRCREACH:
 		case O_ANTISPOOF:
 		case O_IPSEC:
+		case O_IP4_SRC_ME:
+		case O_IP4_DST_ME:
 #ifdef INET6
 		case O_IP6_SRC_ME:
 		case O_IP6_DST_ME:

--Multipart_Mon_Jan_11_03:27:13_2010-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="rc.firewall-me-unify.diff"
Content-Transfer-Encoding: 7bit

Index: etc/defaults/rc.conf
diff -u etc/defaults/rc.conf.orig etc/defaults/rc.conf
--- etc/defaults/rc.conf.orig	2010-01-02 04:09:40.000000000 +0900
+++ etc/defaults/rc.conf	2010-01-08 18:08:10.227416014 +0900
@@ -143,9 +143,7 @@
 firewall_allowservices=""	# List of IPs which have access to
 				# $firewall_myservices for "workstation"
 				# firewall.
-firewall_trusted=""		# List of IPv4s which have full access to this
-				# host for "workstation" firewall.
-firewall_trusted_ipv6=""	# List of IPv6s which have full access to this
+firewall_trusted=""		# List of IPs which have full access to this
 				# host for "workstation" firewall.
 firewall_logdeny="NO"		# Set to YES to log default denied incoming
 				# packets for "workstation" firewall.
Index: etc/rc.firewall
diff -u etc/rc.firewall.orig etc/rc.firewall
--- etc/rc.firewall.orig	2010-01-08 18:07:55.805178124 +0900
+++ etc/rc.firewall	2010-01-08 18:08:42.558168213 +0900
@@ -212,8 +212,8 @@
 	${fwcmd} add pass all from me to ${net}
 	${fwcmd} add pass all from ${net} to me
 	if [ -n "$net6" ]; then
-		${fwcmd} add pass all from me6 to ${net6}
-		${fwcmd} add pass all from ${net6} to me6
+		${fwcmd} add pass all from me to ${net6}
+		${fwcmd} add pass all from ${net6} to me
 	fi
 
 	if [ -n "$net6" ]; then
@@ -221,7 +221,7 @@
 		${fwcmd} add pass all from fe80::/10 to ff02::/16
 		${fwcmd} add pass all from ${net6} to ff02::/16
 		# Allow DHCPv6
-		${fwcmd} add pass udp from fe80::/10 to me6 546
+		${fwcmd} add pass udp from fe80::/10 to me 546
 	fi
 
 	# Allow TCP through if setup succeeded
@@ -232,30 +232,18 @@
 
 	# Allow setup of incoming email
 	${fwcmd} add pass tcp from any to me 25 setup
-	if [ -n "$net6" ]; then
-		${fwcmd} add pass tcp from any to me6 25 setup
-	fi
 
 	# Allow setup of outgoing TCP connections only
 	${fwcmd} add pass tcp from me to any setup
-	if [ -n "$net6" ]; then
-		${fwcmd} add pass tcp from me6 to any setup
-	fi
 
 	# Disallow setup of all other TCP connections
 	${fwcmd} add deny tcp from any to any setup
 
 	# Allow DNS queries out in the world
 	${fwcmd} add pass udp from me to any 53 keep-state
-	if [ -n "$net6" ]; then
-		${fwcmd} add pass udp from me6 to any 53 keep-state
-	fi
 
 	# Allow NTP queries out in the world
 	${fwcmd} add pass udp from me to any 123 keep-state
-	if [ -n "$net6" ]; then
-		${fwcmd} add pass udp from me6 to any 123 keep-state
-	fi
 
 	# Everything else is denied by default, unless the
 	# IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
@@ -402,25 +390,14 @@
 
 	# Allow setup of incoming email
 	${fwcmd} add pass tcp from any to me 25 setup
-	if [ -n "$inet6" ]; then
-		${fwcmd} add pass tcp from any to me6 25 setup
-	fi
 
 	# Allow access to our DNS
 	${fwcmd} add pass tcp from any to me 53 setup
 	${fwcmd} add pass udp from any to me 53
 	${fwcmd} add pass udp from me 53 to any
-	if [ -n "$inet6" ]; then
-		${fwcmd} add pass tcp from any to me6 53 setup
-		${fwcmd} add pass udp from any to me6 53
-		${fwcmd} add pass udp from me6 53 to any
-	fi
 
 	# Allow access to our WWW
 	${fwcmd} add pass tcp from any to me 80 setup
-	if [ -n "$inet6" ]; then
-		${fwcmd} add pass tcp from any to me6 80 setup
-	fi
 
 	# Reject&Log all setup of incoming connections from the outside
 	${fwcmd} add deny log ip4 from any to any in via ${oif} setup proto tcp
@@ -434,15 +411,9 @@
 
 	# Allow DNS queries out in the world
 	${fwcmd} add pass udp from me to any 53 keep-state
-	if [ -n "$inet6" ]; then
-		${fwcmd} add pass udp from me6 to any 53 keep-state
-	fi
 
 	# Allow NTP queries out in the world
 	${fwcmd} add pass udp from me to any 123 keep-state
-	if [ -n "$inet6" ]; then
-		${fwcmd} add pass udp from me6 to any 123 keep-state
-	fi
 
 	# Everything else is denied by default, unless the
 	# IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
@@ -477,18 +448,13 @@
 
 	# For services permitted below.
 	${fwcmd} add pass tcp  from me to any established
-	if [ $ipv6_available -eq 0 ]; then
-		${fwcmd} add pass tcp from me6 to any established
-	fi
 
 	# Allow any connection out, adding state for each.
 	${fwcmd} add pass tcp  from me to any setup keep-state
 	${fwcmd} add pass udp  from me to any       keep-state
 	${fwcmd} add pass icmp from me to any       keep-state
 	if [ $ipv6_available -eq 0 ]; then
-		${fwcmd} add pass tcp from me6 to any setup keep-state
-		${fwcmd} add pass udp from me6 to any keep-state
-		${fwcmd} add pass ipv6-icmp from me6 to any keep-state
+		${fwcmd} add pass ipv6-icmp from me to any keep-state
 	fi
 
 	# Allow DHCP.
@@ -496,7 +462,7 @@
 	${fwcmd} add pass udp  from any 67     to me 68 in
 	${fwcmd} add pass udp  from any 67     to 255.255.255.255 68 in
 	if [ $ipv6_available -eq 0 ]; then
-		${fwcmd} add pass udp from fe80::/10 to me6 546 in
+		${fwcmd} add pass udp from fe80::/10 to me 546 in
 	fi
 	# Some servers will ping the IP while trying to decide if it's 
 	# still in use.
@@ -525,21 +491,15 @@
 	for i in ${firewall_allowservices} ; do
 	  for j in ${firewall_myservices} ; do
 	    ${fwcmd} add pass tcp from $i to me $j
-	    if [ $ipv6_available -eq 0 ]; then
-	      ${fwcmd} add pass tcp from $i to me6 $j
-	    fi
 	  done
 	done
 
 	# Allow all connections from trusted IPs.
 	# Playing with the content of firewall_trusted could seriously
 	# degrade the level of protection provided by the firewall.
-	for i in ${firewall_trusted} ; do
+	for i in ${firewall_trusted} ${firewall_trusted_ipv6}; do
 	  ${fwcmd} add pass ip from $i to me
 	done
-	for i in ${firewall_trusted_ipv6} ; do
-	  ${fwcmd} add pass all from $i to me6
-	done
 
 	${fwcmd} add 65000 count ip from any to any
 

--Multipart_Mon_Jan_11_03:27:13_2010-1
Content-Type: text/plain; charset=US-ASCII


--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/

--Multipart_Mon_Jan_11_03:27:13_2010-1--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?yge8wc5u872.wl%ume>