Firewalls - Writing Shell Scripts (Page 6 of 10 )
Often you will need to automate a process or have a single command initiate a number of statements. In the firewall example, you will generally want to have all your firewall commands executed when your system boots. The best way to do this is to write a shell script. A shell script is a simple text file that contains a command or list of commands. The shell editor executes the commands when it is invoked by a user typing the name of the script.
1. To create a shell script, first open a text editor such as vi or EMACS and type in your command(s).
2. Make sure you put a line at the very top that looks like this:
#! /bin/bash
This tells the script which shell to use to execute the command. You must have that shell on your OS, and the commands you put in your script will have to be valid commands for that shell. This example is for the bash shell location on Mandrake Linux. You can use a different shell, for example, Tcsh or Csh. Just put the path to it on this line. Then save your file.
3. Make the file executable so the shell can run it as a program. You do this with the chmod command. Type:
chmod 700 script_name
where you replace script_name with your file name. This makes the permissions on the file readable, writable, and executable.
To run the script, type the file’s name in the command line. (In the bash shell, you need to add a ./ before the file name to run the script from your local directory.) When you press Enter, the commands in your script should run.
You have to be in the same directory as the file or type the path in the command line statement when you run it. Alternatively, you could add the directory for the script to your PATH statement so it will run from anywhere or put the script in one of your PATH directories.
The example in the following procedure assumes that your local LAN subnet is 192.168.0.1 - 192.168.0.254, that the eth1 interface is your local LAN connection, and that the eth0 interface is your Internet or WAN connection.
1. Start by eliminating any existing rules with a Flush command:
iptables -F FORWARD
This flushes all rules for the FORWARD chain, which is the main “funnel” for any packets wanting to pass through the firewall.
2. Flush the other chains:
iptables -F INPUT
iptables -F OUTPUT
This flushes any rules to your local machine and your output chain.
3. Put your standard “deny all” statement right up front.
iptables -P FORWARD DROP
iptables -A INPUT -i eth0 -j DROP
4. To accept fragmented packets in Iptables, this must be done explicitly.
iptables -A FORWARD -f -j ACCEPT
5. There are two types of common attacks that you should block right away. One is what is known as spoofing, which is when someone forges the IP packet headers to make it look like an outside packet has in internal address. By doing this, someone could route onto your LAN even if you have private IP addresses. The other type of attack is done by sending a stream of packets to the broadcast address of the LAN to overwhelm the network. This is called a smurf attack (although I’m not sure what this has to do with little blue cartoon characters). You can block these types of attacks with two simple statements.
iptables -A FORWARD -s 192.168.0.0/24 -I eth0 -j DROP
iptables -A FORWARD -p icmp –i eth0 –d 192.168.0.0/24 –j DENY
The first statement drops any packets coming from the Internet interface eth0 with the internal address 192.168.0.0/24. By definition, no packets should be coming from the untrusted interface with an internal, private source address. The second statement drops any packets of protocol ICMP coming from the outside address to the inside.
6. You generally do want to accept incoming traffic based on connections initiated from the inside, for example, someone surfing a Web page. As long as the connection is ongoing and it was initiated internally, then it is probably okay. You can, however, limit the type of traffic allowed in. Let’s say that you only want to allow employees Web and e-mail access. You can specify the types of traffic to allow through and only if it is on an already-initiated connection. You can tell if it is an existing connection by seeing that the ACK bit has been set, that is, that the TCP three-way handshake has occurred. The following statements allow HTTP and Web traffic based on this criteria.
iptables –A FORWARD –p tcp –i eth0 –d 192.168.0.0/24 -
dports
www,smtp --tcp-flags SYN,ACK –j ACCEPT
iptables –A FORWARD –p tcp –i eth0 –d 192.168.0.0/24 -sports
www,smtp --tcp-flags SYN,ACK –j ACCEPT
The -dport statement says to only allow e-mail and Web, and the –tcp flags statement says you only want packets with the ACK field set.
7. To be able to accept incoming connections from the outside only on certain ports, such as e-mail coming into your mail server, use a statement like this:
iptables –A FORWARD –m multiport –p tcp –i eth0 –d
192.168.0.0/24
--dports smtp --syn –j ACCEPT
The -m multiport flag tells Iptables that you will be issuing a match statement for ports. The -syn statement tells it to allow SYN packets, which means to initiate TCP connections. And the -dports flag allows only the SMTP mail traffic.
8. You can allow outgoing connections to be initiated by your users, but only on the protocols you want them using. This is where you can prevent your users from using FTP and other nonessential programs. The all-zero IP address is shorthand for saying “any address.”
iptables –A FORWARD –m multiport –p tcp –i eth0 –d
0.0.0.0 --dports www,smtp --syn –j ACCEPT
9. You need to allow certain incoming UDP packets. UDP is used for DNS, and if you block that your users won’t be able to resolve addresses. Because they don’t have a state like TCP packets, you can’t rely on checking the SYN or ACK flags. You want to allow UDP only on port 53, so you specify domain (a built-in variable for port 52) as the only allowable port. You do that with these statements.
iptables –A FORWARD –m multiport –p udp –i eth0 –d
192.168.0.0/24 --dports domain –j ACCEPT
iptables –A FORWARD –m multiport –p udp –i eth0 –s 192.168.0.0/24 --sports domain –j ACCEPT
iptables –A FORWARD –m multiport –p udp –i eth1 –d 0.0.0.0 --dports domain –j ACCEPT
iptables –A FORWARD –m multiport –p udp –i eth1 –s
0.0.0.0 --sports domain –j ACCEPT
10. The first two statements allow the incoming UDP datagrams, and the second two allow the outbound connections. You also want to do this for ICMP packets. These are the network information packets discussed in Chapter 2. You want to allow all types of internal ICMP outwards, but only certain types such as echo-reply inwards. This can be accomplished with the following statements.
iptables –A FORWARD –m multiport –p icmp –I eth0 –d
192.168.0.0/24 --dports 0,3,11 –j ACCEPT
iptables –A FORWARD –m multiport –p icmp –I eth1 –d 0.0.0.0
--dports 8,3,11 –j ACCEPT
11. Finally, you want to set up logging so you can look at the logs to see what is being dropped. You will want to view the logs from time to time even if there isn’t a problem, just to get an idea of the kinds of traffic being dropped. If you see dropped packets from the same network or address repeatedly, you might be being attacked. There is one statement to log each kind of traffic.
iptables –A FORWARD –m tcp –p tcp –j LOG
iptables –A FORWARD –m udp –p udp –j LOG
iptables –A FORWARD –m udp –p icmp –j LOG
That’s it! This will provide you with firewall protection from the most common attacks from the Internet.
Next: IP Masquerading with Iptables >>
More Security Articles
More By Addison-Wesley Prentice Hall PTR
|
This article is excerpted from Open Source Security Tools by Tony Howlett (Addison-Wesley Professional, 2004; ISBN 0321194438). Check it out at your favorite bookstore today. Buy this book now.
|
|