HOWTO: Use iptables as firewall with a daemon on system startup
This howto is intended to set up a firewall without installing firestarter (useful if you don't use any wm, eg: servers). It uses iptables which is available with a fresh Ubuntu install, and a init.d script to run it as a daemon on boot.
Please correct me if I'm wrong about iptables configuration, and feel free to improve the script or tell me new ports to include in the script. Thanks !
Create the default rules script
- Create a new script:
Code:
$ sudo gedit /usr/local/bin/iptables-rules
- Paste the following lines:
Code:
#! /bin/sh
#
# Initialize the rules with iptables.
#
ROOT_UID="0"
#Ctrl-C trapping
trap ctrlc INT
ctrlc()
{
echo -e "\nAborted by user."
rm -rf $TMP_DIR
exit 2
}
#Check if run as root
if [ "$UID" -ne "$ROOT_UID" ] ; then
echo "You must be root to do that!"
exit 1
fi
echo "Which ports do you want to open ?"
allow_icmp="0"
echo -n "Allow ping (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_icmp="1"
fi
allow_ftp="0"
echo -n "Allow ftp (file transfert) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_ftp="1"
fi
allow_ssh="0"
echo -n "Allow ssh (secure shell) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_ssh="1"
fi
allow_smtp="0"
echo -n "Allow smtp (mail sending) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_smtp="1"
fi
allow_http="0"
echo -n "Allow http (web server) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_http="1"
fi
allow_pop3="0"
echo -n "Allow pop3 (pop3 mail server) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_pop3="1"
fi
allow_imap="0"
echo -n "Allow imap (imap mail server) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_imap="1"
fi
allow_https="0"
echo -n "Allow https (secured web server) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_https="1"
fi
allow_mysql="0"
echo -n "Allow mysql (database server) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_mysql="1"
fi
allow_vnc="0"
echo -n "Allow vnc (remote desktop) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_vnc="1"
fi
allow_samba="0"
echo -n "Allow samba (Windows file sharing) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_samba="1"
fi
echo -e "\nDo you really want to apply iptables rules ? This will clear every iptables"
echo "settings. Use Ctrl-C then 'iptables-save' to save your current settings."
echo -n "(y/n)? [n] "
read input
if [ -z "$input" ] || [ "$input" == "n" ] || [ "$input" == "no" ] || [ "$input" == "N" ] || [ "$input" == "NO" ] ; then
exit 1
fi
echo -n "Applying rules..."
#Flushing the current rules
iptables -F
#Allow connections already established
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Accept everything from localhost
iptables -A INPUT -i lo -j ACCEPT
#Ping
if [ $allow_icmp -eq "1" ] ; then
iptables -A INPUT -p icmp -j ACCEPT
fi
#ftp (20,21)
if [ $allow_ftp -eq "1" ] ; then
iptables -A INPUT -p tcp -m multiport --destination-ports ftp-data,ftp -j ACCEPT
fi
#ssh (22)
if [ $allow_ssh -eq "1" ] ; then
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
fi
#smtp (25)
if [ $allow_smtp -eq "1" ] ; then
iptables -A INPUT -p tcp --dport smtp -j ACCEPT
fi
#http (80)
if [ $allow_http -eq "1" ] ; then
iptables -A INPUT -p tcp --dport http -j ACCEPT
fi
#pop3 (110)
if [ $allow_pop3 -eq "1" ] ; then
iptables -A INPUT -p tcp --dport pop3 -j ACCEPT
fi
#imap (143)
if [ $allow_imap -eq "1" ] ; then
iptables -A INPUT -p tcp --dport imap2 -j ACCEPT
fi
#https (443)
if [ $allow_https -eq "1" ] ; then
iptables -A INPUT -p tcp --dport https -j ACCEPT
fi
#mysql (3306)
if [ $allow_mysql -eq "1" ] ; then
iptables -A INPUT -p tcp --dport mysql -j ACCEPT
fi
#vnc (5900)
if [ $allow_vnc -eq "1" ] ; then
iptables -A INPUT -p tcp --dport 5900 -j ACCEPT
fi
#samba (tcp 135,139,445, udp 135,137,138,139,445)
if [ $allow_samba -eq "1" ] ; then
iptables -A INPUT -p tcp -m multiport --destination-ports 135,139,445 -j ACCEPT
iptables -A INPUT -p udp -m multiport --destination-ports 135,137,138,139,445 -j ACCEPT
fi
#Drop everything else
iptables -A INPUT -j DROP
#Outbound: allow everything
iptables -A OUTPUT -j ACCEPT
echo " ok !"
exit 0
- Allow execution:
Code:
$ sudo chmod +x /usr/local/bin/iptables-rules
- Run this script to apply iptables rules:
Code:
$ sudo iptables-rules
Create the firewall daemon
Thank you pinnockio for your iptables firewall script !
- Create a new script:
Code:
$ sudo gedit /etc/init.d/iptables
- Paste the following lines:
Code:
#! /bin/sh
#This is an Ubuntu adapted iptables script from gentoo
#(http://www.gentoo.org) which was originally distributed
#under the terms of the GNU General Public License v2
#and was Copyrighted 1999-2004 by the Gentoo Foundation
#
#This adapted version was intended for and ad-hoc personal
#situation and as such no warranty is provided.
. /lib/lsb/init-functions
IPTABLES_SAVE="/etc/default/iptables-rules"
SAVE_RESTORE_OPTIONS="-c"
checkrules() {
if [ ! -f ${IPTABLES_SAVE} ]
then
echo "Not starting iptables. First create some rules then run"
echo "\"/etc/init.d/iptables save\""
return 1
fi
}
save() {
/sbin/iptables-save ${SAVE_RESTORE_OPTIONS} > ${IPTABLES_SAVE}
return $?
}
start(){
checkrules || return 1
/sbin/iptables-restore ${SAVE_RESTORE_OPTIONS} < ${IPTABLES_SAVE}
return $?
}
case "$1" in
save)
echo -n "Saving iptables state..."
save
if [ $? -eq 0 ] ; then
echo " ok"
else
echo " error !"
fi
;;
start)
log_begin_msg "Loading iptables state and starting firewall..."
start
log_end_msg $?
;;
stop)
log_begin_msg "Stopping firewall..."
for a in `cat /proc/net/ip_tables_names`; do
/sbin/iptables -F -t $a
/sbin/iptables -X -t $a
if [ $a == nat ]; then
/sbin/iptables -t nat -P PREROUTING ACCEPT
/sbin/iptables -t nat -P POSTROUTING ACCEPT
/sbin/iptables -t nat -P OUTPUT ACCEPT
elif [ $a == mangle ]; then
/sbin/iptables -t mangle -P PREROUTING ACCEPT
/sbin/iptables -t mangle -P INPUT ACCEPT
/sbin/iptables -t mangle -P FORWARD ACCEPT
/sbin/iptables -t mangle -P OUTPUT ACCEPT
/sbin/iptables -t mangle -P POSTROUTING ACCEPT
elif [ $a == filter ]; then
/sbin/iptables -t filter -P INPUT ACCEPT
/sbin/iptables -t filter -P FORWARD ACCEPT
/sbin/iptables -t filter -P OUTPUT ACCEPT
fi
done
log_end_msg 0
;;
restart)
log_begin_msg "Restarting firewall..."
for a in `cat /proc/net/ip_tables_names`; do
/sbin/iptables -F -t $a
/sbin/iptables -X -t $a
done;
start
log_end_msg $?
;;
*)
echo "Usage: /etc/init.d/iptables {start|stop|restart|save}" >&2
exit 1
;;
esac
exit 0
- Allow execution:
Code:
$ sudo chmod +x /etc/init.d/iptables
- Add daemon to runlevels to run it before network is started (on boot) and kill it after network is stopped (on halt/reboot):
Code:
$ sudo update-rc.d iptables start 37 S . start 37 0 . start 37 6 .
Starting the firewall daemon
- Make sure that you set up iptables as explained above:
Code:
$ sudo iptables-rules
- Save iptables configuration for the daemon:
Code:
$ sudo /etc/init.d/iptables save
- Start the daemon:
Code:
$ sudo /etc/init.d/iptables start
- Done !
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Little correction, SSH is port 22, and not 23. Looks good apart from that though :)
What what I do to insert my own choice of port numbers to open?
Also, is it possible to have blocked connections logged, such as in Firestarter?
Thanks,
Spudgun
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Quote:
Originally Posted by Spudgun
Little correction, SSH is port 22, and not 23. Looks good apart from that though :)
What what I do to insert my own choice of port numbers to open?
Also, is it possible to have blocked connections logged, such as in Firestarter?
Thanks,
Spudgun
Good view!
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Quote:
Originally Posted by Spudgun
Little correction, SSH is port 22, and not 23. Looks good apart from that though :)
What what I do to insert my own choice of port numbers to open?
Also, is it possible to have blocked connections logged, such as in Firestarter?
Thanks,
Spudgun
Thanks for your reply. I corrected the port number.
For insering your own ports, just edit the script (it should be enough self explaining). Or tell me what you want and I'll add to the script.
About logging, I'm not sure, I'm not an iptables expert. I'll check and post if I find something !
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Could this also be used for creating a router using Ubuntu? Obviously some of the settings would need to be changed, but it seems logical anyway. The Daemon script appears to be very generic and would save any iptables settings that you use. I have been seriously contemplating a nice Ubuntu router since I would love things like DNS on the network. The only thing that gets confusing the the iptables part of the configuration. If I understand correctly, iptables commands have to be issued on every boot, correct? Sorry if I am a little confusing, feel free to ask questions.
Thanks,
Kyle
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Thanks, Sam, this is exactly the information I needed! One question...
You have this command for starting the daemon:
Code:
$ sudo update-rc.d iptables start 37 S . start 37 0 . start 37 6 .
But pinnockio (in his original post that you linked to) has this command instead:
Code:
sudo update-rc.d iptables start 37 S . stop 37 0 .
I've been using Linux for a whole two days so I am obvously a real expert on this -- but is one of these wrong, or are they equivalent?
Thanks.
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Quote:
Originally Posted by Bill Statler
Thanks, Sam, this is exactly the information I needed! One question...
You have this command for starting the daemon:
Code:
$ sudo update-rc.d iptables start 37 S . start 37 0 . start 37 6 .
But pinnockio (in his original
post that you linked to) has this command instead:
Code:
sudo update-rc.d iptables start 37 S . stop 37 0 .
I've been using Linux for a
whole two days so I am obvously a real expert on this -- but is one of these wrong, or are they equivalent?
Thanks.
Both a different. pinnockio's way was wrong, because the firewall is stopped before the network daemons. I took some time to find out that in runlevel 0 and 6 (halt and reboot), services flagged as starting are stopped after those flagged as stopping (sounds weird...). So if you look at the order, the iptables daemon is stopped after other network daemons.
And I also added firewall's deactivation in case of a reboot ('start 37 6').
Hope you understand !
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Thanks for the explanation!
Quote:
Originally Posted by Sam
... in runlevel 0 and 6 (halt and reboot), services flagged as starting are stopped after those flagged as stopping (sounds weird...)
I tried standing on my head to read that, and now it makes perfect sense. This really covers a lot of what I'm trying to do on my new PC -- now all I have to do is add IP masquerading to the stew so my wife's WinXP machine can share the Internet connection. Oh, and then I'll have to figure out Samba. No problem!
Thanks again!
Re: HOWTO: Use iptables as firewall with a daemon on system startup
opening http, imap, smtp and pop3 is just for servers? i access sites and i receive/send a lot of mails, without being a server. if i block those ports, am i going to be able to do what I'm used to?
Re: HOWTO: Use iptables as firewall with a daemon on system startup
Quote:
Originally Posted by LaSSarD
opening http, imap, smtp and pop3 is just for servers? i access sites and i receive/send a lot of mails, without being a server. if i block those ports, am i going to be able to do what I'm used to?
Yes! This firewall works only for incoming traffic. All your outgoing traffic is not blocked (you're supposed to know what you're doing). If you don't use any server services, just allow ping with the firewall setup.
You pointed out that it's not clearly explained with the firewall setup. I'll update this when I'll have some time.