]> git.ipfire.org Git - people/stevee/network.git/commitdiff
firewall: Add basic IPv6 ruleset generation and macros.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 29 Jul 2012 14:30:48 +0000 (14:30 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 29 Jul 2012 14:30:48 +0000 (14:30 +0000)
12 files changed:
Makefile
firewall
functions.constants
functions.firewall
functions.ip
functions.iptables
functions.macros [new file with mode: 0644]
functions.policy
macros/DHCP [new file with mode: 0644]
macros/HTTP [new file with mode: 0644]
macros/HTTPS [new file with mode: 0644]
macros/WWW [new file with mode: 0644]

index 5cf67f246675291c2ee92b321103a220a5b87729..0e7dc2e4c9061854acf65e3c8e19f8f9bcac836d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ prefix=/usr
 bindir=$(prefix)/bin
 sbindir=$(prefix)/sbin
 libdir=$(prefix)/lib
+datadir=$(prefix)/share
 sysconfdir=/etc
 localstatedir=/var
 systemdunitdir=$(prefix)/lib/systemd/system
@@ -27,6 +28,7 @@ install:
        -mkdir -pv $(DESTDIR)$(sbindir)
        -mkdir -pv $(DESTDIR)$(systemdunitdir)
        -mkdir -pv $(DESTDIR)$(tmpfilesdir)
+       -mkdir -pv $(DESTDIR)$(datadir)/firewall
 
        install -m 755 -v firewall $(DESTDIR)$(sbindir)
        install -m 755 -v network $(DESTDIR)$(sbindir)
@@ -60,6 +62,9 @@ install:
        # Install pppoe-server wrapper.
        install -m 755 ppp/pppoe-server $(DESTDIR)$(libdir)/network/
 
+       # Install the firewall macros.
+       cp -av macros $(DESTDIR)$(datadir)/firewall/
+
        # Create the version file.
        : > $(VERSION_FILE)
        echo "# This file is automatically generated." >> $(VERSION_FILE)
index 5b49ed14128306e90b74e92f1579314cb155562a..2fa3db3811f17588bd5c8ed8dce1dfccdc8036c1 100755 (executable)
--- a/firewall
+++ b/firewall
 . /usr/lib/network/functions
 
 function cli_start() {
-       firewall_start
+       firewall_start $@
 }
 
 function cli_stop() {
        firewall_stop
 }
 
+function cli_show() {
+       firewall_show $@
+}
+
+function cli_panic() {
+       if cli_help_requested $@; then
+               cli_show_man firewall-panic
+               exit ${EXIT_OK}
+       fi
+
+       local admin_hosts
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       *)
+                               if ip_is_valid ${1}; then
+                                       admin_hosts="${admin_hosts} ${1}"
+                               else
+                                       warning "Invalid IP address: ${1}"
+                               fi
+                               ;;
+               esac
+               shift
+       done
+
+       firewall_panic ${admin_hosts}
+}
+
 function cli_config() {
        if cli_help_requested $@; then
                cli_usage root-config
@@ -68,6 +95,14 @@ case "${action}" in
                cli_stop $@
                ;;
 
+       show)
+               cli_show $@
+               ;;
+
+       panic)
+               cli_panic $@
+               ;;
+
        config)
                cli_config $@
                ;;
index 84bdbd469726655ad85296766d3fe9d64be6be6c..fa192b31c317dd22e8b63cf0c66d0a3d57ec9c1e 100644 (file)
@@ -93,8 +93,11 @@ IPTABLES_TMPDIR=
 FIREWALL_CONFIG_DIR="/etc/firewall"
 FIREWALL_ZONES_DIR="${FIREWALL_CONFIG_DIR}/zones"
 FIREWALL_CONFIG_FILE="${FIREWALL_CONFIG_DIR}/config"
-FIREWALL_CONFIG_PORTFW="${FIREWALL_CONFIG_DIR}/portfw"
+FIREWALL_CONFIG_RULES="${FIREWALL_CONFIG_DIR}/rules"
 
-FIREWALL_CONFIG_PARAMS=""
+FIREWALL_MACROS_DIRS="${FIREWALL_CONFIG_DIR}/macros /usr/share/firewall/macros"
 
-FIREWALL_LOG_FACILITY="syslog"
+FIREWALL_CONFIG_PARAMS="FIREWALL_LOG_METHOD FIREWALL_NFLOG_THRESHOLD"
+
+FIREWALL_LOG_METHOD="nflog"
+FIREWALL_NFLOG_THRESHOLD=30
index 56a840f10221235ffacfabc3873702f990f692d1..2a5cbedbf7604da437dae799e41c32371c5b246f 100644 (file)
 # High-level function which will create a ruleset for the current firewall
 # configuration and load it into the kernel.
 function firewall_start() {
+       # Test mode.
+       local test="false"
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --test)
+                               test="true"
+                               ;;
+               esac
+               shift
+       done
+
+       if enabled test; then
+               log INFO "Test mode enabled."
+               log INFO "The firewall ruleset will not be loaded."
+       fi
+
        firewall_lock_acquire
 
        # Initialize an empty iptables ruleset.
@@ -39,8 +56,8 @@ function firewall_start() {
                policy_add_zone ${zone}
        done
 
-       # Commit the new ruleset.
-       iptables_commit
+       # Load the new ruleset.
+       iptables_load ${test}
 
        firewall_lock_release
 }
@@ -52,8 +69,37 @@ function firewall_stop() {
        # with default policy ACCEPT.
        iptables_init ACCEPT
 
-       # Commit it.
-       iptables_commit
+       # Load it.
+       iptables_load
+
+       firewall_lock_release
+}
+
+function firewall_show() {
+       # Shows the ruleset that is currently loaded.
+       iptables_status
+
+       return ${EXIT_OK}
+}
+
+function firewall_panic() {
+       local admin_hosts="$@"
+
+       firewall_lock_acquire
+
+       # Drop all communications.
+       iptables_init DROP
+
+       # If an admin host is provided, some administrative
+       # things will be allowed from there.
+       local admin_host
+       for admin_host in ${admin_hosts}; do
+               iptables -A INPUT -s ${admin_host} -j ACCEPT
+               iptables -A OUTPUT -d ${admin_host} -j ACCEPT
+       done
+
+       # Load it.
+       iptables_load
 
        firewall_lock_release
 }
@@ -117,17 +163,17 @@ function firewall_connection_tracking() {
        iptables -A FORWARD -j CONNTRACK
 }
 
-function firewall_import_portfw() {
+function firewall_import_rules() {
        local zone=${1}
        shift
 
        local protocol="ipv6"
-       local chain="filter"
+       local table="filter"
 
        while [ $# -gt 0 ]; do
                case "${1}" in
-                       --chain=*)
-                               chain=$(cli_get_val ${1})
+                       --table=*)
+                               table=$(cli_get_val ${1})
                                ;;
                        --protocol=*)
                                protocol=$(cli_get_val ${1})
@@ -136,12 +182,7 @@ function firewall_import_portfw() {
        done
 
        assert isoneof protocol ipv4 ipv6
-
-       local allowed_chains="filter"
-       if [ "${protocol}" = "ipv4" ]; then
-               allowed_chains="${allowed_chains} nat"
-       fi
-       assert isoneof chain ${allowed_chains}
+       assert isoneof table $(iptables_table ${protocol})
 
        # XXX TODO
 
@@ -153,7 +194,5 @@ function firewall_import_portfw() {
                        nat)
                                ;;
                esac
-       done < ${FIREWALL_CONFIG_PORTFW}
+       done < ${FIREWALL_CONFIG_RULES}
 }
-
-
index 54ed77833e1ebcf8021c171ee2885565dd9f0235..2fa2d7624b560f3cbf9ead244143f1d4183901ea 100644 (file)
@@ -65,6 +65,14 @@ function ip_protocol_is_supported() {
        listmatch ${proto} ${IP_SUPPORTED_PROTOCOLS}
 }
 
+function ip_is_valid() {
+       local address=${1}
+       assert isset address
+
+       local proto=$(ip_detect_protocol ${address})
+       isset proto && return ${EXIT_TRUE} || return ${EXIT_FALSE}
+}
+
 function ip_address_add() {
        local device=${1}
        local address=${2}
index cf1e4769f86e4634d7235a17be0eda6e9585ace5..105140513bdd09f6e7253e8747ad6c82dece7abc 100644 (file)
 function iptables() {
        local arg
        local args
-       local table
+       local table="filter"
+       local src dst
+
+       # Default is both protocols.
+       local proto="6 4"
 
        # Check if the directory where we put our rules in is set and
        # exists.
        assert isset IPTABLES_TMPDIR
        assert [ -d "${IPTABLES_TMPDIR}" ]
 
-       table=filter
-
        # Parsing arguments
        while [ $# -gt 0 ]; do
                case "${1}" in
+                       # Select IPv4 protocol.
+                       -4)
+                               proto="4"
+                               shift
+                               ;;
+                       # Select IPv6 protocol.
+                       -6)
+                               proto="6"
+                               shift
+                               ;;
                        -t)
                                table=${2}
                                shift 2
@@ -44,94 +56,316 @@ function iptables() {
                                ;;
                        *)
                                args="${args} ${1}"
+
+                               # Save some values for further processing.
+                               case "${1}" in
+                                       -s)
+                                               src="${2}"
+                                               ;;
+                                       -d)
+                                               dst="${2}"
+                                               ;;
+                               esac
                                shift
                                ;;
                esac
        done
 
-       echo "${args:1:${#args}}" >> ${IPTABLES_TMPDIR}/${table}
+       # Check that the nat table is not used for IPv6.
+       if isoneof 6 ${proto}; then
+               assert [ "${table}" != "nat" ]
+       fi
+
+       # Detect the version of the IP protocol.
+       local src_proto
+       isset src && src_proto=$(ip_detect_protocol ${src})
+
+       local dst_proto
+       isset dst && dst_proto=$(ip_detect_protocol ${dst})
+
+       # Check that the source and destinations are not
+       # using different versions of the IP protocol.
+       if isset src_proto && isset dst_proto; then
+               assert [ "${src_proto}" = "${dst_proto}" ]
+       fi
+
+       local rulesfile
+       local p
+       for p in ${proto}; do
+               case "${p}" in
+                       6)
+                               listmatch ipv4 ${src_proto} ${dst_proto} \
+                                       && continue
+                               ;;
+                       4)
+                               listmatch ipv6 ${src_proto} ${dst_proto} \
+                                       && continue
+                               ;;
+               esac
+
+               rulesfile=$(iptables_rulesfile ipv${p} ${table})
+               print "${args:1:${#args}}" >> ${rulesfile}
+       done
+}
+
+# Calls the binary iptables command.
+function _iptables() {
+       local iptables_cmd=$(which iptables)
+       assert isset iptables_cmd
+
+       ${iptables_cmd} $@
+}
+
+function iptables_status() {
+       _iptables -L -n -v
+}
+
+# Returns which tables exist for the given protocol.
+function iptables_tables() {
+       local proto=${1}
+       local file
+
+       case "${proto}" in
+               ipv6)
+                       file="/proc/net/ip6_tables_names"
+                       ;;
+               ipv4)
+                       file="/proc/net/ip_tables_names"
+                       ;;
+               *)
+                       return ${EXIT_ERROR}
+                       ;;
+       esac
+
+       assert [ -r "${file}" ]
+
+       print "$(<${file})"
+       return ${EXIT_OK}
+}
+
+function iptables_rulesfile() {
+       local proto=${1}
+       proto=${proto/ipv/}
+
+       local chain=${2}
+       [ -z "${chain}" ] && chain="ruleset"
+
+       print "${IPTABLES_TMPDIR}/${chain}${proto}"
 }
 
 function iptables_init() {
        local policy=${1}
-       assert isoneof policy ACCEPT DROP
+       assert isset policy
 
+       # Create filter table and initialize chains.
        iptables "* filter"
-       iptables_chain_create -t filter INPUT       ${policy}
-       iptables_chain_create -t filter OUTPUT      ${policy}
-       iptables_chain_create -t filter FORWARD     ${policy}
+       iptables_chain_create -t filter INPUT   --policy=${policy}
+       iptables_chain_create -t filter OUTPUT  --policy=${policy}
+       iptables_chain_create -t filter FORWARD --policy=${policy}
 
+       # Create mangle table initialize chains.
        iptables -t mangle "* mangle"
-       iptables_chain_create -t mangle PREROUTING  ACCEPT
-       iptables_chain_create -t mangle INPUT       ACCEPT
-       iptables_chain_create -t mangle OUTPUT      ACCEPT
-       iptables_chain_create -t mangle FORWARD     ACCEPT
-       iptables_chain_create -t mangle POSTROUTING ACCEPT
+       iptables_chain_create -t mangle PREROUTING  --policy=ACCEPT
+       iptables_chain_create -t mangle INPUT       --policy=ACCEPT
+       iptables_chain_create -t mangle OUTPUT      --policy=ACCEPT
+       iptables_chain_create -t mangle FORWARD     --policy=ACCEPT
+       iptables_chain_create -t mangle POSTROUTING --policy=ACCEPT
 
-       iptables -t nat "* nat"
-       iptables_chain_create -t nat    PREROUTING  ACCEPT
-       iptables_chain_create -t nat    OUTPUT      ACCEPT
-       iptables_chain_create -t nat    POSTROUTING ACCEPT
+       # Add NAT table for IPv4.
+       iptables -4 -t nat "* nat"
+       iptables_chain_create -4 -t nat PREROUTING  --policy=ACCEPT
+       iptables_chain_create -4 -t nat OUTPUT      --policy=ACCEPT
+       iptables_chain_create -4 -t nat POSTROUTING --policy=ACCEPT
 }
 
-function iptables_commit() {
-       local chain
+# Load the created ruleset into the kernel.
+function iptables_load() {
+       # If first argument is present and true, we
+       # run in test mode.
+       local test="${1}"
 
-       # Check if the directory where we put our rules in is set and
-       # exists.
-       assert isset IPTABLES_TMPDIR
-       assert [ -d "${IPTABLES_TMPDIR}" ]
+       local rulesfile
 
-       log INFO "Committing firewall configuration..."
+       # First, commit all tables.
+       _iptables_commit
+
+       # Concat the table rulesets into one big file.
+       local proto
+       for proto in 6 4; do
+               rulesfile=$(iptables_rulesfile ipv${proto})
+
+               local table
+               local tablefile
+               for table in $(iptables_tables ipv${proto}); do
+                       tablefile=$(iptables_rulesfile ipv${proto} ${table})
+                       print "$(<${tablefile})"
+               done > ${rulesfile}
+       done
+
+       local error="false"
+       local ret
+
+       # First check if everything is correctly formatted.
+       for proto in 6 4; do
+               rulesfile=$(iptables_rulesfile ipv${proto})
+
+               _iptables_load ipv${proto} ${rulesfile} true
+               if [ $? -ne ${EXIT_OK} ]; then
+                       log CRITICAL "Ruleset load check failed for IPv${proto}"
+                       error="true"
+               fi
+       done
+
+       # Check if there has been an error in the load check.
+       if enabled error; then
+               iptables_dump CRITICAL
+
+               log CRITICAL "New firewall rules could not be loaded."
+               return ${EXIT_ERROR}
+       fi
+
+       # Dump the data, we are going to load.
+       iptables_dump
+
+       # If we are running in test mode, we are done here.
+       enabled test && return ${EXIT_OK}
+
+       # If we got until here, everything is fine to load the ruleset.
+       for proto in 6 4; do
+               rulesfile=$(iptables_rulesfile ipv${proto})
+
+               _iptables_load ipv${proto} ${rulesfile}
+       done
+       return ${EXIT_OK}
+}
+
+# Commit all tables.
+function _iptables_commit() {
        iptables -t filter "COMMIT"
        iptables -t mangle "COMMIT"
-       iptables -t nat    "COMMIT"
 
-       local iptables_ruleset="${IPTABLES_TMPDIR}/commit"
-       : > ${iptables_ruleset}
+       # Commit NAT chain for IPv4.
+       iptables -4 -t nat "COMMIT"
+}
+
+function _iptables_load() {
+       local proto=${1}
+       local file=${2}
+       local testmode=${3}
 
-       # Concat the rules for every chain into one file.
-       local table
-       for table in filter mangle nat; do
-               cat ${IPTABLES_TMPDIR}/${table} \
-                       >> ${iptables_ruleset} 2>/dev/null
-       done
+       local command
+       case "${proto}" in
+               ipv6)
+                       command="ip6tables-restore"
+                       ;;
+               ipv4)
+                       command="iptables-restore"
+                       ;;
+       esac
+       assert isset command
+
+       if enabled testmode; then
+               command="${command} --test"
+       fi
+
+       local time_started=$(date -u "+%s")
+
+       cmd ${command} < ${file}
+       local ret=$?
+
+       case "${ret}" in
+               ${EXIT_OK})
+                       local time_finished=$(date -u "+%s")
+                       time_finished=$(( ${time_finished} - ${time_started} ))
+                       log INFO \
+                               "Successfully loaded new firewall ruleset for IPv${proto/ipv/} in ${time_finished}s!"
+                       ;;
+               *)
+                       if ! enabled testmode; then
+                               log CRITICAL "Error loading firewall ruleset for IPv${proto/ipv/}!"
+                       fi
+                       ;;
+       esac
+
+       return ${ret}
+}
+
+function iptables_dump() {
+       local log_facility=${1-DEBUG}
+
+       # Here is nothing to do, if we are not running in
+       # debug mode.
+       enabled DEBUG || return ${EXIT_OK}
 
-       log DEBUG "Dumping iptables ruleset"
-       local counter=1
+       local rulesfile
+       local counter
        local line
-       while read line; do
-               line=$(printf "%4d | %s\n" "${counter}" "${line}")
-               log DEBUG "${line}"
 
-               counter=$(( $counter + 1 ))
-       done < ${iptables_ruleset}
-       
-       iptables-restore < ${iptables_ruleset}
+       local proto
+       for proto in 6 4; do
+               rulesfile=$(iptables_rulesfile ipv${proto})
+               [ -e "${rulesfile}" ] || continue
+
+               log ${log_facility} "Firewall ruleset for IPv${proto}:"
+
+               counter=1
+               while read line; do
+                       line=$(print "%4d | %s" "${counter}" "${line}")
+                       log ${log_facility} "${line}"
+
+                       counter=$(( $counter + 1 ))
+               done < ${rulesfile}
+       done
 }
 
 function iptables_chain_create() {
+       local chain
+       local table="filter"
+       local policy="-"
+       local proto
        local args
-       if [ "${1}" = "-t" ]; then
-               args="${1} ${2}"
-               shift 2
-       fi
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       -6|-4)
+                               proto=${1}
+                               ;;
+                       -t)
+                               table=${2}
+                               shift
+                               ;;
+                       --policy=*)
+                               policy=$(cli_get_val ${1})
+                               ;;
+                       *)
+                               chain=${1}
+                               ;;
+               esac
+               shift
+       done
+
+       assert isset chain
+       assert isset table
+       assert isoneof policy ACCEPT DROP "-"
 
-       iptables ${args} ":$1 ${2--} [0:0]"
+       iptables ${proto} -t ${table} ":${chain} ${policy} [0:0]"
 }
 
 function iptables_LOG() {
        local prefix=${1}
+       local ret
 
-       if [ "${FIREWALL_LOG_FACILITY}" = "syslog" ]; then
-               echo -n "LOG"
-               [ -n "$prefix" ] && echo -n " --log-prefix \"$prefix\""
-       else
-               echo -n "NFLOG"
-               [ -n "$prefix" ] && echo -n " --nflog-prefix \"$prefix\""
-               echo -n " --nflog-threshold 30"
-       fi
-       echo
+       case "${FIREWALL_LOG_METHOD}" in
+               nflog)
+                       ret="NFLOG --nflog-threshold ${FIREWALL_NFLOG_THRESHOLD}"
+                       isset prefix && ret="${ret} --nflog-prefix \"$prefix\""
+                       ;;
+               syslog)
+                       ret="LOG"
+                       isset prefix && ret="${ret} --log-prefix \"$prefix\""
+                       ;;
+       esac
+
+       print "${ret}"
 }
 
 function iptables_protocol() {
diff --git a/functions.macros b/functions.macros
new file mode 100644 (file)
index 0000000..785e571
--- /dev/null
@@ -0,0 +1,90 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2012  IPFire Network Development Team                         #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+function macro_file() {
+       local macro=${1}
+       assert isset macro
+
+       # Make the name uppercase.
+       macro=${macro^^}
+
+       local file
+       local dir
+       for dir in ${FIREWALL_MACROS_DIRS}; do
+               file="${dir}/${macro}"
+
+               if [ -r "${file}" ]; then
+                       print "${file}"
+                       return ${EXIT_OK}
+               fi
+       done
+
+       return ${EXIT_ERROR}
+}
+
+function macro_exists() {
+       local macro=${1}
+       assert isset macro
+
+       macro_file ${macro} &>/dev/null \
+               && return ${EXIT_TRUE} || return ${EXIT_FALSE}
+}
+
+function macro_read() {
+       local macro=${1}
+       assert isset macro
+
+       # Make the name uppercase.
+       macro=${macro^^}
+
+       local file=$(macro_file ${macro})
+       assert isset file
+
+       log DEBUG "Parsing macro '${macro}' (${file})."
+
+       local src dst
+       local sport dport
+       local proto
+       local var
+       local line
+
+       while read src dst proto sport dport; do
+               # Skip lines that start with a "#".
+               [ "${src:0:1}" = "#" ] && continue
+
+               if [ "${src}" = "INCLUDE" ]; then
+                       macro_read ${dst}
+                       continue
+               fi
+
+               line=""
+
+               # Remove all the dashes.
+               for var in src dst proto sport dport; do
+                       [ "${!var}" = "-" ] && continue
+
+                       line="${line} ${var}=\"${!var}\""
+               done
+
+               line="$(echo ${line})"
+               print "${line}"
+       done < ${file}
+}
index 3871720b10e6d68b7e4ee8f9e3e7a88ddf1e99ff..5584d699da989504636de43b2f6812bc26990c26 100644 (file)
@@ -44,13 +44,13 @@ function policy_add_zone() {
        iptables_chain_create ${chain}_IPS
        iptables -A ${chain} -i ${zone} -j ${chain}_IPS
 
-       # Port forwarding chain.
-       iptables_chain_create ${chain}_PORTFW
-       iptables -A ${chain} -i ${zone} -j ${chain}_PORTFW
+       # Rules for incoming packets.
+       iptables_chain_create ${chain}_RULES_INC
+       iptables -A ${chain} -i ${zone} -j ${chain}_RULES_INC
 
-       # Outgoing firewall
-       iptables_chain_create ${chain}_OUTFW
-       iptables -A ${chain} -o ${zone} -j ${chain}_OUTFW
+       # Rules for outgoing packets.
+       iptables_chain_create ${chain}_RULES_OUT
+       iptables -A ${chain} -o ${zone} -j ${chain}_RULES_OUT
 
        # Policy rules
        iptables_chain_create ${chain}_POLICY
@@ -68,21 +68,21 @@ function policy_add_zone() {
        iptables -t mangle -A ${chain} -o ${zone} -j ${chain}_QOS_OUT
 
        # Create NAT chain.
-       iptables_chain_create -t nat ${chain}
-       iptables -t nat -A PREROUTING  -i ${zone} -j ${chain}
-       iptables -t nat -A POSTROUTING -o ${zone} -j ${chain}
+       iptables_chain_create -4 -t nat ${chain}
+       iptables -4 -t nat -A PREROUTING  -i ${zone} -j ${chain}
+       iptables -4 -t nat -A POSTROUTING -o ${zone} -j ${chain}
 
        # Network Address Translation
-       iptables_chain_create -t nat ${chain}_NAT
-       iptables -t nat -A ${chain} -i ${zone} -j ${chain}_NAT
+       iptables_chain_create -4 -t nat ${chain}_NAT
+       iptables -4 -t nat -A ${chain} -i ${zone} -j ${chain}_NAT
 
-       # Portforwarding
-       iptables_chain_create -t nat ${chain}_PORTFW
-       iptables -t nat -A ${chain} -i ${zone} -j ${chain}_PORTFW
+       # Port forwarding
+       iptables_chain_create -4 -t nat ${chain}_PORTFW
+       iptables -4 -t nat -A ${chain} -i ${zone} -j ${chain}_PORTFW
 
        # UPNP
-       iptables_chain_create -t nat ${chain}_UPNP
-       iptables -t nat -A ${chain} -j ${chain}_UPNP
+       iptables_chain_create -4 -t nat ${chain}_UPNP
+       iptables -4 -t nat -A ${chain} -j ${chain}_UPNP
 
        # After the chains that are always available have been
        # created, we will add a custom policy to every single
@@ -96,6 +96,9 @@ function policy_add_zone() {
        else
                : # XXX TODO
        fi
+
+       # Import all configured rules and those things.
+       policy_import_all_rules ${zone} ${chain}
 }
 
 function policy_add_localhost() {
@@ -116,3 +119,22 @@ function policy_allow_all() {
        # Just accept everything.
        iptables -A ${chain}_POLICY -j ACCEPT
 }
+
+function policy_drop_all() {
+       # Nothing to do here, because that is the
+       # default policy of the INPUT/OUTPUT/FORWARD chain.
+       :
+}
+
+function policy_import_all_rules() {
+       # This will populate all chains with the rules
+       # for the given zone.
+
+       local zone=${1}
+       assert isset zone
+
+       local chain=${2}
+       assert isset chain
+
+       # XXX TODO
+}
diff --git a/macros/DHCP b/macros/DHCP
new file mode 100644 (file)
index 0000000..42c9d78
--- /dev/null
@@ -0,0 +1,5 @@
+# IPFire Macro
+# This macro handles the dynamic host configuration protocol.
+# SRC          DST             PROTO   LOCAL_PORT      REMOTE_PORT
+-              -               tcp     68              67
+-              -               udp     68              67
diff --git a/macros/HTTP b/macros/HTTP
new file mode 100644 (file)
index 0000000..7cf5888
--- /dev/null
@@ -0,0 +1,4 @@
+# IPFire Macro
+# This macro handles plaintext HTTP (WWW) traffic.
+# SRC          DST             PROTO   LOCAL_PORT      REMOTE_PORT
+-              -               tcp     -               80
diff --git a/macros/HTTPS b/macros/HTTPS
new file mode 100644 (file)
index 0000000..f53ecf5
--- /dev/null
@@ -0,0 +1,4 @@
+# IPFire Macro
+# This macro handles secure HTTP (WWW) traffic.
+# SRC          DST             PROTO   LOCAL_PORT      REMOTE_PORT
+-              -               tcp     -               443
diff --git a/macros/WWW b/macros/WWW
new file mode 100644 (file)
index 0000000..09a4718
--- /dev/null
@@ -0,0 +1,5 @@
+# IPFire Macro
+# This macro handles WWW traffic.
+# SRC          DST             PROTO   SRC_PORT        DST_PORT
+INCLUDE                HTTP
+INCLUDE                HTTPS