Thursday, December 18, 2008

IP Tables


Documents to read:

1. Firewall-HOWTO
Use...
$ zless /usr/share/doc/HOWTO/en-txt/Firewall-HOWTO.gz

2. Manual [iptables(8)]

2. iptables documents
Use...
$ lynx /usr/share/doc/iptables/html/


Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.

Create a directory [iptables] in your home directory.
$ mkdir $HOME/iptables

Copy [ iptables.txt ] in iptables directory. The following files might
also be needed for installation.

iptables_1.2.6a-5_i386.deb
libc6_2.2.5-11.2_i386.deb

Note: The location of these files in set of CD
/pool/main/g/glibc/libc6_2.2.5-11.2_i386.deb in CD-1
/pool/main/i/iptables/iptables_1.2.6a-5_i386.deb in CD-1

Installation of [ iptables ] on any Linux operating system is not
enough. The operating system must have support for [ iptables ] in the
kernel or proper module should be included in the kernel.
To build a dedicated firewall, it might be useful to recompile a
suitable kernel from source code.

The following is taken from [iptables] documents by "Rusty" Russet.

"You need a kernel which has the netfilter infrastructure in it:
netfilter is a general framework inside the Linux kernel which
other things ( such as the iptables module ) can plug into. This
means you need kernel 2.3.15 or beyond, and answer `Y' to
CONFIG_NETFILTER in the kernel configuration."

In this experiment, Linux kernel 2.4.18 is used to illustrate very
simple uses of packet filtering firewall.

The user-space tool [ iptables ] is used to set up, maintain, and
inspect the tables of IP packet filter rules in the kernel.

The rules are broadly grouped into tables. In each table related rules
are grouped. These groups are called CHAINS or chain of rules. Users
can create their chains if needed.

Currently there are three tables in [iptables] with their CHAINS.

Table names Chain names

filter - INPUT - set of rules
OUTPUT - set of rules
FORWARD - set of rules


nat - PREROUTING - set of rules
POSTROUTING - set of rules
OUTPUT - set of rules


mangle - PREROUTING - set of rules
INPUT - set of rules
FORWARD - set of rules
OUTPUT - set of rules
POSTROUTING - set of rules

User-defined-chain-1 - set of rules
:
:
User-defined-chain-n - set of rules


For building a firewall, [ filter ] table is used. [nat] and [mangle]
tables are used for other purposes.

Chains are empty by default ( rules are not present in chains ).

Assignment-1:

Clear rules from the three chains of [ filter ] table. This is also
called flushing of rules.
# iptables -t filter -F INPUT
# iptables -t filter -F OUTPUT
# iptables -t filter -F FORWARD

Inspect the chains of [ filter ] table. Likely output is shown.
# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

The verbose option provides more information. Use the following
command and examine the output. The output need not be recorded.
# iptables -t filter -vL

Flush the chains of [ nat ] and [ mangle ] tables..
# iptables -t nat -F
# iptables -t mangle -F


Inspect the chains of [ nat ] table. Likely output is shown.
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination


Inspect the chains of [ mangle ] table. Likely output is shown.
# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination

To clear all chains of all tables and to set the policies of all
chains to ACCEPT, the following command can be used...
# /etc/init.d/iptables clear

This command also removes the user-defined chains.

The policy of a chain is explained later.

End of Assignment-1.


WARNING: You are requested not to make the rules permanent. The rules
should disappear on re-boot. Bad rules might lock-up your PC.


A computer used as firewall is usually has more than one network
interface, such as two Ethernet interfaces. Typically it sits between
two networks. In the following example, the firewall is between local
LAN and INTERNET.

__________________
host-1 | |
| | |
------------ Local LAN -- eth0 Firewall eth1 ----- INTERNET
| | (Computer) |
host-2 |__________________|


Figure-1


The packet filtering (filter table) rules of the kernel broadly decide

1. Which packets can enter the local LAN from the INTERNET.
2. Which packets can go out to the INTERNET from the local LAN.

The above two are FORWARD rules.

3. Which packets can be accepted by processes in the firewall itself
from either of the interfaces. These are INPUT rules.
4. Which packets generated by processes in the firewall itself, can
leave the firewall via either of the interfaces. These are OUTPUT
rules.

Example:
Allow SSH access to the firewall itself for packets coming in
through the eth0 interface. SSH uses TCP port 22.

# iptables -t filter -A INPUT -p tcp --dport 22 -d 127.0.0.1 \
> -i eth0 -j ACCEPT

The options have the following meaning:

-t filter Filter table is specified. If this option is omitted, by
default [ filer ] table is used. For [nat] and [mangle]
tables [t] option has to be used.

-A INPUT A rule is appended to the INPUT chain
-p tcp TCP protocol is specified in the packet
--dport 22 Destination port is 22(ssh)
-d 127.0.0.1 Destination IP address is loopback interface
-i eth0 Packet coming via eth0 interface
-j ACCEPT Such packets jump to target ACCEPT

Inspect the rule you have appended. By default [ filter ] table is
inspected.
# iptables -vnL

From the output verify the following:

One rule was inserted in INPUT chain.
Destination is 127.0.0.1 ( loopback interface ) TCP port 22.
Source is 0.0.0.0/0 ( anywhere ).
Packet comes in via eth0 interface.
Target of such packet is ACCEPT.

Flush the above rule
# iptables -F

As the above setup cannot be created for each PC in the laboratory,
the following setup is to be used for this experiment.

________________________________
| : : |
| Different : Firewall : | PC-1 PC-22
| network : running : | | |
| services : on your PC : eth0 -- Laboratory LAN ---------------
| running on : : | |
| your PC : : | PC-6
|________________________________|


Figure-2

Packet filtering rules in your PC, in this experiment, decide

1. Which packets from the laboratory LAN and beyond, can access
different network services running on your PC ( INPUT rules ).
2. Which packets from your PC can access different services running
on different hosts in the laboratory LAN and beyond ( OUTPUT
rules ).

In the above arrangement FORWARD rules cannot be checked. However such
rules can be written.

Which chain of which table, is applied to a packet, depends on some
factors. At present we assume that the first rule of a particular
chain is applied to a packet.

The packet header is examined against the first rule of the chain. If
the packet header does not match first rule, the next rule is tried
and so on. If none of the rules match, the policy of this particular
chain is consulted. If policy is DROP, the packet is discarded. If the
policy is ACCEPT, the packet is allowed to move on. Policy can be
either ACCEPT or DROP. The default policy is ACCEPT, for all chains.

When a rule matches, an action for that rule is taken. This action is
called "jumping to a target".

Example: Packets coming from local LAN, destined for the prohibited
site (60.2.2.55) are to be blocked. The choice of address
60.2.2.55 is arbitrary.


__________________
host-1 | |
| | |
------------ Local LAN -- eth0 Firewall eth1 ----- INTERNET
| 172.16.1.0 | |
host-2 |__________________| prohibited site
( 60.2.2.55 )

Figure-3

A rule is to be appended to FORWARD chain of [ filter ] table. The
target of the rule is to be DROP.

The rule fires if any packet match all of the following:

1. The destination IP address of the packet is 60.2.2.55
2. The packet enters the firewall through eth0 interface and leaves
the firewall through the eth1 interface.
3. The packet can have any source address and use any protocol.

Add a rule to achieve the above.
# iptables -A FORWARD -d 60.2.2.55 -i eth0 -o eth1 -j DROP

The rule generated by the above command is checked with...
# iptables -vL FORWARD

Fill the table from the output.

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

__ __ _____ ___ ____ ____ __________ 60.2.2.55


The action of the rule (target) is DROP. Note the policy of the chain,
in the above output, which is ACCEPT. With this chain policy, the
packets, which do not match any of the rules of FORWARD chain, with
target DROP, are allowed to move on. When a packet matches a rule,
rest of the rules of that chain are not applied to that packet.

A target may be absent in a rule. Such rules are called accounting
rules. These are used for packet counting. Even if an accounting rule
matches, the next rule is applied to the packet. If the target is a
a user-defined chain and none of the rules in that user-defined chain
match, the flow comes back to the previous chain, to the rule, next to
the rule which caused the jump to the user-defined chain.


A standard target can be any one of the following

Name of target

ACCEPT - packet is allowed to move on.
DROP - packet is discarded without informing sender
QUEUE - packet is passed to user-space
RETURN - stop traversing this chain and resume at the
next rule in the previous ( calling ) chain.
Name of
user-defined
chain.

The following are extended targets available in standard distributions

LOG
MARK
REJECT - packet is discarded with suitable message to sender
TOS
MIRROR
SNAT
DNAT
MASQUERADE
REDIRECT
TCPMSS


The policy of a chain can be changed with [ -P ] option. Policy can be
ACCEPT or DROP.

User-defined chains can be created with -N option.

User-defined chains can be deleted with -X option.


Assignment-2:
In some of the following examples [ mangle ] and [ nat ]
tables are used, though [filter] table is for implementing firewall.


Change the policy of PREROUTING chain of [mangle] table.
# iptables -t mangle -P PREROUTING DROP
Check with [ # iptables -t mangle -L PREROUTING ]

Record the command to set the policy of INPUT chain of [filter] table
to DROP. Verify the result.

Command---------->
Verify command -->

Create two user-defined chains. These are to be called from [ filter ]
table chains.
# iptables -t filter -N feluda
# iptables -t filter -N topsay

Check with [ # iptables -vL ]

"0 references" means that none of the rules of the three chains of
[ filter ] table, has feluda or topsay as target. User-defined chains
have no policy.

Append a rule in FORWARD chain of [ filter ] table. This rule jumps to
chain [ feluda ], whenever a packet header has TCP.
# iptables -t filter -A FORWARD -p tcp -j feluda

Check with [ # iptables -t filter -L ]. Now chain [ feluda ] has one
reference.

Create two user-defined chains to be called from [nat] table
# iptables -t nat -N tintin
# iptables -t nat -N calculus
Check with [ # iptables -t nat -L ]

Delete user defined chain [topsay]
# iptables -t filter -X topsay

Try to delete user defined chain [feluda]
# iptables -t filter -X feluda
This command should fail as one rule is referencing this chain.

Delete the rule of the FORWARD chain of [ filter ] table, referencing
the user defined chain [feluda].

Note: When there are large number of rules in a chain, it might be
convenient to know the number of a chain, for rule deletion
or rule insertion. A command similar to the following can be
used.
# iptables -t filter -L FORWARD --line-numbers

Delete the rule referencing [feluda].
# iptables -t filter -D FORWARD __

Now user-defined chain [feluda] can be removed..
# iptables -t filter -X feluda


Delete user defined chain [tintin]
# iptables -t nat -X tintin

Clear all the chains, delete user-defined chains and set policies
to ACCEPT
# /etc/init.d/iptables clear

End of Assignment-2.


How the packets traverse the chains of [filter] table:
The following figure is reproduced from [iptables] documents.

....................................................
. .
. --------- --------- .
. | | | | .
Incoming ->-| Routing |--->---| FORWARD |---->---- Outgoing
Interface | | | | Interface
. --------- --------- .
. | | .
. \|/ /|\ .
. | | .
. | | .
. ------- -------- .
. | | | | .
. | INPUT | | OUTPUT | .
. | | | | .
. ------- -------- .
. | | .
. \|/ /|\ .
. | | .
. To process From process .
. in firewall in firewall .
. .
. .
....................................................

FIREWALL Figure-4


When a packet enters the firewall through an interface, destination
of the packet is checked by the kernel. This is called "routing".

If destination is firewall, the packet header is checked against the
rules of INPUT chain.

If the destination is not firewall, the packet is to be forwarded to
another host or another network.

For forwarding to take place, [ip_forwarding] is to be enabled in the
kernel. If [ ip_forwarding ] is disabled or there is not enough
information in the kernel routing table, the packet is dropped.

You may use the following command to check [ ip_forwarding ] in your
host.
# cat /proc/sys/net/ipv4/ip_forward

If output is zero, it is disabled. Enable it with...
# echo 1 > /proc/sys/net/ipv4/ip_forward


If forwarding is possible, the packet header is checked against the
rules of FORWARD chain. If the packet is allowed to move on, it goes
out through output interface.


Packets generated in the firewall are checked with the rules in OUTPUT
chain.


Assignment-3:
In this assignment INPUT chain of [filter] table is used.
The [filter] table is the default table. So [ -t filer ] part of the
following commands may be omitted. These rules are applied to packets
going to processes running on the firewall.

Clear the INPUT chain of [filter] table..
# iptables -t filter -F INPUT

Any packet to your host, from anywhere, traverse INPUT chain of
[ filter ] table of your host. Any packet from your host to anywhere,
traverse OUTPUT chain of [ filter ] table of your host.

Clear packet and byte counters of the chains and verify.
# iptables -t filter -Z
# iptables -t filter -vL

Send a [ping] packet to localhost to check that the ICMP echo-request
pass OUTPUT chain and INPUT chain and the ICMP echo-reply traverse the
OUTPUT chain and INPUT chain.
$ ping -c1 127.0.0.1
# iptables -t filter -vL

How many packets traversed the OUTPUT chain ? -->
How many packets traversed the INPUT chain ? -->
How many packets traversed the FORWARD chain ? -->

Clear packet and byte counters of the chains and verify. Record the
commands used by you.

command-->
command-->

Request your friend to send one [ping] packet to your host
command in friend's host-->

How many packets traversed the OUTPUT chain of your host ? -->
How many packets traversed the INPUT chain of your host ? -->
How many packets traversed the FORWARD chain of your host ? -->

Change the policy of INPUT chain to DROP
# iptables -t filter -P INPUT DROP

With this policy, all connections to your host, from anywhere, are
denied.
Try to [ping] localhost, this should fail.
$ ping -c1 127.0.0.1

Now the desired packets are explicitly allowed by appending suitable
rules in the INPUT chain.

Append a rule in INPUT chain of [ filter ] table to allow all types of
ICMP messages from localhost.
# iptables -t filter -A INPUT -p icmp -s 127.0.0.1 -j ACCEPT

Try to [ping] localhost, this should succeed.
$ ping -c1 127.0.0.1

Append a rule in INPUT chain of [ filter ], table to allow ICMP from
your friend's host. 172.16.2.__ is your friend's host address.
# iptables -t filter -A INPUT -p icmp -s 172.16.2.__ \
> -j ACCEPT

Allow [telnet] from your friend's host.
# iptables -A INPUT -p tcp -sport 23 -s 172.16.2.__ -j ACCEPT

Request your friend to try [ping] and [telnet] to your host.
Did the above two succeed ? ( Y / n )

Log the [ telnet ] attempt of the budding hacker ( who tried to shut
down your host on lab network ).

# iptables -t filter -A INPUT -s 172.16.2.zz -j LOG \
--log-prefix "Hacker-Mr.zz"

Request Mr.zz to [telnet] to your host. Check [ /var/log/syslog ] for
the log entry, for this [telnet] attempt.

End of Assignment-3.


Assignment-4:
In this assignment rules are added to the OUTPUT chain of
the [ filter ] table.. These rules are applied on packets generated in
the firewall.


Flush all rules of OUTPUT chain of [ filter ] table. Clear packet and
byte counters of OUTPUT chain of [ filter ] table and verify.
# iptables -t filter -F OUTPUT
# iptables -t filter -Z OUTPUT
# iptables -t filter -vL OUTPUT


Append a rule ( in OUTPUT chain of [filter] table ) to disallow any
connection to the prohibited site 172.16.2.100 from the firewall. The
target is REJECT. We want to send a message to the local process, as
to why the connection failed.

# iptables -t filter -A OUTPUT -d 172.16.2.100/32 -j REJECT \
> --reject-with icmp-host-prohibited

Disallow all connections to CC network

# iptables -t filter -A OUTPUT -d 172.16.2.0/24 -j DROP

Allow all connections to Network Laboratory network

# iptables -t filter -A OUTPUT -d 172.16.2.0/16 -j ACCEPT

Check the rules.
# iptables -t filter -nvL OUTPUT
# iptables -t filter -nL OUTPUT --line-number

Send one [ping] to localhost.
$ ping -c1 127.0.0.1

This should succeed due to default policy of the OUTPUT chain which is
ACCEPT.

Try [telnet] to 172.16.2.100 It should fail.
$ telnet 172.16.2.100

Try [ telnet ] to 172.16.2.11 It should succeed if allowed by that
host.
$ telnet 172.16.2.11

Try [ftp] to 172.16.2.251 It should fail.

End of Assignment-4.

Assignment-5:

Let us assume that your host has two network interfaces eth0 and eth1.
Interface eth0 is connected to 172.16.2.0 network and interface eth1
is connected to a host. A PPP link may be used between the firewall
and the host.


172.16.2.0 ----------------- --------
network | | | |
-------------- eth0 Firewall eth1/ppp0 ------| Host-A |
| | | |
----------------- --------

eth0=172.16.2.___ ppp0=172.16.2.___



Figure-5


With this arrangement FORWARD rules can be tested. Host-A is has no
firewall in itself. This host runs a number of services. The firewall
controls access to services running on Host-A. The firewall also limit
access from Host-A to 172.16.2.0 network and beyond.

With this assumption we add the following rules in the FORWARD chain
of [filter] table. These rules may not be useful in any real firewall.
They are used to show usage. For this experiment to succeed, proper
routing information must exist. If eth0 of firewall does ARP proxy for
Host-A, it can be made visible from other hosts of 172.16.2.0 network.

Remove firewall in Host-A.
Host-A # /etc/init.d/iptables clear

IP address of Host-A is assumed to be 172.16.2.yy

Access some services running on it

Host-A $ other host $ ping -c1 172.16.2.yy
Host-A $ telnet 172.16.2.yy 13 // daytime
Host-A $ ftp 172.16.2.yy
Host-A $ telnet 172.16.2.yy 7 // echo

The above should work.

Remove firewall on the Firewall host.
Firewall # /etc/init.d/iptables clear

From other hosts of 172.16.2.0 network try to access services on Host-
A.

other host $ ping -c1 172.16.2.yy
other host $ telnet 172.16.2.yy 13 // daytime
other host $ ftp 172.16.2.yy
other host $ telnet 172.16.2.yy 7 // echo

The above should work

Change policy of FORWARD chain to DROP.
Firewall # iptables -P FORWARD DROP

None of the from [other host] should work.

Allow ICMP echo-request(ping) entering eth0 interface and leaving eth1
interface.

Firewall # iptables -A FORWARD -p icmp --icmp-type echo-request \
> -i eth0 -o eth1 -j ACCEPT

Use this command if Firewall and Host-A are linked with PPP
Firewall # iptables -A FORWARD -p icmp --icmp-type echo-request \
> -i eth0 -o ppp0 -j ACCEPT


Allow ICMP echo-reply (pong) entering eth1 interface and leaving eth0
interface.

Firewall # iptables -A FORWARD -p icmp --icmp-type echo-reply \
> -i eth1 -o eth0 -j ACCEPT

For PPP link use
Firewall # iptables -A FORWARD -p icmp --icmp-type echo-reply \
> -i ppp0 -o eth0 -j ACCEPT


Check the rules
Firewall # iptables -vL FORWARD

The following command should work now

other host $ ping -c1 172.16.2.yy


Allow access to [daytime] servers using TCP of Host-A
Firewall # iptables -A FORWARD -p tcp --dport 13 -d 172.16.2.yy/32 \
> -i eth0 -o eth1 -j ACCEPT

For PPP link
Firewall # iptables -A FORWARD -p tcp --dport 13 -d 172.16.2.yy/32 \
> -i eth0 -o ppp0 -j ACCEPT


Allow answer from [daytime] servers
Firewall # iptables -A FORWARD -p tcp --sport 13 -s 172.16.2.yy/32 \
> -i eth1 -o eth0 -j ACCEPT

For PPP link
Firewall # iptables -A FORWARD -p tcp --sport 13 -s 172.16.2.yy/32 \
> -i ppp0 -o eth0

Try the following command; this should work.
other host $ telnet 172.16.2.yy 13

End of Assignment-5.
--------------------

Optional Assignment-1:
This assignment is to be done in your host.

Disallow user with effective UID = xxx to use [ telnet ] to localhost.
This rule can be used in OUTPUT chain for locally generated packets.

Record your UID--->

Clear all rules
# /etc/init.d/iptables clear

Add the rule
# iptables -A OUTPUT -p tcp --match owner --uid your-uid \
> -d 127.0.0.1 --dport 23 -j DROP

Check the rule
# iptables -vL OUTPUT

From your account [telnet] to loopback interface. This should fail
$ telnet 127.0.0.1

However [telnet] to [eth0] interface should succeed
$ telnet 172.16.2.____

For UID matching of the above command, the following module is to be
plugged-in, in the running kernel, if not already present.
# insmod ipt_owner

You may examine the available modules, in your free time, in the
[ /lib/modules/2.4.18-bf2.4/kernel/net/ipv4/netfilter/ ] directory.


Assignment-6:
Pull down the firewall..

# /etc/init.d/iptables clear

End of Assignment-6.

---------------------------------