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>