README for SlackFire 0.44
-------------------------

SlackFire (SF below) is an iptables script with a number of configuration
files.  SF is aimed to protect a (Slackware) Linux machine or a LAN with
SF being used on a router/gateway with a stateful firewall.  The main
purpose of the script is to provide a possibility to define a detailed
policy of the firewall in a simple way.

*************************************************************************
  This version can work with configuration files of previous versions
  but I strongly recommend to check new slackfire.conf since there are
  many changes there.
*************************************************************************


0. Why another iptables script?  There are a lot in the Internet, many
   of them with a pretty nice GUI!

  First of all, I do not want to have a firewall that I can manage and
  configure only via GUI.

  Next, I need to work with a LAN with machines having routable IP
  addresses.  Quite a few scripts available in the Net support this
  feature.

  Even lesser number of scripts support configuration of fine-tuned
  rules.  The majority of them just allow all outgoing connections
  permitting replies to go back.  I want to have an opportunity to
  restrict outgoing traffic if necessary.

  I also want that configuration can be performed without touching
  the main script and that this can be done by a person with very
  little or no knowledge of iptables.

  Thus, I found it easier to write a script of my own than to tune
  a script written by somebody else. :-)  YMMV.


1. Limitations of SlackFire

  There are many.  The most noticeable (for me) are:

  * Currently, SF protects at most two network devices.  All other
    network devices are not affected by the firewall in case packets
    are sent directly to the box running SF.  Forwarded packets are
    dropped though. (The latter behaviour can be easily fixed.)

  * SF has only been tested on machines running Slackware >=9.0 with
    C locale.  Certain things can break if messages produced by ifconfig
    use other languages than English.  (This can be easily fixed if
	 needed.)

  * There is no support for NFS through a protected network interface yet.
    This will probably be fixed.

  * Support of FreeS/WAN is not implemented.

  There are undoubtedly more, partially because netfilter provides an
  incredibly rich range of possibilities.  Actually, I haven't seen an
  iptables script in the Internet with all the iptables possibilities
  implemented.


2. Installation

  # installpkg slackfire*.tgz


3. What's then?  Configuration

  In case you have installed SlackFire, 'cd /etc/slackfire' and edit
  slackfire.conf.  It's easy, see instructions therein. This is the 
  only configuration file that is really needed for SF to work.

  By default, SF is configured to allow all outgoing connections through
  a protected interface and only related/established connections back
  in. All other connections are denied.  AFAIU, this policy suits many
  if not the majority of home users.

  The default policy can be tuned, see Section 4 below.

  If you have just `exploded' SF, cd YOUR_DIR/usr/sbin/, open slackfire
  with your favourite editor and edit the line CONFDIR="/etc/slackfire" 
  to look CONFDIR="YOUR_DIR/etc/slackfire". Next, cd YOUR_DIR/etc/slackfire
  and edit slackfire.conf.  Finally, remove ".new" endings of the files you
  want to try.

  Having done one of the above steps, you are ready to start SF.
  This can be done as easy as:

    # slackfire start

  or

    # slackfire up

  or

    # slackfire on

  Shortly, "slackfire start|up|on".

  To stop SF, run

    # slackfire stop|down|off

  Notice that a `full stop' is only provided for a machine that doesn't
  serve as a router.  For a router, `stop' only opens forwarded traffic
  while the router itself remains protected.

  SF prints certain messages on the screen as it starts.  The messages
  are aimed to provide brief information on what is being done.  Notice
  that the screen will "freeze" for some time after the initial 
  "SlackFire 0.44 is starting" message if you start SF on a remote
  machine. This is a normal behaviour since building iptables rules
  begins with blocking all traffic to and from the machine SF is run on.

  In case there is no /etc/rc.d/rc.firewall on the machine, such a link is
  created when the package is installed to enable an automatic start of SF
  upon reboot.  Just remove it if you don't need it.


4. Tuning  

  In all files mentioned below, empty lines and lines starting with
  a `#' are ignored by SF.  Detailed instructions together with examples
  are provided in the files.

  
  4.1 First of all, you may delete all directories under $CONFDIR
  if the default policy suits you.  You may delete $CONFDIR/int 
  and $CONFDIR/fwd directories if you have only one network device
  to protect.  You may delete $CONFDIR/fwd if you have two devices
  but you don't use your box as a router.

  
  4.2 $CONFDIR/blocked_hosts can be used to list hosts you want to block
  all connections with.  Initially, it contains a list of networks
  which never appear in the Internet.  Edit the file up to your taste
  and knowledge.

  Note that rules for IP addresses listed in blocked_hosts only apply to
  an exterior interface (aka Big Bad Internet :-)).

  You may delete this file if you don't need it.


  4.3 $CONFDIR/trojan_ports lists a number of ports used by Trojans.
  These ports will be blocked both for inbound and outbound connections.
  (Actually, incoming connections to these ports are blocked by
  default but this is a widely spread practice to list these ports
  separately.)  You may change this list up to your taste or delete
  the file altogether.


  4.4 $CONFDIR/mangle_tos provides an opportunity to define desired
  values of the Type-of-Service field of outgoing TCP and/or UDP packets,
  see comments inside the file.

  
  4.5 Now, $CONFDIR/ext.  Files in this directory affect traffic through
  the exterior network device (EXT_IF in slackfire.conf).
  
     * icmp.out -- a list of types of _new_ ICMP packets you explicitly
       allow to go out of your box.  All other new ICMP outgoing packets
       will be blocked if you list any there.
  
     * icmp.in -- a list of types of _new_ ICMP packets you allow to
       get into the box.
  
     * tcpudp.out -- a list of allowed _new_ outgoing TCP/UDP connections.
       More precisely, other protocols may be put there but I haven't
       checked how they work.
  
     * tcpudp.in -- a list of (TCP/UDP) services you provide
       to the outer world.  In other words, this is a list of _new_
       TCP/UDP connections you allow to be established to your machine.

     * reject.in -- a list of ports you want to _reject_ connections
       to (instead of denying them).  This may be useful, say, if an ftp
       server you are connecting to sends you `auth' requests but
       you are not running inetd, or in case you are sending mail
       to a server that sends you auth requests and doesn't accept
       mail without a reply.  (Surely, you may reply. :-))

     * denied_hosts -- a list of hosts you want to deny connections from.
       It may be useful if you run public services for the whole world
       (e.g., a mail and a web server) but still want to stop an access
       to them from particular hosts or networks.
       It can also be used to reduce `noise' (pings, scans) coming from
       certain nets.  In the latter case you would probably like to set
       LOG_DENIED=0 in slackfire.conf.

       A record in this file denies connections to _all_ services
       provided by your server.

     * denied_services -- a list of ports (services) you want to be
       denied for particular hosts.  It can be useful, e.g., in case
       you are running a number of public servers but want to restrict
       access only to some of them.

     * ignored_ports -- a list of ports you don't want to log connection
       attempts to.  These may be ports used in M$ networks, probes of
       Windoops Trojan ports of whatever you consider to be unimportant.

     * noisy_hosts -- a list of hosts that produce a lot of new TCP
       packets with other than SYN bit set in the header and you believe
       these are just noise but not scanning attempts.  Listing such
       hosts in the file will suppress logging this "noise".


  Records in *.in (and denied_services) files must take the form

    WHAT  FROM   comments if needed

  Records in *.out files must take the form

    WHAT  TO     comments if needed

  where FROM and TO are IP addresses/ranges (e.g., 1.2.3.4, 0/0, etc.),
  WHAT is either ICMP type or a pair of the form "port protocol".
  The number of spaces between fields is not important.
  Examples are provided within the files.

  You may safely delete any of these files if you don't need it.

  $CONFDIR/int contains exactly the same files as those in $CONFDIR/ext,
  up to comments given therein.  They can be used to configure
  connections from/to the machine through the interior interface (INT_IF
  in slackfire.conf). All the above rules apply to them.

  As of version 0.44, the script supports IP addresses given as ranges,
  e.g., "10.11.0.0-10.12.255.255". A 2.6 or a patched 2.4 kernel is needed
  for this to work.  (Check ftp://ftp.netfilter.org/pub/patch-o-matic-ng)


  4.5 You may need to do some more work if you are running a router.  The
  corresponding directory to look at is $CONFDIR/fwd.  It contains the
  same files as $CONFDIR/{ext,int} except reject.in.  The format of the 
  files is similar to that of corresponding {ext,int} files but contains
  one more column since we now have to define the direction of connections. 
  (denied_hosts has the same format.)  See comments inside the files. 
  Note that source hosts and destination hosts are always listed from
  left to right: 

    PACKET   FROM  --->  TO 

  similar to postal envelopes. (You can change the order by editing
  slackfire script.  Look for READ_LIST variable and change it up to
  your taste.)

  Notice that a record in the denied_hosts file denies connections
  from the listed host/net to _all_ services provided at your LAN.
  Use denied_services to specify granular restrictions.


5. What do different messages mean?

  * Fired NEW TCP connect: a new TCP packet was blocked.

  * Fired NEW UDP connect: the same for a UDP packet.

  * Fired NEW connect: another connection attempt (not ICMP/UDP/TCP) was
    stopped.

  * Fired NEW TCP from PRIVPORT: a new TCP packet originating from
    a privileged port was blocked.

  * Fired NEW UDP from PRIVPORT: the same for a UDP packet.

  * Fired possible traceroute: a new UDP packet that is likely to be
    a traceroute probe was blocked.

  * Fired invalid ICMP/TCP/UDP: an invalid packet of the corresponding type
    was blocked.  Here, `invalid' means that it is associated with no known
    connection, see man iptables.  Sometimes, invalid ICMP packets appear
    after you restart slackfire and break a previously existing connection.
    These packets are not necessarily illegal from the kernel point of view.

  * Fired invalid (sO scan): ditto but the packet has none of the above
    three types.  This may be a packet generated by "nmap -sO" scan.

  * Fired TCP/UDP source port 0: a TCP/UDP packet with (illegal) source port 0
    was blocked.

  * Fired TCP/UDP dest. port 0: a TCP/UDP packet with (illegal) destination
    port 0 was blocked.

  -----------
  The following messages can appear if you set SCAN_CHECK=1 in slackfire.conf:

  * Fired new SYN,ACK (SPT 80), Fired new ACK,RST (SPT 80): a new TCP
    packet originating from port 80 of the remote host and having (only)
    the corresponding bits set was blocked.  Packets of this type are
    used in scanning purposes to mimic a response from a web server. 
    This may also be the result of a broken connection.

  * Fired new SYN,ACK (SPT 22): the same as above but for a packet that
    originated from port 22.  Have you established an ssh connection to
    the host that is sending you these packets? ;-)

  * Fired new SYN,ACK (PRIVSPT): blocked a new TCP packet with only SYN
    and ACK bits set originating from a privileged port (but not 0, 22,
    80).

  * Fired new ACK/RST/ACK,RST/ACK,FIN: a new TCP packet with only the 
    corresponding bit(s) set was blocked.  AFAIU, this maybe either a
    scan or the result of a broken connection.

  * Fired new SYN,ACK/SYN,RST/SYN,FIN: a new TCP packet with the corresponding
    bits set was blocked.  AFAIU, the first case (SYN,ACK) may indicate both
    a broken connection and a scan, while the latter combinations of bits
    are likely to indicate a scan.

  * Fired XMAS/XMAS-PSH/XMAS-ALL/FIN/NULL scan: stopped the corresponding
    scanning, see man nmap for details.

  Thus, one can egrep "new|scan" /var/log/syslog for possible signs of the
  machine/LAN being scanned.
  --------------------

  * Fired NEW not SYN IN: stopped a new incoming TCP packet w/o a proper
    (SYN) bit set but not of the above types.  This message only appears
    in case LOG_NEW_NOT_SYN_IN=1 in slackfire.conf  The message applies
    to packets addressed to the machine running SF and to packets addressed
    to the LAN if there is any.

    According to my experience, all attempts to scan the machine or LAN
    with TCP packets are logged if SCAN_CHECK=1 in slackfire.conf thus
    the rest are just signs of broken connections.

  * Fired NEW not SYN OUT: stopped a new outgoing TCP packet w/o a
    proper (SYN) bit set.  This message only appears in case
    LOG_NEW_NOT_SYN_OUT=1 in slackfire.conf

  * Fired NEW not SYN from LAN: stopped a new TCP packet that was to be
    forwarded from the LAN w/o a proper (SYN) bit set. This message only
    appears in case LOG_NEW_NOT_SYN_OUT=1 in slackfire.conf.

  * Fired TCP flag 64/128: blocked a TCP packet with the corresponding flag.

  * Fired unclean: blocked a packet which seemed to be malformed or unusual.
    This message can only appear in case CHECK_UNCLEAN=1 in slackfire.conf.

  * Fired ICMP fragment: blocked a fragmented ICMP packet.  This may be
    a sign of scanning.

  * Fired ECHO request: an echo request was stopped (in case they are
    not allowed).  LOG_PINGS=1 must be set in slackfire.conf for this
    message to appear.

  * Fired an ICMP packet: blocked an ICMP packet but not a ping.

  * Fired denied host: a connection attempt from a host listed in one of
    the denied_hosts or denied_services was stopped.  LOG_DENIED=1 must
    be set in slackfire.conf for this message to appear.

  * Fired TCP/UDP with REJECT: a TCP/UDP connection attempt was stopped
    with REJECT (instead of DROP).  Any of reject.in files must have a valid
    record for this message could appear.  Besides,  LOG_REJECTED=1 must
    be set in slackfire.conf.

  * Fired possible SYN-flood: a possible SYN-flood attack may take place.
    A check for SYN-flooding and its logging must be enabled in slackfire.conf
    for this message to appear:  DISABLE_SYNFLOOD_PROTECTION=1 must be
    commented and LOG_SYNFLOOD=1 must be commented out.

  * Fired from/TO a blocked host: a connection attempt from/to a host
    listed in blocked_hosts was stopped. These messages can only appear
    in case LOG_FROM_BLOCKED=1 and/or LOG_TO_BLOCKED=1 in
    slackfire.conf.

  * Fired possible Trojan IN/OUT: a connection attempt to/from a port
    listed in trojan_ports was stopped. These messages can only appear
    in case LOG_TROJANS_IN=1 and/or LOG_TROJANS_OUT=1 in slackfire.conf.

  * Fired another TCP/UDP: blocked a TCP/UDP packet that doesn't match any
    of the above.  This may indicate that some rule doesn't work properly.

  * Fired something else: as it says. :-)  This may indicate that a protocol
    other than ICMP/TCP/UDP was used in an incoming packet.


--
  Remark for SlackFire 0.44:
  I excluded the LOG_ACCEPTED setting for the sake of readability of the
  script.  (This saved me about 250 lines of the code!) In case you want
  to log results of any particular rule with the ACCEPT target, just copy
  the rule and replace "-j ACCEPT" by "-j LOG" in the *first* copy of
  the rule. Optionally, one can add something like 

          -m limit --limit $LOG_RATE --log-prefix "Accepted in: "

  or just

          -j $LOG "Accepted in: "

  because LOG is a variable defined in the script for the purpose.

  A trivial example:
  There is a rule that accepts packets incoming through loopback (lo).
  The rule reads:

     iptables -A INPUT -i lo -j ACCEPT

  To log these packets, edit the script this way:

     iptables -A INPUT -i lo -j $LOG "Accepted in loopback: "
     iptables -A INPUT -i lo -j ACCEPT

--

6. Concluding remarks

  The script loads a number of modules: ip_conntrack_ftp and, possibly,
  ip_conntrack_irc, ip_nat_ftp, ip_nat_snmp_basic, ip_nat_irc.  Comment
  the corresponding lines in case you have these modules compiled in
  the kernel.

  There is one more script in usr/sbin besides slackfire, namely, sf4sf.
  This is a filter (written by Arno van Amersfoort and slightly modified by
  myself) that can be used to view syslog messages produced by SF.  It can
  be used, e.g., this way:

  # tail -f /var/log/syslog | sf4sf


7. Acknowledgments

  Thanks to:

  * Todd A. Aiken (Bishop's University) for pointing out that SF, v.0.41,
    didn't allow an NTP server to work properly, and for the very helpful
    and stimulating correspondence which followed.

  * Cedric Blancher and Jose Maria Lopez Hernandez for explaining me
    a number of networking-related issues.

  * Grant Coady for interesting discussions, great help with patch-o-matic,
    a nice script: http://bugsplatter.mine.nu/bash/firewall/rc.firewall.gz,
    and a stimulating correspondence.

  * Juha Laiho for a helpful discussion of ICMP packets.

  * prg (comp.os.linux.networking) for the enlightening discussion of
    INVALID ICMP packets.

  * Yuri Vladysik for a great number of ideas concerning the project web
    site.  I regret I have not been ready to get them.

  * everybody at alt.os.linux.slackware and comp.os.linux.security
    who patiently answered my questions. :-)
 

References

  The script is mainly based on (in no particular order):
 
  * O. Andreasson's Iptables Tutorial, v. 1.1.19 and 1.2.0.

  * Rusty Russel's Packet Filtering HOWTO (1.26) and NAT HOWTO (1.18)

  * comp.os.linux.security FAQ by D. Swan, v. 2.0

  * scripts and articles provided by James N. Stephens,
    http://www.sns.ias.edu/~jns/security/

  * a number of articles on iptables firewalls available at
    http://www.informit.com/

  * Firestarter by Tomas Junnonen and Paul Drain (v. 0.9.3),
    http://firestarter.sourceforge.net/

  * iptables script by Arno van Amersfoort, http://rocky.eld.leidenuniv.nl/
    (v. 1.8.3 beta3).

  * MonMotha's iptables script, http://monmotha.mplug.org/firewall/index.php
    (v. 2.3.8)

  * iptables script by Obsid,
    http://www.sentry.net/~obsid/IPTables/rc.scripts.dir/current/

  * http://www.linuxhelp.net/guides/iptables/iptables-script

  * iptables script by Arunas Vaitekunas, http://linux.fan.lt/fwall

  * scripts generated by Easy Firewall Generator, author Timothy Scott Morizot,
    http://easyfwgen.morizot.net/

  * KISS rc.firewall, http://www.penguinsecurity.net/

  * LASG by G. Mourani, http://www.openna.com/

  * scanning my boxes with the help of nmap and http://scan.sygate.com/  :-)

  * experience obtained while running the script 24/7 since November '04.
  

Your comments, ideas, and bug reports are welcome. 
Please, send them to any of slackfire@{narod.ru,gmail.com}.
It will be nice if you mention SlackFire in the Subject line. :-)

 

Have fun!

--
uckpeHHe,
Muxau/\

# EOF
