Iptables Firewall Script
In this portion of the sample firewall_programs.cfg, we specify an iptables firewall script for a mixed-use configuration of home and commercial networks.
On one network, the "COMNET", we have a Linux firewall system--moniot--connecting a local network of Windows and Linux workstations to the Internet by means of a Comcast cable router.
On a second network, the "ATTNET", we have another Linux firewall system--vitry--connecting a second network of Linux servers to the Internet by means of an AT&T ADSL modem.
A third Linux firewall system--ciconia--serves as backup to the primary vitry firewall system.
All systems, including the firewall systems, are connected to one another by way of a third local network, the "BAKNET". All Linux systems on the BAKNET are PIKT slaves under the direction of the piktmaster system.
In the interest of security, we have censored out many of the firewall details, leaving only enough material suggestive of how one might use PIKT to manage the several firewall configurations from a common code source.
Much of this firewall implementation was inspired by the book Red Hat Linux Firewalls, by Bill McCarty, Wiley Publishing, Inc., 2003.
/////////////////////////////////////////////////////////////////////////////// // // firewall_programs.cfg - programs to specify and help administer // the iptables firewall // /////////////////////////////////////////////////////////////////////////////// #if firewall /////////////////////////////////////////////////////////////////////////////// [... other programs omitted ...] /////////////////////////////////////////////////////////////////////////////// iptables path "/etc/init.d/iptables" mode 740 uid 0 gid 0 #!/bin/bash #ifdef debug set -x #endifdef /////////////////////////////////////////////////////////////////////////////// #if moniot if [ "$1" = "+h" ]; then http=1 shift elif [ "$1" = "-h" ]; then http=0 shift else http=0 # default to no http fi #endif /////////////////////////////////////////////////////////////////////////////// #if moniot CBLDEV\=eth1 CBLIP="192.168.1.100" CBLBASE="192.168.1.0" CBLBCAST="192.168.1.255" CBLGATE="192.168.1.1" COMDEV\=eth0 COMIP="192.168.3.182" COMBASE="192.168.3.0" COMBCAST="192.168.3.255" COMNET="192.168.3.0/8" BAKDEV\=eth2 BAKIP="192.168.2.182" BAKBASE="192.168.2.0" BAKBCAST="192.168.2.255" BAKNET="192.168.2.0/8" #elsif vitry DSLDEV\=eth1 DSLIP="12.100.32.132" DSLBASE="12.100.32.0" DSLBCAST="12.100.32.255" DSLGATE="12.100.32.129" ATTDEV\=eth0 ATTIP="192.168.4.184" ATTBASE="192.168.4.0" ATTBCAST="192.168.4.255" ATTNET="192.168.4.0/8" BAKDEV\=eth2 BAKIP="192.168.2.184" BAKBASE="192.168.2.0" BAKBCAST="192.168.2.255" BAKNET="192.168.2.0/8" #elsif ciconia DSLDEV\=eth1 DSLIP="12.100.32.132" DSLBASE="12.100.32.0" DSLBCAST="12.100.32.255" DSLGATE="12.100.32.129" ATTDEV\=eth0 ATTIP="192.168.4.186" ATTBASE="192.168.4.0" ATTBCAST="192.168.4.255" ATTNET="192.168.4.0/8" BAKDEV\=eth2 BAKIP="192.168.2.186" BAKBASE="192.168.2.0" BAKBCAST="192.168.2.255" BAKNET="192.168.2.0/8" #endif # IP addresses of hosts and networks authorized to ping firewall #if moniot PING="$COMNET $BAKNET" #elsif vitry | ciconia PING="$ATTNET $BAKNET" #endif # IP addresses of piktmaster PIKTMASTER="192.168.2.180" # IP addresses of hosts and networks allowed to SSH into firewall #if moniot SSH="$COMIP $BAKIP $PIKTMASTER" #elsif vitry | ciconia SSH="$ATTIP $BAKIP $PIKTMASTER" #endif #if moniot # IP addresses of AOL system(s) AOLSYS="192.168.3.190" #endif #if vitry | ciconia # IP address of each public server on internal network SMTPIP="192.168.4.132" DNSIP="192.168.4.132" HTTPIP="192.168.4.132" [censored...] #endif # The following assignments should not generally need to be changed #if moniot BADIP="$CBLBASE $CBLBCAST $COMBASE $COMBCAST $BAKBASE $BAKBCAST =badiprfc" #elsif vitry | ciconia BADIP="$DSLBASE $DSLBCAST $ATTBASE $ATTBCAST $BAKBASE $BAKBCAST =badiprfc" #endif /////////////////////////////////////////////////////////////////////////////// #include <programs/adm/iptables_reset_programs.cfg> #include <programs/adm/iptables_tcp_flags_programs.cfg> #include <programs/adm/iptables_syn_flood_programs.cfg> #include <programs/adm/iptables_bad_boys_programs.cfg> #include <programs/adm/iptables_no_http_programs.cfg> #include <programs/adm/iptables_in_icmp_programs.cfg> #include <programs/adm/iptables_out_icmp_programs.cfg> /////////////////////////////////////////////////////////////////////////////// // inbound ip checks =iptables -N IN_IP_CHECK for sip in $BADIP; do =iptables -A IN_IP_CHECK -s $sip -j BAD_IP done #if moniot =iptables -A IN_IP_CHECK -i $CBLDEV -s $CBLIP -j BAD_IP =iptables -A IN_IP_CHECK -i $CBLDEV -s $COMNET -j BAD_IP =iptables -A IN_IP_CHECK -i $COMDEV -s $CBLIP -j BAD_IP #elsif vitry | ciconia =iptables -A IN_IP_CHECK -i $DSLDEV -s $DSLIP -j BAD_IP =iptables -A IN_IP_CHECK -i $DSLDEV -s $ATTNET -j BAD_IP =iptables -A IN_IP_CHECK -i $ATTDEV -s $DSLIP -j BAD_IP #endif /////////////////////////////////////////////////////////////////////////////// // outbound ip checks =iptables -N OUT_IP_CHECK for dip in $BADIP; do =iptables -A OUT_IP_CHECK -d $dip -j BAD_IP done #if moniot =iptables -A OUT_IP_CHECK -o $CBLDEV -s $CBLIP -j RETURN =iptables -A OUT_IP_CHECK -o $COMDEV -s $COMIP -j RETURN =iptables -A OUT_IP_CHECK -o $BAKDEV -s $BAKIP -j RETURN #elsif vitry | ciconia =iptables -A OUT_IP_CHECK -o $DSLDEV -s $DSLIP -j RETURN =iptables -A OUT_IP_CHECK -o $ATTDEV -s $ATTIP -j RETURN =iptables -A OUT_IP_CHECK -o $BAKDEV -s $BAKIP -j RETURN #endif =iptables -A OUT_IP_CHECK -j BAD_IP /////////////////////////////////////////////////////////////////////////////// // destination nat #if vitry | ciconia if [ "$HTTPIP" != "" ]; then =iptables -t nat -A PREROUTING -i $DSLDEV -p tcp -d $DSLIP --dport 80 -j DNAT --to-destination $HTTPIP =iptables -t nat -A PREROUTING -i $DSLDEV -p tcp -d $DSLIP --dport 443 -j DNAT --to-destination $HTTPIP fi if [ "$SMTPIP" != "" ]; then =iptables -t nat -A PREROUTING -i $DSLDEV -p tcp -d $DSLIP --dport 25 -j DNAT --to-destination $SMTPIP fi if [ "$DNSIP" != "" ]; then =iptables -t nat -A PREROUTING -i $DSLDEV -p udp -d $DSLIP --dport 53 -j DNAT --to-destination $DNSIP =iptables -t nat -A PREROUTING -i $DSLDEV -p tcp -d $DSLIP --dport 53 -j DNAT --to-destination $DNSIP fi [censored...] #endif /////////////////////////////////////////////////////////////////////////////// // source nat #if moniot =iptables -t nat -A POSTROUTING -o $CBLDEV -s $COMNET -j SNAT --to-source $CBLIP #elsif vitry | ciconia =iptables -t nat -A POSTROUTING -o $DSLDEV -s $ATTNET -j SNAT --to-source $DSLIP #endif /////////////////////////////////////////////////////////////////////////////// // inbound traffic to network =iptables -N IN_NETWORK =iptables -A IN_NETWORK -p icmp -j IN_ICMP =iptables -A IN_NETWORK -p tcp -j TCP_FLAGS =iptables -A IN_NETWORK -p tcp --syn -j SYN_FLOOD =iptables -A IN_NETWORK -m state --state ESTABLISHED,RELATED -j ACCEPT [censored...] /////////////////////////////////////////////////////////////////////////////// // outbound traffic from network =iptables -N OUT_NETWORK =iptables -A OUT_NETWORK -p icmp -j OUT_ICMP =iptables -A OUT_NETWORK -p tcp -j TCP_FLAGS =iptables -A OUT_NETWORK -m state --state ESTABLISHED,RELATED -j ACCEPT [censored...] #if moniot for ip in $AOLSYS; do =iptables -A OUT_NETWORK -s $ip -m state --state NEW -p tcp --dport 5190 -j ACCEPT # AOL done #endif /////////////////////////////////////////////////////////////////////////////// // inbound traffic to firewall =iptables -N IN_FIREWALL =iptables -A IN_FIREWALL -p icmp -j IN_ICMP =iptables -A IN_FIREWALL -p tcp -j TCP_FLAGS =iptables -A IN_FIREWALL -p tcp --syn -j SYN_FLOOD =iptables -A IN_FIREWALL -j IN_IP_CHECK =iptables -A IN_FIREWALL -m state --state ESTABLISHED,RELATED -j ACCEPT [censored...] =iptables -A IN_FIREWALL -j LOG --log-prefix "IPT IN_FIREWALL: " =logopt =iptables -A IN_FIREWALL -j DROP /////////////////////////////////////////////////////////////////////////////// // outbound traffic from firewall =iptables -N OUT_FIREWALL =iptables -A OUT_FIREWALL -p icmp -j OUT_ICMP =iptables -A OUT_FIREWALL -p tcp -j TCP_FLAGS =iptables -A OUT_FIREWALL -m state --state ESTABLISHED,RELATED -j ACCEPT =iptables -A OUT_FIREWALL -j OUT_IP_CHECK [censored...] =iptables -A OUT_FIREWALL -j LOG --log-prefix "IPT OUT_FIREWALL: " =logopt =iptables -A OUT_FIREWALL -j DROP /////////////////////////////////////////////////////////////////////////////// // main firewall rules =iptables -A FORWARD -j BAD_BOYS #if moniot =iptables -A FORWARD -i $CBLDEV -j IN_NETWORK =iptables -A FORWARD -i $COMDEV -j OUT_NETWORK #elsif vitry | ciconia =iptables -A FORWARD -i $DSLDEV -j IN_NETWORK =iptables -A FORWARD -i $ATTDEV -j OUT_NETWORK #endif =iptables -A FORWARD -j LOG --log-prefix "IPT FORWARD: " =logopt =iptables -A FORWARD -j DROP =iptables -A INPUT -j BAD_BOYS =iptables -A INPUT -i lo -j ACCEPT =iptables -A INPUT -j IN_FIREWALL =iptables -A INPUT -j LOG --log-prefix "IPT INPUT: " =logopt =iptables -A INPUT -j DROP =iptables -A OUTPUT -j BAD_BOYS =iptables -A OUTPUT -o lo -j ACCEPT =iptables -A OUTPUT -j OUT_FIREWALL =iptables -A OUTPUT -j LOG --log-prefix "IPT OUTPUT: " =logopt =iptables -A OUTPUT -j DROP /////////////////////////////////////////////////////////////////////////////// [... other programs omitted ...] /////////////////////////////////////////////////////////////////////////////// #endif // firewall ///////////////////////////////////////////////////////////////////////////////
Files referenced by iptable_programs.cfg include: iptables_reset_programs.cfg, iptables_tcp_flags_programs.cfg, iptables_syn_flood_programs.cfg, iptables_bad_boys_programs.cfg, iptables_no_http_programs.cfg, iptables_in_icmp_programs.cfg, iptables_out_icmp_programs.cfg.
The iptables firewall script makes reference to several PIKT macros, =logopt, =synopt, =badboys, =userips, and others, described in the file firewall_macros.cfg.
On the piktmaster system, we would install the iptables script to each slave firewall system with the command:
# piktc -iv +D debug attentive +P iptables +H firewall
For more examples, see Samples.