Sam
August 15th, 2005, 09:41 AM
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:
$ sudo gedit /usr/local/bin/iptables-rules
Paste the following lines:
#! /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:
$ sudo chmod +x /usr/local/bin/iptables-rules
Run this script to apply iptables rules:
$ sudo iptables-rules
Create the firewall daemon
Thank you pinnockio for your iptables firewall script (http://ubuntuforums.org/showthread.php?t=19106) !
Create a new script:
$ sudo gedit /etc/init.d/iptables
Paste the following lines:
#! /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:
$ 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):
$ 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:
$ sudo iptables-rules
Save iptables configuration for the daemon:
$ sudo /etc/init.d/iptables save
Start the daemon:
$ sudo /etc/init.d/iptables start
Done !
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:
$ sudo gedit /usr/local/bin/iptables-rules
Paste the following lines:
#! /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:
$ sudo chmod +x /usr/local/bin/iptables-rules
Run this script to apply iptables rules:
$ sudo iptables-rules
Create the firewall daemon
Thank you pinnockio for your iptables firewall script (http://ubuntuforums.org/showthread.php?t=19106) !
Create a new script:
$ sudo gedit /etc/init.d/iptables
Paste the following lines:
#! /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:
$ 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):
$ 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:
$ sudo iptables-rules
Save iptables configuration for the daemon:
$ sudo /etc/init.d/iptables save
Start the daemon:
$ sudo /etc/init.d/iptables start
Done !