#!/bin/bash # ------------------------------------------------------------------------------ # Configure a basic firewall, # by generating a set of iptables rules (ipv4 and ipv6), # and saving those to /etc/firewall/ipv4 and /etc/firewall/ipv6 . # The accompanying script /etc/rc.d/rc.firewall will restore these configs. # # This script and rc.firewall are part of liveslak, # a project by Eric Hameleers, see https://download.liveslak.org/ # # Iptables ruleset handling courtesy of Easy Firewall Generator for IPTables, # Copyright 2002 Timothy Scott Morizot # ------------------------------------------------------------------------------ # The script accepts one parameter: the target filesystem: DESTDIR="$1" # This tmp directory is only writable by root: TMP=${TMP:-"/var/log/setup/tmp"} if [ ! -d $TMP ]; then mkdir -p $TMP fi # The script defaults to curses dialog but Xdialog is a good alternative: DIALOG=${DIALOG:-"dialog"} # The iptables tools we use: IPT="/usr/sbin/iptables" IP6T="/usr/sbin/ip6tables" IPTS="/usr/sbin/iptables-save" IP6TS="/usr/sbin/ip6tables-save" IPTR="/usr/sbin/iptables-restore" IP6TR="/usr/sbin/ip6tables-restore" # Localhost Interface LO_IFACE="lo" LO_IP="127.0.0.1" LO_IP6="::1" # The default gateway device will be our primary candidate to firewall: GWDEV=$(/sbin/ip route show |grep ^default |cut -d' ' -f5) # Generate a list of network devices, minus the default gateway and loopback: AVAILDEV=$(ls --indicator-style=none /sys/class/net/ |sed -e "s/${GWDEV}//" -e "s/lo//") # Store all network interfaces in an associative array: declare -A NETDEVARR NETDEVARR=( [$GWDEV]=on ) for INDEV in $AVAILDEV ; do NETDEVARR+=( [$INDEV]=off ) ; done unset INDEV # Store network services in another array: declare -A SERVARR=( ['SSH']=off ['RSYNC']=off ['GIT']=off ['HTTP']=off ['HTTPS']=off ['SMTP']=off ['SMPTS']=off ['IMAP']=off ['IMAPS']=off ['NTP']=off ) # Store the list of custom ports/port ranges: CUSTOM_TCP_LIST="" CUSTOM_UDP_LIST="" # Will we auto-configure a restrictive firewall? AUTOCONFIG="YES" # User pressing ESC will change the default choice in the 1st dialog: DEFAULTNO="" # Loop over the configuration until the user is done: MAINSELECT="start" while [ "$MAINSELECT" != "done" ]; do if [ "$MAINSELECT" = "start" ]; then ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "CONFIGURE FIREWALL" ${DEFAULTNO} \ --yesno "Would you like to protect the system with a basic firewall?\n\n\ You can either block all external connections, or you can expose specific TCP/UDP ports.\n\n\ DHCP will never be blocked." 11 68 if [ $? != 0 ]; then # Not needed. exit 0 else DEFAULTNO="" fi MAINSELECT="devices" fi if [ "$MAINSELECT" = "devices" ]; then # Populate the network device checklist for the dialog: NETDEVLIST="$(for I in ${!NETDEVARR[@]};do echo $I ${NETDEVARR[$I]};done)" unset I ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "PICK INTERFACES" \ --stdout --separate-output \ --no-items \ --ok-label "Next" --no-cancel --extra-button --extra-label "Previous" \ --checklist "\ Select the network interface(s) exposed to the outside world.\n\ Your default gateway is pre-selected.\n\ Un-selected interfaces will accept all incoming traffic." 13 68 5 $NETDEVLIST \ > $TMP/SeTnics RETVAL=$? # Zero out the array values and re-enable only the ones we got returned: for INDEV in ${!NETDEVARR[@]} ; do NETDEVARR[$INDEV]=off ; done for INDEV in $(cat $TMP/SeTnics) ; do NETDEVARR[$INDEV]=on ; done unset INDEV case "$RETVAL" in 0) MAINSELECT="autoselect" ;; 3) MAINSELECT="start" ;; *) MAINSELECT="start" ; DEFAULTNO="--defaultno" ;; esac rm -f $TMP/SeTnics fi if [ "$MAINSELECT" = "autoselect" ]; then ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "ALL CLOSED?" \ --yesno "Do you want to block all incoming external connections?\n\ If 'no', then you will be able to specify ports that need to be open." 7 68 RETVAL=$? case "$RETVAL" in 0) AUTOCONFIG="YES" MAINSELECT="done" ;; 1) AUTOCONFIG="NO" MAINSELECT="services" ;; *) MAINSELECT="start" ; DEFAULTNO="--defaultno" ;; esac fi if [ "$MAINSELECT" = "services" ]; then # Populate the services checklist for the dialog: ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "OPEN PORTS" \ --stdout --separate-output \ --ok-label "Next" --no-cancel --extra-button --extra-label "Previous" \ --checklist "\ Select the service ports you want to remain open for the outside world.\n\ You can enter more ports or portranges in the next dialog." 19 68 13 \ SSH 'SSH (port 22)' ${SERVARR['SSH']} \ RSYNC 'RSYNC (port 873)' ${SERVARR['RSYNC']} \ GIT 'GIT (port 9418)' ${SERVARR['GIT']} \ HTTP 'Web Server (HTTP port 80)' ${SERVARR['HTTP']} \ HTTPS 'Secure Web Server (HTTPS port 443)' ${SERVARR['HTTPS']} \ SMTP 'Receiving Email (SMTP port 25)' ${SERVARR['SMTP']} \ SMTPS 'Secure Receiving Email (SMPTS port 587)' ${SERVARR['SMPTS']} \ IMAP 'IMAP Email Server (IMAP port 143)' ${SERVARR['IMAP']} \ IMAPS 'Secure IMAP Email Server (IMAPS port 993)' ${SERVARR['IMAPS']} \ NTP 'Time Server (NTP port 123)' ${SERVARR['NTP']} \ > $TMP/SeTservices RETVAL=$? # Zero out the array values and re-enable only the ones we got returned: for INSRV in ${!SERVARR[@]} ; do SERVARR[$INSRV]=off ; done for INSRV in $(cat $TMP/SeTservices) ; do SERVARR[$INSRV]=on ; done unset INSRV case $RETVAL in 0) MAINSELECT="customports" ;; 3) MAINSELECT="autoselect" ;; *) MAINSELECT="start" ; DEFAULTNO="--defaultno" ;; esac rm -f $TMP/SeTservices fi if [ "$MAINSELECT" = "customports" ]; then ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "CUSTOM PORTS" \ --stdout \ --ok-label "Next" --no-cancel --extra-button --extra-label "Previous" \ --form "\ Enter additional ports or port ranges.\n\ Port ranges consist of two numbers separated by a colon (example: 3000:3011).\n\ Separate multiple entries with commas,\n\ for example: 22,465,3000:3011,6660:6669,7000" \ 13 68 2 \ "TCP ports/portranges:" 1 1 "$CUSTOM_TCP_LIST" 1 25 40 0 \ "UDP ports/portranges:" 2 1 "$CUSTOM_UDP_LIST" 2 25 40 0 \ > $TMP/SeTcustomports RETVAL=$? CUSTOM_TCP_LIST=$(head -1 $TMP/SeTcustomports) CUSTOM_UDP_LIST=$(tail -1 $TMP/SeTcustomports) case $RETVAL in 0) MAINSELECT="confirm" ;; 3) MAINSELECT="services" ;; *) MAINSELECT="start" ; DEFAULTNO="--defaultno" ;; esac rm -f $TMP/SeTcustomports fi if [ "$MAINSELECT" = "confirm" ]; then # Collect all service ports that need to be remotely accessible. # TCP: TCP_LIST="" if [ "${SERVARR['HTTP']}" = "on" ]; then TCP_LIST="$TCP_LIST 80" fi if [ "${SERVARR['HTTPS']}" = "on" ]; then TCP_LIST="$TCP_LIST 443" fi if [ "${SERVARR['SMTP']}" = "on" ]; then TCP_LIST="$TCP_LIST 25" fi if [ "${SERVARR['SMTPS']}" = "on" ]; then TCP_LIST="$TCP_LIST 587" fi if [ "${SERVARR['IMAP']}" = "on" ]; then TCP_LIST="$TCP_LIST 143" fi if [ "${SERVARR['IMAPS']}" = "on" ]; then TCP_LIST="$TCP_LIST 993" fi if [ "${SERVARR['SSH']}" = "on" ]; then TCP_LIST="$TCP_LIST 22" fi if [ "${SERVARR['GIT']}" = "on" ]; then TCP_LIST="$TCP_LIST 9418" fi if [ "${SERVARR['RSYNC']}" = "on" ]; then TCP_LIST="$TCP_LIST 873" fi TCP_LIST=$(echo $TCP_LIST | sed 's/^ *//g' | tr ' ' ',') # UDP: UDP_LIST="" if [ "${SERVARR['NTP']}" = "on" ]; then UDP_LIST="$UDP_LIST 123" fi if [ "${SERVARR['RSYNC']}" = "on" ]; then UDP_LIST="$UDP_LIST 873" fi UDP_LIST=$(echo $UDP_LIST | sed 's/^ *//g' | tr ' ' ',') TCP_LIST=$(echo $TCP_LIST $CUSTOM_TCP_LIST | sed 's/^ *//g' | tr ' ' ',') UDP_LIST=$(echo $UDP_LIST $CUSTOM_UDP_LIST | sed 's/^ *//g' | tr ' ' ',') DEV_LIST=$(for INDEV in ${!NETDEVARR[@]} ; do if [ "${NETDEVARR[$INDEV]}" = "on" ]; then echo -n $INDEV" " ; fi ; done) ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --title "CONFIRM CONFIGURATION" \ --yes-label "Generate" --no-label "Redo" \ --yesno "These are the ports you configured. Are you OK with them?\n\n\ Press 'Generate' to generate the firewall configuration.\n\ Else press 'Redo' to re-do the setup.\n\n\ Firewalled interface(s): $DEV_LIST \n\ TCP Ports: $TCP_LIST \n\ UDP Ports: $UDP_LIST" 12 68 RETVAL=$? case $RETVAL in 0) MAINSELECT="done" ;; 1) MAINSELECT="devices" ;; *) MAINSELECT="start" ; DEFAULTNO="--defaultno" ;; esac fi done # ------------------------------------------------------------------------------ # End of configuration, let's get to work. # ------------------------------------------------------------------------------ # # Flush Any Existing Rules or Chains # ${DIALOG} --backtitle "@UDISTRO@ (@LIVEDE@) Basic Firewall Setup" \ --infobox "Configuring your firewall ..." 4 68 # Reset Default Policies $IPT -P INPUT ACCEPT $IPT -P FORWARD ACCEPT $IPT -P OUTPUT ACCEPT $IPT -t nat -P PREROUTING ACCEPT $IPT -t nat -P POSTROUTING ACCEPT $IPT -t nat -P OUTPUT ACCEPT $IPT -t mangle -P PREROUTING ACCEPT $IPT -t mangle -P OUTPUT ACCEPT # $IP6T -P INPUT ACCEPT $IP6T -P FORWARD ACCEPT $IP6T -P OUTPUT ACCEPT $IP6T -t mangle -P PREROUTING ACCEPT $IP6T -t mangle -P OUTPUT ACCEPT # Flush all rules $IPT -F $IPT -t nat -F $IPT -t mangle -F # $IP6T -F $IP6T -t mangle -F # Erase all non-default chains $IPT -X $IPT -t nat -X $IPT -t mangle -X # $IP6T -X $IP6T -t mangle -X # # Rules Configuration # # Filter Table # # Set Policies $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP # $IP6T -P INPUT DROP $IP6T -P OUTPUT DROP $IP6T -P FORWARD DROP # # User-Specified Chains # # Create user chains to reduce the number of rules each packet must traverse. # # Create a chain to filter INVALID packets $IPT -N bad_packets $IP6T -N bad_packets # Create another chain to filter bad tcp packets $IPT -N bad_tcp_packets $IP6T -N bad_tcp_packets # Create separate chains for icmp, tcp (incoming and outgoing), # and incoming udp packets. $IPT -N icmp_packets $IP6T -N icmp_packets # Used for UDP packets inbound from the Internet $IPT -N udp_inbound $IP6T -N udp_inbound # Used to block outbound UDP services from internal network # Default to allow all $IPT -N udp_outbound $IP6T -N udp_outbound # Used to allow inbound services if desired # Default fail except for established sessions $IPT -N tcp_inbound $IP6T -N tcp_inbound # Used to block outbound services from internal network # Default to allow all $IPT -N tcp_outbound $IP6T -N tcp_outbound # # Populate User Chains # # bad_packets chain # # Drop INVALID packets immediately $IPT -A bad_packets -p ALL -m state --state INVALID -j DROP $IP6T -A bad_packets -p ALL -m state --state INVALID -j DROP # Then check the tcp packets for additional problems $IPT -A bad_packets -p tcp -j bad_tcp_packets $IP6T -A bad_packets -p tcp -j bad_tcp_packets # All good, so return $IPT -A bad_packets -p ALL -j RETURN $IP6T -A bad_packets -p ALL -j RETURN # bad_tcp_packets chain # # All tcp packets will traverse this chain. # Every new connection attempt should begin with # a syn packet. If it doesn't, it is likely a # port scan. This drops packets in state # NEW that are not flagged as syn packets. $IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP $IP6T -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP $IP6T -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # All good, so return $IPT -A bad_tcp_packets -p tcp -j RETURN $IP6T -A bad_tcp_packets -p tcp -j RETURN # icmp_packets chain # # This chain is for inbound (from the Internet) icmp packets only. # Type 8 (Echo Request) is not accepted by default # Enable it if you want remote hosts to be able to reach you. # 11 (Time Exceeded) is the only one accepted # that would not already be covered by the established # connection rule. Applied to INPUT on the external interface. # # See: http://www.ee.siue.edu/~rwalden/networking/icmp.html # for more info on ICMP types. # # Note that the stateful settings allow replies to ICMP packets. # These rules allow new packets of the specified types. # ICMP packets should fit in a Layer 2 frame, thus they should # never be fragmented. Fragmented ICMP packets are a typical sign # of a denial of service attack. $IPT -A icmp_packets --fragment -p icmp -j DROP $IP6T -A icmp_packets -p ipv6-icmp -m ipv6header --header frag --soft -j DROP # Echo - uncomment to allow your system to be pinged. # $IPT -A icmp_packets -p icmp -s 0/0 --icmp-type 8 -j ACCEPT # $IP6T -A icmp_packets -p ipv6-icmp -s 0/0 --icmpv6-type 8 -j ACCEPT # By default, however, drop pings without logging. Blaster # and other worms have infected systems blasting pings. # Comment the line below if you want pings logged, but it # will likely fill your logs. $IPT -A icmp_packets -p icmp -s 0/0 --icmp-type 8 -j DROP $IP6T -A icmp_packets -p ipv6-icmp -s 0/0 --icmpv6-type 8 -j DROP # Time Exceeded $IPT -A icmp_packets -p icmp -s 0/0 --icmp-type 11 -j ACCEPT $IP6T -A icmp_packets -p ipv6-icmp -s 0/0 --icmpv6-type 11 -j ACCEPT # Not matched, so return so it will be logged $IPT -A icmp_packets -p icmp -j RETURN $IP6T -A icmp_packets -p ipv6-icmp -j RETURN # TCP & UDP # Identify ports at: # http://www.chebucto.ns.ca/~rakerman/port-table.html # http://www.iana.org/assignments/port-numbers # udp_inbound chain # # This chain describes the inbound UDP packets it will accept. # It's applied to INPUT on the external or Internet interface. # Note that the stateful settings allow replies. # These rules are for new requests. # It drops netbios packets (windows) immediately without logging. # Drop netbios calls # Please note that these rules do not really change the way the firewall # treats netbios connections. Connections from the localhost and # internal interface (if one exists) are accepted by default. # Responses from the Internet to requests initiated by or through # the firewall are also accepted by default. To get here, the # packets would have to be part of a new request received by the # Internet interface. You would have to manually add rules to # accept these. I added these rules because some network connections, # such as those via cable modems, tend to be filled with noise from # unprotected Windows machines. These rules drop those packets # quickly and without logging them. This prevents them from traversing # the whole chain and keeps the log from getting cluttered with # chatter from Windows systems. $IPT -A udp_inbound -p udp -s 0/0 --dport 137 -j DROP $IPT -A udp_inbound -p udp -s 0/0 --dport 138 -j DROP $IP6T -A udp_inbound -p udp -s 0/0 --dport 137 -j DROP $IP6T -A udp_inbound -p udp -s 0/0 --dport 138 -j DROP # Ident requests (Port 113) must have a REJECT rule rather than the # default DROP rule. This is the minimum requirement to avoid # long delays while connecting. Also see the tcp_inbound rule. $IPT -A udp_inbound -p udp -s 0/0 --dport 113 -j REJECT $IP6T -A udp_inbound -p udp -s 0/0 --dport 113 -j REJECT # A more sophisticated configuration could accept the ident requests. # $IPT -A udp_inbound -p udp -s 0/0 --dport 113 -j ACCEPT # $IP6T -A udp_inbound -p udp -s 0/0 --dport 113 -j ACCEPT # IPv4 only: # Allow DHCP client request packets inbound from external network $IPT -A udp_inbound -p udp -s 0/0 --source-port 68 --dport 67 \ -j ACCEPT # Dynamic Address # If DHCP, the initial request is a broadcast. The response # doesn't exactly match the outbound packet. This explicitly # allow the DHCP ports to alleviate this problem. # If you receive your dynamic address by a different means, you # can probably comment this line. $IPT -A udp_inbound -p udp -s 0/0 --source-port 67 --dport 68 \ -j ACCEPT # Open the custom UDP ports if they have been configured: if [ -n "$UDP_LIST" ]; then $IPT -A INPUT -p udp -m multiport --dport $UDP_LIST -j ACCEPT $IP6T -A INPUT -p udp -m multiport --dport $UDP_LIST -j ACCEPT fi # Not matched, so return for logging $IPT -A udp_inbound -p udp -j RETURN $IP6T -A udp_inbound -p udp -j RETURN # udp_outbound chain # # This chain is used with a private network to prevent forwarding for # UDP requests on specific protocols. Applied to the FORWARD rule from # the internal network. Ends with an ACCEPT # No match, so ACCEPT $IPT -A udp_outbound -p udp -s 0/0 -j ACCEPT $IP6T -A udp_outbound -p udp -s 0/0 -j ACCEPT # tcp_inbound chain # # This chain is used to allow inbound connections to the # system/gateway. Use with care. It defaults to none. # It's applied on INPUT from the external or Internet interface. # Ident requests (Port 113) must have a REJECT rule rather than the # default DROP rule. This is the minimum requirement to avoid # long delays while connecting. Also see the tcp_inbound rule. $IPT -A tcp_inbound -p tcp -s 0/0 --dport 113 -j REJECT $IP6T -A tcp_inbound -p tcp -s 0/0 --dport 113 -j REJECT # A more sophisticated configuration could accept the ident requests. # $IPT -A tcp_inbound -p tcp -s 0/0 --dport 113 -j ACCEPT # $IP6T -A tcp_inbound -p tcp -s 0/0 --dport 113 -j ACCEPT # Open the requested TCP service ports if they have been configured: if [ -n "$TCP_LIST" ]; then $IPT -A INPUT -p tcp -m multiport --dport $TCP_LIST -j ACCEPT $IP6T -A INPUT -p tcp -m multiport --dport $TCP_LIST -j ACCEPT fi # Not matched, so return so it will be logged $IPT -A tcp_inbound -p tcp -j RETURN $IP6T -A tcp_inbound -p tcp -j RETURN # tcp_outbound chain # # This chain is used with a private network to prevent forwarding for # requests on specific protocols. Applied to the FORWARD rule from # the internal network. Ends with an ACCEPT # No match, so ACCEPT $IPT -A tcp_outbound -p tcp -s 0/0 -j ACCEPT $IP6T -A tcp_outbound -p tcp -s 0/0 -j ACCEPT # # INPUT Chain # # Allow all on localhost interface $IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT $IP6T -A INPUT -p ALL -i $LO_IFACE -j ACCEPT # Allow all on other internal interfaces: for INDEV in ${!NETDEVARR[@]} ; do if [ "${NETDEVARR[$INDEV]}" = "off" ] ; then $IPT -A INPUT -p ALL -i $INDEV -j ACCEPT $IP6T -A INPUT -p ALL -i $INDEV -j ACCEPT fi done unset INDEV # Drop bad packets $IPT -A INPUT -p ALL -j bad_packets $IP6T -A INPUT -p ALL -j bad_packets # DOCSIS compliant cable modems # Some DOCSIS compliant cable modems send IGMP multicasts to find # connected PCs. The multicast packets have the destination address # 224.0.0.1. You can accept them. If you choose to do so, # Uncomment the rule to ACCEPT them and comment the rule to DROP # them The firewall will drop them here by default to avoid # cluttering the log. The firewall will drop all multicasts # to the entire subnet (224.0.0.1) by default. To only affect # IGMP multicasts, change '-p ALL' to '-p 2'. Of course, # if they aren't accepted elsewhere, it will only ensure that # multicasts on other protocols are logged. # Drop them without logging. $IPT -A INPUT -p ALL -d 224.0.0.1 -j DROP # The rule to accept the packets. # $IPT -A INPUT -p ALL -d 224.0.0.1 -j ACCEPT # Inbound Internet Packet Rules for INDEV in ${!NETDEVARR[@]} ; do if [ "${NETDEVARR[$INDEV]}" = "on" ] ; then # Accept Established Connections $IPT -A INPUT -p ALL -i $INDEV -m state --state ESTABLISHED,RELATED \ -j ACCEPT $IP6T -A INPUT -p ALL -i $INDEV -m state --state ESTABLISHED,RELATED \ -j ACCEPT # Route the rest to the appropriate user chain $IPT -A INPUT -p tcp -i $INDEV -j tcp_inbound $IP6T -A INPUT -p tcp -i $INDEV -j tcp_inbound $IPT -A INPUT -p udp -i $INDEV -j udp_inbound $IP6T -A INPUT -p udp -i $INDEV -j udp_inbound $IPT -A INPUT -p icmp -i $INDEV -j icmp_packets $IP6T -A INPUT -p ipv6-icmp -i $INDEV -j icmp_packets fi done unset INDEV # Drop without logging broadcasts that get this far. # Cuts down on log clutter. # Comment this line if testing new rules that impact # broadcast protocols. $IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP $IP6T -A INPUT -m pkttype --pkt-type broadcast -j DROP # Log packets that still don't match $IPT -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-prefix "INPUT packet died: " $IP6T -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-prefix "INPUT packet ipv6 died: " # # FORWARD Chain # # Used if forwarding for a private network # # OUTPUT Chain # # Generally trust the firewall on output # However, invalid icmp packets need to be dropped # to prevent a possible exploit. $IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP $IP6T -A OUTPUT -m state -p ipv6-icmp --state INVALID -j DROP # Localhost $IPT -A OUTPUT -p ALL -s $LO_IP -j ACCEPT $IP6T -A OUTPUT -p ALL -s $LO_IP6 -j ACCEPT $IPT -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT $IP6T -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT # Allow all on other internal interfaces: for OUTDEV in ${!NETDEVARR[@]} ; do if [ "${NETDEVARR[$OUTDEV]}" = "off" ] ; then $IPT -A OUTPUT -p ALL -o $OUTDEV -j ACCEPT $IP6T -A OUTPUT -p ALL -o $OUTDEV -j ACCEPT fi done unset OUTDEV # To internet for OUTDEV in ${!NETDEVARR[@]} ; do if [ "${NETDEVARR[$OUTDEV]}" = "on" ] ; then $IPT -A OUTPUT -p ALL -o $OUTDEV -j ACCEPT $IP6T -A OUTPUT -p ALL -o $OUTDEV -j ACCEPT fi done # Log packets that still don't match $IPT -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-prefix "OUTPUT packet died: " $IP6T -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-prefix "OUTPUT packet ipv6 died: " # # nat table # # The nat table is where network address translation occurs if there # is a private network. If the gateway is connected to the Internet # with a static IP, snat is used. If the gateway has a dynamic address, # masquerade must be used instead. There is more overhead associated # with masquerade, so snat is better when it can be used. # The nat table has a builtin chain, PREROUTING, for dnat and redirects. # Another, POSTROUTING, handles snat and masquerade. # # PREROUTING chain # # # POSTROUTING chain # # # mangle table # # The mangle table is used to alter packets. It can alter or mangle them in # several ways. For the purposes of this generator, we only use its ability # to alter the TTL in packets. However, it can be used to set netfilter # mark values on specific packets. Those marks could then be used in another # table like filter, to limit activities associated with a specific host, for # instance. The TOS target can be used to set the Type of Service field in # the IP header. Note that the TTL target might not be included in the # distribution on your system. If it is not and you require it, you will # have to add it. That may require that you build from source. # Save the firewall configuration so that 'rc.firewall' can load it: mkdir -p $DESTDIR/etc/firewall ${IPTS} > $DESTDIR/etc/firewall/ipv4 ${IP6TS} > $DESTDIR/etc/firewall/ipv6