Εάν όμως θέλετε να ανοίξετε κάποια ports αναγκαστικά θα πρέπει να ασχοληθείτε με τη δομή του iptables. Πολλοί χρήστες δυσκολεύονται σε αυτό καταφεύγοντας σε προγράμματα ρύθμισης iptables με γραφικό περιβάλλον (firestarter, guarddog κλπ).
Ο παρακάτω οδηγός είναι για αυτούς που δεν θέλουν να χρησιμοποιήσουν ή δεν μπορούν να χρησιμοποιήσουν (ubuntu server) προγράμματα ρύθμισης iptables με γραφικό περιβάλλον.
Είναι δύο scripts με τα οποία ο χρήστης μετά το τέλος του οδηγού θα μπορεί να ανοίγει/κλείνει ports απαντώντας με ένα y ή n, χωρίς να ταλαιπωρείται με εντολές και ορισμούς στο iptables. Καλύπτει όλες τις υπηρεσίες που θα χρειαστεί ένας μέσος χρήστης. Για τους πιο έμπειρους είναι πολύ εύκολο να προσθέσουν και άλλες υπηρεσίες.
Τα δύο script είναι:
-iptables-rules
script κανόνων με το οποίο επιλέγουμε ποια ports θα ανοίξουμε
-iptables
init.d script daemon για την εκτέλεση iptables σε κάθε boot.
ΠΡΟΣΟΧΗ!!!
Στον παρακάτω οδηγό χρησιμοποιώ για editor το nano. Μην χρησιμοποιείτε το gedit γιατί παρατήρησα προβλήματα κατά τη διαδικασία copy-paste. Χαλάει τη δομή των script με αποτέλεσμα να μην εκτελούνται. Χρησιμοποιείστε terminal editor (nano, mc κλπ).
Ξεκινάμε...
Δημιουργία του script κανόνων
-Δημιουργούμε ένα νέο script:
- Κώδικας: Επιλογή όλων
sudo nano /usr/local/bin/iptables-rules
-Copy-paste του παρακάτω κώδικα:
- Κώδικας: Επιλογή όλων
#! /bin/bash
#
# 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_webmin="0"
echo -n "Allow webmin (web-based system administration) (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_webmin="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
#webmin (10025)
if [ $allow_webmin -eq "1" ] ; then
iptables -A INPUT -p tcp --dport 10025 -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
-Το κάνουμε εκτελέσιμο:
- Κώδικας: Επιλογή όλων
sudo chmod +x /usr/local/bin/iptables-rules
-Εκτέλεση να δούμε ότι δουλεύει:
- Κώδικας: Επιλογή όλων
sudo iptables-rules
Δημιουργία του firewall daemon
-Δημιουργούμε ένα νέο script:
- Κώδικας: Επιλογή όλων
sudo nano /etc/init.d/iptables
-Copy-paste του παρακάτω κώδικα:
- Κώδικας: Επιλογή όλων
#! /bin/bash
#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
-Το κάνουμε εκτελέσιμο:
- Κώδικας: Επιλογή όλων
sudo chmod +x /etc/init.d/iptables
-Προσθήκη του daemon στο runlevels για να εκτελείται πριν τη εκκίνηση του δικτύου (κατά το boot) και να τερματίζει μετά τη παύση του δικτύου (halt/reboot):
- Κώδικας: Επιλογή όλων
sudo update-rc.d iptables start 37 S . start 37 0 . start 37 6 .
Εκκίνηση του firewall daemon
-Ρυθμίζουμε/ελέγχουμε ξανά τους κανόνες iptables όπως κάναμε παραπάνω:
- Κώδικας: Επιλογή όλων
sudo iptables-rules
-Αποθήκευση των ρυθμίσεων iptables για το daemon:
- Κώδικας: Επιλογή όλων
sudo /etc/init.d/iptables save
-Εκκίνηση του daemon:
- Κώδικας: Επιλογή όλων
sudo /etc/init.d/iptables start
Πως προσθέτουμε δικούς μας κανόνες
Όπως είχα γράψει παραπάνω, οι κανόνες που υπάρχουν στο script θα ικανοποιήσουν τον μέσο χρήστη. Οι πιο έμπειροι μπορούν να προσθέσουν και τους δικούς τους κανόνες.
Για παράδειγμα εάν θέλει κάποιος να δημιουργήσει κανόνα για torrent με TCP port 6881 ακολουθεί τα εξής βήματα:
-Ανοίγουμε το script με τους κανόνες iptables:
- Κώδικας: Επιλογή όλων
sudo nano /usr/local/bin/iptables-rules
-Γράφουμε τα εξής στο τμήμα των κανόνων:
- Κώδικας: Επιλογή όλων
allow_torrent="0"
echo -n "Allow torrent (y/n)? [y] "
read input
if [ -z "$input" ] || [ "$input" == "y" ] || [ "$input" == "yes" ] || [ "$input" == "Y" ] || [ "$input" == "YES" ] ; then
allow_torrent="1"
fi
ΠΡΟΣΟΧΗ!!!
Ο παραπάνω κώδικας μπορεί να προστεθεί πριν ή μετά από οποιοδήποτε κανόνα (δεν παίζει ρόλο η σειρά) μετά το fi του κάθε κανόνα και πουθενά αλλού στο script.
-Γράφουμε τα εξής στο τμήμα ορισμών των ports του κανόνα:
- Κώδικας: Επιλογή όλων
#torrent (6881)
if [ $allow_torrent -eq "1" ] ; then
iptables -A INPUT -p tcp --dport 6881 -j ACCEPT
iptables -A INPUT -p udp --dport 6881 -j ACCEPT
fi
-Αποθηκεύουμε το script
-Ρυθμίζουμε/ελέγχουμε ξανά το iptables με τον νέο κανόνα:
- Κώδικας: Επιλογή όλων
sudo iptables-rules
-Αποθήκευση των ρυθμίσεων iptables για το daemon
- Κώδικας: Επιλογή όλων
sudo /etc/init.d/iptables save
-Επανεκκινούμε το iptables ή κάνουμε επανεκκίνηση του υπολογιστή:
- Κώδικας: Επιλογή όλων
sudo /etc/init.d/iptables restart
-Τέλος...