May 082012
 

The primary use of iptables is as a host-based software firewall. It intercepts network traffic and applies filters to it, deciding what to permit, and what to deny. Iptables is very flexbile, but in its most common configuration it is used to simply filter incoming connections based on source, destination, protocol and port. In other functions, it is used to log traffic, filter outgoing connections, masquerade IP addresses for NAT and limit traffic rates. It is indispensable for maintaining the security of a server, but there’s other things its functions can be used for – simulating application failures.

It’s a relatively common testing scenario – you want to find out what happens when a service or resource becomes unavailable, and want to see how other applications handle this. For example, if your MySQL database goes down, what will Tomcat do? You could simulate this by shutting down the database, but if there are other nodes in the cluster, or other users accessing the database, this may not be possible.

A nice simple solution is to make an ad ad hoc addition to the iptables on the server that is noticing the failure. In the Tomcat/MySQL example, this will be a change to the application host running Tomcat. Since it’s attempting a connection to the MySQL database on port 3306, all that you need to do is configure iptables to block outgoing traffic with a destination port of 3306. Like this:

   # iptables -A OUTPUT -p tcp --dport 3306 -j DROP

Check that the iptables ruleset has been updated with:

   # iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:3306    <<====== This line here has been added

Chain RH-Firewall-1-INPUT (2 references)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 255 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 /* SSH */ 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80 /* http */ 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:8080 /* tomcat */ 
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

This will have the effect of intercepting all outbound traffic heading to port 3306 on any destination host, and dropping it outright. The application will be unable to reach the database, although all other hosts will have no interruption of service.

One your testing is complete, you can undo the previous command by simply replacing the "-A" option ("append") with "-D" ("delete"):

   # iptables -D OUTPUT -p tcp --dport 3306 -j DROP

There are many other ways of using this technique. You could block a hosts ability to use DNS (UDP, port 53):

   # iptables -A OUTPUT -p udp --dport 53 -j DROP

Prevent a host from accessing Internet websites (HTTP, port 80 and 443):

   # iptables -A OUTPUT -p tcp --dport 80 -j DROP
   # iptables -A OUTPUT -p tcp --dport 443 -j DROP

Or block a host from reaching anything that isn't a private local address, by using the negation operator ("!"):

   # iptables -A OUTPUT -d ! 10.0.0.0/8 -j DROP

Which will look like this:

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0           !10.0.0.0/8   

This method could be use for testing monitoring, to force an automated cluster failover, or to eliminate extra traffic when tracing a bug.

The iptables command can be used as a powerful tool for exercising very fine-grained control over your host networking. A site-wide network catastrophe can effectively be locally simulated with one simple trouble-free command. Write it down.


Matt Parsons is a freelance Linux specialist who has designed, built and supported Unix and Linux systems in the finance, telecommunications and media industries.

He lives and works in London.

  2 Responses to “Using iptables to simulate service interruptions”

  1. Great example, saved me hours of time, thanks!

  2. […] 11. NetworkUnavailable 如果希望网络不可用,我们可以参考这里使route都不可用的,这样我们要恢复就很困难了。所以我们期望的网络不可用应该是针对特定进程或者端口的不可用,于是可以考虑使用iptable这个Linux防火墙,iptables -A OUTPUT -p tcp –dport 3306 -j DROP这个命令就是屏蔽3306端口的所有请求,对于监听这个端口的服务相当于不可用了,而通过iptables -D OUTPUT -p tcp –dport 3306 -j DROP即可恢复。iptable的用法可参考这篇文章,而详细的原理与配置可参考这个文档。 […]

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>