Monday, April 07, 2008
Αναστηθήκαμε και μεταφερόμαστε!
Thursday, February 23, 2006
Ο τροχονόμος στην γέφυρα: traffic control στο σπιτικό bridged firewall
Στο προηγούμενο τεχνικό ποστ, ο Harry πρόσθεσε σαν σχόλιο ένα script για QoS και fair queeing βασισμένο στον scheduler CBQ. Φυσικά έχει δίκιο πως καμία υπερφορτωμένη γραμμή δεν μπορεί να λειτουργήσει σωστά χωρίς να ρυθμίσουμε τις «προτεραιότητές» μας. Ποια πακέτα δηλαδή πρέπει να «τρέξουν» όσο γίνεται πιο γρήγορα και ποια μπορούν να περιμένουν και λιγάκι πριν φύγουν προς το διαδίκτυο χωρίς να βάλουμε και τα κλάμματα. Προφανώς, ό,τι αφορά interactive χρήση του δικτύου (π.χ. web) πρέπει να έχει προτεραιότητα από τα «κατεβαστήρια», κι αν η γραμμή μας είναι «μπουκωμένη», τα τελευταία θα πρέπει να παραδώσουν όσο bandwidth χρειάζονται τα πρώτα για να μην κοιμηθούμε πριν φορτώσει η σελίδα.
Ένα βασικό θέμα που θα πρέπει να ξεκαθαρίσουμε από την αρχή είναι πως το Quality of Service (QoS) μπορεί να ελέγξει ό,τι βγαίνει από το gateway προς τα έξω και όχι ότι έρχεται από τον έξω κόσμο. Θεωρητικά, μπορούμε να βάλουμε μια QoS discipline και στην εσωτερική NIC, ελέγχοντας τα πακέτα που φεύγουν από τον gateway προς τους τοπικούς υπολογιστές, αυτό όμως σπάνια είναι χρήσιμο καθότι «προς τα μέσα» έχουμε μια σύνδεση στα 100Mbps (Fast Ethernet) ενώ προς τα έξω κάτι πολυ μικρότερο και άρα καθοριστικό στον κορεσμό της επικοινωνίας.
Ένα άλλο σημαντικό σημείο του QoS είναι πως θα πρέπει να περιορίσουμε το συνολικό upload bandwidth ελάχιστα πιο κάτω από το πραγματικό maximum ώστε να ελέγχουμε εμείς το data flow και όχι το επόμενο hop στο δίκτυο του ISP μας.
Το σημαντικό πλεονέκτημα ενός συστήματος QoS, σε αντίθεση με το «κλασσικό» traffic shaping είναι πως ενώ αυτό το τελευταίο καθορίζει στατικά τα όρια χρήσης του bandwidth για κάθε υπολογιστή, το QoS επιτρέπει σε οποιοδήποτε client να πάρει ολόκληρο το εύρος ζώνης υπό την προυπόθεση πως κάτι άλλο πιο «επείγον» δεν χρειάζεται μέρος ή και το 100% αυτής. Το μειονέκτημα είναι πως το κλασσικό traffic shaping μπορεί κάλλιστα να ελέγξει και το inbound traffic, αφού ορίζει συγκεκριμμένα όρια.
Στην περίπτωσή μας, το χειρότερο πρόβλημα ήταν τα φυσικά όρια του router της fastweb που κατακλειζόταν απο open connections του eMule, καθιστώντας αδύνατη άλλη επικοινωνία εάν δεν έβρισκε κάποιο «χρονικό παράθυρο» ανάμεσα στο κλείσιμο μιας σύνδεσης και στο άνοιγμα της επόμενης. Αυτό λύθηκε με το connection limit target του iptables. Αλλά και με τα 500 μόνο connections που ορίσαμε σαν όριο για κάθε client μπορεί να μην φτάνουμε σε κορεσμό του router, φτάνουμε άνετα σε κορεσμό του εύρους ζώνης. Έπρεπε οπωσδήποτε να βάλουμε ένα σύστημα fair queeing αν και τελικά κατασταλάξαμε στους κανόνες μόλις χτες, ύστερα από πολλές δοκιμές. Συμπληρώνοντας λοιπόν το προηγούμενο ποστ, εδώ παρουσιάζω το scriptακι για το QoS που εφαρμόζουμε.
Προτιμήσαμε σαν βασικό discipline το ΗΤΒ καθότι αρκετά «καθαρό» και straight forward, ενώ στο εσωτερικό κάθε «φέτας», το μοίρασμα ανάμεσα στα πακέτα (και κατ' επέκταση ανάμεσα στα client pc) γίνεται από το SFQ. Μην έχοντας έναν εξωφρενικά μεγάλο αριθμό υπολογιστών πίσω από το gateway, αυτός ο συνδυασμός τα καταφέρνει μια χαρά, ενώ παράλληλα είναι αρκετά απλός στον χειρισμό και την εξέλιξή του με το έξτρα πλεονέκτημα πως είναι αρκετά ελαφρύς ώστε να μην «πνίγει» τον κουρασμένο Duron που βρισκεται καταχωνιασμένος στην αποθήκη...
Χωρίσαμε τα πακέτα σε 3 ιδεατές ομάδες: «υπερεπείγοντα», «διαδραστικά» και «μάζα». Στα «διαδραστικά» καταλείγουν όλα τα πακέτα που αφορούν «νορμάλ» χρήσεις του δικτύου και άρα απευθύνονται σε «κλασσικές» destination ports όπως 80, 25 κτλ. Στα υπερεπείγοντα πάνε όλα τα UDP packets καθότι από την μία είναι «υπερευαίσθητα» ως stateless datagramms και από την άλλη είτε ιδιαίτερα μικρά ώστε να μην πνίγουν την γραμμή από μόνα τους κιας έχουν top priority είτε αφορούν κρίσιμα services όπως το VOIP buster, ένα major hit σε τούτο το σπίτι. Στην «μάζα» καταλήγουν όλα τα υπόλοιπα αφού είναι σχεδόν αποκλειστικά p2p traffic. Μια τελευταία πινελιά είναι ο χειρισμός των πακέτων ACK για την διαδραστική κατηγορία ως υπερεπείγοντα, βοηθώντας περεταίρω στην διαδραστικότητα κυρίως του web που διαφορετικά παρουσίαζε ένα αρχικό latency πριν ξεκινήσει μια ορθολογική ταχύτητα στο φόρτωμα της σελίδας. Εδώ ίσως θα έπρεπε να κόψουμε τα «διαδραστικά» σε δύο υπο-ομάδες διαφορετικής μεταχείρισης παρά την απευθείας μεταφορά των ACK στα υπερεπείγοντα (ένα massive web download θα μπορούσε ίσως να προκαλέσει προβλήματα στο VOIP traffic, αυτό θα πρέπει να δοκιμαστεί).
Ορίστε το script:
#!/bin/bash
#(C) 2006 G. Tsarouchas - G. Grammatikopoulos
#licensed under GPL v.2
#setting variables
UPSPEED=510
OUT_IF=eth1
IN_IF=eth0
BRIDGE_IF=br0
HI=0
NORM=1
LOW=2
#starting up the party
start_tc()
{
#setting root disk, "non otherwise specified" packets end up in the slowest of all discs
tc qdisc add dev $OUT_IF root handle 1: htb default 30
#general orders
tc class add dev $OUT_IF parent 1: classid 1:1 htb rate ${UPSPEED}kbit burst 6k
#hi priority
tc class add dev $OUT_IF parent 1:1 classid 1:10 htb rate $[5*$UPSPEED/10]kbit ceil ${UPSPEED}kbit prio $HI
#normal priority
tc class add dev $OUT_IF parent 1:1 classid 1:20 htb rate $[4*$UPSPEED/10]kbit ceil ${UPSPEED}kbit prio $NORM
#low priority
tc class add dev $OUT_IF parent 1:1 classid 1:30 htb rate $[3*$UPSPEED/10]kbit ceil $[9*$UPSPEED/10]kbit prio $LOW
#fair queeing WITHIN each disc is enforced by SFQ
tc qdisc add dev $OUT_IF parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $OUT_IF parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $OUT_IF parent 1:30 handle 30: sfq perturb 10
#filtering the stuff
#"normal" traffic gets the medium treatment
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 8080 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 143 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 465 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 443 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 110 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 993 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 995 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 5000 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 20 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 21 0xffff flowid 1:20
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip dport 22 0xffff flowid 1:20
#entire UDP protocol traffic gets topmost priority: this includes VOIP buster traffic
tc filter add dev $OUT_IF protocol ip parent 1:0 prio 1 u32 match ip protocol 17 0xff flowid 1:10
#giving topmost priority for ACK packets related to the priviledged 1:20 ports; this should speed up interactive usage even more.
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 80 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 8080 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 143 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 465 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 25 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 443 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 110 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 993 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 995 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 5000 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 20 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 21 0xffff flowid 1:10
tc filter add dev $OUT_IF parent 1:0 protocol ip prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 match ip dport 22 0xffff flowid 1:10
}
#blanking all the tc stuff in one single cute command
stop_tc()
{
/sbin/tc qdisc del dev $OUT_IF root
}
#restarting the whole tc business
restart_tc()
{
stop_tc
start_tc
}
#handling command-line arguments
case "$1" in
start)
echo "Starting traffic control shaping..."
start_tc
;;
stop)
echo "Stopping traffic control shaping..."
stop_tc
;;
restart)
echo "Stopping traffic control shaping..."
stop_tc
echo "Starting traffic control shaping..."
start_tc
;;
*)
echo "Usage: $0 {start|stop|restart}"
;;
esac
Sunday, February 19, 2006
Το μουλάρι, ο πινγκουίνος και η γέφυρα.
Η κατάσταση
Στο σπίτι εχουμε μια σύνδεση τύπου LAN μέσω ενός proprietary router που επιτρέπει μέσω dhcp μόνο 3 IP addresses. Καθώς είμαστε 3 στο σπίτι και εγώ έχω δύο υπολογιστές (tower και laptop), χρησιμοποιώ ένα custom linux gateway για να συνδεθώ στον router. Οι άλλοι δύο συγκάτοικοι ωστόσο αρνούνται πεισματικά να μπούν «πίσω» από το firewall τόσο εξαιτίας του περιορισμού στις ηλιθιώδεις uPNP συνδέσεις που το λογισμικό της Μ$ χρησιμοποιεί κατά κόρον όσο και, όπως υποπτεύομαι, μιας κουτοπόνηρης απληστίας για το bandwidth (φοβούμενοι μάλλον πως πίσω από ένα firewall του οποίου μόνο εγώ έχω τις τεχνικές γνώσεις να ρυθμίσω θα τους «έριχνα» στο traffic shaping).
Ένας δεύτερος περιορισμός είναι πως το upload bandwidth είναι ιδιαίτερα περιορισμένο σε σχέση με το download (4Mbps down / 512Kbps up) με αποτέλεσμα πως όταν το download πλησιάζει τον κορεσμό, το upload να καταλαμβάνεται σχεδόν εντελώς από τα ACK πακέτα.
Το τρίτο, και ίσως σημαντικότερο, πρόβλημα είναι πως ο router είναι μάλλον της πλάκας και έχει ιδιαίτερα περιορισμένη χωρητικότητα στα ARP tables.
Το πρόβλημα
Το πρώτο πρόβλημα που παρουσιάστηκε, αυτό του κορεσμού του upload εξαιτίας του downloading, θα λυνόταν εύκολα με QoS στο firewall. Λόγω της μη συμμετοχής των δύο κύριων λειτουργών του (προσωπικά θα με δείτε να κάνω massive download μόνο στα update της gentoo) το πρόβλημα τελικά λύθηκε με προσωπικά network traffic limits στα P2P «κατεβαστήρια» του καθενός.
Όταν όμως πρόσφατα και οι δύο πέρασαν από το DC πρωτόκολο σε eMule... άρχισε το δράμα, χειρότερο από ποτέ άλλοτε και ιδίως για μένα που και πέρναγα από ενα επιπλέον hop (τον gateway) και δεν κράταγα live connections αφού ως επί το πλείστον έκανα web browsing και check mails. Η κατάσταση έφτασε στο απροχώρητο: loading web pages αρκετές φορές με μισό kb/s, 3 στις 5 φορές οι mail servers έπεφταν σε timeout connection και γενικά η σύνδεσή μου είχε καταντήσει unusable.
Ομολογώ πως έφτασα σε τέτοια απόγνωση που σε μια συζήτηση για το πρόβλημα με έναν φίλο, επαγγελματία sysadmin, αγγίξαμε την ιδέα μεταξύ σοβαρού και αστείου για ARP poisoning, να DoSάρω δλδ τους συγκάτοικους για να μπορώ να δω και κανα μπλογκ! Έκει όμως κάτι έκανε «κλικ» στο μυαλό μας: δεν ηταν το πνιγμένο download που μου έκανε την ζωή δύσκολη, αφού διαπιστωμένα τα «κατεβαστήρια» είχαν λογικά όρια, αλλά τα connections. Το μουλάρι (eMule) από default αφήνει έναν απίστευτα υψηλό αριθμό ανοιχτών συνδέσεων (με «κόφτη» κάπου στις 70000 αν δεν κάνω λάθος) κι ας μην κατεβάζει στα όρια της γραμμής. Αυτή η συμπεριφορά δεν εμφανίζεται σε άλλα πρωτόκολα p2p και εξ ου η δραματική αλλαγή όταν και οι δύο πέρασαν σε συστηματική του χρήση. Μιλάμε επίσης για δύο εντελώς non-techie ανθρώπους που αποκλείεται να έπαιρναν είδηση του τι και γιατί συμβαίνει ενώ οι πρώτες «διερευνητικές» νύξεις μου έπεσαν εντελώς στο κενό. Όποια λύση και να έβρισκα, θα έπρεπε να την βρώ μόνος μου και να είναι εντελώς transparent στους άλλους δύο.
Η λύση
Ο Γιώργος (ο sysadmin) είχε βρεθεί σε μια αντίστοιχη φάση στην εταιρία που δούλευε παλιότερα όταν μια κατοστάρα pc «τσακώνονταν» για μια θέση στα ARP tables μιας SOHO σύνδεσης στα 12Mbps. Μιλάμε φυσικά για «μεσογειακές καταστάσεις» όπου εταιρικός ή μη υπολογιστής, αφού έχει broadband access, θα έχει και το «μουλάρι» του, με αποτέλεσμα όσοι έφταναν πέντε λεπτά νωρίτερα από τους άλλους να κατεβάζουν της παναγιάς τα μάτια και οι υπόλοιποι να αδυνατούν να στείλουν ένα απλό text mail!
Η λύση που έδωσε τότε ήταν το στήσιμο ενός linux firewall με «patchαρισμένο» netfilter για "connection limit" target. Έτσι, κανείς χρήστης δεν μπορούσε να έχει πάνω από έναν συγκεκριμένο αριθμό ανοιχτών connections με αποτέλεσμα να μην «μπουκώνει» ο router και ενώ τα μουλάρια συνέχιζαν να κατεβάζουν με μια λογική ταχύτητα, όλοι είχαν ουσιαστική access στο internet για «πιο χρήσιμα πράγματα» όπως mails και web.
Εδώ όμως είχαμε ένα επιπρόσθετο πρόβλημα: η δουλειά έπρεπε να γίνει εντελώς transparent, σαν να μην υπήρχε καν ο gateway στην θέση του και τα pc να συνδέονταν κατευθείαν στον router. Η λύση στο πρόβλημα ήρθε με την μορφή του bridging, γεφυρώνοντας την «εξωτερική» eth1 με την «εσωτερική» eth0. Για τον έλεγχο του headless gateway προσθέσαμε μια τρίτη NIC με private address και μέσω της οποιάς μπορώ να συνδεθώ με ssh. Τα πρώτα αποτελέσματα είναι εξαιρετικά ικανοποιητικά αν και χρειάζεται ακόμα πολύ fine tunning.
Το «How-To»
Τι χρειάζεστε:
- Τα bridge-utils για την δημιουργία και τον έλεγχο της bridge.
- Έναν πρόσφατο 2.6.x kernel.
- Τον πηγαίο κώδικα του latest stable iptables (προς το παρόν 1.3.5).
- Το latest patchset "patch-o-matic" (εμείς χρησιμοποιήσαμε το patch-o-matic-ng-20060216).
Το «στήσιμο»:
- «Στήνετε» κανονικά (configure - make - make install) τα bridge-utils.
- «Ξεπακεταρετε» στο /usr/src/ τον kernel, το iptables και το patch-o-matic.
- Μπαινετε στην directory του patch-o-matic και τρεχετε το εξης command που θα «πατσάρει» kernel sources και το userland iptables με τα «known to work» features: KERNEL_DIR=/usr/src/linux IPTABLES_DIR=/usr/src/iptables-1.3.5 ./runme base
- Ρυθμίζουμε τον kernel (π.χ. με make menuconfig) ώστε να περιέχει σαν support το bridging καθώς και όλα τα targets του netfilter που μας ενδιαφέρουν κατά προτίμιση σαν modules. ΠΡΟΣΟΧΗ, στον δικό μου 2.6.11-gentoo-r4 το TIME target εκανε fail οπότε και ξύλωσα το support γι' αυτό (δεν ήταν κάτι που με «έκαιγε» κιόλας). Λογικά ένας πιο recent kernel δεν θα αντιμετωπίσει πρόβλημα με κανένα module αλλά που να κατέβαζα 30+Mb με τέτοιο πρόβλημα που είχα...
- Στήνουμε κανονικά τον kernel (make - make modules_install) και τον φορτώνουμε στον bootloader.
- Στήνουμε το userspace iptables με make KERNEL_DIR=/usr/src/linux και make install KERNEL_DIR=/usr/src/linux
- Reboot, και ειμαστε έτοιμοι να φτιάξουμε ένα bridging firewall με connection limiting.
Οι firewall rules
Για να μην σπάμε τα @@ μας, βασιζόμενοι στο αρχικό script του Γιώργου για την εταιρία, στήσαμε τα παρακάτω scriptακια. Φυσικά λοίπουν οι rules για το νορμαλ firewalling που θα πρέπει να προσθέσετε εσείς ανάλογα με τις ανάγκες σας, ενώ interfaces και IP addresses θα πρέπει να προσαρμοστούν στο δικό σας περιβάλλον.
Το /etc/init.d/fw-bridge (αυτόματο «ανέβασμα» και «κατέβασμα» του bridging firewall):
#!/bin/bash
#(C) G. Tsarouchas 2005-2006
DATESTAMP=`date`
LOGFILE=/var/log/fw-status.log
flush_rules()
{
ERRORSTATUS=0
echo -n "Flushing Firewall Rules..."
LIMIT=`grep -v -e '^#' /etc/fw-rules/flush.cfg |wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/flush.cfg | tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
default_policy()
{
ERRORSTATUS=0
echo -n "Applying Default Policy...."
LIMIT=`grep -v -e '^#' /etc/fw-rules/policy.cfg|wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/policy.cfg| tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
create_chains()
{
ERRORSTATUS=0
echo -n "Creating IPTABLES Chains"
LIMIT=`grep -v -e '^#' /etc/fw-rules/chains-declare.cfg |wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/chains-declare.cfg| tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
assign_chains()
{
ERRORSTATUS=0
echo -n "Assigning Default Chain Policies"
LIMIT=`grep -v -e '^#' /etc/fw-rules/chains-policy.cfg |wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/chains-policy.cfg| tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $(echo "$RESULT") 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
outbound_traffic()
{
ERRORSTATUS=0
echo -n "Applying Outbound Policy"
LIMIT=`grep -v -e '^#' /etc/fw-rules/intranet-internet.cfg |wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/intranet-internet.cfg |tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
inbound_traffic()
{
ERRORSTATUS=0
echo -n "Applying Inbound Policy"
LIMIT=`grep -v -e '^#' /etc/fw-rules/internet-intranet.cfg |wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/internet-intranet.cfg |tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
gateway_traffic()
{
ERRORSTATUS=0
echo -n "Applying Gateway's self Policy"
LIMIT=`grep -v -e '^#' /etc/fw-rules/gateway.cfg|wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/gateway.cfg |tail -n $i |line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
natting_rules()
{
echo -n "Applying NAT rules"
LIMIT=`grep -v -e '^#' /etc/fw-rules/nat.cfg|wc -l | cut -d " " -f 1`
for ((i=LIMIT ; i > 0 ; --i))
do
RESULT=`grep -v -e '^#' /etc/fw-rules/nat.cfg|tail -n $i|line`
echo -ne "\tiptables $RESULT " >> $LOGFILE
/sbin/iptables $RESULT 2>> $LOGFILE
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
modules_load()
{
ERRORSTATUS=0
echo -n "Loading IPTABLE'S modules "
for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip*
do
echo -n "Loading Module " >> $LOGFILE
MDL=$(echo $i|cut -d / -f 9|cut -d "." -f 1)
echo -n " $MDL " >> $LOGFILE
modprobe $MDL 2>&1 >/dev/null
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
modules_unload()
{
ERRORSTATUS=0
echo -n "Unloading IPTABLE'S modules "
for i in /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/ip*
do
echo -n "Unloading Module " >> $LOGFILE
MDL=$(echo $i|cut -d / -f 9|cut -d "." -f 1)
echo -n " $MDL " >> $LOGFILE
modprobe -r $MDL 2>&1 >/dev/null
RET_VAL=$?
if [ $RET_VAL != "0" ]
then echo "...FAILED" >> $LOGFILE
ERRORSTATUS=1
else
echo "...done!" >> $LOGFILE
fi
done
if [ $ERRORSTATUS = "1" ]
then echo "......FAILED"
else
echo "......done"
fi
}
bridge_start()
{
echo -n "Activating Bridging ...."
echo 1 > /proc/sys/net/ipv4/ip_forward
echo -n "Shutting down interfaces "
/etc/init.d/net.eth0 stop 2>&1 >> $LOGFILE
if [ "$?" != "0" ]
then echo -n "ETH0 FAILED"
else
echo -n "eth0"
fi
/etc/init.d/net.eth1 stop 2>&1 >> $LOGFILE
if [ "$?" != "0" ]
then echo "ETH1 FAILED"
else
echo "eth1"
fi
echo -n "Getting eth0 in promiscuous mode..."
/sbin/ifconfig eth0 0.0.0.0 up
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "Getting eth1 in promiscuous mode..."
/sbin/ifconfig eth1 0.0.0.0 up
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "Creating bridge br0..."
/sbin/brctl addbr br0
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "adding interfaces "
/sbin/brctl addif br0 eth0
if [ "$?" != "0" ]
then echo -n "ETH0 FAILED"
else
echo -n "eth0"
fi
/sbin/brctl addif br0 eth1
if [ "$?" != "0" ]
then echo "ETH1 FAILED"
else
echo "eth1"
fi
echo -n "Activating dhcp on br0..."
/sbin/dhcpcd br0
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "Activating Bridge " >> $LOGFILE
}
bridge_stop()
{
echo -n "Deactivating Bridging ...."
echo 0 > /proc/sys/net/ipv4/ip_forward
echo -n "Deactivating Bridging " >> $LOGFILE
/sbin/brctl delif br0 eth0
/sbin/brctl delif br0 eth1
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "Destroying bridge br0..."
/sbin/brctl delbr br0
if [ "$?" != "0" ]
then echo "FAILED"
else
echo "Done"
fi
echo -n "Activating ethernet "
/etc/init.d/net.eth0 start
if [ "$?" != "0" ]
then echo -n "ETH0 FAILED"
else
echo -n "eth0"
fi
/etc/init.d/net.eth1 start
if [ "$?" != "0" ]
then echo "ETH1 FAILED"
else
echo "eth1"
fi
}
case "$1" in
start)
echo "Starting Gateway..."
echo "Starting Gateway at $DATESTAMP">> $LOGFILE
bridge_start
modules_load
flush_rules
default_policy
create_chains
assign_chains
outbound_traffic
inbound_traffic
gateway_traffic
natting_rules
;;
stop)
echo "Stopping Gateway..."
echo "Stopping Gateway at $DATESTAMP">> $LOGFILE
flush_rules
modules_unload
bridge_stop
;;
restart)
echo "Restarting Gateway"
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
;;
esac
/etc/fw-rules/chains-declare.cfg:
-N intranet-internet
-N internet-intranet
-N icmp-acc
-N external
-N internal
-N limited
-N bridge-in
-N bridge-out
#end here
/etc/fw-rules/chains-policy.cfg:
-A INPUT -p icmp -j icmp-acc
-A INPUT -i br0 -j external
-A INPUT -i eth2 -j internal
-A FORWARD -p icmp -j icmp-acc
-A FORWARD -i eth2 -o br0 -j intranet-internet
-A FORWARD -i br0 -o eth2 -j internet-intranet
-A limited -j LOG --log-level info --log-prefix Limited_
-A limited -j REJECT
-A FORWARD -m physdev --physdev-in eth1 --physdev-out eth0 -j bridge-in
-A FORWARD -m physdev --physdev-in eth0 --physdev-out eth1 -j bridge-out
-A intranet-internet -j LOG --log-prefix intra-inter_
-A internet-intranet -j LOG --log-prefix out-in_
-A bridge-out -j LOG --log-prefix bridge-out_
-A bridge-in -j LOG --log-prefix bridge-in_
#end here
/etc/fw-rules/flush.cfg:
-Z
-X
-F
-t nat -F
#End Here
/etc/fw-rules/gateway.cfg:
-A external -p tcp -s 0/0 --dport 22 -j ACCEPT
-A internal -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT
#end here
/etc/fw-rules/internet-intranet.cfg:
-A internet-intranet -p icmp -m limit --limit 30/minute -j ACCEPT
-A internet-intranet -p icmp -j REJECT
-A internet-intranet -m state --state ESTABLISHED,RELATED -j ACCEPT
-A internet-intranet -j DROP
#end here
/etc/fw-rules/intranet-internet.cfg:
-A icmp-acc -i eth2 -o br0 -m limit --limit 30/minute -j ACCEPT
connlimit --connlimit-above 25 --connlimit-mask 32 -j limited
-A intranet-internet -s 10.0.0.0/24 -d 0/0 -j ACCEPT
-A intranet-internet -j DROP
#Bridging support rules
-A bridge-in -j ACCEPT
-A bridge-out -p tcp --dport 1024:64000 --syn -m connlimit --connlimit-above 500 --connlimit-mask 32 -j limited
-A bridge-out -j ACCEPT
#end here
/etc/fw-rules/nat.cfg:
-t nat -A POSTROUTING -s 10.0.0.0/24 -o br0 -j MASQUERADE
#end here
/etc/fw-rules/policy.cfg:
-P FORWARD DROP
-P OUTPUT DROP
-A INPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth2 -s 10.0.0.0/24 -d 0/0 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A FORWARD -p udp -s 0.0.0.0/32 -d 255.255.255.255 --sport 67 --dport 68 -j ACCEPT
-A OUTPUT -o lo -s 0/0 -d 0/0 -j ACCEPT
-A OUTPUT -j ACCEPT
#end here
Monday, February 06, 2006
grep [:ITissues:] NikosDimou.blog &> /dev/null και άλλα παλαβιάρικα
Γύρισα τις προάλλες στην «παλιά την μπλογκογειτονιά» μιας και από την μία είχα λίγο ελεύθερο χρόνο και από την άλλη είχα κάτι πολύ σοβαρό (τουλάχιστον για μένα) να πω. Άρχισα να χαζεύω λοιπόν και λιγάκι στα πέριξ. Ένα από τα βασικά πράγματα που πρόσεξα ήταν μια απίστευτη animosity απέναντι στον γνωστό Νίκο Δήμου. Προφανώς κάποιοι νιώθουν πως «απειλούνται» από την παρουσία του στην «παρέα», πως «επισκιάζονται» απο το «ειδικό βάρος» της φήμης του συγγραφέα. Προσωπικά δεν τα καταλαβαίνω αυτά τα πράγματα. Γιατί θα πρέπει να κρίνω και να χειροκροτήσω ή να κατακρίνω τα γραφόμενα οποιουδήποτε με βάση το όνομά του; Ο άνθρωπος καλά έκανε και άνοιξε blog για να λέει τις απόψεις του. Μία χαρακτηριστική κριτική (ορθώς ενυπόγραφη) που διάβασα στο ΚΟΙΝΟΒΙΟ ήταν πως «γιατί ήρθε στο blogspot αφού έχει site;» Καταλαβαίνουμε ελπίζω την διαφορά ανάμεσα σε ένα λιγότερο ή περισσότερο στατικό site με ένα blog... Τώρα γιατί ο κ. Δήμου διάλεξε έναν τρίτο server όπως ετούτος εδώ της google, αυτό εξηγείται μάλλον με τα εξής: 1) Το να στήσεις μία μηχανή blogging πάνω σ'ένα web server δεν είναι δα και ό,τι πιο εύκολο, ενώ το blogspot ή το wordpress προσφέρουν ήδη την μηχανή έτοιμη. Φτάνει απλά να στήσεις το layout σου και είσαι έτοιμος. 2) Μπορεί κάλλιστα να θέλησε να «ψαρέψει» όσο το δυνατόν περισσότερα comments μπαίνοντας μέσα σε μία στημένη και μεγάλη κοινότητα. Πού το κακό ρε παίδες; Αν δεν γουστάρετε να βλέπετε τις γνώμες των άλλων γιατί αφήνετε τα comments ανοιχτά στα blog σας; Το feedback πιστεύω είναι ο σοβαρότερος λόγος που το blogging έχει αυτή την τάση δημιουργίας «εξάρτησης». Τα παραπάνω βέβαια ας μην εκληφθούν σαν «λουστράρισμα» του Ν. Δήμου από μέρους μου. Κι εδώ έρχομαι στο πρώτο μέρος του τίτλου. Με τον Νίκο Δήμου διαφωνώ σε πολλά θέματα και μάλιστα κατά τρόπο που μπορεί να χαρακτηριστεί συστηματικός όταν η κουβέντα γυρνάει σε θέματα πληροφορικής. Οι unixοθραμμένοι της παρέας καταλάβανε μάλλον ήδη από την ψευδοεντολή του τίτλου τι εννοώ. Τελευταίο παράδειγμα των ριζικών διαφορών στις απόψεις μας; Ένα, ασήμαντο κατά τ' άλλα, snippet από πρόσφατο post του κ. Δήμου: Ο Bill Gates αποφάσισε ότι θα δώσει το 95% της περιουσίας του στον Τρίτο Κόσμο. Δεν είναι μόνο ότι δίνει δισεκατομμύρια – έφτιαξε άλλη μία Microsoft, για να επιβλέψει την σωστή διανομή. Μάλιστα, ας γλείψουμε άλλο λίγο τον Βασιλάκη τον Πόρτα. Thank you my lord! God - fucking - bless you my lord! Αυτό μοιάζει σαν να σε πιάσουν να σε πηδήξουν, και αφού σου αφήσουν ένα πενηντάευρο για την «εξυπηρέτηση» να πεις και ευχαριστώ! Πως την έκανε την περιουσία ρε Δήμου ο μάγκας; Δεν έχω καταλάβει τον λόγο που στην ελλάδα αρνούμαστε πεισματικά να καταλάβουμε τι γίνεται γύρω μας. Η κυρά η Microsoft έχει ΚΑΤΑΔΙΚΑΣΤΕΙ τελεσίδικα για παράνομο μονοπώλειο από δικαστήριο των ΗΠΑ. Επίσης η Ε.Ε. θα της επιβάλει τεράστια πρόστιμα αν συνεχίσει τον χαβά της και δεν προσφέρει άμεσα αποδείξεις συνεργασίας της με άλλους δημιουργούς software αντί για τις συνήθεις θολές τακτικές της να αποκλείει την σωστή λειτουργία εφαρμογών τρίτων όταν ανταγωνίζονται δικά της προιόντα. Αυτό είναι ήδη λημμένη ΑΠΟΦΑΣΗ της Ευρωπαικής Επιτροπής. Όχι και άγιος ο Billys ρε παιδιά, μην ξεράσουμε! Για το φιλανθρωπικό του project έλεγε στον Αλογοσκούφη ο Βασιλάκης τις προάλλες;! Μια χαρά είναι η φιλανθρωπία, φτάνει να μην συνεπάγεται πως η πατρίδα μου θα σκλαβωθεί στις διαθέσεις μιας πολυεθνικής για τα επόμενα 20 χρόνια και το όλο σκέρτσο θα μου κοστίσει κάτι τρισεκκατομύρια ευρώ! Άσε ρε, βάζω FLOSS και αυτά που περισσεύουν - γιατί θα περισσέψουν ΠΑΡΑ ΠΟΛΛΑ - τα δίνω εγώ ο ίδιος στην Αφρική!!! Και ανοίγω και δουλειές στην ίδια μου την χώρα! Δεν με πιστεύετε; Καλά, ρωτήστε την γαλλική εφορία...