Using iptables on EC2 instancesEdit
Most of the time you don’t need to worry about using a host-level firewall such as iptables when running Amazon EC2, because Amazon allows you to run instances inside a "security group", which is effectively a firewall policy that you use to specify which connections from the outside world should be allowed to reach the instance.
However, this is a "whitelist" approach, and it is not straightforward to use it for "blacklisting" purposes on a running instance.
Example scenario
A bot is trying a bruteforce attack, annoyingly driving up the system load and filling your logs with crap like this (dozens of lines per second):
pop3[22145]: badlogin: fc.df.84ae.static.theplanet.com [174.132.223.252] plaintext branden SASL(-13): authentication failure: checkpass failed
You want to drop all connections from that IP until the attack is over.
Temporarily blocking a single IP
For this purpose, temporarily turning on the host-level firewall and setting up a rule is probably the simplest way to go.
First up, check the existing rules; by default they will allow all traffic:
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Now set up a rule to drop all packets from the attacker; you can run iptables -L
again to see the results:
# iptables -I INPUT -s 174.132.223.252 -j DROP
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- fc.df.84ae.static.theplanet.com anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
See the iptables man page for details on the other kinds of rules you can specify. You can do things like rate-limiting, and matching on specific ports, and a lot of much more complicated variations than just dropping all packets like in the example above.
As iptables probably isn’t running (you can check this with service --status-all
) you’ll need to start it:
# service iptables start
Note that it most likely isn’t configured to start up at boot either (check with chkconfig --list
); if you want it to be permanent you’ll have to use chkconfig
to set that up.
Once the attack is over you can drop the rule with iptables -D INPUT
and the full specification of the rule:
# iptables -D INPUT -s 174.132.223.252 -j DROP
Or by referencing it’s rule number (1 in this case):
# iptables -D INPUT 1
Dynamically detecting attacks
# iptables -N bansshee
# iptables -A bansshee -p tcp --dport 110 -m state --state NEW -m recent --set --name pop3connect
# iptables -A bansshee -p tcp --dport 110 -m state --state NEW -m recent --rcheck --seconds 60 --hitcount 10 --name pop3connect -j DROP
# iptables -I INPUT -j bansshee
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
bansshee all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain bansshee (1 references)
target prot opt source destination
tcp -- anywhere anywhere tcp dpt:pop3 state NEW recent: SET name: pop3connect side: source
DROP tcp -- anywhere anywhere tcp dpt:pop3 state NEW recent: CHECK seconds: 60 hit_count: 10 name: pop3connect side: source
# iptables -N bansshee
# iptables -A bansshee -p tcp --dport 110 -m state --state NEW -m recent --set --name pop3connect
# iptables -A bansshee -p tcp --dport 110 -m state --state NEW -m recent --rcheck --seconds 60 --hitcount 10 --name pop3connect -j DROP
# iptables -I INPUT -j bansshee
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
bansshee all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain bansshee (1 references)
target prot opt source destination
tcp -- anywhere anywhere tcp dpt:pop3 state NEW recent: SET name: pop3connect side: source
DROP tcp -- anywhere anywhere tcp dpt:pop3 state NEW recent: CHECK seconds: 60 hit_count: 10 name: pop3connect side: source
Basically:
- Create a custom "bansshee" chain which can easily be added or removed from default INPUT chain
- Record the IP addresses making any new POP connections in a list named "pop3connect"
- If any IP address makes more than 10 such new connections in any 60 second period, drop the packets on the floor
- Insert the "bansshee" chain in the default INPUT chain
Source
Making the configuration permanent
# service iptables save # writes config to /etc/sysconfig/iptables
# chkconfig iptables on
# service iptables save # writes config to /etc/sysconfig/iptables
# chkconfig iptables on