Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Nov 2009 00:39:35 +0900
From:      Hajimu UMEMOTO <ume@FreeBSD.org>
To:        net@FreeBSD.org, current@FreeBSD.org
Subject:   [CFR] unified rc.firewall
Message-ID:  <ygeljhyk1qg.wl%ume@mahoroba.org>

next in thread | raw e-mail | index | archive | help
--Multipart_Mon_Nov_23_00:39:35_2009-1
Content-Type: text/plain; charset=US-ASCII

Hi,

The ipfw and ip6fw were unified into ipfw2, now.  But, we still have
rc.firewall and rc.firewall6.  However, there are conflicts with each
other, and it confuses the users, IMHO.
So, I made a patch to unify rc.firewall and rc.firewall6, and obsolete
rc.firewall6 and rc.d/ip6fw.
Please review the attached patch.  If there is no objection, I'll
commit it in next weekend.

Sincerely,

--Multipart_Mon_Nov_23_00:39:35_2009-1
Content-Type: application/octet-stream; type=patch
Content-Disposition: attachment; filename="ipfw-unify.diff"
Content-Transfer-Encoding: 7bit

Index: etc/Makefile
diff -u etc/Makefile.orig etc/Makefile
--- etc/Makefile.orig	2009-10-25 10:10:29.000000000 +0900
+++ etc/Makefile	2009-11-22 22:07:19.840275808 +0900
@@ -15,7 +15,7 @@
 	inetd.conf libalias.conf login.access login.conf mac.conf motd \
 	netconfig network.subr networks newsyslog.conf nsswitch.conf \
 	phones profile protocols \
-	rc rc.bsdextended rc.firewall rc.firewall6 rc.initdiskless \
+	rc rc.bsdextended rc.firewall rc.initdiskless \
 	rc.sendmail rc.shutdown \
 	rc.subr remote rpc services shells \
 	sysctl.conf syslog.conf \
Index: etc/defaults/rc.conf
diff -u etc/defaults/rc.conf.orig etc/defaults/rc.conf
--- etc/defaults/rc.conf.orig	2009-10-25 10:10:29.000000000 +0900
+++ etc/defaults/rc.conf	2009-11-22 21:25:22.343296205 +0900
@@ -118,7 +118,10 @@
 firewall_quiet="NO"		# Set to YES to suppress rule display
 firewall_logging="NO"		# Set to YES to enable events logging
 firewall_flags=""		# Flags passed to ipfw when type is a file
-firewall_client_net="192.0.2.0/24" # Network address for "client" firewall.
+firewall_client_net="192.0.2.0/24" # IPv4 Network address for "client"
+				# firewall.
+#firewall_client_net_ipv6="2001:db8:2:1::/64" # IPv6 network prefix for
+				# "client" firewall.
 firewall_simple_iif="ed1"	# Inside network interface for "simple"
 				# firewall.
 firewall_simple_inet="192.0.2.16/28" # Inside network address for "simple"
@@ -127,12 +130,22 @@
 				# firewall.
 firewall_simple_onet="192.0.2.0/28" # Outside network address for "simple"
 				# firewall.
+#firewall_simple_iif_ipv6="ed1"	# Inside IPv6 network interface for "simple"
+				# firewall.
+#firewall_simple_inet_ipv6="2001:db8:2:800::/56" # Inside IPv6 network prefix
+				# for "simple" firewall.
+#firewall_simple_oif_ipv6="ed0"	# Outside IPv6 network interface for "simple"
+				# firewall.
+#firewall_simple_onet_ipv6="2001:db8:2:0::/56" # Outside IPv6 network prefix
+				# for "simple" firewall.
 firewall_myservices=""		# List of TCP ports on which this host
 				# offers services for "workstation" firewall.
 firewall_allowservices=""	# List of IPs which have access to
 				# $firewall_myservices for "workstation"
 				# firewall.
-firewall_trusted=""		# List of IPs which have full access to this
+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
 				# host for "workstation" firewall.
 firewall_logdeny="NO"		# Set to YES to log default denied incoming
 				# packets for "workstation" firewall.
@@ -470,13 +483,18 @@
 				# faithd(8) setup.
 ipv6_ipv4mapping="NO"		# Set to "YES" to enable IPv4 mapped IPv6 addr
 				# communication. (like ::ffff:a.b.c.d)
-ipv6_firewall_enable="NO"	# Set to YES to enable IPv6 firewall
-				# functionality
-ipv6_firewall_script="/etc/rc.firewall6" # Which script to run to set up the IPv6 firewall
-ipv6_firewall_type="UNKNOWN"	# IPv6 Firewall type (see /etc/rc.firewall6)
-ipv6_firewall_quiet="NO"	# Set to YES to suppress rule display
-ipv6_firewall_logging="NO"	# Set to YES to enable events logging
-ipv6_firewall_flags=""		# Flags passed to ip6fw when type is a file
+#ipv6_firewall_enable="NO"	# Set to YES to enable IPv6 firewall
+				# functionality (DEPRECAED)
+#ipv6_firewall_script="/etc/rc.firewall6" # Which script to run to set up the
+				# IPv6 firewall (DEPRECAED)
+#ipv6_firewall_type="UNKNOWN"	# IPv6 Firewall type (see /etc/rc.firewall6)
+				# (DEPRECAED)
+#ipv6_firewall_quiet="NO"	# Set to YES to suppress rule display
+				# (DEPRECAED)
+#ipv6_firewall_logging="NO"	# Set to YES to enable events logging
+				# (DEPRECAED)
+#ipv6_firewall_flags=""		# Flags passed to ip6fw when type is a file
+				# (DEPRECAED)
 ipv6_ipfilter_rules="/etc/ipf6.rules"	# rules definition file for ipfilter,
 					# see /usr/src/contrib/ipfilter/rules
 					# for examples
Index: etc/rc.d/Makefile
diff -u etc/rc.d/Makefile.orig etc/rc.d/Makefile
--- etc/rc.d/Makefile.orig	2009-10-25 10:10:29.000000000 +0900
+++ etc/rc.d/Makefile	2009-11-22 20:42:16.398311126 +0900
@@ -15,7 +15,7 @@
 	hcsecd \
 	hostapd hostid hostid_save hostname \
 	inetd initrandom \
-	ip6addrctl ip6fw ipfilter ipfs ipfw ipmon \
+	ip6addrctl ipfilter ipfs ipfw ipmon \
 	ipnat ipsec ipxrouted \
 	jail \
 	kadmind kerberos keyserv kldxref kpasswdd \
Index: etc/rc.d/ipfw
diff -u etc/rc.d/ipfw.orig etc/rc.d/ipfw
--- etc/rc.d/ipfw.orig	2009-11-22 20:43:59.000000000 +0900
+++ etc/rc.d/ipfw	2009-11-22 20:46:17.663938405 +0900
@@ -61,7 +61,13 @@
 	# Enable the firewall
 	#
 	if ! ${SYSCTL_W} net.inet.ip.fw.enable=1 1>/dev/null 2>&1; then
-		warn "failed to enable firewall"
+		warn "failed to enable IPv4 firewall"
+	fi
+	if ifconfig lo0 inet6 >/dev/null 2>&1; then
+		if ! ${SYSCTL_W} net.inet6.ip6.fw.enable=1 1>/dev/null 2>&1
+		then
+			warn "failed to enable IPv6 firewall"
+		fi
 	fi
 }
 
@@ -70,6 +76,9 @@
 	# Disable the firewall
 	#
 	${SYSCTL_W} net.inet.ip.fw.enable=0
+	if ifconfig lo0 inet6 >/dev/null 2>&1; then
+		${SYSCTL_W} net.inet6.ip6.fw.enable=0
+	fi
 	if [ -f /etc/rc.d/natd ] ; then
 		/etc/rc.d/natd quietstop
 	fi
Index: etc/rc.firewall
diff -u etc/rc.firewall.orig etc/rc.firewall
--- etc/rc.firewall.orig	2009-10-25 10:10:29.000000000 +0900
+++ etc/rc.firewall	2009-11-22 23:44:43.101805845 +0900
@@ -40,6 +40,27 @@
 	fi
 fi
 
+# afexists af
+#	Returns 0 if the address family is enabled in the kernel
+#	1 otherwise.
+afexists()
+{
+	local _af
+	_af=$1
+
+	case ${_af} in
+	inet)
+		sysctl -n net.inet > /dev/null 2>&1
+		;;
+	inet6)
+		sysctl -n net.inet6 > /dev/null 2>&1
+		;;
+	*)
+		err 1 "afexists(): Unsupported address family: $_af"
+		;;
+	esac
+}
+
 ############
 # Define the firewall type in /etc/rc.conf.  Valid values are:
 #   open        - will allow anyone in
@@ -85,6 +106,32 @@
 	${fwcmd} add 100 pass all from any to any via lo0
 	${fwcmd} add 200 deny all from any to 127.0.0.0/8
 	${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
+	if afexists inet6; then
+		${fwcmd} add 400 deny ip6 from any to ::1
+		${fwcmd} add 500 deny ip6 from ::1 to any
+	fi
+}
+
+setup_ipv6_mandatory () {
+	afexists inet6 || return 0
+
+	############
+	# Only in rare cases do you want to change these rules
+	#
+	# ND
+	#
+	# DAD
+	${fwcmd} add pass ip6 from :: to ff02::/16 proto ipv6-icmp
+	# RS, RA, NS, NA, redirect...
+	${fwcmd} add pass ip6 from fe80::/10 to fe80::/10 proto ipv6-icmp
+	${fwcmd} add pass ip6 from fe80::/10 to ff02::/16 proto ipv6-icmp
+
+	# Allow ICMPv6 destination unreach
+	${fwcmd} add pass ip6 from any to any icmp6types 1 proto ipv6-icmp
+
+	# Allow NS/NA/toobig (don't filter it out)
+	${fwcmd} add pass ip6 from any to any icmp6types 2,135,136 \
+	    proto ipv6-icmp
 }
 
 if [ -n "${1}" ]; then
@@ -109,6 +156,7 @@
 ${fwcmd} -f flush
 
 setup_loopback
+setup_ipv6_mandatory
 
 ############
 # Network Address Translation.  All packets are passed to natd(8)
@@ -166,11 +214,13 @@
 	# against people from outside your own network.
 	#
 	# Configuration:
-	#  firewall_client_net:		Network address of local network.
+	#  firewall_client_net:		Network address of local IPv4 network.
+	#  firewall_client_net_ipv6:	Network address of local IPv6 network.
 	############
 
 	# set this to your local network
 	net="$firewall_client_net"
+	net6="$firewall_client_net_ipv6"
 
 	# Allow limited broadcast traffic from my own net.
 	${fwcmd} add pass all from ${net} to 255.255.255.255
@@ -178,6 +228,16 @@
 	# Allow any traffic to or from my own net.
 	${fwcmd} add pass all from me to ${net}
 	${fwcmd} add pass all from ${net} to me
+	if [ -n "$net6" ]; then
+		${fwcmd} add pass ip6 from me6 to ${net6}
+		${fwcmd} add pass ip6 from ${net6} to me6
+	fi
+
+	if [ -n "$net6" ]; then
+		# Allow any link-local multicast traffic
+		${fwcmd} add pass ip6 from fe80::/10 to ff02::/16
+		${fwcmd} add pass ip6 from ${net6} to ff02::/16
+	fi
 
 	# Allow TCP through if setup succeeded
 	${fwcmd} add pass tcp from any to any established
@@ -212,23 +272,35 @@
 	# on the inside at this machine for those services.
 	#
 	# Configuration:
-	#  firewall_simple_iif:		Inside network interface.
-	#  firewall_simple_inet:	Inside network address.
-	#  firewall_simple_oif:		Outside network interface.
-	#  firewall_simple_onet:	Outside network address.
+	#  firewall_simple_iif:		Inside IPv4 network interface.
+	#  firewall_simple_inet:	Inside IPv4 network address.
+	#  firewall_simple_oif:		Outside IPv4 network interface.
+	#  firewall_simple_onet:	Outside IPv4 network address.
+	#  firewall_simple_iif_ipv6:	Inside IPv6 network interface.
+	#  firewall_simple_inet_ipv6:	Inside IPv6 network prefix.
+	#  firewall_simple_oif_ipv6:	Outside IPv6 network interface.
+	#  firewall_simple_onet_ipv6:	Outside IPv6 network prefix.
 	############
 
 	# set these to your outside interface network
 	oif="$firewall_simple_oif"
 	onet="$firewall_simple_onet"
+	oif6="$firewall_simple_oif_ipv6"
+	onet6="$firewall_simple_onet_ipv6"
 
 	# set these to your inside interface network
 	iif="$firewall_simple_iif"
 	inet="$firewall_simple_inet"
+	iif6="$firewall_simple_iif_ipv6"
+	inet6="$firewall_simple_inet_ipv6"
 
 	# Stop spoofing
 	${fwcmd} add deny all from ${inet} to any in via ${oif}
 	${fwcmd} add deny all from ${onet} to any in via ${iif}
+	if [ -n "$oif6" -a -n "$onet6" -a -n "$iif6" -a -n "$inet6" ]; then
+		${fwcmd} add deny ip6 from ${inet6} to any in via ${oif6}
+		${fwcmd} add deny ip6 from ${onet6} to any in via ${iif6}
+	fi
 
 	# Stop RFC1918 nets on the outside interface
 	${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
@@ -254,7 +326,7 @@
 	case ${natd_enable} in
 	[Yy][Ee][Ss])
 		if [ -n "${natd_interface}" ]; then
-			${fwcmd} add divert natd all from any to any via ${natd_interface}
+			${fwcmd} add divert natd ip4 from any to any via ${natd_interface}
 		fi
 		;;
 	esac
@@ -273,6 +345,55 @@
 	${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif}
 	${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif}
 
+	if [ -n "$oif6" -a -n "$onet6" -a -n "$iif6" -a -n "$inet6" ]; then
+		# Stop unique local unicast address on the outside interface
+		${fwcmd} add deny ip6 from fc00::/7 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to fc00::/7 via ${oif6}
+
+		# Stop site-local on the outside interface
+		${fwcmd} add deny ip6 from fec0::/10 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to fec0::/10 via ${oif6}
+
+		# Disallow "internal" addresses to appear on the wire.
+		${fwcmd} add deny ip6 from ::ffff:0.0.0.0/96 to any \
+		    via ${oif6}
+		${fwcmd} add deny ip6 from any to ::ffff:0.0.0.0/96 \
+		    via ${oif6}
+
+		# Disallow packets to malicious IPv4 compatible prefix.
+		${fwcmd} add deny ip6 from ::224.0.0.0/100 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ::224.0.0.0/100 via ${oif6}
+		${fwcmd} add deny ip6 from ::127.0.0.0/104 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ::127.0.0.0/104 via ${oif6}
+		${fwcmd} add deny ip6 from ::0.0.0.0/104 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ::0.0.0.0/104 via ${oif6}
+		${fwcmd} add deny ip6 from ::255.0.0.0/104 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ::255.0.0.0/104 via ${oif6}
+
+		${fwcmd} add deny ip6 from ::0.0.0.0/96 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ::0.0.0.0/96 via ${oif6}
+
+		# Disallow packets to malicious 6to4 prefix.
+		${fwcmd} add deny ip6 from 2002:e000::/20 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:e000::/20 via ${oif6}
+		${fwcmd} add deny ip6 from 2002:7f00::/24 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:7f00::/24 via ${oif6}
+		${fwcmd} add deny ip6 from 2002:0000::/24 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:0000::/24 via ${oif6}
+		${fwcmd} add deny ip6 from 2002:ff00::/24 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:ff00::/24 via ${oif6}
+
+		${fwcmd} add deny ip6 from 2002:0a00::/24 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:0a00::/24 via ${oif6}
+		${fwcmd} add deny ip6 from 2002:ac10::/28 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:ac10::/28 via ${oif6}
+		${fwcmd} add deny ip6 from 2002:c0a8::/32 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to 2002:c0a8::/32 via ${oif6}
+
+		${fwcmd} add deny ip6 from ff05::/16 to any via ${oif6}
+		${fwcmd} add deny ip6 from any to ff05::/16 via ${oif6}
+	fi
+
 	# Allow TCP through if setup succeeded
 	${fwcmd} add pass tcp from any to any established
 
@@ -291,7 +412,11 @@
 	${fwcmd} add pass tcp from any to me 80 setup
 
 	# Reject&Log all setup of incoming connections from the outside
-	${fwcmd} add deny log tcp from any to any in via ${oif} setup
+	${fwcmd} add deny log ip4 from any to any in via ${oif} setup proto tcp
+	if [ -n "$oif6" -a -n "$onet6" -a -n "$iif6" -a -n "$inet6" ]; then
+		${fwcmd} add deny log ip6 from any to any in via ${oif6} \
+		    setup proto tcp
+	fi
 
 	# Allow setup of any other TCP connection
 	${fwcmd} add pass tcp from any to any setup
@@ -313,7 +438,7 @@
 	#			 	 offers services.
 	#  firewall_allowservices:	List of IPs which has access to
 	#				 $firewall_myservices.
-	#  firewall_trusted:		List of IPs which has full access 
+	#  firewall_trusted:		List of IPv4s which has full access 
 	#				 to this host. Be very carefull 
 	#				 when setting this. This option can
 	#				 seriously degrade the level of 
@@ -324,17 +449,31 @@
 	#  firewall_nologports:		List of TCP/UDP ports for which
 	#				 denied incomming packets are not
 	#				 logged.
-	
+	#  firewall_trusted_ipv6:	List of IPv6s which has full access 
+	#				 to this host. Be very carefull 
+	#				 when setting this. This option can
+	#				 seriously degrade the level of 
+	#				 protection provided by the firewall.
+
 	# Allow packets for which a state has been built.
 	${fwcmd} add check-state
 
 	# For services permitted below.
 	${fwcmd} add pass tcp  from me to any established
+	if afexists inet6; then
+		${fwcmd} add pass ip6 from any to any proto tcp 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 afexists inet6; then
+		${fwcmd} add pass ip6 from me6 to any proto tcp setup
+		${fwcmd} add pass ip6 from me6 to any proto udp keep-state
+		${fwcmd} add pass ip6 from me6 to any proto ipv6-icmp \
+		    keep-state
+	fi
 
 	# Allow DHCP.
 	${fwcmd} add pass udp  from 0.0.0.0 68 to 255.255.255.255 67 out
@@ -343,6 +482,10 @@
 	# Some servers will ping the IP while trying to decide if it's 
 	# still in use.
 	${fwcmd} add pass icmp from any to any icmptype 8
+	if afexists inet6; then
+		${fwcmd} add pass ip6 from any to any icmp6type 128,129 \
+		    proto ipv6-icmp
+	fi
 
 	# Allow "mandatory" ICMP in.
 	${fwcmd} add pass icmp from any to any icmptype 3,4,11
@@ -361,6 +504,9 @@
 	for i in ${firewall_allowservices} ; do
 	  for j in ${firewall_myservices} ; do
 	    ${fwcmd} add pass tcp from $i to me $j
+	    if afexists inet6; then
+	      ${fwcmd} add pass tcp from $i to me6 $j setup
+	    fi
 	  done
 	done
 
@@ -370,7 +516,10 @@
 	for i in ${firewall_trusted} ; do
 	  ${fwcmd} add pass ip from $i to me
 	done
-	
+	for i in ${firewall_trusted_ipv6} ; do
+	  ${fwcmd} add pass ip6 from $i to me6
+	done
+
 	${fwcmd} add 65000 count ip from any to any
 
 	# Drop packets to ports where we don't want logging

--Multipart_Mon_Nov_23_00:39:35_2009-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_Nov_23_00:39:35_2009-1--



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