Using catalogs: /etc/sgml/sgml-docbook-4.1.cat Using stylesheet: /usr/share/sgml/docbook/dsssl-stylesheets/html/ldp.dsl Working on: /home/joeg/misc/linif/iptc/iptc.sgml Linux Security

Linux Security

v0.1, 23 October 2002

This document includes the class notes and presentation material used to teach a basic 8 session class on Linux Security. The bulk of the class involves IP Tables. The text for the class is "Linux Firewalls" 2nd Edition by Robert L. Ziegler ISBN# 0-7357-1099-6.


Table of Contents
1. Session 1 - Introduction
1.1. What a firewall can do
1.2. Default Policies
1.3. Built-in Chains
1.4. Demonstration - Simple IP Tables Rules for a Single System
2. Session 2 - IP Tables Syntax
2.1. Review Last Session
2.2. Allowing SSH Access to the Local Machine
2.3. List Command Options
2.4. Source and Destination Match
2.5. User Defined Chains
2.6. ICMP Filtering and Logging
2.7. The Help Command
3. Session 3 - IP Tables Forwarding and Network Address Translation (NAT)
3.1. Simple Forwarding Example
3.2. Adding a Webserver
3.3. Reducing Spoofing Risks
3.4. Establishing a DMZ Zone
3.5. Network Address Translation
3.6. Masquerading Packets - A Form of Source NAT
3.7. Considerations for Large Networks
3.8. Typical Dial Up Masquerade Case
3.9. Destination Network Address Translation (DNAT)
3.10. Local Redirection
4. Session 4 - Iptables Optimization and Debugging.
4.1. Optimizing iptables
4.2. Debugging iptables
4.3. IPSec (FreeS/WAN) and iptables
5. Session 5 - iptables and Multiple Networks/DMZ
5.1. Small Organization Setup
5.2. Three Machine Example
5.3. Example Script 1
5.4. Multiple IP Example
5.5. Example Script 2
5.6. Example with IPSec
5.7. Example Script 3
5.8. Summary

1. Session 1 - Introduction

1.1. What a firewall can do

Some source address spoofing
Useful information revealed in response to port scans
Malformed broadcast packets used to identify UNIX systems
Some forms of network mapping
Some denial-of-service attacks
Source-routed packets
Some forms of fragmentation bombs
Local mistakes that affect remote sites
Access to private LAN services
Additional protection against local server misconfigurations


1.2. Default Policies

Two main options:

  1. Deny everything by default and explicitly allow selected packets through.

  2. Accept everything by default and explicitly deny selected packets.

Deny everything is best - it protects against unanticipated dangers.


1.3. Built-in Chains

  1. Input - Filtering packets received by the interface

  2. Forward - Filtering packets that pass through the interface

  3. Output - Filtering packets that are sent by the interface

In general, packets that do not match our rules are dropped. Responses to invalid packets just increase network traffic and possibly give an attacker more information.


1.4. Demonstration - Simple IP Tables Rules for a Single System

A single system can be secured quite simply using a simple rule set. With IP Tables installed on a system a few simple commands are all that is needed to lock down the system.


1.4.1. Port Scanning using nmap

First we use the nmap command to scan the system. We use nmapfe which is a GUI front end to nmap. The result of the scan shows open ports.


1.4.2. IP Tables List Command

The first iptables command we will use is the list command:

					# iptables --list --verbose
	
					Chain INPUT (policy DROP 4989 packets, 215K bytes)
					 pkts bytes target     prot opt in     out     source               destination         
	
					Chain FORWARD (policy DROP 0 packets, 0 bytes)
					 pkts bytes target     prot opt in     out     source               destination         
	
					Chain OUTPUT (policy ACCEPT 504 packets, 30837 bytes)
					 pkts bytes target     prot opt in     out     source               destination         
				
This command lists the current rule set. We see the three built-in chains along with their default policy.

Each IP Tables command has two versions a shorthand version and a verbose version. We will use the verbose command in our examples and then show the shorthand version also. It may be a good idea for you to learn the verbose version first and then learn the shortcuts. The shorthand version of the list command is:

					# iptables -L -v
				
The verbose versions all use a double dash "--" and the shorthand versions use a single dash "-".


1.4.3. IP Tables Flush Command

If there are any rules listed we first need to clear them. To do that we use the flush command:

					iptables --flush
				

The shorthand version of the flush command is:

					iptables -F
				


1.4.4. IP Tables Policy Command

Next we set the default policy for each of the chains:

					iptables --policy INPUT DROP
					iptables --policy FORWARD DROP
					iptables --policy OUTPUT DROP
				
This sets our overall policy to drop every packet that we don't explicitly allow.

The shorthand version of the policy command is:

					# iptables -P INPUT DROP
				

The system is very secure now. By re-running nmap we see that the machine does not even show up on the network now. The system can't access the outside world either, however.

					# ping localhost
				
The machine can't even ping itself now.


1.4.5. Open the Loopback Interface

Next we open up the loopback interface for all internal traffic.

					iptables --append INPUT  --in-interface  lo --jump ACCEPT
					iptables --append OUTPUT --out-interface lo --jump ACCEPT
				

The shorthand version of these commands is:

					iptables -A INPUT  -i lo -j ACCEPT
					iptables -A OUTPUT -o lo -j ACCEPT
				

We can see that "ping localhost" does work now.

The process of opening the loopback interface introduces us to the append chain command. The --in-interface|-i and --out-interface|-o are basic match operations. If no interface is specified, all interfaces are implied. The --jump|-j command accepts ACCEPT, DROP, or a user-defined chain.


1.4.6. Allow Connections Initiated by the Machine

To be able to access the outside world we need to allow connections that the machine initiates and those that are related to the machine initiated ones.

					iptables --append OUTPUT --out-interface eth0 --jump ACCEPT
					iptables --append INPUT  --match state --state ESTABLISHED,RELATED --jump ACCEPT
				

The shorthand version of these commands is:

					iptables -A OUTPUT -o eth0 -j ACCEPT
					iptables -A INPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
				

The machine is now able to access the outside world.

New syntax in the above commands are the --match|-m command. The "-m state" tells iptables that we are going to use the match extensions module to check the state. The "--state ESTABLISHED,RELATED" part is a parameter that tells the states we want to accept. Legal values also include NEW and INVALID.


2. Session 2 - IP Tables Syntax

2.1. Review Last Session

We will start by quickly reviewing the last session's demo. This will set up our demo machine for us to continue learning the syntax for the iptables program.


2.2. Allowing SSH Access to the Local Machine

We now continue the demo from the last session to keep building our knowledge of iptables syntax.

We will now open up our demo machine to allow ssh access from other machines. This will introduce a little new syntax and allow us to show the remaining demo from one machine.

This single command should do it since we already have related and established connections accepted and connection tracking going.

				iptables -A INPUT -i eth0 \
	 				--protocol tcp --source-port 1024:65535 --destination-port 22 \
					-m state --state NEW -j ACCEPT
			
The abbreviated version is:
				iptables -A INPUT -i eth0 \
					-p tcp --sport 1024:65535 --dport 22 \
					-m state --state NEW -j ACCEPT
			

The new syntax in this command is the --protocol|-p match operation. Here we are specifying the TCP protocol. The --source-port|-sport is a parameter that matches source ports of the specified value 1024-65535. The --destination-port|--dport is a parameter that matches the destination ports specified which in this case is 22, the ssh port.

One should also note that lines that are too long are continued using a "\".


2.3. List Command Options

The list command with the verbose option lists the number of packets and bytes associated with each rule or policy. These counters can be cleared by:

				iptables --zero
			
The abbreviated version is:
				iptables -Z
			
The zero function can be combined with the list function:
				iptables -Z -L -v
			
This lists first then clears the counters.

The list command has an option to show the line number for each rule:

				iptables --list --line-numbers
			
There is no abbreviated version that I know of. Line numbers are handy when deleting a specific rule.

The list command has an option to list ports and IP addresses numerically, rather than by name:

				iptables --list --numeric
			
The abbreviated version is:
				iptables -L -n
			

If you are doing much listing in iptables an alias is nice:

				alias 'il=iptables -L -v --line-numbers'
			
This is what I like (and will use from now on).


2.4. Source and Destination Match

Listing the rules we can see that the earlier rule we put in to allow ssh shows a destination of "anywhere". We can tighten this up by specifying a destination as shown in the following command:

			iptables -A INPUT -i eth0 \
			-p tcp --sport 1024:65535 --destination 192.168.10.2 --dport 22 \
			-m state --state NEW -j ACCEPT
		
The abbreviated version is:
			iptables -A INPUT -i eth0 \
			-p tcp --sport 1024:65535 -d 192.168.10.2 --dport 22 \
			-m state --state NEW -j ACCEPT
		
Now we see our list shows two commands:
	Chain INPUT (policy DROP 11 packets, 2611 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	1       26  1692 ACCEPT     all  --  lo     any     anywhere             anywhere           
	2     1072  258K ACCEPT     all  --  any    any     anywhere             anywhere           state RELATED,ESTABLISHED 
	3        1    60 ACCEPT     tcp  --  eth0   any     anywhere             anywhere           tcp spts:1024:65535 dpt:ssh state NEW 
	4        0     0 ACCEPT     tcp  --  eth0   any     anywhere             insideguy          tcp spts:1024:65535 dpt:ssh state NEW 
		
Number 3 and 4 are actually the old and new versions of the same command. We really only want the latest one so we will use the delete command as follows:
			iptables --delete INPUT 3
		
The abbreviated version is:
			iptables -D INPUT 3
		
The chain is specified and the line number of the command to delete. Okay now the earlier command is gone. What we should have done is used the replace command:

	[root@insideguy root]# iptables -R INPUT 3 -i eth0 -p tcp --sport 1024:65535 -d insideguy --dport 22 -m state --state NEW -j ACCEPT
	[root@insideguy root]# 
	[root@insideguy root]# il
	Chain INPUT (policy DROP 18 packets, 4260 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	1       26  1692 ACCEPT     all  --  lo     any     anywhere             anywhere           
	2     1415  284K ACCEPT     all  --  any    any     anywhere             anywhere           state RELATED,ESTABLISHED 
	3        0     0 ACCEPT     tcp  --  eth0   any     anywhere             insideguy          tcp spts:1024:65535 dpt:ssh state NEW 
		
The replace commands verbose version is --replace as expected.

The chain and line number must be specified as with the delete command.

Also note that it is allowable to use names like "insideguy" instead of the ip address. Of course the name must be defined at the time it is used.

Specifying sources is as one would expect "--source|-s".


2.5. User Defined Chains

In addition to the INPUT, FORWARD, and OUTPUT chains, users may define their own chains. This has a real advantage for documentation. To add a chain the following command is used:

			iptables --new-chain OUTPUTDROP
		
The abbreviated version is:
			iptables -N OUTPUTDROP
		
A listing will show the new chain with no references. Since I really wanted to call the chain OUTACCEPT we will delete it using:
			iptables --delete-chain OUTPUTDROP
		
The abbreviated version is:
			iptables -X OUTPUTDROP
		
We then recreate it using:
			iptables -N OUTACCEPT
		
Now we will put two entries in the chain corresponding to the entries we currently have in the OUTPUT chain:
			iptables -A OUTACCEPT -o lo -j ACCEPT
			iptables -A OUTACCEPT -o eth0 -j ACCEPT
		
A listing now shows:
	Chain OUTPUT (policy DROP 0 packets, 0 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	1       34  2252 ACCEPT     all  --  any    lo      anywhere             anywhere           
	2     1651  299K ACCEPT     all  --  any    eth0    anywhere             anywhere           
	
	Chain OUTACCEPT (0 references)
	num   pkts bytes target     prot opt in     out     source               destination         
	1        0     0 ACCEPT     all  --  any    lo      anywhere             anywhere           
	2        0     0 ACCEPT     all  --  any    eth0    anywhere             anywhere           
		
The new chain is still unreferenced so we add the rule:
			iptables -I OUTPUT 1 -j OUTACCEPT
		
This command show the use of the insert command whose verbose version is --insert and requires the chain to be specified and optionally a line number. The default line number is 1 if it is not specified.

This command jumps to OUTACCEPT for anything coming to the OUTPUT chain. Now the output chain rules 2 and 3 are redundant so we delete them.

			iptables -D OUTPUT 2
			iptables -D OUTPUT 2
		
Note that rule 3 becomes rule 2 when 2 is deleted so we specify 2 in each case. One must be careful to list after each delete unless the rules furthest down in the list are deleted first. Now the listing looks as follows:
	Chain INPUT (policy DROP 41 packets, 9711 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	1       48  3232 ACCEPT     all  --  lo     any     anywhere             anywhere           
	2     2835  757K ACCEPT     all  --  any    any     anywhere             anywhere           state RELATED,ESTABLISHED 
	3        0     0 ACCEPT     tcp  --  eth0   any     anywhere             insideguy          tcp spts:1024:65535 dpt:ssh state NEW 
	
	Chain FORWARD (policy DROP 0 packets, 0 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	
	Chain OUTPUT (policy DROP 0 packets, 0 bytes)
	num   pkts bytes target     prot opt in     out     source               destination         
	1      421 71264 OUTACCEPT  all  --  any    any     anywhere             anywhere           
	
	Chain OUTACCEPT (1 references)
	num   pkts bytes target     prot opt in     out     source               destination         
	1       14   980 ACCEPT     all  --  any    lo      anywhere             anywhere           
	2      407 70284 ACCEPT     all  --  any    eth0    anywhere             anywhere           
		

We can still access the outside world now, so our new chain is working.


2.6. ICMP Filtering and Logging

A destination for a rule we haven't talked about is the LOG destination. It is used as follows:

			iptables -I INPUT 1 -p icmp -j LOG
		
Log entries are recorded in /var/log/messages so we open another window and tail the log:
			tail -n 50 -f /var/log/messages
		
Now from the other machine we ping and we can see the result in the log.

Additionally this command shows how to match the icmp protocol (udp would be done in a similar way.

One bit of syntax we haven't looked at is the NOT operator:

			iptables -R INPUT 1 -p ! tcp  -j LOG
		
This rule specifies that any protocol but tcp should be matched. When we ping we should again see the packets in the log.

			iptables -R INPUT 1 -p icmp --icmp-type echo-request -j LOG --log-prefix "--->>>"
		
We can match specific types of icmp packet such as an echo-request. The LOG destination also has parameters like the log prefix above.


2.7. The Help Command

By typing "iptables -h" all the iptables command and options are listed. There is a special case command "iptables -p icmp -h" that prints all the icmp protocol types that can be matched.


3. Session 3 - IP Tables Forwarding and Network Address Translation (NAT)

3.1. Simple Forwarding Example

This section is to present to the reader the FORWARD chain of the iptables filter table by example and is not comprehensive as a proper firewall setup should be.

Packet forwarding in Linux is provided at the kernel level. To forward packets you need to indicate to the kernel by placing a "1" (no quotes) in /proc/sys/net/ipv4/ip_forward like this:

			echo 1 > /proc/sys/net/ipv4/ip_forward
			

Packet forward filtering is controlled in iptables primarily on the FORWARD chain on the filter table. We can filter packets on the FORWARD chain just as we have on the INPUT and OUTPUT chains. The main difference to note is that while we are limited to filtering on the input interface on the INPUT chain and the output interface on the OUTPUT chain, we can filter on both input and output interfaces on the FORWARD chain.

A sample network on which forwarding might be performed is pictured below.

		                                                            |-----------|
		                                              |-------------| client .2 |
		                    eth0        eth1          |             |-----------|
		                       |--------|             |
		    Internet ----------| router |-------------|  192.168.1.0/24
		                       |--------|             |
		                10.0.0.1        .1            |             |-----------|
		                                              |-------------| client .3 |
							                    |-----------|
			
10.0.0.1 represents our public interface while the 192.168.1.0/24 network is our internal network. Assume all IPs in this diagram are public in nature.

Following our INPUT ruleset samples we start by setting the default policy to DROP.

			iptables -P FORWARD DROP
			

If all we wish to accomplish is to allow the client machines Internet access, the ruleset might look like the following.

			     iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
			     iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
			

This ruleset allows traffic from the internal network to flow out and traffic from the Internet to flow in only if it related to a connection already initiated by an internal machine. Any traffic not matching one of those rules is DROPPED to the bit bucket.


3.2. Adding a Webserver

If we want to host a web server on the 192.168.1.3 machine we can add an additional rule.

			     iptables -A FORWARD -i eth0 -o eth1 -p tcp -d 192.168.1.3 --port 80 -m state --state NEW -j ACCEPT
			

This rule now allows incoming connection to be initiated to the web server on port 80 using the tcp protocol. If we wanted to additionally run a mail server on the 192.168.1.2 machine we could add this rule.

			     iptables -A FORWARD -i eth0 -o eth1 -p tcp -d 192.168.1.2 --port 25 -m state --state NEW -j ACCEPT
			

Note the use of the state limiter. We simply want to add the acceptance of inbound connections with these rules. Doing this allows us to still block what iptables sees as "invalid" packets.


3.3. Reducing Spoofing Risks

We could further more reduce spoofing risks by inserting two rules that say packets appearing to be from our internal subnet can not enter on the router's eth0 interface and no packets not from our subnet enter via the eth1 interface.


			     iptables -I FORWARD -i eth0 -s 192.168.1.0/24 -j DROP
			     iptables -I FORWARD -i eth1 -s ! 192.168.1.0/24 -j DROP
			

The Linux kernel also has anti-spoofing measures built in that can be activated as desired (defense-in-depth). See additional files in /proc/sys/net/ipv4.

As a general rule, it is wise to monitor packets that hit the policy as they do not match any of the rules. This allows you to better monitor unusual and unexpected traffic and gives you a sense of whether or not you are covering all the bases.


			     iptables -A FORWARD -m limit --limit 1/second -j LOG
			


3.4. Establishing a DMZ Zone

In an alternate scenario where we wish to create a DMZ (Zone in which we will host services), we might have a setup that looks as follows.

			                                                            |----------------|
			                                              |-------------| private server |
			                                              |             |----------------|
			                                              |
			                                              |
			                                              |             |-----------|
			                                              |-------------| client .2 |
			                    eth0        eth1          |             |-----------|
			               10.0.0.1|--------| .1          |
			    Internet ----------| router |-------------|  192.168.1.0/24
			                       |--------|             |
			                           |eth2              |             |-----------|
			                           | .1               |-------------| client .3 |
			                           |                                |-----------|
			                       |-----------|
			                       | public    | 192.168.2.0/24 
			                       | server .2 | 
			                       |-----------|
			

10.0.0.1 represents our public interface while the 192.168.1.0/24 network is our internal network. 192.168.2.0/24 represents the DMZ network. Assume all IPs in this diagram are public in nature.

The basics ideas change little. We just need to allow for two three networks where the Internet is not trusted, our DMZ is not trusted by the internal network and the internal network is generally trusted. The main idea is to move our hosting server(s) or most vulnerable to a direct attack to a separate network. Divide to resist being conquered.


			     iptables -P FORWARD DROP
			
			     iptables -A FORWARD -i ! eth0 -o eth0 -j ACCEPT
			     iptables -A FORWARD -i eth1   -o eth2 -j ACCEPT
			     iptables -A FORWARD -i eth0   -o ! eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
			     iptables -A FORWARD -i eth2   -o eth1   -m state --state ESTABLISHED,RELATED -j ACCEPT
			     iptables -A FORWARD -i eth0   -o eth2   -p tcp -d 192.168.1.2 --port 25,80   -m state --state NEW -j ACCEPT
			     iptables -I FORWARD -i eth0   -s 192.168.1.0/24   -j DROP
			     iptables -I FORWARD -i eth0   -s 192.168.2.0/24   -j DROP
			     iptables -I FORWARD -i eth1   -s ! 192.168.1.0/24 -j DROP
			     iptables -I FORWARD -i eth2   -s ! 192.168.2.0/24 -j DROP
			
			

The largest difficulty to overcome when you move to three or more networks is dealing with all the potential cross traffic patterns. As you can see above, it adds a few rules beyond simply moving the server(s). There are limited security gains from this type of configuration but are beyond the scope of this demonstration.


3.5. Network Address Translation

In this section we will cover NAT (Network Address Translation). NAT is currently defined in RFC 3022 and was created as a means to alleviate the shortage of public Internet addresses until IPv6 was implemented. It has sense become a permanent fixture as the time frame for IPv6 implementation stretches forward indefinitely. NAT rules reside on the PREROUTING and POSTROUTING chains of the NAT table.

There are several forms of NAT. SNAT (the more common implementation) allows for the source address of a packet to be modified and is on the POSTROUTING chain while DNAT (Destination NAT) deals with the destination address and is on the PREROUTING chain.

It is worth noting at this point that NAT simply alters the packets. The actual job of filtering belongs to the FORWARD chain on the filter table.


3.6. Masquerading Packets - A Form of Source NAT

Most Linux users who have networks at home are familiar with Masquerading and/or SNAT (Source NAT). SNAT provides the ability to use a series of private addresses and allow them public network access. This is by no means the only use for SNAT but by far is the typical usage.

Here is our sample network:

			                                                            |-----------|
			                                              |-------------| client .2 |
			                    eth0        eth1          |             |-----------|
			                       |--------|             |
			    Internet ----------| router |-------------|  192.168.1.0/24
			                       |--------|             |
			          204.228.204.28        .1            |             |-----------|
			                                              |-------------| client .3 |
								                    |-----------|
			

We wish to provide Internet access to our privately addressed clients using our single public *STATIC* IP.


			     iptables -P FORWARD DROP
			
			     iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
			     iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
			     iptables -I FORWARD -i eth0 -s 192.168.1.0/24 -j DROP
			     iptables -I FORWARD -i eth1 -s ! 192.168.1.0/24 -j DROP
			     iptables -A FORWARD -m limit --limit 1/second -j LOG
			
			     iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28
			

As previously mentioned, we have to allow for forwarding on the FORWARD chain.


3.7. Considerations for Large Networks

Note that for large networks, we may wish to use several IPs to SNAT a large number of private IPs.


			     iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28 - 204.228.204.29
			

iptables will attempt to match the outgoing port on the --to-source IP to the original outgoing port on the client machine if possible. If we so desired we could limit the ports that outgoing connections are mapped to like so.


			     iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28:20000-30000
			

It is worth noting that since most of the notation usable on the filter table chains is valid on the nat table too, we can do a one to one IP mapping if we so desired.


			     iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.2 -j SNAT --to-source 204.228.204.28
			     iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.29
			

Here, we give our 192.168.1.2 its own public IP and place everyone else on the second public IP. This works both where we have multiple public routes and where IP aliasing takes place on a public interface.


3.8. Typical Dial Up Masquerade Case

If we did not have a static IP such as those who dial in to an ISP or the where the ISP uses DHCP over DSL/wireless we would need to use the special case masquerade SNAT.

			                                                            |-----------|
			                                              |-------------| client .2 |
			                    ppp0        eth0          |             |-----------|
			                       |--------|             |
			    Internet ----------| router |-------------|  192.168.1.0/24
			                       |--------|             |
			                    IP?         .1            |             |-----------|
			                                              |-------------| client .3 |
								                    |-----------|
			


			     iptables -P FORWARD DROP
			
			     iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT
			     iptables -A FORWARD -i ppp0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
			     iptables -I FORWARD -i ppp0 -s 192.168.1.0/24 -j DROP
			     iptables -I FORWARD -i eth1 -s ! 192.168.1.0/24 -j DROP
			     iptables -A FORWARD -m limit --limit 1/second -j LOG
			
			     iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
			
			

While you do not specify an IP (how can you if you do not know what it will be?) you can still use the port notation to limit the outgoing ports on ppp0 on which masquerading will take place.


			     iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE --to-ports 20000-30000
			

If you know your external address, SNAT provides better response times since the masquerade code must lookup the external IP on each packet.


3.9. Destination Network Address Translation (DNAT)

DNAT, on the other hand, provides us a way to let the public IP world into our private IP space in a limited fashion. We can host services on a private IP host and have the firewall redirect incoming packets to the private host.

Given our network.

			
			                                                            |-----------|
			                                              |-------------| client .2 |
			                    eth0        eth1          |             |-----------|
			                       |--------|             |
			    Internet ----------| router |-------------|  192.168.1.0/24
			                       |--------|             |
			          204.228.204.28        .1            |             |-----------|
			                                              |-------------| client .3 |
								                    |-----------|
			
			

Should we want to host a webserver on the 192.168.1.2 client, we would write the following ruleset.

			
			     iptables -P FORWARD DROP
			
			     iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
			     iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
			     iptables -I FORWARD -i eth0 -s 192.168.1.0/24 -j DROP
			     iptables -I FORWARD -i eth1 -s ! 192.168.1.0/24 -j DROP
			     iptables -A FORWARD -m limit --limit 1/second -j LOG
			
			     iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28
			
			     iptables -t nat -A PREROUTING  -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80
			
			

Now we can get out on the private IP clients an we can run our public webserver on the 192.168.1.2 private host.


3.10. Local Redirection

DNAT also has a special case where we can redirect locally. We can grab all traffic coming in on port 80 and redirect it to 3389 (squid). Using this we can transparently proxy and/or filter web traffic through squid with no client configuration required.

Stock DNAT and its special case REDIRECT can also be used on the nat table OUTPUT chain to redirect the LOCAL machine's outbound traffic.


4. Session 4 - Iptables Optimization and Debugging.

4.1. Optimizing iptables

iptables allows for very complex and lengthy rulesets. Improper rule structure can lead to inefficiency in your packet filtering system which can in turn decrease effective bandwidth and serving capabilities. It is important that you carefully consider the order and structure of your packet filter layout.

The ultimate goal of packet filtering is to control and limit traffic to only that which you desire to accept, send, and forward. The secondary goal is to get each packet out of iptables as soon as possible by placing the packet on an ACCEPT or DROP target. While secondary, inefficiencies in your iptables structure can render the packet filtering capabilities useless as effectively throttling your bandwidth can run off your potential users and/or customers.

To the end of goal two, there are several techniques that can be applied. iptables allows you to create your own chains and add them as targets from rules on other (including the default set of) chains. This allows us to create a shallow, wide decision tree instead of a deep and narrow. While keeping in mind that if a packet gets incorrectly filtered, the whole system is useless, the shallower a decision tree, the faster the packets will be filtered.

Example 1a. (FORWARD chain):

		Packet start
         eth0 (External) -
                         |
                         + Is the packet from an outside IP?
                        / \
                      Yes No - DROP
                       |
                       |
          ACCEPT -YES- + Is the packet tcp and to port 25 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet tcp and to port 53 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet udp and to port 53 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet tcp and to port 80 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet tcp and to port 110 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet tcp and to port 143 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet tcp and to port 443 and a new connection?
                      NO
                       |
          ACCEPT -YES- + Is the packet icmp and of the type ICMP_ECHOREPLY?
                      NO
                       |
          ACCEPT -YES- + Is the packet icmp and of the type ICMP_UNREACH?
                      NO
                       |
          ACCEPT -YES- + Is the packet icmp and of the type ICMP_TIMXCEED?
                      NO
                       |
          ACCEPT -YES- + Is the packet icmp and of the type ICMP_SOURCEQUENCH?
                      NO
                       |
          ACCEPT -YES- + Is the part of an ESTABLISHED or RELATED connection?
                      NO
                       |
                       + LOG packets here.
                       |
                    Policy - DROP
			
Example 1b. (FORWARD chain):
                   Packet start
         eth0 (External) -
                         |
                         + Is the packet from an outside IP?
                        / \
                      Yes No - DROP
                       |
          ACCEPT -YES- + Is it part of an ESTABLISHED or RELATED connection?
                      NO
                       |
    Is the packet tcp? + TCP_CHAIN -YES- --------------------------------------------- 
                      NO                                                             |
                       |                                                ACCEPT -YES- + port 25,53,80,110,143,443 and a new connection?
    Is the packet udp? + UDP_CHAIN -YES- -----------------------------               NO
                      NO                                             |               |
                       |                                             |             RETURN
   Is the packet icmp? + ICMP_CHAIN -YES- -------|      ACCEPT -YES- + port 53 and new?
                      NO                         |                  No
                       |                         |                   |
                       + LOG packets here.       |                RETURN
                       |                         |
                    Policy - DROP                ---------------------
                                                                     |
                                                        ACCEPT -YES- + type ICMP_ECHOREPLY?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                                  RETURN
			

The changes to the second ruleset give us several optimizations. First, we will receive more related traffic than anything else, so we move the related rule to be right after our spoofing rule. Most of our packets will be targeted by rule two instead of rule 13. Second, we have broken out the TCP, UDP and ICMP rules. What this allows us to to prevent ICMP packets from wasting time on the TCP or UDP new connection rules, UDP from wasting time on TCP and ICMP new connection rules and so on. Ultimately we have shortened the longest possible path from 15 to 11 and made it so that the large majority of packets are targeted in a lot less time.


4.2. Debugging iptables

Debugging iptables rulesets is no different that any other debugging process. When in doubt, print, or in this case, log. While it is wise to keep logging to a minimum for performance reasons, well placed logging rules can be beneficial for tracing the travel of a misdirected packet and for monitoring the effectiveness of rulesets in section and their entirety.

We will start with our optimized ruleset and make a few minor changes. Example 2 (FORWARD chain):

	                   Packet start
	         eth0 (External) -
                         |
                         + Is the packet from an outside IP?
                        / \
                      Yes No - DROP
                       |
          ACCEPT -YES- + Is the part of an ESTABLISHED or RELATED connection?
                      NO
                       |
    Is the packet tcp? + TCP_CHAIN -YES- ------------------------------------------------- 
                      NO                                                                 |
                       |                                                    ACCEPT -YES- + port 25,53,80,110,143,443 and a new connection?
    Is the packet udp? + UDP_CHAIN -YES- -----------------------------                  NO
                      NO                                             |                   |
                       |                                             |                   + LOG packets with prefix "Bad TCP connreq: "
   Is the packet icmp? + ICMP_CHAIN -YES- --------|     ACCEPT -YES- + port 53 and new?  |
                      NO                          |                 No                  DROP
                       |                          |                  |
                       + LOG packets here with    |                  + LOG packets with prefix "Bad UDP connreq: "
                       | prefix "Unknown pkt: "   |                  |
                       |                          |                 DROP
                    Policy - DROP                 |
                                                  --------------------
                                                                     |
                                                        ACCEPT -YES- + type ICMP_ECHOREPLY?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                        ACCEPT -YES- + type ICMP_UNREACH?
                                                                    NO
                                                                     |
                                                                     + LOG packets with prefix "Bad UDP connreq: "
                                                                     |
                                                                    DROP
			

What we have done, is to add two additional rules to each branch end. By default, user created chains return the packet to the calling chain if the packet reaches the end of the target chain. The additional rules we added simply logs each packet if it reaches the end of a branch and then DROPs the packet right there.

Ultimately we have added no length to the travel of any single packet as they were all logged and DROPed by the FORWARD chains last rule and policy. What we gained was information placed in the logs telling us what type of unwanted packets we are DROPing. This is a quite regular "log and drop" scenario. It is worth noting that each logged packet includes all the details about the packet, so our example is bit redundant, but it does make spotting patterns easier when tailing the log file. Also, you can apply this log and drop to the end of any branch. If we branch to handle a special case server behind the firewall, we might be well suited to log unwanted packets to that server with a special prefix so we can easily spot them in the logs.

iptables allows us to place any number of log rules anywhere. Log rules can log packets for certain criteria or all packets in general as they obey all the same options, switches, and criteria as other rules.

We may have a ruleset with the following rule:

			     iptables -A INPUT -p udp --dport 137:138 -j ACCEPT  
			
and wonder why we are having problems with samba sharing files. By adding two log rules like so:
			     iptables -A INPUT -j LOG --log-prefix "Pre SMB: "
			     iptables -A INPUT -p udp --dport 137:138 -j ACCEPT
			     iptables -A INPUT -j LOG --log-prefix "Post SMB: "
			

We might notice a pattern of port 139 UDP packets that occurs in sync with ports 137 and 138 that cause log entries that start with "Pre SMB: ", but while we also have port 139 packets duplicated in the logs with "Post SMB: ". A quick review and change of our smb entry (sans log rules) to:

			     iptables -A INPUT -p udp --dport 137:139 -j ACCEPT
			
fixes our problem.

A better example might be a ruleset like the following:

     Internal Network: 192.168.1.0/24
     External Interface: eth0 - 204.228.204.28
     External Interface: eth1 - 192.168.1.1
     Mail Server: 192.168.1.3
     Web Server:  192.168.1.4
			

Starting ruleset:

     iptables -A INPUT   -i lo   -j ACCEPT
     iptables -A INPUT   -p icmp -j icmp_packets
     iptables -A INPUT   -p tcp  -j tcp_packets
     iptables -A INPUT   -p udp  -j udp_packets
     iptables -A INPUT   -d 204.228.204.28 -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A INPUT   -d 192.168.1.1    -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A INPUT   -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT INPT packet died: " --log-level 6
			
     iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
     iptables -A FORWARD -i eth0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j allowed_frwd
     iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A FORWARD -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT FRWD packet died: " --log-level 6
			
     iptables -A OUTPUT  -o lo -j lo_ntrfce
     iptables -A OUTPUT  -p udp -m udp --sport 500 --dport 500 -j ACCEPT
     iptables -A OUTPUT  -s 204.228.204.28 -o eth0 -j ACCEPT
     iptables -A OUTPUT  -s 192.168.1.1    -o eth1 -j ACCEPT
     iptables -A OUTPUT  -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT OTPT packet died: " --log-level 6
			
     iptables -A allowed -p tcp -m tcp   --tcp-flags SYN,RST,ACK SYN -j ACCEPT
     iptables -A allowed -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A allowed -p tcp -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT allowed bad state: " --log-level 6
     iptables -A allowed -p tcp -j DROP
			
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport   25 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport  110 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport  143 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.4 --dport   81 -j ACCEPT
			
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  0 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  3 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  5 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type 11 -j ACCEPT
     iptables -A icmp_packets -i eth1   -p icmp -m icmp --icmp-type  8 -j ACCEPT
     iptables -A icmp_packets -i lo     -p icmp -m icmp --icmp-type  8 -j ACCEPT
			
     # This first rule here keeps Windows neighbors from packing my logs (DROP before log).
     iptables -A tcp_packets -p tcp -m tcp                                 --dport 137:139         -j DROP
     iptables -A tcp_packets -p tcp -m tcp -s 192.168.1.5   -d 192.168.1.1 --dport 22      -i eth1 -j allowed
     iptables -A tcp_packets -p tcp -m tcp -s 204.228.204.18               --dport 22      -i eth0 -j allowed
			
     iptables -A udp_packets -p udp -m udp                --sport   53                         -j ACCEPT
     iptables -A udp_packets -p udp -m udp                --sport  500 --dport 500             -j ACCEPT

     # Noise in the log prevention (DROP before log).
     iptables -A udp_packets -p udp -m udp                             --dport  67:68          -j DROP
     iptables -A udp_packets -p udp -m udp                             --dport 137:139         -j DROP
     iptables -A udp_packets -p udp -m udp                             --dport  1900   -i eth1 -j DROP
     iptables -A udp_packets -p udp -m udp                --sport 2301 --dport  2301   -i eth1 -j DROP
     iptables -A udp_packets -p udp -m udp -s 192.168.1.2              --dport 16024   -i eth1 -j DROP
			
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport   25  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:25
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  110  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:110
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  143  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:143
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport   80  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.4:80

     iptables -A PREROUTING -s ! 192.168.1.0/24 -i eth1 -j DROP
     iptables -A PREROUTING -s 192.168.1.0/24   -i eth0 -j DROP
			
     iptables -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28
			

Problem: The web server is not responding to our external guests, but does for the internal guests. Ruleset with logs rules added for examination of FORWARD packet travel.

     iptables -A INPUT   -i lo   -j ACCEPT
     iptables -A INPUT   -p icmp -j icmp_packets
     iptables -A INPUT   -p tcp  -j tcp_packets
     iptables -A INPUT   -p udp  -j udp_packets
     iptables -A INPUT   -d 204.228.204.28 -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A INPUT   -d 192.168.1.1    -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A INPUT   -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT INPT packet died: " --log-level 6

     iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
     iptables -A FORWARD -i eth0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j allowed_frwd
     iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A FORWARD -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT FRWD packet died: " --log-level 6
			
     iptables -A OUTPUT  -o lo -j lo_ntrfce
     iptables -A OUTPUT  -p udp -m udp --sport 500 --dport 500 -j ACCEPT
     iptables -A OUTPUT  -s 204.228.204.28 -o eth0 -j ACCEPT
     iptables -A OUTPUT  -s 192.168.1.1    -o eth1 -j ACCEPT
     iptables -A OUTPUT  -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT OTPT packet died: " --log-level 6
			
     iptables -A allowed -p tcp -m tcp   --tcp-flags SYN,RST,ACK SYN -j ACCEPT
     iptables -A allowed -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
     iptables -A allowed -p tcp -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT allowed bad state: " --log-level 6
     iptables -A allowed -p tcp -j DROP
			
     iptables -A allowed -p tcp -j LOG --log-prefix "FWD START: "
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport   25 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport  110 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.3 --dport  143 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.4 --dport   80 -j ACCEPT
     iptables -A allowed_frwd -i eth0 -p tcp -m tcp -d 192.168.100.4 --dport  443 -j ACCEPT
     iptables -A allowed -p tcp -j LOG --log-prefix "FWD END: "
			
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  0 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  3 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type  5 -j ACCEPT
     iptables -A icmp_packets           -p icmp -m icmp --icmp-type 11 -j ACCEPT
     iptables -A icmp_packets -i eth1   -p icmp -m icmp --icmp-type  8 -j ACCEPT
     iptables -A icmp_packets -i lo     -p icmp -m icmp --icmp-type  8 -j ACCEPT
			
     # This first rule here keeps Windows neighbors from packing my logs (DROP before log).
     iptables -A tcp_packets -p tcp -m tcp                                 --dport 137:139         -j DROP
     iptables -A tcp_packets -p tcp -m tcp -s 192.168.1.5   -d 192.168.1.1 --dport 22      -i eth1 -j allowed
     iptables -A tcp_packets -p tcp -m tcp -s 204.228.204.18               --dport 22      -i eth0 -j allowed
			
     iptables -A udp_packets -p udp -m udp                --sport   53                         -j ACCEPT
     iptables -A udp_packets -p udp -m udp                --sport  500 --dport 500             -j ACCEPT
     # Noise in the log prevention (DROP before log).
     iptables -A udp_packets -p udp -m udp                             --dport  67:68          -j DROP
     iptables -A udp_packets -p udp -m udp                             --dport 137:139         -j DROP
     iptables -A udp_packets -p udp -m udp                             --dport  1900   -i eth1 -j DROP
     iptables -A udp_packets -p udp -m udp                --sport 2301 --dport  2301   -i eth1 -j DROP
     iptables -A udp_packets -p udp -m udp -s 192.168.1.2              --dport 16024   -i eth1 -j DROP
			
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport   25  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:25
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  110  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:110
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  143  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.3:143
     iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport   80  -d 204.228.204.28 -j DNAT --to-destination 192.168.1.5:80
			
     iptables -A PREROUTING -s ! 192.168.1.0/24 -i eth1 -j DROP
     iptables -A PREROUTING -s 192.168.1.0/24   -i eth0 -j DROP

     iptables -A POSTROUTING -o eth0 -j SNAT --to-source 204.228.204.28
			

Greping the logs after a few external access attempts might return the following (sample edited for readability):

     grep "DPT=80" /var/log/messages | grep "IN=eth0 OUT=eth1"
			
     Nov 21 13:09:41 linif kernel: FWD START:	IN=eth0 
						OUT=eth1
						MAC=ff:ff:ff:ff:ff:ff:00:05:02:89:f9:bc:08:00
						SRC=204.228.204.18
						DST=192.168.100.5
						LEN=115
						TOS=0x00
						PREC=0x00
						TTL=64
						ID=12357
						PROTO=TCP
						SPT=4891
						DPT=80
						LEN=95

     Nov 21 13:09:41 linif kernel: FWD END:	IN=eth0
						OUT=eth1
						MAC=ff:ff:ff:ff:ff:ff:00:05:02:89:f9:bc:08:00
						SRC=204.228.204.18
						DST=192.168.100.5
						LEN=115
						TOS=0x00
						PREC=0x00
						TTL=64
						ID=12357
						PROTO=TCP
						SPT=4891
						DPT=80
						LEN=95
			

Inspection of these log entries tells us that we are blocking port 80 requests to 192.168.1.5!? Why are packets coming in on eth0 and leaving on eth1 trying to go to 192.168.1.5 when the server is on .4? Obviously we have a PREROUTING NAT error and a closer inspection of the PREROUTING chain shows that we are DNATing port 80 to 192.168.1.5. To fix this, we simply need to change the incorrect PREROUTING rule and drop the log rules we added that will eventually flood our logs with useless information.


4.3. IPSec (FreeS/WAN) and iptables

IPSec is becoming more popular as a security tool to link disparate networks. It allows for secured communications between hosts communicating on public networks. One of the requirements to run IPSec, however, is to be able to get the IPSec packets through your firewall. IPSec packets must pass unadulterated. This means that IPSec through NAT is not possible and that you cannot modify the packets in any way with your PREROUTING, POSTROUTING, and OUTPUT chains on the nat and mangle tables.

>From the FreeS/WAN documentation Filtering rules for IPsec packets The basic constraint is that an IPsec gateway must have packet filters that allow IPsec packets, at least when talking to other IPsec gateways:

			          UDP port 500 for IKE negotiations
			          protocol 50 if you use ESP encryption and/or authentication (the typical case)
			          protocol 51 if you use AH packet-level authentication
			
Your gateway and the other IPsec gateways it communicates with must be able to exchange these packets for IPsec to work. Firewall rules must allow UDP 500 and at least one of AH or ESP on the interface that communicates with the other gateway. For nearly all FreeS/WAN applications, you must allow UDP port 500 and the ESP protocol.

Here are the specific rules needed to create the following FreeS/WAN setup.

			     Network 1: 192.168.1.0/24 (north)  IP 204.228.204.18
			     Network 2: 192.168.2.0/24 (south)  IP 204.228.204.28
			

On both machines, eth0 is external, eth1 is internal. Each machine's eth1 is the network's .1 IP. Both internal networks are "trusted".

These are the rules for the firewall/NAT gateway on the north network.

     iptables -A INPUT -p 50 -s 204.228.204.18 -j ACCEPT
     iptables -A INPUT -p 51 -s 204.228.204.18 -j ACCEPT
     iptables -A INPUT -p udp -m udp -s 204.228.204.28 --sport 500 -d 204.228.204.18 --dport 500 -j ACCEPT
			
     iptables -A FORWARD -i ipsec0 -o eth1 -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT
     iptables -A FORWARD -i eth1 -o ipsec0 -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT
			
     iptables -A OUTPUT -p 50 -d 204.228.204.28 -j ACCEPT
     iptables -A OUTPUT -p 51 -d 204.228.204.28 -j ACCEPT
     iptables -A OUTPUT -p udp -m udp -s 204.228.204.18 --sport 500 -d 204.228.204.28 --dport 500 -j ACCEPT
			

These are the rules for the firewall/NAT gateway on the south network.

     iptables -A INPUT -p 50 -s 204.228.204.28 -j ACCEPT
     iptables -A INPUT -p 51 -s 204.228.204.28 -j ACCEPT
     iptables -A INPUT -p udp -m udp -s 204.228.204.18 --sport 500 -d 204.228.204.28 --dport 500 -j ACCEPT

     iptables -A FORWARD -i ipsec0 -o eth1 -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT
     iptables -A FORWARD -i eth1 -o ipsec0 -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT
			
     iptables -A OUTPUT -p 50 -d 204.228.204.18 -j ACCEPT
     iptables -A OUTPUT -p 51 -d 204.228.204.18 -j ACCEPT
     iptables -A OUTPUT -p udp -m udp -s 204.228.204.28 --sport 500 -d 204.228.204.18 --dport 500 -j ACCEPT
			


5. Session 5 - iptables and Multiple Networks/DMZ

5.1. Small Organization Setup

While constructing a firewall from iptables for a single host or for a single network may prove to be straight forward, handling multiple networks which may have disparate purposes may not be. The most common small organization scenario is a workstation network and a DMZ. The DMZ is where the organization's publicly accessed servers reside. The idea is to minimize the potential impact of a server compromise but still provide the servers some of the advantages of a gateway firewall.


5.2. Three Machine Example

For our example, we will start with a network of workstations and a network that houses our mail and web servers. For the purposes of this example assume all IPs are RFC globally routable (public). Both internally and externally, clients must connect to 192.168.2.2 and 192.168.2.3 for mail and web services respectively

			                           __________
			            192.168.0.254 |          | 192.168.1.1   Workstations
			   Internet --------------|  router  |------------- net 192.168.1.0
			                     eth0 |__________| eth1
			                                |
			                           eth2 | 192.168.2.1
			                           DMZ  |
			                                |              __________
			                                | 192.168.2.2 |          |
			                                |-------------|  mail    |
			                                |             |__________|
			                                |
			                                |              ----------
			                                | 192.168.2.3 |          |
			                                |-------------|  web     |
			                                              |__________|
			
			Notes:
			 * We trust all outbound traffic from our workstations. (eth1)
			 * We do NOT trust traffic on the public Internet and the DMZ. (eth0, eth2)
			

We want to allow our workstations full access to the world and full access to the servers as there may be private services (Apache to MySQL) or services only needed internally (IMAP, POP3). We want the world to be able to access the publicly offered services. The servers should have unfettered access to the world to obtain public services (updates, time, etc...). And finally, we need to allow established traffic in all directions.


5.3. Example Script 1

	 ### INPUT only deals with traffic directed TO the router.

	 # Filter untrusted traffic
	 iptables -A INPUT -i eth0 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth0 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth0 -p udp  -j udp_packets
	 iptables -A INPUT -i eth2 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth2 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth2 -p udp  -j udp_packets
	
	 # Allow implicitly trusted traffic.
	 iptables -A INPUT -i eth1 -j ACCEPT
	 iptables -A INPUT -i lo   -j ACCEPT
	
	 # Trust traffic we initiated from untrusted networks.
	 iptables -A INPUT -i eth0 -d 192.168.0.254 -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A INPUT -i eth2 -d 192.168.2.1   -m state --state RELATED,ESTABLISHED -j ACCEPT
	
	 # Log dropped traffic.
	 iptables -A INPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT INPUT packet died: " --log-level 6
	
	 ### OUTPUT only deals with traffic directed FROM the router.

	 # lo device traffic
	
	 iptables -A OUTPUT -s 127.0.0.1 -o lo -j ACCEPT
	 # These should not be needed, but I have had occasional back luck without them (YMMV).
	 iptables -A OUTPUT -s 192.168.0.254 -d 192.168.0.254 -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1   -d 192.168.1.1   -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1   -d 192.168.2.1   -o lo -j ACCEPT

	 # Allow outbound traffic over interfaces only if originating from the correct IP for that interface.
	 iptables -A OUTPUT -s 192.168.0.254 -o eth0 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1   -o eth1 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1   -o eth2 -j ACCEPT

	 # Log dropped traffic.
	 iptables -A OUTPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT OUTPUT packet died: " --log-level 6
	
	 ### Routed traffic.

	 # We trust traffic passing from the workstations to anywhere (source IP and device verified).
	 iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT

	 # We (for this example) are trusting server originating traffic heading to the public Internet.
	 iptables -A FORWARD -i eth2 -s 192.168.2.0/24 -o eth0 -j ACCEPT

	 # Allow inbound public server connection traffic (public initiating connections to servers).
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.2 -p tcp -m tcp --dport  25 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport  80 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport 443 -j ACCEPT

	 # Allow establish traffic to pass in any direction.
	 iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

	 # Log dropped traffic.
	 iptables -A FORWARD -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT FORWARD packet died: " --log-level 6

	 ### Filtered (inbound to the router directly) traffic
	 ## Manage the following TCP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A tcp_packets -p tcp -m tcp --dport 137:139 -j DROP

	 # Allow incoming port 22 for SSH connection for remote admin and incoming encrypted ppp tunnels.
	 iptables -A tcp_packets -p tcp -m tcp --dport 22      -j allowed
	
	 ## Validate potentially allowed tcp traffic.
	 iptables -A allowed -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT
	 iptables -A allowed -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A allowed -p tcp -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT allowed bad state: " --log-level 6
	 iptables -A allowed -p tcp -j DROP
	 
	 ## Manage the following ICMP traffic inbound to the router directly.
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 0 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 3 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 5 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT
	 iptables -A icmp_packets -i eth1 -p icmp -m icmp --icmp-type 8 -j ACCEPT
	 iptables -A icmp_packets -i lo -p icmp -m icmp --icmp-type 8 -j ACCEPT
	
	 ## Manage the following UDP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A udp_packets -p udp -m udp --dport 137:139 -j DROP

	 # Allow potentially untracked valid DNS traffic.
	 iptables -A udp_packets -p udp -m udp --sport 53 -j ACCEPT
			


5.4. Multiple IP Example

In the spirit of demonstrating common scenarios, here is the same example, but with eth1 and eth2 sporting private IPs while eth0 is the router's public interface. In this example assume all 192.168.0.0 address are RFC non-routable while 10.0.0.254 will be routable. The router of course will route between the two private networks within the constraints of the firewall. Internally, clients must connect to 192.168.2.2 and 192.168.2.3 for mail and web services respectively while external users connect to 10.0.0.254 for mail and web services. While logically, the internal clients could connect to 10.0.0.254 for all services, I have, again, had bad luck with such a configuration. A better solution with one virtual interface internally would be to DNAT all services from 192.168.1.1 also. The best solution would simply be to maintain an internal DNS server on the 192.168.1.0 network mapping the names to the actual unNAT'd IPs.

			                           __________
			               10.0.0.254 |          | 192.168.1.1   Workstations
			   Internet --------------|  router  |------------- net 192.168.1.0
			                     eth0 |__________| eth1
			                                |
			                           eth2 | 192.168.2.1
			                           DMZ  |
			                                |              __________
			                                | 192.168.2.2 |          |
			                                |-------------|  mail    |
			                                |             |__________|
			                                |
			                                |              ----------
			                                | 192.168.2.3 |          |
			                                |-------------|  web     |
			                                              |__________|
			
			Notes:
			 * We trust all outbound traffic from our workstations. (eth1)
			 * We do NOT trust traffic on the public Internet and the DMZ. (eth0, eth2)
			
			
The same desires exist here as with the above example.


5.5. Example Script 2

	 ### INPUT only deals with traffic directed TO the router.

	 # Filter untrusted traffic
	 iptables -A INPUT -i eth0 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth0 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth0 -p udp  -j udp_packets
	 iptables -A INPUT -i eth2 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth2 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth2 -p udp  -j udp_packets

	 # Allow implicitly trusted traffic.
	 iptables -A INPUT -i eth1 -j ACCEPT
	 iptables -A INPUT -i lo   -j ACCEPT

	 # Trust traffic we initiated from untrusted networks.
	 iptables -A INPUT -i eth0 -d 10.0.0.254  -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A INPUT -i eth2 -d 192.168.2.1 -m state --state RELATED,ESTABLISHED -j ACCEPT

	 # Log dropped traffic.
	 iptables -A INPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT INPUT packet died: " --log-level 6
	
	 ### OUTPUT only deals with traffic directed FROM the router.

	 # lo device traffic
	 iptables -A OUTPUT -s 127.0.0.1 -o lo -j ACCEPT

	 # These should not be needed, but I have had occasional back luck without them (YMMV).
	 iptables -A OUTPUT -s 10.0.0.254  -d 10.0.0.254  -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1 -d 192.168.1.1 -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1 -d 192.168.2.1 -o lo -j ACCEPT

	 # Allow outbound traffic over interfaces only if originating from the correct IP for that interface.
	 iptables -A OUTPUT -s 10.0.0.254  -o eth0 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1 -o eth1 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1 -o eth2 -j ACCEPT

	 # Log dropped traffic.
	 iptables -A OUTPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT OUTPUT packet died: " --log-level 6
	
	 ### Routed traffic.

	 # We trust traffic passing from the workstations to anywhere (source IP and device verified).
	 iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -j ACCEPT

	 # We (for this example) are trusting server originating traffic heading to the public Internet.
	 iptables -A FORWARD -i eth2 -s 192.168.2.0/24 -o eth0 -j ACCEPT

	 # Allow inbound public server connection traffic (public initiating connections to servers).
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.2 -p tcp -m tcp --dport  25 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport  80 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport 443 -j ACCEPT

	 # Allow establish traffic to pass in any direction.
	 iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

	 # Log dropped traffic.
	 iptables -A FORWARD -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT FORWARD packet died: " --log-level 6
	
	 ### Filtered (inbound to the router directly) traffic
	 ## Manage the following TCP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A tcp_packets -p tcp -m tcp --dport 137:139 -j DROP

	 # Allow incoming port 22 for SSH connection for remote admin and incoming encrypted ppp tunnels.
	 iptables -A tcp_packets -p tcp -m tcp --dport 22      -j allowed
	
	 ## Validate potentially allowed tcp traffic.
	 iptables -A allowed -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT
	 iptables -A allowed -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A allowed -p tcp -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT allowed bad state: " --log-level 6
	 iptables -A allowed -p tcp -j DROP
	 
	 ## Manage the following ICMP traffic inbound to the router directly.
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 0 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 3 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 5 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT
	 iptables -A icmp_packets -i eth1 -p icmp -m icmp --icmp-type 8 -j ACCEPT
	 iptables -A icmp_packets -i lo -p icmp -m icmp --icmp-type 8 -j ACCEPT
	
	 ## Manage the following UDP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A udp_packets -p udp -m udp --dport 137:139 -j DROP

	 # Allow potentially untracked valid DNS traffic.
	 iptables -A udp_packets -p udp -m udp --sport 53 -j ACCEPT
	
	 ### Set up DNAT for incoming connection requests.
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  25 -j DNAT --to-destination 192.168.2.2:25
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  80 -j DNAT --to-destination 192.168.2.3:80
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.2.3:443
				


5.6. Example with IPSec

Multiple workstation networks with DMZ. One workstation network connected via IPSec.

			                           __________
			               10.0.0.254 |          | 192.168.1.1   Workstations
			   Internet --------------|  router  |------------- net 192.168.1.0
			              |      eth0 |__________| eth1
			              |                 |
			              |            eth2 | 192.168.2.1
			       net 192.168.3.0      DMZ |
			            ipsec0              |              __________
			                                | 192.168.2.2 |          |
			                                |-------------|  mail    |
			                                |             |__________|
			                                |
			                                |              ----------
			                                | 192.168.2.3 |          |
			                                |-------------|  web     |
			                                              |__________|
			
			Notes:
			 * We trust all outbound traffic from our workstations. (eth1, ipsec0)
			 * We do NOT trust traffic on the public Internet and the DMZ. (eth0, eth2)
			

The same desires exist here as with the above examples with the addition of another IPsec connected trusted network. Note that the IPSec machines cannot talk to the router itself. Even if the firewall allowed it, thick communication is impossible due to the limitations of IPSec via FreeS/WAN. Therefore, the rules to allow such communications have been left out for simplicity of maintenance. We have the IPSec connected machine connecting to a DNS server that maps the server names to their real IPs as with the original workstation network.


5.7. Example Script 3

	 ### INPUT only deals with traffic directed TO the router.

	 # Filter untrusted traffic
	 iptables -A INPUT -i eth0 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth0 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth0 -p udp  -j udp_packets
	 iptables -A INPUT -i eth2 -p icmp -j icmp_packets
	 iptables -A INPUT -i eth2 -p tcp  -j tcp_packets
	 iptables -A INPUT -i eth2 -p udp  -j udp_packets

	 # Allow incoming IPSec authentication packets.
	 iptables -A INPUT -p 50 -j ACCEPT
	 iptables -A INPUT -p 51 -j ACCEPT

	 # Allow implicitly trusted traffic.
	 iptables -A INPUT -i eth1 -j ACCEPT
	 iptables -A INPUT -i lo   -j ACCEPT

	 # Trust traffic we initiated from untrusted networks.
	 iptables -A INPUT -i eth0 -d 10.0.0.254  -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A INPUT -i eth2 -d 192.168.2.1 -m state --state RELATED,ESTABLISHED -j ACCEPT

	 # Log dropped traffic.
	 iptables -A INPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT INPUT packet died: " --log-level 6
	
	 ### OUTPUT only deals with traffic directed FROM the router.

	 # lo device traffic
	 iptables -A OUTPUT -s 127.0.0.1 -o lo -j ACCEPT

	 # Allow outgoing IPSec authentication packets.
	 iptables -A OUTPUT -p 50 -j ACCEPT
	 iptables -A OUTPUT -p 51 -j ACCEPT
	 iptables -A OUTPUT -p udp -m udp --sport 500 --dport 500 -j ACCEPT

	 # These should not be needed, but I have had occasional back luck without them (YMMV).
	 iptables -A OUTPUT -s 10.0.0.254  -d 10.0.0.254  -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1 -d 192.168.1.1 -o lo -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1 -d 192.168.2.1 -o lo -j ACCEPT

	 # Allow outbound traffic over interfaces only if originating from the correct IP for that interface.
	 iptables -A OUTPUT -s 10.0.0.254  -o eth0 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.1.1 -o eth1 -j ACCEPT
	 iptables -A OUTPUT -s 192.168.2.1 -o eth2 -j ACCEPT

	 # Log dropped traffic.
	 iptables -A OUTPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT OUTPUT packet died: " --log-level 6
	
	 ### Routed traffic.

	 # We trust traffic passing from the workstations to anywhere (source IP and device verified).
	 iptables -A FORWARD -i eth1   -s 192.168.1.0/24 -j ACCEPT
	 iptables -A FORWARD -i ipsec0 -s 192.168.3.0/24 -j ACCEPT

	 # We (for this example) are trusting server originating traffic heading to the public Internet.
	 iptables -A FORWARD -i eth2 -s 192.168.2.0/24 -o eth0 -j ACCEPT

	 # Allow inbound public server connection traffic (public initiating connections to servers).
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.2 -p tcp -m tcp --dport  25 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport  80 -j ACCEPT
	 iptables -A FORWARD -i eth0 -o eth2 -d 192.168.2.3 -p tcp -m tcp --dport 443 -j ACCEPT

	 # Allow establish traffic to pass in any direction.
	 iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

	 # Log dropped traffic.
	 iptables -A FORWARD -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT FORWARD packet died: " --log-level 6
	
	 ### Filtered (inbound to the router directly) traffic
	 ## Manage the following TCP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A tcp_packets -p tcp -m tcp --dport 137:139 -j DROP

	 # Allow incoming port 22 for SSH connection for remote admin and incoming encrypted ppp tunnels.
	 iptables -A tcp_packets -p tcp -m tcp --dport 22      -j allowed
	
	 ## Validate potentially allowed tcp traffic.
	 iptables -A allowed -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT
	 iptables -A allowed -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
	 iptables -A allowed -p tcp -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPT allowed bad state: " --log-level 6
	 iptables -A allowed -p tcp -j DROP
	 
	 ## Manage the following ICMP traffic inbound to the router directly.
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 0 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 3 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 5 -j ACCEPT
	 iptables -A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT
	 iptables -A icmp_packets -i eth1 -p icmp -m icmp --icmp-type 8 -j ACCEPT
	 iptables -A icmp_packets -i lo -p icmp -m icmp --icmp-type 8 -j ACCEPT
	
	 ## Manage the following UDP traffic inbound to the router directly.

	 # Drop all SMB traffic to prevent log flooding from obvious useless dropped traffic.
	 iptables -A udp_packets -p udp -m udp --dport 137:139 -j DROP

	 # Allow potentially untracked valid DNS traffic.
	 iptables -A udp_packets -p udp -m udp --sport  53             -j ACCEPT

	 # Allow IPSec authentication traffic.
	 iptables -A udp_packets -p udp -m udp --sport 500 --dport 500 -j ACCEPT
	
	 ### Set up DNAT for incoming connection requests.
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  25 -j DNAT --to-destination 192.168.2.2:25
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport  80 -j DNAT --to-destination 192.168.2.3:80
	 iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 192.168.2.3:443
			


5.8. Summary

These multi network examples do not reach the highest level of paranoia where nobody trusts anybody. They do however cover common situations that small to medium organizations might usefully engage to offer reasonable security with practical usability.

Done.