#!/bin/sh # # Shorewall Packet Filtering Firewall Capabilities Detector # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 2006 - Tom Eastep (teastep@shorewall.net) # # This file should be placed in /sbin/shorewall. # # Shorewall documentation is available at http://shorewall.sourceforge.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # # # This program may be used to create a /etc/shorewall/capabilities file for # use in compiling Shorewall firewalls on another system. # # On the target system (the system where the firewall program is to run): # # [ IPTABLES= ] [ MODULESDIR= ] shorecap > capabilities # # Now move the capabilities file to the compilation system. The file must # be placed in a directory on the CONFIG_PATH to be used when compiling firewalls # for the target system. # # Default values for the two variables are: # # IPTABLES - iptables # MODULESDIR - /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter # # Shorewall need not be installed on the target system to run shorecap. If the '-e' flag is # used during firewall compilation, then the generated firewall program will likewise not # require Shorewall to be installed. VERSION=3.1.7 # # Suppress all output for a command # qt() { "$@" >/dev/null 2>&1 } # # Split a colon-separated list into a space-separated list # split() { local ifs=$IFS IFS=: set -- $1 echo $* IFS=$ifs } # # Internal version of 'which' # mywhich() { local dir for dir in $(split $PATH); do if [ -x $dir/$1 ]; then echo $dir/$1 return 0 fi done return 2 } # # Load a Kernel Module # loadmodule() # $1 = module name, $2 - * arguments { local modulename=$1 local modulefile local suffix moduleloader=modprobe if ! qt mywhich modprobe; then moduleloader=insmod fi if [ -z "$(lsmod | grep $modulename)" ]; then shift for suffix in $MODULE_SUFFIX ; do modulefile=$MODULESDIR/${modulename}.${suffix} if [ -f $modulefile ]; then case $moduleloader in insmod) insmod $modulefile $* ;; *) modprobe $modulename $* ;; esac return fi done fi } # # Load kernel modules required for Shorewall # load_kernel_modules() { [ -z "$MODULESDIR" ] && \ MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter # # Essential Modules # loadmodule ip_tables loadmodule iptable_filter loadmodule ip_conntrack # # Helpers # loadmodule ip_conntrack_ftp loadmodule ip_conntrack_tftp loadmodule ip_conntrack_irc loadmodule iptable_nat loadmodule ip_nat_ftp loadmodule ip_nat_tftp loadmodule ip_nat_irc loadmodule ip_set loadmodule ip_set_iphash loadmodule ip_set_ipmap loadmodule ip_set_macipmap loadmodule ip_set_portmap # # Traffic Shaping # loadmodule sch_sfq loadmodule sch_ingress loadmodule sch_htb loadmodule cls_u32 # # Extensions # loadmodule ipt_addrtype loadmodule ipt_ah loadmodule ipt_CLASSIFY loadmodule ipt_CLUSTERIP loadmodule ipt_comment loadmodule ipt_connmark loadmodule ipt_CONNMARK loadmodule ipt_conntrack loadmodule ipt_dscp loadmodule ipt_DSCP loadmodule ipt_ecn loadmodule ipt_ECN loadmodule ipt_esp loadmodule ipt_hashlimit loadmodule ipt_helper loadmodule ipt_ipp2p loadmodule ipt_iprange loadmodule ipt_length loadmodule ipt_limit loadmodule ipt_LOG loadmodule ipt_mac loadmodule ipt_mark loadmodule ipt_MARK loadmodule ipt_MASQUERADE loadmodule ipt_multiport loadmodule ipt_NETMAP loadmodule ipt_NOTRACK loadmodule ipt_owner loadmodule ipt_physdev loadmodule ipt_pkttype loadmodule ipt_policy loadmodule ipt_realm loadmodule ipt_recent loadmodule ipt_REDIRECT loadmodule ipt_REJECT loadmodule ipt_SAME loadmodule ipt_sctp loadmodule ipt_set loadmodule ipt_state loadmodule ipt_tcpmss loadmodule ipt_TCPMSS loadmodule ipt_tos loadmodule ipt_TOS loadmodule ipt_ttl loadmodule ipt_TTL loadmodule ipt_ULOG } # # Determine which optional facilities are supported by iptables/netfilter # determine_capabilities() { [ -z "$IPTABLES" ] && IPTABLES=$(mywhich iptables) [ -z "$IPTABLES" ] && { echo "ERROR: Can't find IPTABLES executable" ; exit 2; } qt $IPTABLES -t nat -L -n && NAT_ENABLED=Yes || NAT_ENABLED= qt $IPTABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= CONNTRACK_MATCH= MULTIPORT= XMULTIPORT= POLICY_MATCH= PHYSDEV_MATCH= IPRANGE_MATCH= RECENT_MATCH= OWNER_MATCH= IPSET_MATCH= CONNMARK= CONNMARK_MATCH= RAW_TABLE= IPP2P_MATCH= LENGTH_MATCH= CLASSIFY_TARGET= ENHANCED_REJECT= USEPKTTYPE= qt $IPTABLES -N fooX1234 qt $IPTABLES -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes qt $IPTABLES -A fooX1234 -p tcp -m multiport --dports 21,22 -j ACCEPT && MULTIPORT=Yes qt $IPTABLES -A fooX1234 -p tcp -m multiport --dports 21:22 -j ACCEPT && XMULTIPORT=Yes qt $IPTABLES -A fooX1234 -m policy --pol ipsec --mode tunnel --dir in -j ACCEPT && POLICY_MATCH=Yes qt $IPTABLES -A fooX1234 -m physdev --physdev-in eth0 -j ACCEPT && PHYSDEV_MATCH=Yes qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT && IPRANGE_MATCH=Yes qt $IPTABLES -A fooX1234 -m recent --update -j ACCEPT && RECENT_MATCH=Yes qt $IPTABLES -A fooX1234 -m owner --uid-owner 0 -j ACCEPT && OWNER_MATCH=Yes qt $IPTABLES -A fooX1234 -m connmark --mark 2 -j ACCEPT && CONNMARK_MATCH=Yes qt $IPTABLES -A fooX1234 -p tcp -m ipp2p --ipp2p -j ACCEPT && IPP2P_MATCH=Yes qt $IPTABLES -A fooX1234 -m length --length 10:20 -j ACCEPT && LENGTH_MATCH=Yes qt $IPTABLES -A fooX1234 -j REJECT --reject-with icmp-host-prohibited && ENHANCED_REJECT=Yes qt $IPTABLES -t mangle -N fooX1234 qt $IPTABLES -t mangle -A fooX1234 -j CONNMARK --save-mark && CONNMARK=Yes qt $IPTABLES -t mangle -A fooX1234 -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes qt $IPTABLES -t mangle -F fooX1234 qt $IPTABLES -t mangle -X fooX1234 qt $IPTABLES -t raw -L -n && RAW_TABLE=Yes if qt mywhich ipset; then qt ipset -X fooX1234 # Just in case something went wrong the last time if qt ipset -N fooX1234 iphash ; then if qt $IPTABLES -A fooX1234 -m set --set fooX1234 src -j ACCEPT; then qt $IPTABLES -D fooX1234 -m set --set fooX1234 src -j ACCEPT IPSET_MATCH=Yes fi qt ipset -X fooX1234 fi fi qt $IPTABLES -A fooX1234 -m pkttype --pkt-type broadcast -j ACCEPT && USEPKTTYPE=Yes qt $IPTABLES -F fooX1234 qt $IPTABLES -X fooX1234 } report_capability() # $1 = Capability { local setting eval setting=\$$1 echo $1=$setting } report_capabilities() { echo "#" echo "#Shorewall $VERSION detected the following iptables/netfilter capabilities - $(date)" echo "#" report_capability NAT_ENABLED report_capability MANGLE_ENABLED report_capability MULTIPORT [ -n "$MULTIPORT" ] && report_capability XMULTIPORT report_capability CONNTRACK_MATCH report_capability USEPKTTYPE report_capability POLICY_MATCH report_capability PHYSDEV_MATCH report_capability LENGTH_MATCH report_capability IPRANGE_MATCH report_capability RECENT_MATCH report_capability OWNER_MATCH report_capability IPSET_MATCH report_capability CONNMARK report_capability CONNMARK_MATCH report_capability RAW_TABLE report_capability IPP2P_MATCH report_capability CLASSIFY_TARGET report_capability ENHANCED_REJECT } load_kernel_modules determine_capabilities report_capabilities