# #
###############################################################################
+# This function initializes all kernel parameters that need to be adjusted
+# to run this firewall properly.
+function firewall_kernel_init() {
+ log INFO "Configuring kernel parameters..."
+ local option
+
+ # Enable conntrack accounting
+ conntrack_set_accounting "true"
+
+ # Adjust max. amount of simultaneous connections
+ conntrack_set_max_connections "${CONNTRACK_MAX_CONNECTIONS}"
+
+ # Increase UDP connection timeout (fixes DNS)
+ conntrack_set_udp_timeout "${CONNTRACK_UDP_TIMEOUT}"
+
+ # Disable sending redirects
+ log INFO "Disabling sending redirects"
+ sysctl_set_recursively "net.ipv6.conf" "send_redirects" 0
+ sysctl_set_recursively "net.ipv4.conf" "send_redirects" 0
+
+ # Enable source route protection
+ log INFO "Enabling source route protection"
+ sysctl_set_recursively "net.ipv6.conf" "accept_source_route" 0
+ sysctl_set_recursively "net.ipv4.conf" "accept_source_route" 0
+
+ # ICMP broadcast protection (smurf amplifier protection)
+ log INFO "Enabling ICMP broadcast protection (smurf amplifier protection)"
+ sysctl_set "net.ipv4.icmp_echo_ignore_broadcasts" 1
+
+ # ICMP Dead Error Message protection
+ log INFO "Enabling ICMP dead error message protection"
+ sysctl_set "net.ipv4.icmp_ignore_bogus_error_responses" 0
+
+ # Enable packet forwarding
+ log INFO "Enabling packet forwarding"
+ sysctl_set_recursively "net.ipv6.conf" "forwarding" 1
+ sysctl_set_recursively "net.ipv4.conf" "forwarding" 1
+
+ # Setting some kernel performance options
+ log INFO "Setting some kernel performance options"
+ for option in window_scaling timestamps sack dsack fack; do
+ sysctl_set "net.ipv4.tcp_${option}" 1
+ done
+ sysctl_set "net.ipv4.tcp_low_latency" 0
+
+ # Reduce DoS ability by reducing timeouts
+ log INFO "Reducing DoS ability"
+ sysctl_set "net.ipv4.tcp_fin_timeout" 30
+ sysctl_set "net.ipv4.tcp_keepalive_time" 1800
+
+ # Set number of times to retry SYN in a new connection
+ sysctl_set "net.ipv4.tcp_syn_retries" 3
+
+ # Set number of times to retry a SYN-ACK in a half-open new connection
+ sysctl_set "net.ipv4.tcp_synack_retries" 2
+
+ # Enable a fix for RFC1337 - time-wait assassination hazards in TCP
+ sysctl_set "net.ipv4.tcp_rfc1337" 1
+
+ # SYN-flood protection
+ if enabled FIREWALL_SYN_COOKIES; then
+ log INFO "Enabling SYN-flood protection via SYN-cookies"
+ sysctl_set_bool "net.ipv4.tcp_syncookies" 1
+ else
+ log INFO "Disabling SYN-flood protection via SYN-cookies"
+ sysctl_set_bool "net.ipv4.tcp_syncookies" 0
+ fi
+
+ # rp_filter
+ if enabled FIREWALL_RP_FILTER; then
+ log INFO "Enabling anti-spoof from non-routable IP addresses"
+ sysctl_set_recursively "net.ipv4.conf" "rp_filter" 1
+ else
+ log INFO "Disabling anti-spoof from non-routable IP addresses"
+ sysctl_set_recursively "net.ipv4.conf" "rp_filter" 0
+ fi
+
+ # Log martians
+ if enabled FIREWALL_LOG_MARTIANS; then
+ log INFO "Enabling the logging of martians"
+ sysctl_set_recursively "net.ipv4.conf" "log_martians" 1
+ else
+ log INFO "Disabling the logging of martians"
+ sysctl_set_recursively "net.ipv4.conf" "log_martians" 0
+ fi
+
+ # ICMP redirect messages
+ if enabled FIREWALL_ACCEPT_ICMP_REDIRECTS; then
+ log INFO "Enabling accepting ICMP-redirect messages"
+ sysctl_set_recursively "net.ipv6.conf" "accept_redirects" 1
+ sysctl_set_recursively "net.ipv4.conf" "accept_redirects" 1
+ else
+ log INFO "Disabling accepting ICMP-redirect messages"
+ sysctl_set_recursively "net.ipv6.conf" "accept_redirects" 0
+ sysctl_set_recursively "net.ipv4.conf" "accept_redirects" 0
+ fi
+
+ # Explicit Congestion Notification
+ if enabled FIREWALL_USE_ECN; then
+ log INFO "Enabling ECN (Explicit Congestion Notification)"
+ sysctl_set "net.ipv4.tcp_ecn" 1
+ else
+ log INFO "Disabling ECN (Explicit Congestion Notification)"
+ sysctl_set "net.ipv4.tcp_ecn" 2
+ fi
+
+ # Dynamic IP address hacking
+ log INFO "Enabling kernel support for dynamic IP addresses"
+ sysctl_set "net.ipv4.ip_dynaddr" 1
+
+ if enabled FIREWALL_PMTU_DISCOVERY; then
+ log INFO "Enabling PMTU discovery"
+ sysctl_set "net.ipv4.ip_no_pmtu_disc" 0
+ else
+ log INFO "Disabling PMTU discovery"
+ sysctl_set "net.ipv4.ip_no_pmtu_disc" 1
+ fi
+
+ # TTL
+ if ipv4_ttl_valid "${FIREWALL_DEFAULT_TTL}"; then
+ log INFO "Setting default TTL to ${FIREWALL_DEFAULT_TTL}"
+ sysctl_set "net.ipv4.ip_default_ttl" "${FIREWALL_DEFAULT_TTL}"
+ else
+ log ERROR "Invalid value for default TTL '${FIREWALL_DEFAULT_TTL}'"
+ log ERROR " Must be between 10 and 255!"
+ fi
+
+ return ${EXIT_OK}
+}
+
# High-level function which will create a ruleset for the current firewall
# configuration and load it into the kernel.
function firewall_start() {
+ local protocol="${1}"
+ assert isset protocol
+ shift
+
# Test mode.
local test="false"
--test)
test="true"
;;
+ *)
+ error "Unrecognized argument: ${1}"
+ return ${EXIT_ERROR}
+ ;;
esac
shift
done
firewall_lock_acquire
# Initialize an empty iptables ruleset.
- iptables_init DROP
+ iptables_init "${protocol}" "DROP"
# Add default chains.
- firewall_tcp_state_flags
- firewall_custom_chains
- firewall_connection_tracking
- firewall_tcp_clamp_mss
+ firewall_filter_rh0_headers "${protocol}"
+ firewall_filter_icmp "${protocol}"
+ firewall_filter_invalid_packets "${protocol}"
+ firewall_custom_chains "${protocol}"
+ firewall_connection_tracking "${protocol}"
+ firewall_tcp_clamp_mss "${protocol}"
# Add policies for every zone.
- firewall_localhost_create_chains
+ firewall_localhost_create_chains "${protocol}"
local zone
for zone in $(zones_get_all); do
# Create all needed chains for the zone.
- firewall_zone_create_chains ${zone}
+ firewall_zone_create_chains "${protocol}" "${zone}"
# After the chains that are always available have been
# created, we will add a custom policy to every single
# zone.
- policy_zone_add ${zone}
+ policy_zone_add "${protocol}" "${zone}"
done
# Load the new ruleset.
- iptables_load ${test}
+ local args
+ if enabled testmode; then
+ list_append args "--test"
+ fi
+ iptables_commit "${protocol}" ${args}
firewall_lock_release
}
function firewall_stop() {
+ local protocol="${1}"
+ assert isset protocol
+
firewall_lock_acquire
# Initialize an empty firewall ruleset
# with default policy ACCEPT.
- iptables_init ACCEPT
+ iptables_init "${protocol}" ACCEPT
# Load it.
- iptables_load
+ ipables_load "${protocol}"
firewall_lock_release
}
function firewall_show() {
+ local protocol="${1}"
+ assert isset protocol
+
# Shows the ruleset that is currently loaded.
- iptables_status
+ iptables_status "${protocol}"
return ${EXIT_OK}
}
function firewall_panic() {
+ local protocol="${1}"
+ assert isset protocol
+ shift
+
local admin_hosts="$@"
- firewall_lock_acquire
+ firewall_lock_acquire "${protocol}"
# Drop all communications.
- iptables_init DROP
+ iptables_init "${protocol}" 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
+ iptables "${protocol}" -A INPUT -s "${admin_host}" -j ACCEPT
+ iptables "${protocol}" -A OUTPUT -d "${admin_host}" -j ACCEPT
done
# Load it.
- iptables_load
+ iptables_commit "${protocol}"
firewall_lock_release
}
}
function firewall_custom_chains() {
+ local protocol="${1}"
+ assert isset protocol
+
log INFO "Creating CUSTOM* chains..."
# These chains are intened to be filled with
# rules by the user. They are processed at the very
# beginning so it is possible to overwrite everything.
- iptables_chain_create CUSTOMINPUT
- iptables -A INPUT -j CUSTOMINPUT
+ iptables_chain_create "${protocol}" CUSTOMINPUT
+ iptables "${protocol}" -A INPUT -j CUSTOMINPUT
- iptables_chain_create CUSTOMFORWARD
- iptables -A FORWARD -j CUSTOMFORWARD
+ iptables_chain_create "${protocol}" CUSTOMFORWARD
+ iptables "${protocol}" -A FORWARD -j CUSTOMFORWARD
- iptables_chain_create CUSTOMOUTPUT
- iptables -A OUTPUT -j CUSTOMOUTPUT
+ iptables_chain_create "${protocol}" CUSTOMOUTPUT
+ iptables "${protocol}" -A OUTPUT -j CUSTOMOUTPUT
- iptables_chain_create -4 -t nat CUSTOMPREROUTING
- iptables -4 -t nat -A PREROUTING -j CUSTOMPREROUTING
+ iptables_chain_create "${protocol}" -t nat CUSTOMPREROUTING
+ iptables "${protocol}" -t nat -A PREROUTING -j CUSTOMPREROUTING
- iptables_chain_create -4 -t nat CUSTOMPOSTROUTING
- iptables -4 -t nat -A POSTROUTING -j CUSTOMPOSTROUTING
+ iptables_chain_create "${protocol}" -t nat CUSTOMPOSTROUTING
+ iptables "${protocol}" -t nat -A POSTROUTING -j CUSTOMPOSTROUTING
- iptables_chain_create -4 -t nat CUSTOMOUTPUT
- iptables -4 -t nat -A OUTPUT -j CUSTOMOUTPUT
+ iptables_chain_create "${protocol}" -t nat CUSTOMOUTPUT
+ iptables "${protocol}" -t nat -A OUTPUT -j CUSTOMOUTPUT
}
-function firewall_tcp_state_flags() {
- log INFO "Creating TCP State Flags chain..."
- iptables_chain_create BADTCP_LOG
- iptables -A BADTCP_LOG -p tcp -j $(iptables_LOG "Illegal TCP state: ")
- iptables -A BADTCP_LOG -j DROP
-
- iptables_chain_create BADTCP
- iptables -A BADTCP -p tcp --tcp-flags ALL NONE -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags FIN,RST FIN,RST -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags ACK,FIN FIN -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags ACK,PSH PSH -j BADTCP_LOG
- iptables -A BADTCP -p tcp --tcp-flags ACK,URG URG -j BADTCP_LOG
-
- iptables -A INPUT -p tcp -j BADTCP
- iptables -A OUTPUT -p tcp -j BADTCP
- iptables -A FORWARD -p tcp -j BADTCP
+function firewall_filter_invalid_packets() {
+ local protocol="${1}"
+ assert isset protocol
+
+ local log_limit="-m limit --limit 5/m --limit-burst 10"
+
+ # Create a chain
+ iptables_chain_create "${protocol}" FILTER_INVALID
+ iptables "${protocol}" -A INPUT -j FILTER_INVALID
+ iptables "${protocol}" -A OUTPUT -j FILTER_INVALID
+ iptables "${protocol}" -A FORWARD -j FILTER_INVALID
+
+ # Create a chain where only TCP packets go
+ iptables_chain_create "${protocol}" FILTER_INVALID_TCP
+ iptables "${protocol}" -A FILTER_INVALID -p tcp -j FILTER_INVALID_TCP
+
+ # Create a chain where only UDP packets go
+ iptables_chain_create "${protocol}" FILTER_INVALID_UDP
+ iptables "${protocol}" -A FILTER_INVALID -p udp -j FILTER_INVALID_UDP
+
+ # Create a chain where only ICMP packets go
+ iptables_chain_create "${protocol}" FILTER_INVALID_ICMP
+ iptables "${protocol}" -A FILTER_INVALID -p icmp -j FILTER_INVALID_ICMP
+
+
+ # Optionally log all port scans
+
+ if enabled FIREWALL_LOG_STEALTH_SCANS; then
+ log INFO "Logging of stealth scans enabled"
+
+ # NMAP FIN/URG/PSH - XMAS scan
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN,URG,PSH \
+ "${log_limit}" -j "$(iptables_LOG "Stealth XMAS scan")"
+
+ # SYN/RST/ACK/FIN/URG
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
+ "${log_limit}" -j "$(iptables_LOG "Stealth XMAS-PSH scan")"
+
+ # ALL/ALL
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL ALL \
+ "${log_limit}" -j "$(iptables_LOG "Stealth XMAS-ALL scan")"
+
+ # NMAP FIN Stealth
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN \
+ "${log_limit}" -j "$(iptables_LOG "Stealth FIN scan")"
+
+ # SYN/RST
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,RST SYN,RST \
+ "${log_limit}" -j "$(iptables_LOG "Stealth SYN/RST scan")"
+
+ # SYN/FIN
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,FIN SYN,FIN \
+ "${log_limit}" -j "$(iptables_LOG "Stealth SYN/FIN scan")"
+
+ # Null scan
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL NONE \
+ "${log_limit}" -j "$(iptables_LOG "Stealth NULL scan")"
+ else
+ log INFO "Logging of stealth scans disabled"
+ fi
+
+
+ # Drop scan packets
+
+ # NMAP FIN/URG/PSH
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
+
+ # SYN/RST/ACK/FIN/URG
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
+
+ # ALL/ALL
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL ALL -j DROP
+
+ # NMAP FIN Stealth
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL FIN -j DROP
+
+ # SYN/RST
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
+
+ # SYN/FIN
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
+
+ # Null scan
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-flags ALL NONE -j DROP
+
+
+ # Log packets with bad flags
+
+ if enabled FIREWALL_LOG_BAD_TCP_FLAGS; then
+ log INFO "Logging of packets with bad TCP flags enabled"
+
+ # Option 64
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 64 \
+ "${log_limit}" -j "$(iptables_LOG "Bad TCP flag(64)")"
+
+ # Option 128
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 128 \
+ "${log_limit}" -j "$(iptables_LOG "Bad TCP flag(128)")"
+ else
+ log INFO "Logging of packets with bad TCP flags disabled"
+ fi
+
+ # Drop packets with bad flags
+
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 64 -j DROP
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp --tcp-option 128 -j DROP
+
+
+ # Log invalid packets
+
+ if enabled FIREWALL_LOG_INVALID_TCP; then
+ log INFO "Logging of INVALID TCP packets enabled"
+
+ iptables "${protocol}" -A FILTER_INVALID_TCP -p tcp -m conntrack --ctstate INVALID \
+ "${log_limit}" -j "$(iptables_LOG "INVALID TCP")"
+ else
+ log INFO "Logging of INVALID TCP packets disabled"
+ fi
+
+ if enabled FIREWALL_LOG_INVALID_UDP; then
+ log INFO "Logging of INVALID UDP packets enabled"
+
+ iptables "${protocol}" -A FILTER_INVALID_UDP -p udp -m conntrack --ctstate INVALID \
+ "${log_limit}" -j "$(iptables_LOG "INVALID UDP")"
+ else
+ log INFO "Logging of INVALID UDP packets disabled"
+ fi
+
+ if enabled FIREWALL_LOG_INVALID_ICMP; then
+ log INFO "Logging of INVALID ICMP packets enabled"
+
+ iptables "${protocol}" -A FILTER_INVALID_ICMP -p icmp -m conntrack --ctstate INVALID \
+ "${log_limit}" -j "$(iptables_LOG "INVALID ICMP")"
+ else
+ log INFO "Logging of INVALID ICMP packets disabled"
+ fi
+
+ # Drop all INVALID packets
+ iptables "${protocol}" -A FILTER_INVALID -m conntrack --ctstate INVALID -j DROP
}
function firewall_tcp_clamp_mss() {
# Do nothing if this has been disabled.
enabled FIREWALL_CLAMP_PATH_MTU || return ${EXIT_OK}
+ local protocol="${1}"
+ assert isset protocol
+
log DEBUG "Adding rules to clamp MSS to path MTU..."
- iptables -t mangle -A FORWARD \
+
+ iptables "${protocol}" -t mangle -A FORWARD \
-p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
}
function firewall_connection_tracking() {
+ local protocol="${1}"
+ assert isset protocol
+
log INFO "Creating Connection Tracking chain..."
- iptables_chain_create CONNTRACK
- iptables -A CONNTRACK -m state --state ESTABLISHED,RELATED -j ACCEPT
- iptables -A CONNTRACK -m state --state INVALID -j $(iptables_LOG "INVALID packet: ")
- iptables -A CONNTRACK -m state --state INVALID -j DROP
-
- iptables -A INPUT -j CONNTRACK
- iptables -A OUTPUT -j CONNTRACK
- iptables -A FORWARD -j CONNTRACK
+
+ iptables_chain_create "${protocol}" CONNTRACK
+ iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
+ iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate INVALID -j "$(iptables_LOG "INVALID packet: ")"
+ iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate INVALID -j DROP
+
+ iptables "${protocol}" -A INPUT -j CONNTRACK
+ iptables "${protocol}" -A OUTPUT -j CONNTRACK
+ iptables "${protocol}" -A FORWARD -j CONNTRACK
}
function firewall_localhost_create_chains() {
+ local protocol="${1}"
+ assert isset protocol
+
log DEBUG "Creating firewall chains for localhost..."
# Accept everything on lo
- iptables -A INPUT -i lo -m state --state NEW -j ACCEPT
- iptables -A OUTPUT -o lo -m state --state NEW -j ACCEPT
+ iptables "${protocol}" -A INPUT -i lo -j ACCEPT
+ iptables "${protocol}" -A OUTPUT -o lo -j ACCEPT
+}
+
+function firewall_filter_rh0_headers() {
+ local protocol="${1}"
+ assert isset protocol
+
+ # Only IPv6.
+ [ "${protocol}" = "ipv6" ] || return ${EXIT_OK}
+
+ # Filter all packets that have RH0 headers
+ # http://www.ietf.org/rfc/rfc5095.txt
+ iptables_chain_create "${protocol}" FILTER_RH0
+ iptables "${protocol}" -A FILTER_RH0 -m rt --rt-type 0 -j DROP
+
+ iptables "${protocol}" -A INPUT -j FILTER_RH0
+ iptables "${protocol}" -A FORWARD -j FILTER_RH0
+ iptables "${protocol}" -A OUTPUT -j FILTER_RH0
+}
+
+function firewall_filter_icmp() {
+ local protocol="${1}"
+ assert isset protocol
+
+ # Only IPv6.
+ [ "${protocol}" = "ipv6" ] || return ${EXIT_OK}
+
+ local chain="FILTER_ICMPV6"
+
+ # Create an extra chain for handling ICMP packets.
+ iptables_chain_create "${protocol}" "${chain}_COMMON"
+
+ local suffix
+ for suffix in INC FWD OUT; do
+ iptables_chain_create "${protocol}" "${chain}_${suffix}"
+ iptables "${protocol}" -A "${chain}_${suffix}" -j "${chain}_COMMON"
+ done
+ iptables "${protocol}" -A INPUT -p icmpv6 -j "${chain}_INC"
+ iptables "${protocol}" -A FORWARD -p icmpv6 -j "${chain}_FWD"
+ iptables "${protocol}" -A OUTPUT -p icmpv6 -j "${chain}_OUT"
+
+ # Packets that must always pass the firewall.
+ # Type 4: Parameter Problem
+ local type
+ for type in ttl-zero-during-reassembly bad-header; do
+ iptables "${protocol}" -A "${chain}_COMMON" \
+ -p icmpv6 --icmpv6-type "${type}" -j ACCEPT
+ done
+
+ # Packets that are accepted if they belong to an existing connection.
+ for type in echo-reply destination-unreachable packet-too-big \
+ unknown-header-type unknown-option; do
+ iptables "${protocol}" -A "${chain}_COMMON" \
+ -m conntrack --ctstate ESTABLISHED,RELATED \
+ -p icmpv6 --icmpv6-type "${type}" -j ACCEPT
+ done
+
+ # Packets that are always discarded.
+ # Type 100, 101, 200, 201: Private Experimentation
+ for type in 100 101 200 201; do
+ iptables "${protocol}" -A "${chain}_COMMON" \
+ -p icmpv6 --icmpv6-type "${type}" -j DROP
+ done
+
+ # Discard packets from local networks with hop limit smaller than $hoplimit.
+ # Type 148: Path solicitation
+ # Type 149: Path advertisement
+ local hoplimit=255
+ for type in {router,neighbour}-{advertisement,solicitation} 148 149; do
+ iptables "${protocol}" -A "${chain}_INC" \
+ -p icmpv6 --icmpv6-type "${type}" \
+ -m hl --hl-lt "${hoplimit}" -j DROP
+ done
+
+ # The firewall is always allowed to send ICMP echo requests.
+ iptables "${protocol}" -A "${chain}_OUT" \
+ -p icmpv6 --icmpv6-type echo-request -j ACCEPT
+
+ return ${EXIT_OK}
}
function firewall_zone_create_chains() {
- local zone=${1}
+ local protocol="${1}"
+ assert isset protocol
+
+ local zone="${2}"
assert isset zone
log DEBUG "Creating firewall chains for zone '${zone}'."
local chain_prefix="ZONE_${zone^^}"
# Create filter chains.
- iptables_chain_create "${chain_prefix}_INPUT"
- iptables -A INPUT -i ${zone} -j "${chain_prefix}_INPUT"
+ iptables_chain_create "${protocol}" "${chain_prefix}_INPUT"
+ iptables "${protocol}" -A INPUT -i ${zone} -j "${chain_prefix}_INPUT"
- iptables_chain_create "${chain_prefix}_OUTPUT"
- iptables -A OUTPUT -o ${zone} -j "${chain_prefix}_OUTPUT"
+ iptables_chain_create "${protocol}" "${chain_prefix}_OUTPUT"
+ iptables "${protocol}" -A OUTPUT -o ${zone} -j "${chain_prefix}_OUTPUT"
# Custom rules.
- iptables_chain_create "${chain_prefix}_CUSTOM"
+ iptables_chain_create "${protocol}" "${chain_prefix}_CUSTOM"
# Intrusion Prevention System.
- iptables_chain_create "${chain_prefix}_IPS"
+ iptables_chain_create "${protocol}" "${chain_prefix}_IPS"
# Create a chain for each other zone.
# This leaves us with n^2 chains. Duh.
local other_zone other_chain_prefix
for other_zone in $(zones_get_all); do
other_chain_prefix="${chain_prefix}_${other_zone^^}"
- iptables_chain_create ${other_chain_prefix}
+ iptables_chain_create "${protocol}" "${other_chain_prefix}"
# Connect the chain with the FORWARD chain.
- iptables -A FORWARD -i ${zone} -o ${other_zone} \
+ iptables "${protocol}" -A FORWARD -i "${zone}" -o "${other_zone}" \
-j "${other_chain_prefix}"
# Handle custom rules.
- iptables -A ${other_chain_prefix} -j "${chain_prefix}_CUSTOM"
+ iptables "${protocol}" -A "${other_chain_prefix}" -j "${chain_prefix}_CUSTOM"
# Link IPS.
- iptables -A ${other_chain_prefix} -j "${chain_prefix}_IPS"
+ iptables "${protocol}" -A "${other_chain_prefix}" -j "${chain_prefix}_IPS"
# Rules.
- iptables_chain_create "${other_chain_prefix}_RULES"
- iptables -A ${other_chain_prefix} -j "${other_chain_prefix}_RULES"
+ iptables_chain_create "${protocol}" "${other_chain_prefix}_RULES"
+ iptables "${protocol}" -A "${other_chain_prefix}" -j "${other_chain_prefix}_RULES"
# Policy.
- iptables_chain_create "${other_chain_prefix}_POLICY"
- iptables -A ${other_chain_prefix} -j "${other_chain_prefix}_POLICY"
+ iptables_chain_create "${protocol}" "${other_chain_prefix}_POLICY"
+ iptables "${protocol}" -A "${other_chain_prefix}" -j "${other_chain_prefix}_POLICY"
done
## Create mangle chain.
- #iptables_chain_create -t mangle ${chain_prefix}
- #iptables -t mangle -A PREROUTING -i ${zone} -j ${chain_prefix}
- #iptables -t mangle -A POSTROUTING -o ${zone} -j ${chain_prefix}
+ #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}"
+ #iptables "${protocol}" -t mangle -A PREROUTING -i "${zone}" -j "${chain_prefix}"
+ #iptables "${protocol}" -t mangle -A POSTROUTING -o "${zone}" -j "${chain_prefix}"
## Quality of Service
- #iptables_chain_create -t mangle "${chain_prefix}_QOS_INC"
- #iptables -t mangle -A ${chain_prefix} -i ${zone} -j "${chain_prefix}_QOS_INC"
- #iptables_chain_create -t mangle "${chain_prefix}_QOS_OUT"
- #iptables -t mangle -A ${chain_prefix} -o ${zone} -j "${chain_prefix}_QOS_OUT"
+ #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}_QOS_INC"
+ #iptables "${protocol}" -t mangle -A "${chain_prefix}" -i "${zone}" -j "${chain_prefix}_QOS_INC"
+ #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}_QOS_OUT"
+ #iptables "${protocol}" -t mangle -A "${chain_prefix}" -o "${zone}" -j "${chain_prefix}_QOS_OUT"
# Create NAT chain.
- iptables_chain_create -4 -t nat ${chain_prefix}
- iptables -4 -t nat -A PREROUTING -i ${zone} -j ${chain_prefix}
- iptables -4 -t nat -A POSTROUTING -o ${zone} -j ${chain_prefix}
+ iptables_chain_create "${protocol}" -t nat "${chain_prefix}"
+ iptables "${protocol}" -t nat -A PREROUTING -i "${zone}" -j "${chain_prefix}"
+ iptables "${protocol}" -t nat -A POSTROUTING -o "${zone}" -j "${chain_prefix}"
# Network Address Translation
- iptables_chain_create -4 -t nat "${chain_prefix}_DNAT"
- iptables -4 -t nat -A PREROUTING -i ${zone} -j "${chain_prefix}_DNAT"
- iptables_chain_create -4 -t nat "${chain_prefix}_SNAT"
- iptables -4 -t nat -A POSTROUTING -o ${zone} -j "${chain_prefix}_SNAT"
+ iptables_chain_create "${protocol}" -t nat "${chain_prefix}_DNAT"
+ iptables "${protocol}" -t nat -A PREROUTING -i "${zone}" -j "${chain_prefix}_DNAT"
+ iptables_chain_create "${protocol}" -t nat "${chain_prefix}_SNAT"
+ iptables "${protocol}" -t nat -A POSTROUTING -o "${zone}" -j "${chain_prefix}_SNAT"
# UPnP
- iptables_chain_create -4 -t nat "${chain_prefix}_UPNP"
- iptables -4 -t nat -A ${chain_prefix} -j "${chain_prefix}_UPNP"
+ iptables_chain_create "${protocol}" -t nat "${chain_prefix}_UPNP"
+ iptables "${protocol}" -t nat -A "${chain_prefix}" -j "${chain_prefix}_UPNP"
return ${EXIT_OK}
}