For kernels prior to 2.4, ipchains is used to do packet filtering. For kernels from 2.4 and up, iptables (see below) is used instead.
/etc/rc.d/init.d/packetfilter:
Turns packet filtering on/off, using ipchains.
Will reload saved rules from /etc/ipchains.rules or run /etc/rc.d/init.d/firewall-rules, if it exists.
"start" - Looks for firewall-rules and runs it or, if not found, restores previously-stored ipchains rulesets. "stop" - Saves ipchains rules (just in case) and shuts down ipchains.
You must create the packetfilter script, a sample of which, is shown below:
#! /bin/sh # Script to start/stop packet filtering. # # If there is a set of firewall rules in "/etc/rc.d/init.d/firewall-rules" # then this shell script is invoked. Otherwise, any saved rules that are # found in "/etc/ipchains.rules" are reinstated. # # # Set the name of the external network interface here. If you are using # "diald", this should be "sl0". For PPP, use "ppp0". For a DSL line or # cable modem, use the ethernet card that they are connected to. Usually # this will be "eth1" but for PPPoE it will be "ppp0". extint="sl0" # # If there are no firewall rules and no store ipchains rules, do nothing. # [ -f /etc/rc.d/init.d/firewall-rules ] || [ -f /etc/ipchains.rules ] \ || exit 0 case "$1" in # # Upon startup, invoke the firewall rules or reinstate the ipchains # rules. # start) if [ -f /etc/rc.d/init.d/firewall-rules ]; then echo -n "Turning on the firewall:" /etc/rc.d/init.d/firewall-rules $extint start else echo -n "Turning on packet filtering and masquerading:" /sbin/ipchains-restore < /etc/ipchains.rules || exit 1 echo 1 > /proc/sys/net/ipv4/ip_forward fi touch /var/lock/subsys/packetfilter echo "." ;; # # Upon shutdown, save the ipchains rules, then, turn of packet # filtering. # stop) echo -n "Turning off firewalling, packet filtering and masquerading:" echo 0 > /proc/sys/net/ipv4/ip_forward /sbin/ipchains-save >/etc/ipchains.rules /sbin/ipchains -X /sbin/ipchains -F /sbin/ipchains -P input ACCEPT /sbin/ipchains -P output ACCEPT /sbin/ipchains -P forward ACCEPT rm -f /var/lock/subsys/packetfilter echo "." ;; # # For all other cases, give help. # *) echo "Usage: /etc/rc.d/init.d/packetfilter {start|stop}" exit 1 ;; esac exit 0
/etc/ipchains.rules:
File where previously existing ipchains rulesets are stored upon system shutdown.
/sbin/ipchains-save >/etc/ipchains.rules
Will save the current ipchains rulesets in /etc/ipchains.rules. This is done automatically at system shutdown by the packet filter.
/etc/rc.d/init.d/firewall-rules:
Setup rules for the firewall. Define which packets are to be filtered, how packets are to be routed, etc.
"start" - Perform a normal startup of packet filtering. "register" - Used to reregister the filtering rulesets when the IP address of any of the links to the outside world is changed (e.g. when diald brings up a PPP connection).
A sample of the firewall-rules script is shown below:
#!/bin/sh # # /etc/rc.d/init.d/firewall-rules: Semi-Strong IPCHAINS firewall ruleset. # # This script takes two arguments. The first is the name of the device that # connects to the Internet (e.g. ppp0, eth1, etc.). The second is a # parameter that indicates whether we are initially starting the firewall or # just reregistering it because the link to the outside world changed (e.g. # in the case of diald bringing up the link). By setting this parameter to # anything other than "start", the overhead of loading the masquerade modules # and creating the firewall chain can be avoided when the new link is simply # being registered. # # Note that the file /etc/rc.d/init.d/firewall-off may be defined to cause # this script to set up masquerade but leave the rest of the firewall off. # This may be useful for debugging. # PATH=/sbin:/bin:/usr/sbin:/usr/bin # # Specify your Static IP address here. # # If you have a DYNAMIC IP address, you need to tell this script about your # IP address everytime you get a new one. To do this, enable the following # line which sets "extip" from the ifconfig results of querying the PPP link. # (Please note that the different single and double quote characters MATTER). # # # DHCP users: # ----------- # # If you get your TCP/IP address via DHCP, you will need to enable the # comented out command in the PPP/DHCP section AND replace the word "ppp0" # with the name of your EXTERNAL Internet connection (eth0, eth1, etc.) on # the lines for "ppp-ip" and "extip". It should be also noted that the DHCP # server can change IP addresses on you. To fix this, users should configure # their DHCP client to re-run the firewall ruleset everytime the DHCP lease # is renewed. # # NOTE #1: Some newer DHCP clients like "pump" do NOT have this ability to # run scripts after a lease-renew. Because of this, you need to replace them # with something like "dhcpcd" or "dhclient". # # NOTE #2: The syntax for "dhcpcd" has changed in recent versions. # # Older versions used syntax like: # # dhcpcd -c /etc/rc.d/init.d/firewall-rules eth0 # # Newer versions use syntax like: # # dhcpcd eth0 /etc/rc.d/init.d/firewall-rules # # # PPP users: # ---------- # # If you aren't already aware, the "/etc/ppp/ip-up script" is always run when # a PPP connection comes up. Because of this, we can have "ip-up" invoke the # firewall ruleset script with the new PPP IP address and thereby update # the strong firewall ruleset. # # If the /etc/ppp/ip-up file already exists, you should edit it and add a # line containing "/etc/rc.d/init.d/firewall-rules $1 register" near the end # of the file. # # If you don't already have a /etc/ppp/ip-up sccript, you need to create one # that invokes "/etc/rc.d/init.d/firewall-rules $1 register". # # If you use "diald", you need to create an "addroute" script that will be # invoked whenever the PPP link is brought up or taken down. In the # "addroute" script, use: # # /etc/rc.d/init.d/firewall-rules $1 register # # At initialization time, the rules should be set up using "sl0". This will # cause masquerade to aim outbound packets at "sl0" which will cause "diald" # to dial up the link. Once PPP is up and running, the "addroute" script # will change masquerade to point to the active link on "ppp0". When the # link is dropped, the "addroute" script will again be invoked to change # masquerade so that it points back at "sl0", thereby restoring the initial # configuration that waits for more outbound packets. # # # PPP and DHCP Users: # ------------------- # Remove the '' on the shell line below and place a '#' in front of the # shell line after that, unless you have a static IP address. # extip="`/sbin/ifconfig $1 | grep 'inet addr' | awk '{print $2}' \ | sed -e 's/.*://'`" # # # Users with STATIC IP addresses: # ------------------------------- # # For PPP with a static IP address or for any other Internet connection that uses a static IP address (e.g. DSL or cable modem on eth1), place a '' in front of the shell line above and remove the '' from the shell line below. # Also, fill in your correct static IP address. # # extip="your.static.PPP.address" # # Set the correct internal network information below. Usually this is the # device "eth0" and the network defined by "192.168.1.0" (if you've been # following all of the examples). The "24" indicates that the network # addresses have the top 24 bits on in their netmask (i.e. 255.255.255.0). # intint="eth0" intnet="192.168.1.0/24" # # Perform startup processing, if this is the first time. # case "$2" in # # Upon startup, load all required IP MASQ modules. Any other time, the # modules will still be loaded so there's no need to redo this. # # NOTE: Only load the IP MASQ modules you need. Most current IP MASQ # modules are shown below but are commented out to prevent loading. # # Set up the firewall rules once. They will get reused from that point # on so that repeating the set up is superfluous. # start) # # Needed to initially load modules # depmod -a # # Supports the proper masquerading of FTP file transfers using the # PORT method # modprobe ip_masq_ftp # # Supports the masquerading of RealAudio over UDP. Without this # module, RealAudio WILL function but in TCP mode. This can cause a # reduction in sound quality # modprobe ip_masq_raudio # # Supports the masquerading of IRC DCC file transfers # #modprobe ip_masq_irc # # Supports the masquerading of the CuSeeme video conferencing software # #modprobe ip_masq_cuseeme # # Supports the masquerading of the VDO-live video conferencing software # #modprobe ip_masq_vdolive # # Set up the firewall chain to filter inbound packets. Only packets # coming off of the external interface to the world are passed to this # chain so there's no need to check the interface or addresses. All # that we check are port numbers. Our aim is to only let through the # good stuff and reject all of the dangerous stuff. # ipchains -N fw-chain # # Start by letting responses to any of the previously masqueraded # packets through. # ipchains -A fw-chain -p TCP --dport 61000:65096 -j ACCEPT ipchains -A fw-chain -p UDP --dport 61000:65096 -j ACCEPT # # Also, let through packets bound for ports in the dynamic port # assignment range. Any programs that are running on this machine # which send packet traffic out to the world will do so from ports # in this range (e.g. if you run the Netscape browser on this # machine). In order for such programs to receive responses from # the Internet we must let the responses back in to the dynamic # ports that they are using. This is akin to letting the masquerade # responses back in (above) but for programs on this machine instead # of for those on the local net. # # Make sure that you do not run any services that listen on these # ports. Look at /etc/services and see which services use port # numbers > 1023. Disable these services, either by editing the # startup files in /etc/rc.d or editing /etc/inetd.conf (for those # services run by inetd. If you wish to be really paranoid and # don't care about running stuff from this machine (i.e. its only # being used for routing), comment out these lines. # # Note that you can check the ports that your system will use in the # dynamic port assignment range by executing the following command: # # cat /proc/sys/net/ipv4/ip_local_port_range # ipchains -A fw-chain -p TCP --dport 1024:4999 -j ACCEPT ipchains -A fw-chain -p UDP --dport 1024:4999 -j ACCEPT # # Let inbound DNS requests pass. This is perfectly safe because # DNS is pretty well behaved. # ipchains -A fw-chain -p TCP --dport 53 -j ACCEPT ipchains -A fw-chain -p UDP --dport 53 -j ACCEPT # # Let returning DNS querries pass. Note that if you didn't comment # out the lines above that pass packets to ports 1024-4999, you # needn't do anything here. # # You can uncomment the two lines below that accept general network # traffic from source port 53 (DNS). This will certainly allow DNS # to work. However, allowing traffic from a particular source port # is dangerous, since a spoofer can claim to be anything they want. # It is much safer to only allow traffic to a particular destination # port on our machine (we know what's there and what it will do with # the inbound packets). # # My DNS always makes requests to the outside world from port 1024. # I allow packets through bound for port 1024. You can do the same, # if you figure out which port your DNS is requesting on. Look in # /var/log/messages for the rejected packets coming from port 53. # The port that they are bound to is the one your DNS is listening # on. # # ipchains -A fw-chain -p TCP --sport 53 -j ACCEPT # ipchains -A fw-chain -p UDP --sport 53 -j ACCEPT # ipchains -A fw-chain -p TCP --dport 1024 -j ACCEPT # ipchains -A fw-chain -p UDP --dport 1024 -j ACCEPT # # Allow access to the Web server. Depending on the holes in Apache, # this could be dangerous. # # ipchains -A fw-chain -p TCP --dport 80 -j ACCEPT ipchains -A fw-chain -p TCP --dport 8180 -j ACCEPT ipchains -A fw-chain -p TCP --dport 8280 -j ACCEPT ipchains -A fw-chain -p TCP --dport 8380 -j ACCEPT # # Let inbound NTP requests pass. This is perfectly safe because # NTP is pretty well behaved. # ipchains -A fw-chain -p TCP --dport 123 -j ACCEPT # # Accept ping and responses to ping. # ipchains -A fw-chain -p icmp --icmp-type ping -j ACCEPT ipchains -A fw-chain -p icmp --icmp-type pong -j ACCEPT # # Packets which are one of the error ICMPs get accepted so that we can # see network errors being reported to us. # ipchains -A fw-chain -p icmp --icmp-type destination-unreachable \ -j ACCEPT ipchains -A fw-chain -p icmp --icmp-type source-quench -j ACCEPT ipchains -A fw-chain -p icmp --icmp-type time-exceeded -j ACCEPT ipchains -A fw-chain -p icmp --icmp-type parameter-problem -j ACCEPT # # All other packets will reach the end of the chain. Since it is a # user defined chain, it will return to the input chain from whence # it was called. The input chain will deny and log the packets. # # By arranging the chain this way, we can dynamically add rules to # the end of the chain, where they can accept additional packets. # This allows us to determine which packets to accept on the fly. # ;; # # For all other cases, just fall through to the setting of IPCHAINS. # *) ;; esac # # It is CRITICAL that we enable IP forwarding since it is disabled by default # # Redhat users should also change the options in # /etc/sysconfig/network from: # # FORWARD_IPV4=false to FORWARD_IPV4=true # echo "1" > /proc/sys/net/ipv4/ip_forward # # Set the masquerade timeouts: # # 2 hrs. - for TCP session timeouts # 10 secs. - for traffic after the TCP/IP "FIN" packet is received # 60 secs. - for UDP traffic (masqueraded ICQ users must enable a # 30 sec. firewall timeout in ICQ itself) # ipchains -M -S 7200 10 60 # # RULE SETS # ############################################################################# # # If the firewall is off, for incoming, flush and set the default policy of # accept. # if [ -f /etc/rc.d/init.d/firewall-off ]; then ipchains -F input ipchains -P input ACCEPT # # For incoming, flush and set the default policy of reject. Actually the # default policy is irrelevant because there is a catch all rule at the end # of the chain which will reject and log all rejected packets. However, the # default reject policy will prevent any packets from slipping through the # cracks while we are setting up the other rules. # else ipchains -F input ipchains -P input REJECT # # Any packets received from the fast Internet interface bound for local # addresses or with addresses that claim to be a local (i.e. IP # spoofing) can get lost. # # Note that you can comment out the following two lines to test the # fast Internet interface on the regular internal network to ensure # that it works prior to hooking it up to the Cable/DSL modem. # ipchains -A input -i $inetint -s 0.0.0.0/0 -d $intnet -l -j REJECT ipchains -A input -i $inetint -s $intnet -d 0.0.0.0/0 -l -j REJECT # # Any other packets from any source on the fast Internet interface bound # to any other destination are allowed. The Internet is wide open # baby. Let 'er rip! # # Actually, you should only use this rule for PPPoE. In that case, # the inbound packets will get filtered by the rule for the PPP # interface. If you aren't using PPPoE remove this rule and uncomment # the appropriate fw-chain rule (below). # ipchains -A input -i $inetint -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT # # Special rules for local TiVo digital recorders. If the TiVo tries # to send anything to the outside world, don't let it. Its probably # calling home for a new version of the software that will fuck us. If # it can't download the software, maybe it can't screw us. # ipchains -A input -i $intint -s 192.168.1.62 -d $intnet -j ACCEPT ipchains -A input -i $intint -s 192.168.1.62 -d 0.0.0.0/0 -j REJECT # # Any packets received on the local network interface, with local # addresses, going anywhere are allowed. # ipchains -A input -i $intint -s $intnet -d 0.0.0.0/0 -j ACCEPT # # Any packets received from the remote interface with addresses that # claim to be a local (i.e. IP spoofing) can get lost. # ipchains -A input -i $1 -s $intnet -d 0.0.0.0/0 -l -j REJECT # # Packets received from the loopback interface are always valid. # ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT # # Any packets received from the remote interface, with any source, that # are addressed to our externally visible IP address are generally valid # (that's how we receive incomming packets). However, in the interest # of having a strong firewall, we will pass all of the inbound packets # through the firewall chain to apply the specific firewalling rules. # # This rule should appear second last, just before the catch all rule. # Any packets that are not specifically allowed by the firewall chain # will fall off the end of the chain and arrive at the catch all rule # when the return from falling of the end. The catch all rule will # reject them. Meanwhile, this allows us to dynamically add rules to # the firewall chain. # # Note that there is one rule for diald/PPPoE (the first) and one for # a bridging Cable/DSL modem (the second). You should pick the one # that suits your purposes. # ipchains -A input -i $1 -s 0.0.0.0/0 -d $extip/32 -j fw-chain #ipchains -A input -i $inetint -s 0.0.0.0/0 -d $extip/32 -j fw-chain # # If you are running Samba on this machine, it can generate a lot of # packets bound for the external interface (i.e. three every 30 seconds) # that will be rejected and logged. These packets are employed in its # feeble attempt to discover any other Mickeysoft networks in the outside # world. Needless to say, we don't care about filling our log up with # this incessant drivel. # # The following two rules should ditch this junk nicely. Basically, we # were going to toss any packets that made it this far anyway. We just # check to see if the protocol is either IGMP or Mickeysoft's network # discovery protocol and if it is, we reject the packet silently. If # you don't care about keeping your log clean or don't use Samba, you can # safely comment out these two rules. # ipchains -A input -p 2 -d 0.0.0.0/0 -j REJECT ipchains -A input -p 103 -d 0.0.0.0/0 -j REJECT # # This is the catch all rule. All other incoming packets are denied and # logged. Pity there is no log option on the default policy but this # does the job instead. # ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT fi ############################################################################# # # If the firewall is off, for outgoing, flush and set the default policy of # accept. # if [ -f /etc/rc.d/init.d/firewall-off ]; then ipchains -F output ipchains -P output ACCEPT # # For outgoing, flush and set the default policy of reject. Actually the # default policy is irrelevant because there is a catch all rule at the end # of the chain which will reject and log all rejected packets. However, the # default reject policy will prevent any packets from slipping through the # cracks while we are setting up the other rules. # else ipchains -F output ipchains -P output REJECT # # Any packet addressed to the local network but being sent via the fast # Internet interface is a result of a broken routing and any packet with # a local address being sent anywhere via the fast Internet interface # signifies broken masquerading so deny them. # # Note that you can comment out the following two lines to test the # fast Internet interface on the regular internal network to ensure # that it works prior to hooking it up to the Cable/DSL modem. # ipchains -A output -s 0.0.0.0/0 -d $intnet -i $inetint -l -j REJECT ipchains -A output -s $intnet -d 0.0.0.0/0 -i $inetint -l -j REJECT # # Packets from any source going to the fast Internet interface are # valid. # ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -i $inetint -j ACCEPT # # Packets from any source going to the local net via the local interface # are valid. # ipchains -A output -s 0.0.0.0/0 -d $intnet -i $intint -j ACCEPT # # Any packet addressed to the local network but being sent via the remote # interface is a result of a broken routing so deny it. # ipchains -A output -s 0.0.0.0/0 -d $intnet -i $1 -l -j REJECT # # Any packet with a local address being sent anywhere via the remote # interface signifies broken masquerading so deny it (remember that # masquerade replaces all internal addresses with our externally visible # address before packets get to the output chain). # ipchains -A output -s $intnet -d 0.0.0.0/0 -i $1 -l -j REJECT # # Any packet addressed from our externally visible address outgoing on # the remote interface is valid (that's how we send packets to the # world). # ipchains -A output -s $extip/32 -d 0.0.0.0/0 -i $1 -j ACCEPT # # The loopback interface is always valid. # ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT # # This is the catch all rule. All other outgoing packets are denied and # logged. Once again, its a pity there is no log option on the default # policy but this does the job instead. # ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT fi ############################################################################# # # For forwarding, flush and set the default policy of reject. Actually the # default policy is irrelevant because there is a catch all rule at the end # of the chain which will reject and log all rejected packets. However, the # default reject policy will prevent any packets from slipping through the # cracks while we are setting up the other rules. # ipchains -F forward ipchains -P forward REJECT # # Masquerade all packets addressed from the local net bound to anywhere via # the remote interface. # ipchains -A forward -s $intnet -d 0.0.0.0/0 -i $1 -j MASQ # # This is the catch all rule. All other forwarded packets are denied and # logged. The usual story about it being a pity that there is no log option # on the default policy. This does the job instead. # ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT