Block IP addresses with ipfw

bsdipfw

I'm a total noob to ipfw so my apologies in advance if my questions are basic, but I've not found any resources for it that help with the gap between using the GUI and knowing the commandline ipfw really well.


I'd like to block ips that are hitting my webserver repeatedly. The firewall is ipfw. I found this command:

ipfw add deny ip from the.ip.to.block to my.computer.ip.address

There are two things I'm unclear about:

  1. I understand that the rule will be flushed on restart. What I would like to know is will running this command affect any existing rules that are running? I'm guessing not but I'd like to be sure.

  2. Is there any software that interlinks with ipfw to add ip's for a short amount of time and then remove them? If not, I'll knock up a script for it, but is there a built-in way to add from several conf files? It would make it a lot easier to do if I could have one file with the stable rules and another that loads with the dynamic ones.

Any help is much appreciated, even RTFM's if you can give a link to a resource that helps me understand it a bit better.


My firewall scripts:

\#!/bin/sh

/usr/bin/sudo /sbin/ipfw -q flush
/usr/bin/sudo /sbin/ipfw -q delete set 31

/usr/bin/sudo /sbin/ipfw -q /usr/local/bin/Firewall/default.conf

#Check dynamic rules
#anything that's already had the
# green light can continue
add 1000 check-state

add 1050 allow tcp from any to any established

add 1080 allow tcp from any to any out keep-state

add 1090 allow udp from any to any out keep-state

add 1095 allow icmp from any to any out

#loopback
add 1100 allow ip from 127.0.0.1/8 to 127.0.0.1/8 via lo0

add 1200 deny log ip from 127.0.0.1/8 to any in
add 1300 deny log ip from any to 127.0.0.1/8 in

#allow pings and traceroute
# Ping out; accept ping answers.
add 1400 allow icmp from any to any icmptypes 8 out
add 1410 allow icmp from any to any icmptypes 0 in

# Allow me to traceroute.
add 1420 allow icmp from any to any icmptypes 11 in

add 1500 allow tcp from any to any 11305 keep-state setup

#http and https
add 1600 allow tcp from any to any 80 keep-state setup

# rules for reverse proxying
add 1610 allow tcp from me to any 4567 keep-state setup
add 1611 allow tcp from me to any 4568 keep-state setup
add 1612 allow tcp from me to any 4569 keep-state setup

add 1620 allow tcp from me to any 4577 keep-state setup
add 1621 allow tcp from me to any 4578 keep-state setup
add 1622 allow tcp from me to any 4579 keep-state setup
add 1630 allow tcp from me to any 4560 keep-state setup
add 1631 allow tcp from me to any 4561 keep-state setup
add 1632 allow tcp from me to any 4562 keep-state setup
add 1640 allow tcp from me to any 4570 keep-state setup
add 1641 allow tcp from me to any 4571 keep-state setup
add 1642 allow tcp from me to any 4572 keep-state setup


add 1700 allow tcp from any to any 443 keep-state setup

#Bonjour
#add 2000 allow udp from any to any 5653 keep-state setup

#Everything that isn't in a prior rule 

add 65533 reject log udp from any to any in

add 65534 deny log ip from any to any in

Best Answer

  1. Correct rules need to be reestablished every reboot. It will not directly affect other rules, but can indirectly (for instance, if another rule allowed the IP for whatever reason, this might block the IP...)

  2. You're looking for the ever popular fail2ban, which reads logs files and bans IPs of people doing "bad" things.

Also, you don't really want too keep adding rules for each individual ban, this would quickly pollute the rules. You can add a rule to block a table however, then add the IPs to the table. A table is just a list of IPs so you can easily apply rules to the whole table rather than specifying them all individually.

For example, I have a 'default' firewall script that I use, the first two rules in this script are:

00030 deny ip from "table(1)" to me
00031 deny ip from "table(2)" to me

The keyword "me" means any of my local IP address. Table 1 is for Fail2Ban, when it finds an IP it doesn't like, it adds the IP to that table for a while. Table 2 is for Spamhaus's DROP list, a list of known professional spam systems (see their website for details).

You can add IPs to a table manually with this command:

ipfw table 2 add

On my servers Table 2 is populated automatically at start-up by a script /usr/local/etc/rc.d/spamhaus-drop as follows:

#!/bin/csh
fetch -i /tmp/drop.lasso -o /tmp/drop.lasso "http://www.spamhaus.org/drop/drop.lasso"
sed -i '' "s/;.*//" /tmp/drop.lasso
ipfw table 2 flush
foreach IP ( `cat /tmp/drop.lasso` )
        ipfw table 2 add $IP
end

I highly encourage you to write your own script to configure your firewall. It's pretty easy in FreeBSD with ipfw, and I wouldn't bother with a GUI (I know that sounds hard when it's all new, but the basics are easier than you think).

My configuration script is in /etc/ipfw.rules and goes like this:

#!/bin/sh

#FOR KEAIRA  - The computer this script was customized for.

ipfw -q -f flush       # Delete all rules
cmd="ipfw add"

# Ban tables
$cmd 00030 deny ip from "table(1)" to me
$cmd 00031 deny ip from "table(2)" to me

# Statefull firewall config, more secure
$cmd 00060 check-state

# Allow outbound traffic
$cmd 00130 allow ip from me to any keep-state

# SSH - I have SSH on port 2222 to keep the script kiddies out.
$cmd 11020 allow tcp from any to me dst-port 2222 setup keep-state

# DNS
$cmd 11090 allow tcp from any to me domain setup keep-state
$cmd 11092 allow udp from any to me domain

# NTP
$cmd 11100 allow tcp from any to me ntp setup keep-state
$cmd 11101 allow udp from any to me ntp

# General Network - ICMP & IGMP
$cmd 61001 allow icmp from any to any
$cmd 61002 allow igmp from any to any

# Deny the rest
$cmd 65500 deny ip from any to any

This server is running SSH (on an alternate port), DNS, and NTP (time). The rest is just generic stuff I put in all of my firewall scripts. If you have other services you need to open, just let me know and I'll customize the example. Most service names you can get from /etc/services though, which makes writing these very easy. It's not strictly necessary for each rule to have a different number, but it makes managing them easier. Rules are processed in order by number, but otherwise there's no significance to the numbers.

This script is "activated" by putting these lines in /etc/rc.conf

firewall_enable="YES"                   # Firewall On
firewall_script="/etc/ipfw.rules"       # Firewall Script

Setting up Fail2Ban is a bit more work, but it's pretty straight forward too. If you want more details on that, just ask.

Related Topic