Firewall - Blocking a specific IP
This week I needed a solution to block and unblock certain IPs from accessing the internet at certain times.
I didn't want to change my firewall script too much and didn't want to change it every time the rules changed (which change a lot due to variable circumstances).
So I created a two-part solution. In this post I will describe how I changed my firewall and show a simple script that can block or unblock a specific IP address.
In a following post I will describe how I created a script with a configuration file where I can define when to do what.
iptables and chains
Firewalls in Linux are built with iptables and "chains". Check this article for some basics about writing your own firewall script.
In a chain you can put several rules to filter network packets. It is possible to call a chain from another chain. If the called chain does not filter the packet, it automatically returns to the calling chain.
For instance, we have the standard "FORWARD" chain in a firewall.
In the beginning of this chain, we can always call a user-defined chain called "f_ip".
We create the user-defined chain with:
And pass all forwarded packets through this chain by including this line as one of our first rules in the FORWARD chain:
If the "f_ip" chain is empty, or none of the rules filter the packet to be forwarded, the "FORWARD" chain takes over again:
Now I also want to know if a blocked IP address tried to use the internet, so I created another user-defined chain to log & drop packets:
Take note that for the time being, nothing goes to the f_ip_drop chain!
But now I can use an external script to add rules to the f_ip chain to filter a specific address without having to change my firewall script.
This external script could contain something like:
(where "a.b.c.d" is substituted by a real IP address of course)
This part of the firewall then works as follows:
The external script
So now I had my firewall altered and I was ready to write my script to block and unblock specific IP addresses.
The result is here:
I saved this script as /usr/local/sbin/fw_ipfilt and made it executable and readable only for root (chmod 700).
Now I can block an IP address at any time with:
and unblock it with>
To unblock all previously blocked addresses use:
As always, if you have any questions or suggestions, feel free to comment on this post!
I didn't want to change my firewall script too much and didn't want to change it every time the rules changed (which change a lot due to variable circumstances).
So I created a two-part solution. In this post I will describe how I changed my firewall and show a simple script that can block or unblock a specific IP address.
In a following post I will describe how I created a script with a configuration file where I can define when to do what.
iptables and chains
Firewalls in Linux are built with iptables and "chains". Check this article for some basics about writing your own firewall script.
In a chain you can put several rules to filter network packets. It is possible to call a chain from another chain. If the called chain does not filter the packet, it automatically returns to the calling chain.
For instance, we have the standard "FORWARD" chain in a firewall.
In the beginning of this chain, we can always call a user-defined chain called "f_ip".
We create the user-defined chain with:
iptables -N f_ip
And pass all forwarded packets through this chain by including this line as one of our first rules in the FORWARD chain:
iptables -A FORWARD -j f_ip
If the "f_ip" chain is empty, or none of the rules filter the packet to be forwarded, the "FORWARD" chain takes over again:
Now I also want to know if a blocked IP address tried to use the internet, so I created another user-defined chain to log & drop packets:
iptables -N f_ip_drop
iptables -A f_ip_drop -j LOG --log-level 6 --log-prefix "FW: ip: "
iptables -A f_ip_drop -j DROP
Take note that for the time being, nothing goes to the f_ip_drop chain!
But now I can use an external script to add rules to the f_ip chain to filter a specific address without having to change my firewall script.
This external script could contain something like:
iptables -A f_ip -s a.b.c.d -j f_ip_drop
(where "a.b.c.d" is substituted by a real IP address of course)
This part of the firewall then works as follows:
The external script
So now I had my firewall altered and I was ready to write my script to block and unblock specific IP addresses.
The result is here:
#!/bin/bash
#
# fw_ipfilt Filter specific IP addresses
# Needs rc.firewall 0.2.3 or newer
#
# Version: 0.0.1 - Thursday, Jul 23, 2009
#
# Author: Niels Horn (niels.horn@gmail.com)
###################
## Configuration ##
###################
IPT=iptables
######################
## Clear IP filters ##
######################
ip_clear() {
# flush f_ip chain
$IPT -F f_ip
}
######################
## Add IP to filter ##
######################
ip_addip() {
ip=$1
# send all packets from or to $ip to f_ip_drop chain
$IPT -A f_ip -s $ip -j f_ip_drop
$IPT -A f_ip -d $ip -j f_ip_drop
}
###########################
## Remove IP from filter ##
###########################
ip_delip() {
ip=$1
# delete rules for $ip from f_ip chain
$IPT -D f_ip -s $ip -j f_ip_drop
$IPT -D f_ip -d $ip -j f_ip_drop
}
###################
## Check Command ##
###################
case "$1" in
'add')
ip_addip $2
;;
'clear')
ip_clear
;;
'del')
ip_delip $2
;;
*)
echo "use $0 add|del <ip> or $0 clear"
esac
I saved this script as /usr/local/sbin/fw_ipfilt and made it executable and readable only for root (chmod 700).
Now I can block an IP address at any time with:
fw_ipfilt add 192.168.1.123
and unblock it with>
fw_ipfilt del 192.168.1.123
To unblock all previously blocked addresses use:
fw_ipfilt clear
As always, if you have any questions or suggestions, feel free to comment on this post!
Labels: Firewall, Linux, shell scripting, Slackware
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home