Jeoss Easy Firewall
A Firewall is basically a policy-based network filter. Linux firewalls are built around Netfilter; the kernel's network packet processing framework which is made of several kernel modules performing specific tasks:
- The FILTER module (always loaded by default) mainly allows us to ACCEPT or DROP IP packets based on a certain matching criteria.
- The NAT module set allows us to perform Network Address Translations (SNAT, DNAT, MASQUERADE).
- The MANGLE module allows us to alter certain IP packet fields (TOS, TTL).
Users configure the Netfilter framework to suit their fairewall needs using iptables from the command line. With iptables we define rules that instruct the kernel what to do with IP packets when they arrive into, pass through, or leave our Linux box.
Each Netfilter main process is represented by a TABLE (FILTER, NAT, MANGLE) on iptables lingo. They have several specific hook points on the network packet flow map where they are invoked by the kernel to perform their duties.
Certain specifically located sequences of TABLE calls are generically called built-in CHAINS receiving the names of PREROUTING, INPUT, FORWARD, OUTPUT, and POSTROUTING.
It is easy to remember if we associate a TABLE with a "type of process" and a CHAIN with the "location" on the network packet flow map where instances of those processes are invoked.
Since an IP packet is received on a network interface, or created by a local process, until it is finally delivered or discarded the Netfilter engine will sequentially test and apply the rules contained along the network packet flow map. At each block identified by a TABLE@CHAIN pair the user can add one or more of these consecutive rules containing an IP packet matching criteria and a corresponding course of action. There are actions (i.e. ACCEPT, DROP, etc.) that can be performed by more than one TABLE and other actions (i.e. SNAT, DNAT, etc.) that are TABLE specific.
i.e. when an IP packet arrives from a network interface it is first processed by the PREROUTING chain invoking the MANGLE table user defined rules if any. If there are not rules that match the current packet the corresponding MANGLE@PREROUTING default course of action or "policy" applies. At this point if the packet was not dropped the process will continue now invoking the rules of the NAT table at the PREROUTING chain (see the map) and so on.
In order to facilitate the rules layout, users can also create their own custom chains and "jump" into them from different points of the map as they wish.
While built-in chains can have user defined policies of either ACCEPT or DROP packets, user defined chains have allways an unchangeable default policy of RETURN to the caller to continue the process.
The iptables main commands populate the network packet flow map with the required processing rules. The generic iptables rule can be written as:
# iptables <table> <Add/Insert/Delete> <CHAIN> <PKT_MATCHING_CRITERIA> <ACTION>
It could be read like:
Iptables please <Add/Insert/Delete> this rule for <table> at <CHAIN> where packets matching <PKT_MATCHING_CRITERIA> have to be <ACTION>ed
<table> -t filter (the filter table is assumed when omitted) -t nat -t mangle
<Add/Insert/Delete> -A (append rule at the end of the chain list) -I (insert rule at the begining of the chain list) -D (Delete rule)
<CHAIN> PREROUTING INPUT FORWARD OUTPUT POSTROUTING USER_DEFINED_CHAIN
ISO Level-2 matching: -i [!] <if_name> or --in-interface [!] <if_name> (OUTPUT and POSTROUTING chains cannot match on input interfaces)
-o [!] <if_name> or --out-interface [!] <if_name>
(INPUT and PREROUTING chains cannot match on output interfaces)
-mac-source [!] <xx-xx-xx-xx-xx-xx>
(OUTPUT and POSTROUTING chains cannot match on input interfaces)
ISO Level-3 matching: -s [!] <src_ip> or --src [!] <src_ip> or --source [!] <src_ip>
-d [!] <dst_ip> or --src [!] <dst_ip> or --destination [!] <dst_ip>
ISO Level-4 matching: -p [!] <prot_name> or --protocol [!] <prot_name> (udp|tcp|icmp)
Also available when ICMP protocol is defined
--icmp-type [!] <icmp_type> Also available when UDP protocol is defined
--source-port [!] <udp_src_port> or --sport [!] <udp_src_port> --destination-port [!] <udp_dst_port> or --dport [!] <udp_dst_port>
Also available when TCP protocol is defined
--source-port [!] <tcp_src_port> or --sport [!] <tcp_src_port> --destination-port [!] <tcp_dst_port> or --dport [!] <tcp_dst_port>
--tcp-flags [!] <tcp_flags> (SYN|ACK|FIN|RST|URG|PSH|ALL|NONE)
--syn --tcp-option [!] <tcp_option#> --state [!] <state> -m <match> [options]
note: [!] = negation operator <ACTION> (also called TARGET) -j ACCEPT (process continues with rules of the next table in map)
-j DROP (discard current packet)
-j REJECT (discard current packet with ICMP notification) option: --reject-with <reject_type>
-j USER_DEFINED_CHAIN (start traversing USER_DEFINED_CHAIN rules) -j RETURN (return from USER_DEFINED_CHAIN)
-j LOG (log to syslog, then process next rule in table) options:
--log-uid nat table specific -j SNAT (rewrite the source IP address of the packet) option: --to <ip_address> -j SAME (idem SNAT; used when more than one source address)
--to <a1-a2> -j MASQUERADE (idem SNAT; used when the replace IP is dynamic) -j DNAT (rewrite the destination IP address of the packet) option: --to <ip_address> -j REDIRECT (rewrite dst IP to 127.0.0.1, PREROUTING and OUTPUT only) option: –-to-port <port#> mangle table specific -j ROUTE (explicitly route packets, valid at PREROUTING)
--ifindex <iface_idx> -j MARK (set Netfilter mark values) options:
--or-mark <value> -j TOS (set the IP header Type of Service field) option:
--set-tos <value> -j DSCP (set the IP header Differentiated Services Field) options:
-j TTL (set the IP header Time To Live field)
The iptables auxiliary commands complete the scenario setting default conditoins, listing rules, flushing rules, etc.
#iptables -t <table> -L (Lists the <table> rules in all chains) #iptables -t <table> -L <CHAIN> (Lists the <table> rules in <CHAIN>)
#iptables -t <table> -N <CHAIN>
(Creates a user-defined <CHAIN> for holding <table> rules) #iptables -t <table> -E <CHAIN> <NEWCHAIN> (Renames <CHAIN> that holds <table> rules to <NEWCHAIN>)
#iptables -t <table> -X (Deletes all user-defined chains created for holding <table> rules) #iptables -t <table> -X <CHAIN> (Deletes user-defined <CHAIN> created for holding <table> rules)
#iptables -t <table> -P <CHAIN> <ACTION> where <ACTION> = ACCEPT|DROP
(Sets the default policy of <table> rules at <CHAIN> to <ACTION>)
#iptables -t <table> -F (Flushes (deletes) all <table> rules in all chains)
#iptables -t <table> -F <CHAIN> (Flushes (deletes) all <table> rules in <CHAIN>) #iptables -t <table> -R <CHAIN> <INDEX> <NEWRULE> (Replaces <table> rule at position <INDEX> in <CHAIN> with <NEWRULE>
Iptables loads our commands into Netfilter engine at runtime, Netfilter inmediatelly enforces the loaded rules and settings but they are not persistant. Afeter reboot all previously loaded Netfilter rules and settings will be lost. For this reason there are iptables utilities that allow to save the currently active ruleset to a file and to reload it later.
#iptables-save > fileName (Save the currently active Netfilter ruleset to fileName) #iptables-restore < fileName (Restore Netfilter ruleset to the one saved in fileName)
Netfilter is an extremely flexible and powerful framework but there is a price to pay for it; Iptables is complex. From an user point of view certain terms like TABLE, CHAIN, TARGET do not really match very well the concept they represent and do not make much sense at first. The topic is long, commands seem to have an endless list of parameters. To make things worse there is not a single book that really masters Iptables. They mostly fall into two categories: "recipe book" or "manpage book". I think this introduction gives you a snapshot of the Netfilter/Iptables landscape plus the necessary dose of pre-digested manpage stuff. If you are new at iptables, after reading these paragraphs a couple of times you will be ready to read iptables examples. With some practice you will soon find yourself writting your own rules.
A firewall is mainly designed to dynamically permit or deny network traffic based upon a set of rules. At this point it is easy to understand why the Linux Netfilter/Iptables framework is perfect for firewall construction.
Looking at the network packet flow map we find two particularly interesting spots on the FILTER table at the INPUT and FORWARD chains; We can decide there upon IP source address, IP protocol (UDP/TCP), destination port (80, 21, 443, etc), etc, if we ACCEPT, REJECT, or just DROP a particular IP packet. This is what a firewall does 80% of the time when i.e. protects a web server from unauthorized network requests. The other 20% of the time is manipulating (NAT, MANGLE) network packets.
There are hundreds of different firewall layouts addresing different needs but 3 of them could be considered the most typical firewall scenarios.
- Simple web server with one or more interfaces connected to Internet. Policy includes basic rules to permit restricted inbound access, unrestricted outbound access, and anti-spoofing rules. IP forwarding is off.
- This firewall connects to Internet and to a protected internal area. Policy includes basic rules to permit restricted inbound access, unrestricted outbound access, and anti-spoofing rules. Since the protected area uses private IP addresses source NAT is needed. IP forwarding is on.
- This firewall connects to Internet, internal protected and demilitarized area. Policy includes basic rules to permit restricted inbound access, unrestricted outbound access and anti-spoofing rules. Since protected and DMZ areas use private IP addresses they need source and destination NAT. IP forwarding is on.
Setting a firewall in 4 easy steps: configure-make-test-install.
to be continued