This is a really nice rewrite of rc.firewall that cleans it up and adds
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 22 Oct 2004 20:26:11 +0000 (20:26 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 22 Oct 2004 20:26:11 +0000 (20:26 +0000)
additional firewall_* rc.conf variables, with appropriate defaults, for
quick and easy rc-based firewall configuration.  More sophisticated
configurations should continue to use the ipfw.conf mechanism.

The default client firewall is now similar to the description in the
'man firewall' manual page, allowing certain basic services ports
through and those ICMP messages required for proper network and protocol
management.

Submitted-by: Andreas Hauser <andy@splashground.de>
etc/defaults/rc.conf
etc/rc.firewall

index e6052ae..07798f3 100644 (file)
@@ -14,7 +14,7 @@
 # All arguments must be in double or single quotes.
 #
 # $FreeBSD: src/etc/defaults/rc.conf,v 1.180 2003/06/26 09:50:50 smkelly Exp $
-# $DragonFly: src/etc/defaults/rc.conf,v 1.15 2004/10/06 17:03:49 joerg Exp $
+# $DragonFly: src/etc/defaults/rc.conf,v 1.16 2004/10/22 20:26:11 dillon Exp $
 
 ##############################################################
 ###  Important initial Boot-time options  ####################
@@ -52,6 +52,9 @@ extra_netfs_types="NO"        # List of network extra filesystem types for delayed
 ##############################################################
 
 ### Basic network and firewall/security options: ###
+#
+# see 'man firewall' for an explanation of the default firewall rules
+#
 hostname=""                    # Set this!
 nisdomainname="NO"             # Set to NIS domain if using NIS (or NO).
 dhclient_program="/sbin/dhclient"      # Path to dhcp client program.
@@ -59,6 +62,11 @@ dhclient_flags=""            # Additional flags to pass to dhcp client.
 firewall_enable="NO"           # Set to YES to enable firewall functionality
 firewall_script="/etc/rc.firewall" # Which script to run to set up the firewall
 firewall_type="UNKNOWN"                # Firewall type (see /etc/rc.firewall)
+firewall_trusted_nets="192.168.0.0/16" # list of trusted nets
+firewall_trusted_interfaces=""  # list of trusted interfaces e.g. "rl0 xl0"
+firewall_allowed_icmp_types="0 3 8 11 12 13 14"
+firewall_open_tcp_ports="22 25 53 80 113 443"
+firewall_open_udp_ports="53"
 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
index f898bba..190058f 100644 (file)
 #!/bin/sh
-# Copyright (c) 1996  Poul-Henning Kamp
-# All rights reserved.
 #
+# Copyright (c) 2004 The DragonFly Project.  All rights reserved.
+# 
+# This code is derived from software contributed to The DragonFly Project
+# by Andreas Hauser <andy-dragonfly@splashground.de>
+# 
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
+# 
 # 1. Redistributions of source code must retain the above copyright
 #    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 3. Neither the name of The DragonFly Project nor the names of its
+#    contributors may be used to endorse or promote products derived
+#    from this software without specific, prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/etc/rc.firewall,v 1.30.2.16 2003/02/10 05:45:06 trhodes Exp $
-# $DragonFly: src/etc/rc.firewall,v 1.2 2003/06/17 04:24:45 dillon Exp $
+# $DragonFly: src/etc/rc.firewall,v 1.3 2004/10/22 20:26:03 dillon Exp $
+# A simple packetfilter configurable via /etc/rc.conf
 #
-
+# Variables in rc.conf:
 #
-# Setup system for firewall service.
+# firewall_type
+#     UNKNOWN  - disables the loading of firewall rules.
+#     open     - will allow anyone in
+#     client   - enables the packetfilter
+#     simple   - enables the packetfilter
+#     closed   - totally disables IP services except via lo0 interface
+#     filename - will load the rules in the given filename (full path required)
 #
+#  firewall_trusted_nets
+#  firewall_trusted_interfaces
+#  firewall_allowed_icmp_types
+#  firewall_open_tcp_ports
+#  firewall_open_udp_ports
 
-# Suck in the configuration variables.
 if [ -z "${source_rc_confs_defined}" ]; then
-       if [ -r /etc/defaults/rc.conf ]; then
-               . /etc/defaults/rc.conf
-               source_rc_confs
-       elif [ -r /etc/rc.conf ]; then
-               . /etc/rc.conf
-       fi
-fi
-
-############
-# Define the firewall type in /etc/rc.conf.  Valid values are:
-#   open     - will allow anyone in
-#   client   - will try to protect just this machine
-#   simple   - will try to protect a whole network
-#   closed   - totally disables IP services except via lo0 interface
-#   UNKNOWN  - disables the loading of firewall rules.
-#   filename - will load the rules in the given filename (full path required)
-#
-# For ``client'' and ``simple'' the entries below should be customized
-# appropriately.
-
-############
-#
-# If you don't know enough about packet filtering, we suggest that you
-# take time to read this book:
-#
-#      Building Internet Firewalls, 2nd Edition
-#      Brent Chapman and Elizabeth Zwicky
-#
-#      O'Reilly & Associates, Inc
-#      ISBN 1-56592-871-7
-#      http://www.ora.com/
-#      http://www.oreilly.com/catalog/fire2/
-#
-# For a more advanced treatment of Internet Security read:
-#
-#      Firewalls & Internet Security
-#      Repelling the wily hacker
-#      William R. Cheswick, Steven M. Bellowin
-#
-#      Addison-Wesley
-#      ISBN 0-201-63357-4
-#      http://www.awl.com/
-#      http://www.awlonline.com/product/0%2C2627%2C0201633574%2C00.html
-#
-
-setup_loopback () {
-       ############
-       # Only in rare cases do you want to change these rules
-       #
-       ${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 [ -n "${1}" ]; then
-       firewall_type="${1}"
+        if [ -r /etc/defaults/rc.conf ]; then
+                . /etc/defaults/rc.conf
+                source_rc_confs
+        elif [ -r /etc/rc.conf ]; then
+                . /etc/rc.conf
+        fi
 fi
 
-############
-# Set quiet mode if requested
-#
 case ${firewall_quiet} in
 [Yy][Ee][Ss])
-       fwcmd="/sbin/ipfw -q"
-       ;;
+        fwcmd="/sbin/ipfw -q"
+        ;;
 *)
-       fwcmd="/sbin/ipfw"
-       ;;
+        fwcmd="/sbin/ipfw"
+        ;;
 esac
 
-############
-# Flush out the list before we begin.
-#
-${fwcmd} -f flush
-
-############
-# Network Address Translation.  All packets are passed to natd(8)
-# before they encounter your remaining rules.  The firewall rules
-# will then be run again on each packet after translation by natd
-# starting at the rule number following the divert rule.
-#
-# For ``simple'' firewall type the divert rule should be put to a
-# different place to not interfere with address-checking rules.
-#
-case ${firewall_type} in
-[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt])
-       case ${natd_enable} in
-       [Yy][Ee][Ss])
-               if [ -n "${natd_interface}" ]; then
-                       ${fwcmd} add 50 divert natd all from any to any via ${natd_interface}
-               fi
-               ;;
-       esac
+case ${firewall_logging} in
+[Yy][Ee][Ss])
+        log="log"
+        ;;
+*)
+        log=""
+        ;;
 esac
 
-############
-# If you just configured ipfw in the kernel as a tool to solve network
-# problems or you just want to disallow some particular kinds of traffic
-# then you will want to change the default policy to open.  You can also
-# do this as your only action by setting the firewall_type to ``open''.
-#
-# ${fwcmd} add 65000 pass all from any to any
-
-
-# Prototype setups.
-#
-case ${firewall_type} in
-[Oo][Pp][Ee][Nn])
-       setup_loopback
-       ${fwcmd} add 65000 pass all from any to any
-       ;;
-
-[Cc][Ll][Ii][Ee][Nn][Tt])
-       ############
-       # This is a prototype setup that will protect your system somewhat
-       # against people from outside your own network.
-       ############
-
-       # set these to your network and netmask and ip
-       net="192.0.2.0"
-       mask="255.255.255.0"
-       ip="192.0.2.1"
-
-       setup_loopback
-
-       # Allow any traffic to or from my own net.
-       ${fwcmd} add pass all from ${ip} to ${net}:${mask}
-       ${fwcmd} add pass all from ${net}:${mask} to ${ip}
-
-       # Allow TCP through if setup succeeded
-       ${fwcmd} add pass tcp from any to any established
-
-       # Allow IP fragments to pass through
-       ${fwcmd} add pass all from any to any frag
-
-       # Allow setup of incoming email
-       ${fwcmd} add pass tcp from any to ${ip} 25 setup
-
-       # Allow setup of outgoing TCP connections only
-       ${fwcmd} add pass tcp from ${ip} to any setup
-
-       # 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 ${ip} to any 53 keep-state
-
-       # Allow NTP queries out in the world
-       ${fwcmd} add pass udp from ${ip} to any 123 keep-state
-
-       # Everything else is denied by default, unless the
-       # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
-       # config file.
-       ;;
-
-[Ss][Ii][Mm][Pp][Ll][Ee])
-       ############
-       # This is a prototype setup for a simple firewall.  Configure this
-       # machine as a named server and ntp server, and point all the machines
-       # on the inside at this machine for those services.
-       ############
-
-       # set these to your outside interface network and netmask and ip
-       oif="ed0"
-       onet="192.0.2.0"
-       omask="255.255.255.240"
-       oip="192.0.2.1"
-
-       # set these to your inside interface network and netmask and ip
-       iif="ed1"
-       inet="192.0.2.16"
-       imask="255.255.255.240"
-       iip="192.0.2.17"
-
-       setup_loopback
-
-       # Stop spoofing
-       ${fwcmd} add deny all from ${inet}:${imask} to any in via ${oif}
-       ${fwcmd} add deny all from ${onet}:${omask} to any in via ${iif}
-
-       # Stop RFC1918 nets on the outside interface
-       ${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
-       ${fwcmd} add deny all from any to 172.16.0.0/12 via ${oif}
-       ${fwcmd} add deny all from any to 192.168.0.0/16 via ${oif}
+# we handle start, stop, firewall_type and nothing as argument
+if [ -n "$1" ]; then
+    case $1 in
+        start)
+        ;;
+        stop)
+        firewall_type="open"
+        ;;
+        *)
+        firewall_type="$1"
+        ;;
+    esac
+fi
 
-       # Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
-       # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
-       # on the outside interface
-       ${fwcmd} add deny all from any to 0.0.0.0/8 via ${oif}
-       ${fwcmd} add deny all from any to 169.254.0.0/16 via ${oif}
-       ${fwcmd} add deny all from any to 192.0.2.0/24 via ${oif}
-       ${fwcmd} add deny all from any to 224.0.0.0/4 via ${oif}
-       ${fwcmd} add deny all from any to 240.0.0.0/4 via ${oif}
+allow_loopback() {
+    ${fwcmd} add pass all from any to any via lo0
+    ${fwcmd} add deny ${log} all from any to 127.0.0.0/8
+    ${fwcmd} add deny ${log} ip from 127.0.0.0/8 to any
+}
 
-       # Network Address Translation.  This rule is placed here deliberately
-       # so that it does not interfere with the surrounding address-checking
-       # rules.  If for example one of your internal LAN machines had its IP
-       # address set to 192.0.2.1 then an incoming packet for it after being
-       # translated by natd(8) would match the `deny' rule above.  Similarly
-       # an outgoing packet originated from it before being translated would
-       # match the `deny' rule below.
-       case ${natd_enable} in
-       [Yy][Ee][Ss])
-               if [ -n "${natd_interface}" ]; then
-                       ${fwcmd} add divert natd all from any to any via ${natd_interface}
-               fi
-               ;;
-       esac
+deny_spoof() {
+    # XXX we don't have verrevpath yet
+    # ${fwcmd} add deny ${log} ip from any to any not verrevpath in
+    echo no verrevpath yet, so no anti-spoof
+}
 
-       # Stop RFC1918 nets on the outside interface
-       ${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif}
-       ${fwcmd} add deny all from 172.16.0.0/12 to any via ${oif}
-       ${fwcmd} add deny all from 192.168.0.0/16 to any via ${oif}
+allow_icmp_types() {
+    for type in $*; do
+        ${fwcmd} add allow icmp from any to any icmptypes ${type}
+    done
+}
 
-       # Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
-       # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
-       # on the outside interface
-       ${fwcmd} add deny all from 0.0.0.0/8 to any via ${oif}
-       ${fwcmd} add deny all from 169.254.0.0/16 to any via ${oif}
-       ${fwcmd} add deny all from 192.0.2.0/24 to any via ${oif}
-       ${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}
+allow_trusted_nets() {
+    for net in $*; do
+        ${fwcmd} add pass all from me to ${net}
+        ${fwcmd} add pass all from ${net} to me
+    done
+}
 
-       # Allow TCP through if setup succeeded
-       ${fwcmd} add pass tcp from any to any established
+allow_trusted_interfaces() {
+    for interface in $*; do
+        ${fwcmd} add pass all from any to any via ${interface}
+    done
+}
 
-       # Allow IP fragments to pass through
-       ${fwcmd} add pass all from any to any frag
+allow_connections() {
+    ${fwcmd} add pass tcp from any to any established
+    ${fwcmd} add pass all from any to any frag
+    ${fwcmd} add pass tcp from me to any setup
+    ${fwcmd} add pass udp from me to any keep-state
+}
 
-       # Allow setup of incoming email
-       ${fwcmd} add pass tcp from any to ${oip} 25 setup
+open_tcp_ports() {
+    for port in $*; do
+        ${fwcmd} add pass tcp from any to me ${port} setup
+    done
+}
 
-       # Allow access to our DNS
-       ${fwcmd} add pass tcp from any to ${oip} 53 setup
-       ${fwcmd} add pass udp from any to ${oip} 53
-       ${fwcmd} add pass udp from ${oip} 53 to any
+open_udp_ports() {
+    for port in $*; do
+        ${fwcmd} add pass udp from any to me ${port}
+        ${fwcmd} add pass udp from me ${port} to any
+    done
+}
 
-       # Allow access to our WWW
-       ${fwcmd} add pass tcp from any to ${oip} 80 setup
+deny_not_routed_nets()
+{
+    # These nets should not be routed
+    nets="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 0.0.0.0/8 \
+        169.254.0.0/16 192.0.2.0/24 224.0.0.0/4 240.0.0.0/4"
+    for net in ${nets} ; do
+        ${fwcmd} add deny ${log} all from any to $net
+    done
+}
 
-       # Reject&Log all setup of incoming connections from the outside
-       ${fwcmd} add deny log tcp from any to any in via ${oif} setup
+deny_rest() {
+    ${fwcmd} add 65000 deny ${log} all from any to any
+}
 
-       # Allow setup of any other TCP connection
-       ${fwcmd} add pass tcp from any to any setup
 
-       # Allow DNS queries out in the world
-       ${fwcmd} add pass udp from ${oip} to any 53 keep-state
 
-       # Allow NTP queries out in the world
-       ${fwcmd} add pass udp from ${oip} to any 123 keep-state
+${fwcmd} -f flush
 
-       # Everything else is denied by default, unless the
-       # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
-       # config file.
-       ;;
+case ${firewall_type} in
+    [Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt])
+    case ${natd_enable} in
+        [Yy][Ee][Ss])
+        if [ -n "${natd_interface}" ]; then
+            ${fwcmd} add 50 divert natd all from any to any via ${natd_interface}
+        fi
+        ;;
+    esac
+esac
 
-[Cc][Ll][Oo][Ss][Ee][Dd])
-       setup_loopback
-       ;;
-[Uu][Nn][Kk][Nn][Oo][Ww][Nn])
-       ;;
-*)
-       if [ -r "${firewall_type}" ]; then
-               ${fwcmd} ${firewall_flags} ${firewall_type}
-       fi
-       ;;
+case ${firewall_type} in
+    [Oo][Pp][Ee][Nn])
+        allow_loopback
+        deny_spoof
+        ${fwcmd} add 1 pass all from any to any
+    ;;
+
+    # historical names
+    [Cc][Ll][Ii][Ee][Nn][Tt]|[Ss][Ii][Mm][Pp][Ll][Ee]|"")
+        allow_loopback
+        deny_spoof
+        allow_trusted_nets ${firewall_trusted_nets}
+        allow_trusted_interfaces ${firewall_trusted_interfaces}
+        allow_connections
+        deny_not_routed_nets
+        allow_icmp_types ${firewall_allowed_icmp_types}
+        open_tcp_ports ${firewall_open_tcp_ports}
+        open_udp_ports ${firewall_open_udp_ports}
+        deny_rest
+    ;;
+
+    [Cc][Ll][Oo][Ss][Ee][Dd])
+        setup_loopback
+        deny_rest
+    ;;
+
+    [Uu][Nn][Kk][Nn][Oo][Ww][Nn])
+    ;;
+
+    *)
+        if [ -r "${firewall_type}" ]; then
+            ${fwcmd} ${firewall_flags} ${firewall_type}
+        fi
+    ;;
 esac