From ef953be28b0ddd18bf09cf435ab41025d128711c Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 5 May 2013 18:13:57 +0200 Subject: [PATCH] firewall: Add kernel initialization. When the network/firewall is started, prior to that the firewall-kernel-init script is started that loads our configuration into the kernel. The static sysctl configuration files are removed to be able to configure some of the options. --- Makefile | 1 + functions.conntrack | 70 ++++++ functions.constants-firewall | 36 +++ functions.firewall | 130 ++++++++++ functions.ipv4 | 12 + functions.sysctl | 94 ++++++++ .../firewall-kernel-init | 9 +- man/firewall-config.xml | 225 ++++++++++++++++++ sysctl.d/network-ipv4.conf | 14 -- sysctl.d/network-ipv6.conf | 6 - systemd/firewall-init.service | 8 + systemd/firewall4.service | 4 +- systemd/firewall6.service | 4 +- systemd/network.service | 2 + systemd/network@.service | 2 + 15 files changed, 593 insertions(+), 24 deletions(-) create mode 100644 functions.conntrack create mode 100644 functions.sysctl rename sysctl.d/firewall-acct.conf => helpers/firewall-kernel-init (92%) mode change 100644 => 100755 create mode 100644 man/firewall-config.xml delete mode 100644 sysctl.d/network-ipv4.conf delete mode 100644 sysctl.d/network-ipv6.conf create mode 100644 systemd/firewall-init.service diff --git a/Makefile b/Makefile index 5a6645ed..0111ad1b 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ CLEANFILES = # man pages MAN_PAGES = \ + man/firewall-config.8 \ man/network.8 \ man/network-config.8 \ man/network-device.8 \ diff --git a/functions.conntrack b/functions.conntrack new file mode 100644 index 00000000..aa432efa --- /dev/null +++ b/functions.conntrack @@ -0,0 +1,70 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2013 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 . # +# # +############################################################################### + +# Accounting + +function conntrack_get_accounting() { + sysctl_get "net.netfilter.nf_conntrack_acct" +} + +function conntrack_set_accounting() { + local value="${1}" + assert isset value + + # Convert boolean values into 0 and 1. + if enabled value; then + log INFO "Enabling connection tracking accounting" + value="1" + else + log INFO "Disabling connection tracking accounting" + value="0" + fi + + sysctl_set "net.netfilter.nf_conntrack_acct" "${value}" +} + +# Max. connections + +function conntrack_get_max_connections() { + sysctl_get "net.netfilter.nf_conntrack_max" +} + +function conntrack_set_max_connections() { + local value="${1}" + assert isinteger value + + log INFO "Conntrack: Setting max. amount of concurrent connections to ${value}" + sysctl_set "net.netfilter.nf_conntrack_max" "${value}" +} + +# UDP timeout + +function conntrack_get_udp_timeout() { + sysctl_get "net.netfilter.nf_conntrack_udp_timeout" +} + +function conntrack_set_udp_timeout() { + local value="${1}" + assert isinteger value + + log INFO "Conntrack: Setting UDP timeout to ${value}s" + sysctl_set "net.netfilter.nf_conntrack_udp_timeout" "${value}" +} diff --git a/functions.constants-firewall b/functions.constants-firewall index decd7084..365ffd23 100644 --- a/functions.constants-firewall +++ b/functions.constants-firewall @@ -50,6 +50,42 @@ FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_NFLOG_THRESHOLD" FIREWALL_CLAMP_PATH_MTU="false" FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_CLAMP_PATH_MTU" +# Conntrack: Max. amount of simultaneous connections. +CONNTRACK_MAX_CONNECTIONS="16384" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} CONNTRACK_MAX_CONNECTIONS" + +# Conntrack: UDP timeout +CONNTRACK_UDP_TIMEOUT="60" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} CONNTRACK_UDP_TIMEOUT" + +# Use SYN cookies or not +FIREWALL_SYN_COOKIES="true" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_SYN_COOKIES" + +# rp_filter +FIREWALL_RP_FILTER="true" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_RP_FILTER" + +# Log martians +FIREWALL_LOG_MARTIANS="false" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_MARTIANS" + +# Accept ICMP redirects +FIREWALL_ACCEPT_ICMP_REDIRECTS="false" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_ACCEPT_ICMP_REDIRECTS" + +# ECN (Explicit Congestion Notification) +FIREWALL_USE_ECN="false" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_USE_ECN" + +# Path MTU discovery +FIREWALL_PMTU_DISCOVERY="true" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_PMTU_DISCOVERY" + +# Default TTL +FIREWALL_DEFAULT_TTL="64" +FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_DEFAULT_TTL" + FIREWALL4_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS}" FIREWALL6_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS}" diff --git a/functions.firewall b/functions.firewall index 6e82e022..947367a4 100644 --- a/functions.firewall +++ b/functions.firewall @@ -19,6 +19,136 @@ # # ############################################################################### +# 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() { diff --git a/functions.ipv4 b/functions.ipv4 index ba97aaa1..d7a6b85a 100644 --- a/functions.ipv4 +++ b/functions.ipv4 @@ -362,3 +362,15 @@ function ipv4_in_subnet() { return ${EXIT_FALSE} } + +function ipv4_ttl_valid() { + local ttl="${1}" + + isinteger ttl || return ${EXIT_FALSE} + + # Must be between 10 and 255. + [ "${ttl}" -lt 10 ] && return ${EXIT_FALSE} + [ "${ttl}" -gt 255 ] && return ${EXIT_FALSE} + + return ${EXIT_TRUE} +} diff --git a/functions.sysctl b/functions.sysctl new file mode 100644 index 00000000..79b9ce9b --- /dev/null +++ b/functions.sysctl @@ -0,0 +1,94 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2013 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 . # +# # +############################################################################### + +SYSCTL_PATH="/proc/sys" + +function sysctl_key_to_path() { + local key="${1}" + assert isset key + + print "${SYSCTL_PATH}/${key//.//}" + + return ${EXIT_OK} +} + +function sysctl_key_exists() { + local key="${1}" + assert isset key + + local path="$(sysctl_key_to_path "${key}")" + + [ -e "${path}" ] && return ${EXIT_OK} + return ${EXIT_ERROR} +} + +function sysctl_get() { + local key="${1}" + assert isset key + + fread "$(sysctl_key_to_path "${key}")" || return $? + return ${EXIT_OK} +} + +function sysctl_set() { + local key="${1}" + assert isset key + + local value="${2}" + + fwrite "$(sysctl_key_to_path "${key}")" "${value}" || return $? + return ${EXIT_OK} +} + +function sysctl_set_bool() { + local key="${1}" + + local value="${2}" + if enabled value; then + value="1" + else + value="0" + fi + + sysctl_set "${key}" "${value}" +} + +function sysctl_set_recursively() { + local basekey="${1}" + assert isset basekey + + local subkey="${2}" + assert isset subkey + + local value="${3}" + + local basepath="$(sysctl_key_to_path "${basekey}")" + local subpath="/${subkey//\.//}" + + local path + for path in $(find "${basepath}" -type f); do + [[ ${path} =~ ${subpath}$ ]] || continue + + fwrite "${path}" "${value}" + done + + return ${EXIT_OK} +} diff --git a/sysctl.d/firewall-acct.conf b/helpers/firewall-kernel-init old mode 100644 new mode 100755 similarity index 92% rename from sysctl.d/firewall-acct.conf rename to helpers/firewall-kernel-init index 253f8db3..4cac4a04 --- a/sysctl.d/firewall-acct.conf +++ b/helpers/firewall-kernel-init @@ -1,3 +1,4 @@ +#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # @@ -18,5 +19,9 @@ # # ############################################################################### -# Enable connection tracking accounting. -net.netfilter.nf_conntrack_acct=1 +. /usr/lib/network/functions + +# Initialize kernel parameters for the firewall. +firewall_kernel_init + +exit ${EXIT_OK} diff --git a/man/firewall-config.xml b/man/firewall-config.xml new file mode 100644 index 00000000..6bc8f62f --- /dev/null +++ b/man/firewall-config.xml @@ -0,0 +1,225 @@ + + + + + + firewall-config + network + + + + Developer + Michael + Tremer + michael.tremer@ipfire.org + + + + + + firewall-config + 8 + + + + firewall-config + Firewall Configuration Control Program + + + + + firewall-config + + + + firewall-config KEY=VALUE + + + + + Description + + + The firewall-config command may be used to set + global firewall configuration options. + + + Please have a look at the individual man pages for more options. + + + + + Commands + + + If no additional argument is given, running the command will + dump a list of all configuration variables and their current values. + + + + You may set a new value by adding the variable name and the new + value to the command line. + + + + + Variables + + + + + CONNTRACK_MAX_CONNECTIONS = 16384 + + + + + Limits the max. number of simultaneous connections. + + + Modify this if you want to handle a larger number of concurrent + connections. Every connection will use approx. 16 kBytes of memory. + + + + + + + CONNTRACK_UDP_TIMEOUT = 60 + + + + + Defines the timeout (in seconds) the kernel will wait until + a half-assured UDP connection is fully established. + + + + + + + FIREWALL_ACCEPT_ICMP_REDIRECTS = [true|false] + + + + + Enable if you want to accept ICMP redirect messages. + + + + + + + FIREWALL_CLAMP_PATH_MTU = [true|false] + + + + + If Path MTU Discovery does not work well, enable this option. + It sets the MSS value of a packet so that the remote site would + never send a packet bigger than the MSS value. + + + No ICMP packets are needed to make this work, so use this on + networks with broken ICMP filtering. + + + + + + + FIREWALL_DEFAULT_TTL = 64 + + + + + Here you can change the default TTL used for sending packets. + + + The given value must be between 10 and 255. + Don't mess with this unless you know what you are doing. + + + + + + + FIREWALL_LOG_MARTIANS = [true|false] + + + + + Enable this to log packets with impossible addresses. + + + + + + + FIREWALL_PMTU_DISCOVERY = [true|false] + + + + + Enables Path MTU Discovery. + Disable it when you are experiencing problems. + + + + + + + FIREWALL_RP_FILTER = [true|false] + + + + + Enable to drop connection from non-routable IPs, + e.g. prevent source routing. + + + + + + + FIREWALL_SYN_COOKIES = [true|false] + + + + + Enable for SYN-flood protection. + + + + + + + FIREWALL_USE_ECN = [true|false] + + + + + Enables the ECN (Explicit Congestion Notification) TCP flag. + + + Some routers on the Internet still do not support ECN properly, + so this is not enabled by default. + When this setting is disabled, ECN is only advertised + when asked for. + + + + + + + + See Also + + + + firewall + 8 + + + + diff --git a/sysctl.d/network-ipv4.conf b/sysctl.d/network-ipv4.conf deleted file mode 100644 index a6d6e5ec..00000000 --- a/sysctl.d/network-ipv4.conf +++ /dev/null @@ -1,14 +0,0 @@ -# Kernel configuration file for IPv4 -# - -# Enable IPv4 packet forwarding -net.ipv4.ip_forward = 1 - -# Enable source route verification -net.ipv4.conf.default.rp_filter = 1 - -# Do not accept source routing -net.ipv4.conf.default.accept_source_route = 0 - -# Enable ARP filter -net.ipv4.conf.default.arp_filter = 1 diff --git a/sysctl.d/network-ipv6.conf b/sysctl.d/network-ipv6.conf deleted file mode 100644 index 87af7285..00000000 --- a/sysctl.d/network-ipv6.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Kernel configuration file for IPv6 -# - -# Enable IPv6 forwarding -net.ipv6.conf.all.forwarding = 1 -net.ipv6.conf.default.forwarding = 1 diff --git a/systemd/firewall-init.service b/systemd/firewall-init.service new file mode 100644 index 00000000..5e06bb6c --- /dev/null +++ b/systemd/firewall-init.service @@ -0,0 +1,8 @@ +[Unit] +Description=Initialize kernel parameters for the firewalls +Before=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/lib/network/helpers/firewall-kernel-init diff --git a/systemd/firewall4.service b/systemd/firewall4.service index 9a147051..45d20b2c 100644 --- a/systemd/firewall4.service +++ b/systemd/firewall4.service @@ -1,6 +1,8 @@ [Unit] Description=Firewall for IPv4 -Before=network.service +After=firewall-init.service +Before=network.target +Requires=firewall-init.service [Service] Type=oneshot diff --git a/systemd/firewall6.service b/systemd/firewall6.service index 1b3abad5..eedeea4e 100644 --- a/systemd/firewall6.service +++ b/systemd/firewall6.service @@ -1,6 +1,8 @@ [Unit] Description=Firewall for IPv6 -Before=network.service +After=firewall-init.service +Before=network.target +Requires=firewall-init.service [Service] Type=oneshot diff --git a/systemd/network.service b/systemd/network.service index 0fdb7de0..5b884ed9 100644 --- a/systemd/network.service +++ b/systemd/network.service @@ -1,6 +1,8 @@ [Unit] Description=Network Connectivity +After=firewall-init.service Before=network.target +Requires=firewall-init.service [Service] Type=oneshot diff --git a/systemd/network@.service b/systemd/network@.service index 2ae3a72e..07df33ad 100644 --- a/systemd/network@.service +++ b/systemd/network@.service @@ -1,5 +1,7 @@ [Unit] Description=Network Connectivity for zone %I +After=firewall-init.service +Requires=firewall-init.service [Service] Type=oneshot -- 2.39.2