The ConnectMe page: Configuring Internet Connection Sharing & Firewall.


This page is linked from the TrickMe, Linux and ConfigMe - Network Server pages.
Aside from practical use, page's actual role is to understand the concept of iptables.

Paragraphs in this page are:

Introduction
Iptables Overview
The rules from the Gateway side
The settings from the Client host side
Conclusion



Introduction

Let's overview this task using a more computer oriented language than the so-called "Connection Sharing" definition.

We are going to transform a computer host equipped with a internet connection to a Gateway & Firewall. The mechanism is the following:

Using Network Adress Translation rules, the Gateway will "transform" the client hosts requests as its own and redirect them to the "wider" network, in our case the Internet.
This action is called "Ip Masquerading".

Using Filtering rules, the Gateway will also have a firewall role, keeping external connections out of our Local Area Network.

But instead of getting help from friendly utilities or third party tools or frontends, we will use the Iptables kernel mechanism directly.

Once the basics are understood, the choice of a friendly app (if needed) is an easy task.



Iptables Overview

Issue man iptables to overview the documentation.

Iptables handles the tables of ip packet rules inside the linux kernel.

The structure is as follows:

Some predefined tables are: filter, nat and mangle.
These tables contain predefined chains.

For every table-chain combination we issue rules that, if match according to criteria, take an action that is called "target".

So, the rule logic is: iptables (command) { table - chain - criteria - target }.

In predefined table-chains, we can have Policies, meaning "what to do in by default if no specific rules are found matching".

Some things to know:

1) In each table-chain, for each network issue, the rules are read sequentially, from first (top) to last (bottom).

So, the special rules to accept connections must be above the generic rules that reject the unwanted connections.

OR: The special rules to reject connections must be above the generic rules that accept the rest of the connections.

2) There are many ways to design actions through iptables. For example, we can define the policies to block connections and then, using rules, explicitly define the ones that we want to allow. Alternatively, we can define the policies to accept and then issue rules in order to block the unwanted network connections.



The rules from the Gateway side

Rules have to be issued with root privileges. They can be either added by hand, placed in a separate script or (my solution) included in /etc/rc.d/rc.local.

The rules: "#" are optional

modprobe ipt_MASQUERADE

iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
#iptables -t nat -A PREROUTING -i ppp0 -p TCP --dport 22 -j DNAT --to 192.168.0.192:22
#iptables -t nat -A PREROUTING -i ppp0 -p TCP --dport 80 -j DNAT --to 192.168.0.192:80
#iptables -t nat -A PREROUTING -i ppp0 -p TCP --dport 20 -j DNAT --to 192.168.0.192:20
#iptables -t nat -A PREROUTING -i ppp0 -p TCP --dport 21 -j DNAT --to 192.168.0.192:21
#iptables -t nat -A PREROUTING -i ppp0 -p ICMP -j DNAT --to 192.168.0.192
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
#iptables -A INPUT -i ppp0 -p TCP --destination-port 22 -j ACCEPT
#iptables -A INPUT -i ppp0 -p TCP --destination-port 80 -j ACCEPT
#iptables -A INPUT -i ppp0 -p TCP --destination-port 20 -j ACCEPT
#iptables -A INPUT -i ppp0 -p TCP --destination-port 21 -j ACCEPT
iptables -A INPUT -i ppp0 -p TCP -m state --state NEW,INVALID -j DROP
iptables -A INPUT -i ppp0 -p UDP -m state --state NEW,INVALID -j DROP

Explanations:

General:

When  the table is not mentioned (with the -t parameter), the default "filter" table is assumed by default.

The "-F" (flush) command flushes all chains in a single table, but tables have to be mentioned explicitly (except the filter table). Using the flush command, everytime the script runs we are sure that no stale rules remain.

Nat:

Using the nat table and its internal "POSTROUTING" chain, we issue the rule for the "internet connection sharing" ability. The MASQUERADE target is good for dynamic ip internet connections. For static ones, the SNAT target is prefered.

Optional redirection "nat" table rules from the outside to the internal network take place. As obvious, the external "new" connections are redirected to the internal server, and ports can be assigned to other ports.

But everything we design for one table must be cross-referenced in the other tables, because something we redirect correctly in the nat might be blocked in the filter by mistake.

The kernel does not forward the packets by default. Using the /proc filesystem we communicate with the kernel, alter behavior or browse for information.

Filter:

My policies for the filter table is ACCEPT for all chains. The ACCEPT target doesn't have to be mentioned, though, as it is assumed by default.

Optional rules to accept all connections to some ports, leading to specific servers inside the # network have been added.
They are separate in order to be altered individually.

If these rules are below the rules that drop the new connections, then they won't work.

Always perform a "mental" simulation of how the rules would be read and obeyed ... meaning "think of it first"!

port 80 is for the web server
port 22 is for the ssh server
port 21 is for the ftp server
port 20 is for the ftp file transfer

Tcp works both ways. This means that if we block all input, then, even if we can output data, we will never be able to browse pages or download from ftp or see our mail. The method here is to DROP (reject without returning error) only NEW and INVALID connections. So, the ESTABLISHED and RELATED ones will be accepted (they are not mentioned but remember that the policy is to ACCEPT). So, browsing a web page, checking for mail and downloading from an http or ftp site will be possible but connecting from the outside will be impossible.

Caution: Using such rules and not specifying the interface will result in all our network connections being affected, including the internal LAN's ones.

I issue the same rule for the UDP protocol. The reason I block new and invalid connections only for TCP and UDP is to leave the ICMP protocol free. Why? Because the simplest tool to test whether our network connections work well (LAN, Dial-up etc.) is the ping command.

So, if a user has trouble to connect in my web server, it would be just naive to block the simplest tool for the user to check whether the actual network connection is healthy. Allowing ICMP helps debug problems a lot.

I do not just accept ping, I also redirect it to the server inside.



The settings from the Client host side

This has to be done for each client.

Gateway:

Simple. If the gateway's IP adress is 192.168.0.1 then issue as root:
route add default gw 192.168.0.1
and if this is to be permanent, either add the entire command in /etc/rc.d/rc.local
or configure
the /etc/rc.d/rc.inet1.conf

Dns:

Since the gateway does not provide name services, the clients have to rely on external DNS for name resolution.

See ConfigMe - /etc/resolv.conf for this.




Conclusion

After the commands on the Gateway side take effect, it would be prefered to test all our applications and see which work and which don't.

In general, messengers, games and file sharing applications have a hard time operating with these rules, which in their turn might have to be more "elastic" in order to serve every network application we are accustomed to use.

Iptables is a very powerful and configurable tool.
It can check for many more issues than the ones above. For example:

It can block users from the internal network who try to connect to the gateway's external IP address instead of the internal one (inside the LAN).

It can redirect the external http requests to the inside web server but use another port instead of 80, therefore having the web server (if capable) to behave differently depending on outside or inside requests.

It can help operating different mail/web servers for inside and outside the LAN.

It can reject specific connection attempts and return ICMP errors like "Host Unreachable" etc.

It can "drop" connections instead of "rejecting" them. In this way, a port scanning outside tool will continue to scan the port instead of proceeding to the next automatically, thus stalling the trespasser a lot.

It can do a simple load-balancing "work" if redirection from the outside points to multiple hosts (i.e. web servers) in the LAN.

It can behave differently according to specific IP or MAC (Data Link Layer NIC) addresses.

It can change rules on the fly. Rules can be added, inserted, deleted or "flushed" (meaning mass-deletion) without stopping any active network connection, therefore no LAN or dial-up has to disconnect or restart.