[ISN] Ten minute host firewall, Part 1

From: InfoSec News (isnat_private)
Date: Mon Jul 07 2003 - 00:08:58 PDT

  • Next message: InfoSec News: "[ISN] Vmyths Hovering at Death's Door"

    +------------------------------------------------------------------+
    |  Linux Security: Tips, Tricks, and Hackery                       |
    |  Published by Onsight, Inc.                                      |
    |                                                                  |
    |  03-July-2003                                                    |
    |  http://www.hackinglinuxexposed.com/articles/20030703.html       |
    +------------------------------------------------------------------+
    
    This issue sponsored by IP Justice
    
    Support IP Justice, a new international civil liberties organization
    focusing on global intellectual property issues. The mission of the
    new advocacy group is to promote balanced intellectual property laws
    and protect freedom of expression in both traditional and digital
    media. A grassroots membership based organization with offices in San
    Francisco, IP Justice advocates for respecting the rights of both
    creators and consumers of intellectual property.
    
    To learn more about IP Justice, visit http://www.ipjustice.org.
    
    --------------------------------------------------------------------
    
    Ten minute host firewall, Part 1
    By Brian Hatch
    
    Summary: Create a simple but effective host firewall for your machine
    in ten minutes or less.
    
    One of my friends finds himself in a very annoying situation: he
    started a new job and now has a Windows machine on his desk. Worse
    yet, he's not allowed, by corporate policy, to wipe it clean and
    install Linux on it "for security reasons". Being that we both live
    up here in Seattle, close to the belly of the beast itself, it's not
    surprising that the Microsoft FUD machine is strong.
    
    The IT department grudgingly agreed that he could use Linux if he had
    an adequate firewall installed. They intend to port scan him and, if
    all ports refuse inbound connections, they'll consider his machine
    secure.
    
    Now this is not my definition of a very secure firewall.[1] However
    it is immeasurably better than no firewall rules at all, and it takes
    no more than a few minutes to set it up.
    
    First, let's assume we're on a 2.4 kernel that has Netfilter
    (iptables) support compiled in. I'll assume you're using a 2.4 kernel
    for these examples, but I've restricted myself to commands that can
    be munged into their ipchains counterparts, meaning I've ignored
    Netfilter's ability to do connection tracking and the like. If you
    want to create a more secure firewall, then there are various
    pre-canned firewall scripts you can use, or you can read up on
    Netfilter's finer details online or in books such as Ziegler's "Linux
    Firewalls".
    
    In this minimal setup, we want to allow all outbound access, and deny
    all inbound access that isn't in response to one of our outbound
    connections. This is surprisingly easy to manage.
    
    We'll be adding rules to the INPUT chain. First, let's make the
    default rule (the 'policy') be to to DROP packets. This throws away
    the packet without informing the sender.
    
     # iptables -P INPUT DROP
    
    You now have a very secure machine - nothing can get in. Perhaps we
    should open things up a bit...
    
    There are three protocols we'll want to support, TCP, UDP, and ICMP.
    TCP is the IP protocol that does the majority of the work on the
    Internet. It's a connection-based protocol that underlies all the
    major services, such as web (HTTP/HTTPS), mail (SMTP, POP, IMAP),
    remote login (SSH), and file transfer (FTP).
    
    Any TCP connection has the oft-mentioned "three way handshake". The
    machine that wants to create a connection sends a packet to the
    destination with the SYN (synchronise) flag set. The server responds
    with a packet that has both SYN and ACK (acknowledge) set, and
    thereafter the SYN bit is never seen again. If we configure our
    firewall ACLs to drop any packets which contain the SYN bit without
    that ACK, we can prevent the first packet of TCP connections from
    reaching our machine, and no TCP connections can be created at all.
    
    Iptables[2] can selectively block packets based on the SYN flag using
    the --syn flag, for example:
    
      # iptables -A INPUT -p tcp ! --syn -j ACCEPT
    
    Voila! No machines can connect to your machine with TCP, but you can
    make outbound connections and the associated packets will be allowed
    back in. You can't be a server (no SSH to your machine, for example)
    but all outbound TCP stuff should work fairly well.
    
    Well, that's true about most 'well behaved' TCP-based protocols. Some
    protocols like to use more than one port. FTP is the classic example
    of a bastardly-designed protocol. Each time you type 'get', 'put', or
    'ls' a new TCP connection is initiated to snag the data.
    
    Note also that even though outsiders can't connect to your TCP ports,
    scanning tools such as Nmap will be able to see that the port is open
    if they are used in any mode other than straight TCP connection
    scanning. Newer Nmap versions use stealth scanning by default when
    run as root.
    
    If the protocol you use wants to have the client (your newly
    firewalled machine) make an additional connection to the server, then
    your --syn firewall won't be a problem. However if it wants to have
    the server contact the client, these connections will be denied.
    
    Protocols that create these ephemeral side connections include many
    P2P protocols, and most notably FTP. Most of these offer both a
    'client connects to server' and 'server connects back to client'
    option. In the case of FTP, the former is called "Passive", while the
    latter is called "Active". Active was the original (really annoying
    for firewalls and proxies) model, and Passive has been favoured for
    some time now. Most FTP clients let you choose Passive if it's not
    already the default. For example typing pftp instead of ftp on the
    command line, or including --passive-ftp as an argument to wget.[3]
    
    Now, to be a bit more restrictive, let's block UDP as well. UDP is a
    connectionless protocol, so it's harder to proxy and firewall.
    However it's also less commonly used. DNS is the the most important
    UDP protocol. Without DNS you're going to need to memorise many IP
    addresses, so we best open this up.
    
    DNS servers live on UDP port 53.[4] Our machine will need to send
    packets to port 53 on one or more DNS servers, and receive packets
    that come from port UDP 53. So, restricting on the source port (the
    port on the DNS server) you'd have
    
      # iptables -A INPUT -p udp --source-port 53 -j ACCEPT
    
    This will allow any DNS servers to reply to you, which may be helpful
    if you get your DNS servers from DHCP and want to be lazy. If you
    want to hard code your DNS server's IP addresses to be most
    restrictive, you can use the following
    
      # iptables -A INPUT --source DNS.SVR1.IP.ADDR -p udp --source-port 53 -j ACCEPT
      # iptables -A INPUT --source DNS.SVR2.IP.ADDR -p udp --source-port 53 -j ACCEPT
    
    If your machine needs to get an IP address from the network using
    BOOTP or DHCP, then you'll need the following rule as well:
    
      # iptables -A INPUT -p udp --destination-port 68 -j ACCEPT
    
    Any packets that aren't for DNS or BOOTP/DHCP will be dropped by the
    INPUT chain's policy.
    
    What services are likely to brake when you're blocking UDP? Most
    streaming media uses UDP for it's highest-speed connections, but may
    offer TCP based connections as well. Filesharing protocols such as
    NFS may die, but again may offer TCP versions that get around this
    limitation. It all depends on your setup.
    
    Now we haven't listed which interfaces these rules apply on. If you
    want them to apply to all interfaces, this is probably good. However
    you should allow packets that go on the localhost interface to work
    universally, lest you break some daemons that expect to be able to
    communicate within your machine, or features like SSH port
    forwarding. So, as the very first rule, you should include the
    following:
    
      # for interface in /proc/sys/net/ipv4/conf/*/rp_filter
          do
              echo 1> $interface
          done
    
      # iptables -A INPUT -i lo -j ACCEPT
    
    The iptables rule says "allow any packets that come into localhost
    without any filtering". The for loop sets Reverse Path filtering on
    all interfaces, which will block packets that come in from the wrong
    interface.[5]
    
    Lastly, we can lock down allowed ICMP packets, which are used in
    conjunction with TCP and UDP protocols to indicate error conditions
    and the like. Here I'll be a bit more permissive than may be
    necessary in order to fit the needs of a wider audience. To get a
    full list of possible ICMP codes, run iptables -p icmp --help. We'll
    allow the following types for greatest network stability:
    
     # iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type source-quench -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type redirect -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type router-advertisement -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
     # iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
    
    You may wish to exclude some of these, such as echo-request (prevent
    your machine from being pinged), redirect and router-advertisement
    (if you have only one router, and no dynamic routes.)
    
    Next week I'll bring this all together in one big script and show you
    how to let these rules be created at reboot automatically.[6]
    
    NOTES:
    
    [1] I much prefer to have my firewall rules explicitly define what
    packets are allowed to go in *and go out*. This helps block outbound
    access that could be created by trojans, viruses, or evil hax0rs.
    
    [2] Iptable's predecessors and other firewall/filtering products have
    also used this trick for years.
    
    [3] Netfilter has modules that you can load as well to support
    specific protocols such as FTP or IRC that do wacky things like this.
    
    [4] They may also listen on TCP port 53 for larger queries and DNS
    zone transfers, but outbound TCP is already covered by our previous
    --syn rule.
    
    [5] For more information about this and other helpful /proc interface
    files, see "Firewalling proc entries" (http://
    www.hackinglinuxexposed.com/articles/20021015.wml)
    
    [6] I understand the irony of having a 10 minute firewall discussion
    spread out over two weeks...
    
                                -------------                            
    Brian Hatch is Chief Hacker at Onsight, Inc and author of Hacking
    Linux Exposed and Building Linux VPNs. In the rare times where he
    gets uninterrupted time to write, he never seems to stop. The muses
    smiled upon him today. Brian can be reached at
    brianat_private
    
    --------------------------------------------------------------------
    This newsletter is distributed by Onsight, Inc.
    
    The list is managed with MailMan (http://www.list.org). You can
    subscribe, unsubscribe, or change your password by visiting
    http://lists.onsight.com/ or by sending email to
    linux_security-requestat_private
    
    Archives of this and previous newsletters are available at
    http://www.hackinglinuxexposed.com/articles/
    
    --------------------------------------------------------------------
    
    Copyright 2003, Brian Hatch.
    
    
    
    -
    ISN is currently hosted by Attrition.org
    
    To unsubscribe email majordomoat_private with 'unsubscribe isn'
    in the BODY of the mail.
    



    This archive was generated by hypermail 2b30 : Mon Jul 07 2003 - 02:35:39 PDT