For those who are not sure of the term iptables let me clarify you (From Wiki)
iptables are the tables provided by the Linux kernel firewall
(implemented as different Netfilter modules) and the chains and rules it
stores.
Few important points on iptables
- iptables requires elevated privileges to operate and must be executed by user root, otherwise it fails to function.
- On most Linux systems, iptables is installed as /usr/sbin/iptables and documented in its man pages which can be opened using man iptables when installed. It may also be found in /sbin/iptables, but since iptables is more like a service rather than an "essential binary", the preferred location remains /usr/sbin.
- It generally works in Layer 3 and layer 4 i.e. network and transport layer.
- iptables is also responsible for managing ICMP (Internet Control messaging Protocol) that comes in data link layer
- iptables also supports MAC level filtering so it works on Layer 2 as well (Data Link layer)
- Layer 3 focuses on source (192.168.0.x) and destination (172.168.0.x) addresses.
- Layer 4 focuses on protocols, ports, TCP : 80, UDP : 69 (Most of the applications are dependent on TCP and UDP ports.
NOTE: TCP/UDP ports use a 16-bit range (0-65535) and IP addresses are based on 32-bit ranges (4 billion)
Package
Verify that iptables rpm is installed in your machine
# rpm -qa | grep iptables
iptables-1.4.7-4.el6.i686
iptables-ipv6-1.4.7-4.el6.i686
To check if kernel is compiled to use iptables (here config-2.6.x.x may vary as per your kernel)
# less /boot/config-2.6.32-220.el6.i686 | grep CONFIG_NETFILTER
CONFIG_NETFILTER=y
Make sure the first line as shown above should be "y"
Types of tables in iptables
- mangle - alter packets (TOS/TTL) with TCP/UDP/ICMP
- NAT (Network Address Translation)
- Filter (IP packet filtering)
NOTE: NAT allows to change IP address along with the port
ACL syntax for iptables
- name of chain - action (Append/Insert/Replace)
- name of table (filter) - mangle/nat/user-defined
- layer 3 object (source/destination)
- optionally layer 4 subject (tcp/udp protocols/ports)
- Jump/Target -j - ACCEPT/DROP/DENY/REJECT/LOG
Some Examples
Block a source IP 192.168.0.20 from communicating with our system
# iptables -A INPUT -s 192.168.0.30 -j DROP
So here I am appending a rule into the input chain for the source 192.168.0.30 and the action to be taken is DROP all the packets coming from the source machine.
To view the current rules in iptables
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.0.30 anywhere
ACCEPT tcp -- anywhere anywhere tcp spt:ssh
DROP tcp -- anywhere anywhere tcp dpt:telnet
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
So now if 192.168.0.30 tries to connect to our local machine it would get a request time out.
Other commands to view the iptables
# iptables -L -v
Chain INPUT (policy ACCEPT 2559 packets, 223K bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any 192.168.0.30 anywhere
0 0 ACCEPT tcp -- any any anywhere anywhere tcp spt:ssh
0 0 DROP tcp -- any any anywhere anywhere tcp dpt:telnet
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 297 packets, 40151 bytes)
pkts bytes target prot opt in out source destination
Here -v reveals bytes in (k/M/G) which means the bytes of packets blocked or allowed for any rule which was applied in iptables
# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- 192.168.0.30 anywhere
2 ACCEPT tcp -- anywhere anywhere tcp spt:ssh
3 DROP tcp -- anywhere anywhere tcp dpt:telnet
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.0.30 anywhere
ACCEPT tcp -- anywhere anywhere tcp spt:ssh
DROP tcp -- anywhere anywhere tcp dpt:telnet
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Appending/Inserting rules
You can either Append a new rule into any chain or you can insert the
rule where the difference is while appending the rule will end up in the
last row while if you want your rule to be preferred first beofre any
other rule in the chain then use INSERT along with iptables as shown below
# iptables -I INSERT -s 192.168.0.30 -j DROP
Some more examples
Create a rule to permit ssh connection from everyone to your local machine
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Create a rule to deny telnet access from everyone to your local machine
# iptables -A INPUT -p tcp --dport telnet -j DROP
Deleting rules
For deleting any rule from the chain you will require line number
For Example:
# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- 192.168.0.30 anywhere
2 ACCEPT tcp -- anywhere anywhere tcp spt:ssh
3 DROP tcp -- anywhere anywhere tcp dpt:telnet
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Suppose I want to delete the rule for source 192.168.0.30
# iptables -D INPUT 1
In case you want to go the hard way, you will have to delete rule on the
basis of the first match by giving the complete rule along with D switch
# iptables -D INPUT -s 192.168.0.30 -j DROP
Replace rules
You can also replace rules instead of deleting and creating any rule if there are some change which you want to do.
For example in the above question suppose we want to block communication from 192.168.0.25 instead of 192.168.0.30 so we can easily replace the rule
# iptables -R INPUT 1 -s 192.168.0.25 -j DROP
Saving or Restoring rules in iptables
# iptables -save (defaults dumps to STDOUT)
# iptables -restore (default reads rule from STDIN)
Example:
# iptables-save > rules.txt
# iptables-restore < rules.txt
Flushing rules
This term is used to delete all the rules from all the chains.
# iptables -F
This command will temporarily remove all the rules but once you restart your iptables services all the rules will come back to default setup.
Creating user defined chains
Now by default as I had said in my last post Basic iptables tutorials in Linux I 3
chains are present in iptables which are NAT, filter and mangle but
what if you want to create or add an extra CHAIN, so is it possible?
Well the answer is YES, you can create a new chain and use it as per
your requirement where mostly this is done to reduce the complexity.
To create a new chain# iptables -n INTRANET
This will create a new chain
You can verify the same
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain INTRANET (o references)
target prot opt source destination
Now as you can see above a new chain has been created now you need to divide the traffic or rules toINTRANET chain as per your requirement. Now for our case we can take any example to show you how it works
Create references for user defined chain
# iptables -I INPUT 1 -s 192.168.0.0/24 -j INTRANET
So as per the above rule I am creating and inserting a new rule inside INPUT chain at no. 1 position as I want to give this rule max priority which says any rule which is created with source IP 192.168.0.0/24will be visible under INTRANET chain.
# iptables -I INTRANET -p tcp --dport telnet -j DROP
So as per the above rule I am inserting a new rule inside INTRANET chain for source 192.168.0.0/24(as we have already defined this IP source using our last rule for INTRANET chain) connection to telnet port 23 should be dropped.
Now lets see if our rule has been implemented properly using
# iptables -L INTRANET
Chain INTRANET (1 references)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:telnet
As per the above rule list any connection coming from 192.168.0.0/24 using port 23 will be dropped.
Rules can be varied for various sport, dport, source destination inside any user defined chain.
Some more example
Block port 22 from 192.168.0.30 for the local machine inside INTRANET chain.
# iptables -A INTRANET -s 192.168.0.30 -p tcp --dport 22 -j DROP
So as you see in the above rule I am appending a new rule inside
INTRANET chain for source 192.168.0.30 and blocking communication from
port no. 22
Rename user defined chain
# iptables -E old_chain_name new_chain_name
# iptables -E INTRANET EXTRANET
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
EXTRANET all -- 192.168.1.0/24 anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain EXTRANET (1 references)
target prot opt source destination
Delete user defined chain
NOTE: Make sure the chain you are deleting has no rules in it
# iptables -X INTRANET
IMPORTANT NOTE: Default chains cannot be deleted
Chain Policies
By this term I mean the default policies for all the chains which most
of us miss. In case you re look at the chains below, consider the
highlighted term.
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
INTRANET all -- 192.168.0.0/24 anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain INTRANET (1 references)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:telnet
Now as you see by default all the chains have default ACCEPT policy
which can be dangerous for critical machines as apart from any rule
which you have created all other connections are allowed.
Change default policies of chains
Now since we have created a new chain so we should change the default policy of INPUT chain as we only want those users to communicate with us whom we have allowed in our rules
# iptables -P INPUT DROP
NOTE: Default DROP policy may prevent typical TCP/UDP/ICMP communications
TCP - uses 3-way handshake
1. SYN
2. SYN-ACK
3. ACK
# iptables -L INPUT
Chain INPUT (policy DROP)
target prot opt source destination
INTRANET all -- 192.168.0.0/24 anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
So as you see now only those machines will be allowed to communicate with us which you will allow through rules in your machine.
TCP Matches - Connection Oriented
- TCP works on layer 4 also known as Connection oriented protocol.
- TCP packets contains information of sender as well as receiver.
- Eg: HTTP, FTP, telnet etc
-p tcp, --protocol tcp
--sport,--source-port
NOTE: The source port is generally picked arbitrarily from > 1024Example:
Block telnet connection from 192.168.1.0/24 for localhost using EXTRANET chain
# iptables -A EXTRANET -p tcp --dport telnet -j DROP
UDP Matches: - Connectionless
- UDP works on Layer 4 and is considered connection less protocol.
- UDP considered packets are considered much faster as compared to TCP because they are not as heavy as TCP as they do not contain much details on the packet.
- These are generally used for broadcasting.
- Eg: DNS, DHCP, syslog, NTP etc
The syntax used
-p udp, --protocol udp
--sport,--source-port - same source port as destination port
Internet Control Messaging Protocol (ICMP)
ICMP Types:a. echo-request - PING
b. echo-reply - pong
PING - local system sends via OUTPUT chain an echo-request(PING)
Remote system received echo-request in its INPUT chain => Remote system responds with an echo-reply(Pong)
The sysntax used
-p icmp, --protocol icmp
For more details on icmp ping protocol usage follow the below link
Match multiple ports with fewer rules
Now suppose you want to block multiple ports more than 5-6 for the same
machine so imagine you will have to write 5-6 rules which will make the
rules list look messy which you can fix by using a single rule for
multiple ports.
Let me give you an example
Block connection from 192.168.0.100 from port 22,23,80,8080 to your machine in a single rule
# iptables -A INTRANET -s 192.168.0.30 -p tcp -m multiport --dport 22,23,80,8080 -j DROP
Here in above rule I am appending a new rule in INTRANET chain for source 192.168.0.30 defining that the rule is for multiple ports using -m switch for --dport 22,23,80,8080 to drop any connection from these ports.
Lets see if our rule was implemented properly
# iptables -L INTRANET
Chain INTRANET (1 references)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:telnet
DROP tcp -- 192.168.0.30 anywhere multiport dports ssh,telnet,http,webcache
Block the above ports for all machines from source 192.168.0.0/24
# iptables -A INTRANET -p tcp -m multiport --dport 22,23,80,8080 -j DROP
NOTE: Maximum of 15 ports can be blocked or permitted in a single rule
MAC address level filtering
Suppose you have blocked any source with IP 192.168.0.100 from
connecting your machine, but what if it chages its ip to some other
range. In that case your machine is not secure any more. So for these
cases we use MAC address filtering where you block the MAC ID of the
source machine from connection.This is a layer 2 blocking i.e. Data Link Layer
Block connection from machine with mac id 00:0C:29:BD:AC:81 from connecting your machine using port 23
# iptables -A INPUT -p tcp -m mac --mac-source 00:0C:29:BD:AC:81 --dport 23 -j DROP
# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere MAC 00:0C:29:BD:AC:81 tcp dpt:telnet
Log iptables traffic
Now how do you collect logs for all the rules in your iptables?
By default all the generated logs are stored in /var/log/messages and it
not easy to look out for particularly iptables log inside
/var/log/messages as it stores many other logs as well. So it is always a
good idea to use a different file for iptables logs
NOTE: To enable logging by firewall we need to enable kernel level logging in the linux machine
Follow these steps for the same
# vi /etc/rsyslog.conf (In RHEL 5 or older /etc/syslog.conf) #### RULES ####
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
kern.* /var/log/firewall.log
Uncomment the above line and make necessary change as shown with blue color
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none;kern.none /var/log/messages
Add an extra word "kern.none" as shown above
Restart the services
# service rsyslog restart
For RHEL 5 or older
# service syslog restart
Create a new rule to log all the taffic for telnet port
# iptables -A INPUT 1 -p tcp --dport telnet -j LOG
Now I will try to do telnet to my linux box(10.10.20.26) from source (10.10.20.30)
Let us check the log generated in firewall.log
# less /var/log/firewall.log
Sep 16 12:23:34 localhost kernel: IN=eth0 OUT= MAC=00:0c:29:bd:ac:80:ac:16:2d:00:00:87:08:00SRC=10.10.20.30 DST=10.10.20.26 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=12317 DF PROTO=TCP SPT=58754DPT=23 WINDOW=8192 RES=0x00 SYN URGP=0
Examples
Log all the traffic for ssh and telnet port on 10.10.20.26
# iptables -A INPUT -d 10.10.20.26 -p tcp -m multiport --dport 22,23 -j LOG
# less /var/log/firewall.log
Sep 16 12:32:22 localhost kernel: IN=eth0 OUT= MAC=00:0c:29:bd:ac:80:ac:16:2d:00:00:87:08:00SRC=10.10.20.30 DST=10.10.20.26 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=4022 DF PROTO=TCP SPT=58707DPT=22 WINDOW=256 RES=0x00 ACK URGP=0
Sep 16 12:32:22 localhost kernel: IN=eth0 OUT= MAC=00:0c:29:bd:ac:80:ac:16:2d:00:00:87:08:00SRC=10.10.20.30 DST=10.10.20.26 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=4023 DF PROTO=TCP SPT=58707DPT=22 WINDOW=246 RES=0x00 ACK URGP=0
So as you see a log has been reported for the attempt of connection inside firewall.log
But again what if you have created a log entry for multiple ports and sources so for those cases you can use --log-prefix to distribute the log traffic and makes easy visibility inside log.
LOG PREFIX
Examples:
# iptables -A INPUT -d 10.10.20.26 -p tcp -m multiport --dport 22,23 -j LOG --log-prefix "SSH ACCESS ATTEMPT: "
# less /var/log/messages
Sep 16 12:34:49 localhost kernel: SSH ACCESS ATTEMPT:
IN=eth0 OUT= MAC=00:0c:29:bd:ac:80:ac:16:2d:00:00:87:08:00
SRC=10.10.20.30 DST=10.10.20.26 LEN=40 TOS=0x00 PREC=0x00 TTL=64
ID=11101 DF PROTO=TCP SPT=58707 DPT=22 WINDOW=2429 RES=0x00 ACK URGP=0
Sep 16 12:34:49 localhost kernel: SSH ACCESS ATTEMPT:
IN=eth0 OUT= MAC=00:0c:29:bd:ac:80:ac:16:2d:00:00:87:08:00
SRC=10.10.20.30 DST=10.10.20.26 LEN=92 TOS=0x00 PREC=0x00 TTL=64
ID=11102 DF PROTO=TCP SPT=58707 DPT=22 WINDOW=2429 RES=0x00 ACK PSH
URGP=0
We can create a new chain which will contain all the log related rules
# iptables -N LOGGER
# iptables -I INPUT 1 -j LOGGER
So here we are creating a refrence where all the INPUT chain traffic
will take the refrence of LOGGER chain for additional rules.
# iptables -I LOGGER -m multiport --dport 80,443,22,23 -j LOG
Here we are creating a rule for LOGGER chain to log all the traffic on ports 80,443,22 and 23
No comments:
Post a Comment