Ασφαλιστικά μέτρα ΑΕΠΙ κατά παρόχων, 2013 edition

Πριν λίγες μέρες έγινε πάρα πολύ σημαντική δίκη για το Ελληνικό Internet. Δυστυχώς όμως δεν έγινε καμία αναφορά από τους δημοσιογράφους που ασχολούνται με τα “νέα μέσα” για το θέμα, οι μόνοι οι οποίοι έχουν αναφερθεί στο θέμα και μάλιστα το έχουν παρακολουθήσει από πολύ κοντά είναι τα παιδιά του adslgr.com (Thread).

Λίγο ιστορία…
Πέρυσι είχαμε την “χαρά” το Πρωτοδικείο Αθηνών με την απόφαση 4658/2012 να δικαιώσει την ΑΕΠΙ στα ασφαλιστικά μέτρα που είχε κάνει εναντίον όλων των Ελλήνων παρόχων (ISPs) ώστε να αποκλειστεί η πρόσβαση προς 2 sites που βρισκόταν εκτός της χώρας μας. Η αίτηση των ασφαλιστικών μέτρων έγινε τον Οκτώβριο του 2010 και η τελική δίκη μετά τις αναβολές έγινε το Μάϊο του 2012. Τα 2 sites ήταν το ellinadiko.com και το music-bazaar.com. Ενώ η ΑΕΠΙ είχε ζητήσει να αποκλειστούν από τους παρόχους και οι IPs που κατείχαν τότε τα 2 sites αλλά και να αποκλειστούν από το επίπεδο του DNS, τα δικαστήρια διέταξαν μόνο τον αποκλεισμό των IPs. Οι περισσότεροι χρήστες του Ελληνικού Internet δεν έχουν την παραμικρή ιδέα για αυτή τη απόφαση και αυτό γιατί δεν τους επηρέασε στο ελάχιστο. Το ellinadiko για δικούς του λόγους είχε κλείσει πριν γίνει η δίκη, και έτσι οι χρήστες είχαν ήδη στραφεί σε άλλα sites, ενώ το music-bazaar είχε αλλάξει IP. Ενώ, δηλαδή, το δικαστήριο επέβαλε στους παρόχους να αποκλείσουν την IP 1.2.3.4 το music-bazaar είχε ήδη πριν την δίκη μεταφερθεί στην 5.6.7.8. Έτσι, και η IP του ellinadiko και η IP του music-bazaar στις οποίες γινόταν αναφορά στα ασφαλιστικά μέτρα του 2012 είναι αυτή τη στιγμή μη προσβάσιμες από τους Έλληνες χρήστες χωρίς να φιλοξενούν οτιδήποτε σχετικό με τα προηγούμενα sites. Και το ακόμα καλύτερο; Κανείς δεν γνωρίζει αν και πότε θα αρθούν αυτοί οι αποκλεισμοί, καθώς δεν υπάρχει τέτοια πρόβλεψη στην απόφαση. Οπότε ο δικαστής αυτός δημιούργησε δύο μαύρες τρύπες για το Ελληνικό Internet.

Τώρα που πήρε φόρα…
Στις 14/01/2013 η ΑΕΠΙ επανήλθε με 2 νέες αιτήσεις ασφαλιστικών μέτρων! Η πρώτη αφορούσε αποκλειστικά το website με όνομα www.thepiratebay.se και την IP του (194.71.107.15) και η δεύτερη αφορούσε το website με όνομα www.activeloads.com και την IP του (93.190.139.103). Σαν να μην έφτανε αυτό στις 26/04/2013 έρχεται και νέα αίτηση για ασφαλιστικά μέτρα για τα παρακάτω sites: www.greek-team.cc (www.mytog.net), www.p2planet.net, www.greek.to, www.tsibato.info, www.greekddl.eu, www.greek-best.com, www.kat.ph, www.isohunt.com, www.1337x.org, www.h33t.com και τις IPs που είχαν τότε. Στα ασφαλιστικά μέτρα ζητείται να αποκλειστεί η πρόσβαση στα website ή στις IP ή αν τα παραπάνω δεν γίνουν, ζητά να απαγορευτούν τα downloads (καταφορτώσεις) μουσικών έργων από αυτά τα websites (ζητά δηλαδή την εφαρμογή DPI (Deep Packet Inspection) από τους παρόχους). Η αίτηση της ΑΕΠΙ αναφέρει με 2 λόγια πως αφού δεν μπορούν να εντοπίσουν τους ιδιοκτήτες των websites αυτών, ζητούν από τα δικαστήρια να προστατέψει τα μέλη της ΑΕΠΙ από την “πειρατεία” εξαναγκάζοντας τους παρόχους να “τα κόψουν”. Μετά από διαπραγματεύσεις καταλήγει να γίνει μία δίκη και για τις τρεις αιτήσεις, τον Σεπτέμβριο του 2013. Η δίκη αναβάλλεται για τις 13/12/2013 όπου και έγινε. Τα επιχειρήματα των παρόχων ήταν για άλλη μια φορά πολύ καλά, αλλά μάλλον δεν παίζει και ιδιαίτερο ρόλο στα αυτιά των δικαστών που κατά πάσα πιθανότητα αγνοούν εντελώς τις τεχνικές λεπτομέρειες του εγχειρήματος, αν θεωρείται δύσκολο να εξηγήσει κανείς πως ακριβώς δουλεύουν τα torrents και γιατί τα websites αυτά δεν φιλοξενούν τα ίδια παράνομο περιεχόμενο, σκεφτείτε πόσο πιο δύσκολο είναι να να εξηγήσει κανείς πως δουλεύουν τα magnet links και το DHT. Άλλωστε φαίνεται πως οι δικαστές δεν ενδιαφέρονται ιδιαίτερα για το διαδίκτυο ή για την ιδιωτικότητα γενικότερα, διότι οι όποιες αποφάσεις βγουν θα επηρεάσουν σημαντικά την ιδιωτικότητα όλων των Ελλήνων χρηστών. Είμαστε πλέον σε αναμονή της απόφασης η οποία μπορεί να κάνει ακόμα και 3 μήνες για να βγει.

Ίδια απόφαση με την 4658/2012 ή μήπως όχι;
Η απόφαση ακόμα δεν έχει βγει αλλά κατά την εκτίμηση μου υπάρχει σοβαρή περίπτωση να είναι διαφορετική από την 4658/2012 και μάλιστα προς το χειρότερο. Αυτό γιατί στο ενδιάμεσο έχει υπάρξει άλλη μια απίστευτη κίνηση από μεριάς του κράτους η οποία υπονομεύει την ελεύθερη λειτουργία του Internet στην Ελλάδα. Το κράτος λοιπόν, θέλοντας να τα τσεπώνει από τις άδειες που χορηγεί στα sites σχετικά με τον τζόγο (στοιχήματα) έχει δημιουργήσει την ΕΕΕΠ. Τι είναι η ΕΕΕΠ; Επιτροπή Εποπτείας και Ελέγχου Παιγνίων. Αυτή η επιτροπή λοιπόν έχει το δικαίωμα να αποφασίζει ποια websites τζόγου θα αποκλειστούν από τους παρόχους ώστε να μην έχουν πρόσβαση οι χρήστες τους σε αυτά. Όποιος δεν πληρώνει, κόβεται. Μάλιστα, επειδή ξέρουν πόσο δύσκολο είναι να απαγορεύσεις την πρόσβαση σε ένα site στο Internet μπλοκάροντας απλά μια IP, αυτοί έχουν την εξουσία να παραγγέλνουν από τους ISPs να μπλοκάρουν URLs χωρίς να ενδιαφέρονται για το πως θα το υλοποιήσει ο πάροχος. Κάθε τόσο λοιπόν εμφανίζουν μια λίστα με URLs στους παρόχους και τους αναγκάζουν να κόψουν την πρόσβαση. Η πιο πρόσφατη λίστα όσο γράφεται αυτό το post είναι αυτή: BlackList EEEP 22/11/2013. Αυτό το pdf είναι και το μόνο που παρέχουν στους παρόχους, ούτε καν μια λίστα σε μορφή txt για να είναι ευκολότερη η αυτοματοποίηση. Και το επισημαίνω για άλλη μια φορά, δίνουν URLs και όχι domains ή IPs.

Τί σημαίνει αυτό όμως στην ουσία για παρόχους και χρήστες;
Οι πάροχοι δεν μπορούν να κόψουν τις IPs των betting sites γιατί α) είναι πιθανόν στις ίδιες IPs να συστεγάζονται και άλλα sites, β) κάποια betting sites γίνονται host σε εταιρίες τύπου Akamai, Cloudflare,κτλ δεν είναι δυνατόν να κόψει ένας πάροχος τα CDN αυτά, γ) ένα site μπορεί να αλλάζει IPs όποτε θέλει, άρα ποιος θα παρακολουθεί τι κάνει το κάθε site κάθε μέρα; Επειδή, από όσο μπορώ να γνωρίζω, οι ελληνικοί πάροχοι σταθερού Internet (xDSL) δεν έχουν αυτή τη στιγμή δυνατότητα να κάνουν DPI, να κοιτάνε δηλαδή κάθε πακέτο ποια “web/URL” (και όχι IP) διεύθυνση αναφέρει μέσα του και να κόβουν μόνο αυτά, μένουν με ένα και μοναδικό “όπλο” στα χέρια τους. Το DNS block. Δηλαδή, οι DNS servers των ελληνικών ISPs λένε ψέμματα στους χρήστες για τις πραγματικές διευθύνσεις των betting sites που θέλει να κόψει η ΕΕΕΠ. Αντί να δίνουν στους χρήστες τις σωστές IPs ενός site, δίνουν μια ψεύτικη ή δεν απαντούν καθόλου και αυτό κάνει τον χρήστη να θεωρεί πως δεν δουλεύει πλέον το website που θέλει να επισκεπτεί. Φυσικά οι χρήστες έχουν την δυνατότητα να χρησιμοποιήσουν άλλους DNS servers, εκτός του παρόχου τους – εκτός Ελλάδας βασικά, για να μάθουν τις σωστές απαντήσεις στα DNS ερωτήματά τους. Αυτό όμως με την σειρά του δημιουργεί διάφορα θέματα. Καταρχήν όταν ρωτάς ένα DNS server στο εξωτερικό όλα τα DNS ερωτήματα καθυστερούν λίγο παραπάνω, το λίγο μπορεί να σημαίνει πως από τα 10-20ms που έχει κάποιος με τους DNS servers του ISP του μπορεί να φτάσει τα 60-80 ή και 100ms, δηλαδή μια καθυστέρηση τουλάχιστον της τάξης του 3-5x. Έπειτα σημαίνει πως ο νέος “DNS” πάροχος αυτός ξέρει ό,τι κάνει κάποιος Έλληνας χρήστης και μπορεί φυσικά να χρησιμοποιήσει τα δεδομένα αυτά όπως του αρέσει. Φυσικά o πάροχος αυτός δεν υπόκειται στην Ελληνική νομοθεσία, άρα τα προσωπικά δεδομένα των χρηστών – δηλαδή το ποια sites επισκέπτεται ο καθένας, μπορεί να τα χειριστεί ο πάροχος αυτός χωρίς να χρειάζεται να συμμορφωθεί με τους ελληνικούς νόμους περί προστασίας των δεδομένων. Αν εγώ αύριο χρησιμοποιήσω ένα DNS server του εξωτερικού κανείς δεν μου εγγυάται πως α) οι δικές του απαντήσεις δεν θα με στέλνουν σε sites με malware ή δεν θα βγάλει κάποτε μια λίστα με το ποια sites ζήτησα να επισκεφτώ…Το πρόβλημα όμως δεν τελειώνει εκεί, αν διαβάσει κανείς το ένα από τα ΦΕΚ που αφορούν την λειτουργία της ΕΕΕΠ θα δει πως τα πράγματα είναι πολύ χειρότερα από όσο μπορεί να φανταστεί. Οι τολμηροί ας διαβάσουν το άρθρο 52 του ν.4002/2011 (Α 218). Παραδείγματα:
Αν σε πιάσουν ως χρήστη να παίζεις σε μη αδειοδοτημένο website…

Όποιος μετέχει σε τυχερό παίγνιο, το οποίο διοργανώνεται χωρίς άδεια από την Ελληνική Δημοκρατία, τιμωρείται με ποινή φυλάκισης έως τριών (3) μηνών και με χρηματική ποινή από 5.000 έως 20.000 ευρώ.

Αν σε πιάσουν να παρέχεις proxy ή άλλο μέσο ώστε να παίζει κάποιος τρίτος σε μη αδειοδοτημένο website…

Όποιος μετέχει σε παίγνια μέσω παρενθέτου φυσικού ή νομικού προσώπου τιμωρείται με φυλάκιση έως δύο (2) ετών και χρηματική ποινή από 100.000 έως 200.000 ευρώ. Με τις ίδιες ποινές τιμωρείται και το παρένθετο φυσικό πρόσωπο και αν πρόκειται για νομικό πρόσωπο, τα πρόσωπα που καθορίζονται ως αυτουργοί με την παράγραφο 11.

Και κάτι ακόμα ως τροφή για σκέψη, σε μια από τις προσκλήσεις για συζήτηση της ΕΕΕΠ προς τους παρόχους, δύο από τα θέματα της ατζέντας ήταν μεταξύ άλλων το πως θα ελεγχθεί/αποκλειστεί η πρόσβαση στα betting sites μέσω proxy και έπειτα αν μπορεί η ΕΕΕΠ να έχει μια λίστα με τους χρήστες που επισκέπτονται αυτά τα sites (!?).

Αυτά συμβαίνουν σήμερα στο Ελληνικό Internet, δεν είναι από κάποιο φαντασιακό μέλλον, αλλά από το σήμερα.

Τι μπορεί να γίνει με τα ασφαλιστικά μέτρα;
Γυρνώντας στα πρόσφατα ασφαλιστικά μέτρα, κάποιος δικαστής που θα κάνει ένα ελαφρύ διάβασμα και θα ρωτήσει και 2-3 άλλους (ή θα του το ψιθυρίσει η ΑΕΠΙ) θα δει πως υπάρχει ο 4002/2011 που απαγορεύει γενικά και αόριστα την πρόσβαση σε sites. Το πως το αφήνει στους παρόχους…κάντε ό,τι καταλαβαίνετε…αλλιώς θα πάτε φυλακή. Άρα η προσωπική μου εκτίμηση για την απόφαση είναι πως αν μείνει στον αποκλεισμό IP των websites που αναφέρονται στα ασφαλιστικά μέτρα, μάλλον θα πρόκειται για “νίκη”. Δεν θεωρώ όμως πως αυτό το σενάριο έχει ιδιαίτερη βάση. Για μένα είτε θα βγει μια ακυρωτική απόφαση για τα ασφαλιστικά μέτρα, είναι η αλήθεια πως οι πάροχοι αυτή τη φορά το είχαν πάρει το θέμα πολύ πιο σοβαρά από την προηγούμενη, είτε η απόφαση θα αναφέρει συγκεκριμένα το DNS block. Το DNS block απλά θα ανοίξει τους ασκούς του Αιόλου για το τι μπορεί να ακολουθήσει. Και να είμαστε όλοι σίγουροι πως η ΑΕΠΙ δεν θα σταματήσει στο DNS block… Αλλά δεν είναι το πρόβλημα μόνο η ΑΕΠΙ ή η ΕΕΕΠ. Το πρόβλημα είναι πως έχει αρχίσει και στην Ελλάδα να υπάρχει η νοοτροπία αλλά και η νομική κάλυψη περί απαγόρευσης πρόσβασης σε συγκεκριμένες ιστοσελίδες που οι servers τους δεν βρίσκονται καν στην χώρα μας. Με το πρόσχημα είτε της πειρατείας είτε της μη αδειοδότησης, αποκλείονται ιστότοποι από τους Έλληνες χρήστες. Μάλιστα, τα μέτρα που λαμβάνονται κάθε φορά φαίνεται να έχουν όλο και πιο προηγμένο τεχνολογικό χαρακτήρα και λίγο μας χωρίζει πλέον από το να λαμβάνει η χώρα μας μέτρα τύπου Ιράν και Κίνας. Μπορεί να ακούγεται τραβηγμένο, αλλά από την στιγμή που θα εγκατασταθεί η τεχνολογία (DPI) για να κόβεις την “πειρατεία” ή τα “παράνομα” sites τζόγου δεν μπορείς να είσαι σίγουρος για το τι άλλο θα κηρυχθεί παράνομο αύριο και θα κοπεί με την ίδια τεχνολογία.
Προσωπικά σιχαίνομαι τα betting sites όσο τίποτε άλλο, αλλά αυτό δεν με σταματάει από το να υποστηρίζω το δικαίωμά τους να μην λογοκρίνονται. Γιατί αυτό είναι και το ζουμί της υπόθεσης, αρχίζει πλέον το κράτος/εξουσία να λογοκρίνει όλο και περισσότερα κομμάτια του Internet που δεν αρέσουν.

Και στο μέλλον;
Δεν είναι τυχαίο άλλωστε πως στο σχεδιαζόμενο “samaras-wifi” ανακοινώθηκε πως φυσικά θα υπάρχει φίλτρο περιεχομένου, πριν καν μάθουμε οποιεσδήποτε άλλες ποιοτικές πληροφορίες για το δίκτυο το ίδιο:

“όταν εγκατασταθεί (το wifi), να τοποθετηθούν ειδικά φίλτρα που να απαγορεύουν πρόσβαση σε σελίδες με άσεμνο περιεχόμενο και γενικά σε σελίδες σεξ, καθώς και να υπάρχουν φίλτρα ώστε να μην μπορεί κανείς να «κατεβάσει» τραγούδια ή κινηματογραφικές ταινίες!”.

Πέραν της υπονοούμενης αναφοράς σε DPI, το ποιός θα αποφασίζει τι επιτρέπεται (τι σημαίνει “άσεμνο”;;;) και τί όχι, το πώς, κτλ αφήνεται εντελώς ασαφές. Η λογοκρισία μπαίνει στη ζωή κάθε πολίτη με μικρά αλλά σταθερά βήματα, θεωρώντας δεδομένη την κατάσταση που επικρατεί ήδη, η εκάστοτε κυριαρχία/εξουσία επιβάλει όλο και περισσότερες απαγορεύσεις, “για το καλό μας”.

Υ.Γ. Οι παραπάνω απόψεις είναι προφανώς προσωπικές πολύ πιθανόν ο εργοδότης μου να έχει εντελώς διαφορετικές 🙂
Υ.Γ.2 Ίσως να μην είναι αργά ακόμα, αν κάποιοι δημοσιογράφοι αναδείξουν το θέμα κατάλληλα μπορεί και να καταφέρουμε την ακύρωση των ασφαλιστικών μέτρων. Ελπίζω να γλυτώσουμε όμως την κλάψα μετά την απόφαση, το “δεν ήξερα” δεν μπορεί να είναι πλέον δικαιολογία.
Υ.Γ.3 Δεν είμαι νομικός, αν κάποιος νομικός γνωρίζει περισσότερα για τα παραπάνω ας με διορθώσει.

Creating a new GPG key with subkeys

A few weeks ago I created my new GPG/PGP key with subkeys and a few people asked me why and how. The rationale for creating separate subkeys for signing and encryption is written very nicely in the subkeys page of the debian wiki. The short answer is that having separate subkeys makes key management a lot easier and protects you in certain occasions, for example you can create a new subkey when you need to travel or when your laptop gets stolen, without losing previous signatures. Obviously you need to keep your master key somewhere very very safe and certainly not online or attached to a computer.

You can find many other blog posts on the net on the subject, but most of them are missing a few parts. I’ll try to keep this post as complete as possible. If you are to use gpg subkeys you definitely need an encrypted usb to store the master key at the end. So if you don’t already have an encrypted USB go and make one first.

When this process is over you will have a gpg keypair on your laptop without the master key, you will be able to use that for everyday encryption and signing of documents but there’s a catch. You won’t be able to sign other people’s keys. To do that you will need the master key. But that is something that does not happen very often so it should not be a problem in your everyday gpg workflow. You can read about signing other people’s keys at the end of this post. AFAIK you can’t remove your master key using some of the gpg GUIs, so your only hope is the command line. Live with it…

First some basic information that will be needed later.
When listing secret keys with gpg -K keys are marked with either ‘sec’ or ‘ssb’. When listing (public) keys with gpg -k keys are marked with ‘pub’ or ‘sub’.

sec => 'SECret key'
ssb => 'Secret SuBkey'
pub => 'PUBlic key'
sub => 'public SUBkey'

When editing a key you will see a usage flag on the right. Each key has a role and that is represented by a character. These are the roles and their corresponding characters:

Constant           Character      Explanation
─────────────────────────────────────────────────────
PUBKEY_USAGE_SIG      S       key is good for signing
PUBKEY_USAGE_CERT     C       key is good for certifying other signatures
PUBKEY_USAGE_ENC      E       key is good for encryption
PUBKEY_USAGE_AUTH     A       key is good for authentication

Before doing anything make sure you have a backup of your .gnupg dir.
$ umask 077; tar -cf $HOME/gnupg-backup.tar -C $HOME .gnupg

Secure preferences
Now edit your .gnupg/gpg.conf and add or change the following settings (most are stolen from Riseup: OpenPGP Best Practices):

# when outputting certificates, view user IDs distinctly from keys:
fixed-list-mode
# long keyids are more collision-resistant than short keyids (it's trivial to make a key with any desired short keyid)
keyid-format 0xlong
# when multiple digests are supported by all recipients, choose the strongest one:
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# preferences chosen for new keys should prioritize stronger algorithms:
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed
# If you use a graphical environment (and even if you don't) you should be using an agent:
# (similar arguments as https://www.debian-administration.org/users/dkg/weblog/64)
use-agent
# You should always know at a glance which User IDs gpg thinks are legitimately bound to the keys in your keyring:
verify-options show-uid-validity
list-options show-uid-validity
# when making an OpenPGP certification, use a stronger digest than the default SHA1:
cert-digest-algo SHA256
# prevent version string from appearing in your signatures/public keys
no-emit-version 

Create new key
Time to create the new key. I’m marking user input with bold (↞) arrows

$ gpg --gen-key
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection?
Your selection?  1 ↞↞↞↞ 
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)  4096 ↞↞↞↞ 
Requested keysize is 4096 bits
Please specify how long the key should be valid.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)  0 ↞↞↞↞ 
Key does not expire at all
Is this correct? (y/N)  y ↞↞↞↞ 
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
Real name: foo bar ↞↞↞↞ 
Email address: foobar@void.gr ↞↞↞↞ 
Comment:
You selected this USER-ID:
"foo bar <foobar@void.gr>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?  O ↞↞↞↞ 
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.............+++++
..+++++

gpg: key 0x6F87F32E2234961E marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   3  signed:  14  trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: depth: 1  valid:  14  signed:   9  trust: 13-, 1q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2014-03-18
pub   4096R/0x6F87F32E2234961E 2013-12-01
      Key fingerprint = 407E 45F0 D914 8277 3D28  CDD8 6F87 F32E 2234 961E
uid                 [ultimate] foo bar <foobar@void.gr>
sub   4096R/0xD3DCB1F51C37970B 2013-12-01

Optionally, you can add another uid and add it as the default:

$ gpg --edit-key 0x6F87F32E2234961E                                      
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/0x6F87F32E2234961E  created: 2013-12-01  expires: never       usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xD3DCB1F51C37970B  created: 2013-12-01  expires: never       usage: E   
[ultimate] (1). foo bar <foobar@void.gr>
gpg> adduid ↞↞↞↞ 
Real name: foo bar ↞↞↞↞ 
Email address: foobar@riseup.net ↞↞↞↞ 
Comment: 
You selected this USER-ID:
    "foo bar <foobar@riseup.net>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?  O ↞↞↞↞ 
You need a passphrase to unlock the secret key for
user: "foo bar <foobar@void.gr>"
4096-bit RSA key, ID 0x6F87F32E2234961E, created 2013-12-01

pub  4096R/0x6F87F32E2234961E  created: 2013-12-01  expires: never       usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xD3DCB1F51C37970B  created: 2013-12-01  expires: never       usage: E   
[ultimate] (1)  foo bar <foobar@void.gr>
[ unknown] (2). foo bar <foobar@riseup.net>
gpg> uid 2 ↞↞↞↞ 
gpg> primary ↞↞↞↞ 
gpg> save ↞↞↞↞ 

Let’s see what we’ve got until now, 0x6F87F32E2234961E is the master key (SC flags) and 0xD3DCB1F51C37970B (E flag)is a separate subkey for encryption.

Add new signing subkey
Since we already have a separate encryption subkey, it’s time for a new signing subkey. Expiration dates for keys is a very hot topic. IMHO there’s no point in having an encryption subkey with an expiration date, expired keys are working just fine for decryption anyways, so I’ll leave it without one, but I want the signing key that I’m regularly using to have an expiration date. You can read more about this topic on the gnupg manual (Selecting expiration dates and using subkeys).

$ gpg --edit-key 0x6F87F32E2234961E
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/0x6F87F32E2234961E  created: 2013-12-01  expires: never       usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xD3DCB1F51C37970B  created: 2013-12-01  expires: never       usage: E   
[ultimate] (1). foo bar <foobar@riseup.net>
[ultimate] (2)  foo bar <foobar@void.gr>
gpg> addkey ↞↞↞↞ 

Key is protected.

You need a passphrase to unlock the secret key for
user: “foo bar <foobar@riseup.net>”
4096-bit RSA key, ID 0x6F87F32E2234961E, created 2013-12-01

Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)

Your selection? 4 ↞↞↞↞ 
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096 ↞↞↞↞ 
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 5y ↞↞↞↞ 
Key expires at Fri 30 Nov 2018 03:36:47 PM EET
Is this correct? (y/N) y ↞↞↞↞ 
Really create? (y/N) y ↞↞↞↞ 
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
+++++
...............+++++

pub  4096R/0x6F87F32E2234961E  created: 2013-12-01  expires: never       usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xD3DCB1F51C37970B  created: 2013-12-01  expires: never       usage: E   
sub  4096R/0x296B12D067F65B03  created: 2013-12-01  expires: 2018-11-30  usage: S   
[ultimate] (1). foo bar <foobar@riseup.net>
[ultimate] (2)  foo bar <foobar@void.gr>
gpg> save ↞↞↞↞ 

As you can see there’s a new subkey 0x296B12D067F65B03 with just the S flag, that the signing subkey.
Before moving forward it’s wise to create a revocation certificate:

$ gpg --output 0x6F87F32E2234961E.gpg-revocation-certificate --armor --gen-revoke 0x6F87F32E2234961E
sec  4096R/0x6F87F32E2234961E 2013-12-01 foo bar <foobar@riseup.net>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision?  1 ↞↞↞↞ 
Enter an optional description; end it with an empty line:
> This revocation certificate was generated when the key was created. ↞↞↞↞ 
> 
Reason for revocation: Key has been compromised
This revocation certificate was generated when the key was created.
Is this okay? (y/N) y ↞↞↞↞ 
You need a passphrase to unlock the secret key for
user: "foo bar <foobar@riseup.net>"
4096-bit RSA key, ID 0x6F87F32E2234961E, created 2013-12-01

Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!

Encrypt this file and store it someplace safe, eg your encrypted USB. You should definitely not leave it at your laptop’s hard disk. You can even print it and keep it in this form, it’s small enough so one could type it if needed.

Remove Master key
And now the interesting part, it’s time to remove the master key from your laptops’s keychain and just leave the subkeys. You will store the master key in the encrypted usb so it stays safe.

First go and backup your .gnupg dir on your encrypted USB. Don’t move forward until you do that. DON’T!

$ rsync -avp $HOME/.gnupg /media/encrypted-usb
or
$ umask 077; tar -cf /media/encrypted-usb/gnupg-backup-new.tar -C $HOME .gnupg

Did you backup your key? Are you sure ?

Then it’s time to remove the master key!

$ gpg --export-secret-subkeys 0x6F87F32E2234961E > /media/encrypted-usb/subkeys
$ gpg --delete-secret-key 0x6F87F32E2234961E
$ gpg --import /media/encrypted-usb/subkeys
$ shred -u /media/encrypted-usb/subkeys

What you’ve accomplished with this process is export the subkeys to /media/encrypted-usb/subkeys then delete the master key and re-import just the subkeys. Master key resides only on the encrypted USB key now. Don’t lose that USB key. USB keys are extremely cheap, make multiple copies of the encrypted key and place them in safe places, you can give one such key to your parents or your closest friend in case of emergency. For safety, make sure there’s at least one copy outside of your residence.

You can see the difference of the deleted master key by comparing the listing of the secret keys in your .gnupg and your /media/encrypted-usb/.gnupg/ dir.

$ gpg -K 0x6F87F32E2234961E                                             
sec#   4096R/0x6F87F32E2234961E 2013-12-01
uid                            foo bar <foobar@riseup.net>
uid                            foo bar <foobar@void.gr>
ssb   4096R/0xD3DCB1F51C37970B 2013-12-01
ssb   4096R/0x296B12D067F65B03 2013-12-01 [expires: 2018-11-30] 
$ gpg --home=/media/encrypted-usb/.gnupg/ -K 0x6F87F32E2234961E                                             
sec   4096R/0x6F87F32E2234961E 2013-12-01
uid                            foo bar <foobar@riseup.net>
uid                            foo bar <foobar@void.gr>
ssb   4096R/0xD3DCB1F51C37970B 2013-12-01
ssb   4096R/0x296B12D067F65B03 2013-12-01 [expires: 2018-11-30] 

Notice the pound (#) in the ‘sec’ line from your ~/.gnupg/. That means that the master key is missing.

Upload your new key to the keyservers if you want to…

Key Migration
In case you’re migrating from an older key you need to sign your new key with the old one (not the other way around!)
$ gpg --default-key 0xOLD_KEY --sign-key 0x6F87F32E2234961E

Write a transition statement and sign it with both the old and the new key:

$ gpg --armor -b -u 0xOLD_KEY -o sig1.txt gpg-transition.txt
$ gpg --armor -b -u 0x6F87F32E2234961E -o sig2.txt gpg-transition.txt

That’s about it…upload the transition statement and your signatures to some public space (or mail it to your web of trust).

Signing other people’s keys
Because your laptop’s keypair does not have the master key anymore and the master key is the only one with the ‘C’ flag, when you want to sign someone else’s key, you will need to mount your encrypted USB and then issue a command that’s using that encrypted directory:
$ gpg --home=/media/encrypted-usb/.gnupg/ --sign-key 0xSomeones_keyid
Export your signature and send it back to people whose key you just signed..

Things to play with in the future
Next stop ? An OpenPGP Smartcard! (eshop) or a yubikey NEO, (related blogpost). Any Greeks want to join me for a mass (5+) order?

References
https://wiki.debian.org/subkeys
https://help.riseup.net/en/security/message-security/openpgp/best-practices
https://alexcabal.com/creating-the-perfect-gpg-keypair/

P.S. 0x6F87F32E2234961E is obviously just a demo key. You can find my real key here.
P.S.2 The above commands were executed on gpg 1.4.12 on Debian Wheezy. In the future the output of the commands will probably differ.

Anonymize headers in postfix

E-mail headers usually leak some information about the person sending the email. Most servers reveal the sender’s originating IP, but sometimes we might not want this behavior. Here’s a simple way to modify your postfix server to remove just the IP of the sender. The original idea is from https://we.riseup.net/debian/mail but with postfix 2.9 version (Debian Wheezy) using the way proposed in the riseup article you will also be anonymizing all intermediate ‘Received: from’ headers and not just the sender’s. The setup proposed by riseup article seems to work fine with postfix 2.7 (Debian Squeeze).

1. Install postfix-pcre if you haven’t already.
# apt-get install postfix-pcre


2.
Create a file /etc/postfix/smtp_header_checks with content:
/^\s*(Received: from)[^\n]*(.*)/ REPLACE $1 [127.0.0.1] (localhost [127.0.0.1])$2


3.
Edit /etc/postfix/master.cf
Find the section about submission and add at the end of it: -o cleanup_service_name=subcleanup
e.g.

submission inet n       -       -       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

submission inet n       -       -       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  -o cleanup_service_name=subcleanup

Then at the end of /etc/postfix/master.cf file add the following:

subcleanup unix n       -       -       -       0       cleanup
    -o header_checks=pcre:/etc/postfix/smtp_header_checks

That’s it, reload your postfix and you’re done. When you’ll be sending emails over submission (you do use submission instead of smtp to send your emails, right?) then the first ‘Received’ header will be modified like the following example.
Instead of:

Received: from foo.bar (abcd.efgh.domain.tld [111.222.100.200])
        by mail.domain.tld (Postfix) with ESMTPA id BAB8A1A0224
        for <user@dst.domain2.tld>; Sun, 24 Nov 2013 15:47:50 +0100 (CET)

It will be:

Received: from [127.0.0.1] (localhost [127.0.0.1])
        by mail.domain.tld (Postfix) with ESMTPA id BAB8A1A0224
        for <user@dst.domain2.tld>; Sun, 24 Nov 2013 15:47:50 +0100 (CET)

Extra
If you want to anonymize even more headers, try adding the following to /etc/postfix/smtp_header_checks

/^\s*User-Agent/        IGNORE
/^\s*X-Enigmail/        IGNORE
/^\s*X-Mailer/          IGNORE
/^\s*X-Originating-IP/  IGNORE

Logging
As the riseup article says, be very careful of what is being logged at the server. If you don’t want to log the replacements done by pcre then add something like the following in your rsyslog.conf before any other rule:
:msg, contains, "replace: header Received:" ~

New traffic record for GRNET NOC streaming service

Around a year ago I wrote a blog post about how me and @zmousm scaled our streaming infrastructure at GRNET NOC so that we could cope with a sudden demand on the streaming service that we provide to the Greek Parliament. That setup was re-used again in January 2013 (Lagarde-list discussion) where we managed to surpass our previous record of 1.66Gbps reaching 1.79Gbps. We knew that the previous solution could definitely be improved though. Wowza does not seem to scale very well in our environment(*cough* java *cough*), so we modified our setup quite a bit.

What we did was take the original Wowza streamer, and ‘hide’ it behind two different categories of ‘proxy-servers’ that clients communicate with. The first category is made of three varnish proxies sitting at two different datacenters. All clients that fetch HTTP streams communicate only with the varnish proxies and not with the original streamer. Varnish uses very few resources and scales wonderfully. Then we added an nginx-rtmp server to offload RTMP clients from the original streamer. Now all RTMP clients communicate with nginx-rtmp only. We’ve also notified website owners that prefer using our RTMP stream to serve it through their own (flash) applications to switch to the nginx-rtmp endpoint. This means that the original Wowza streamer now mainly serves the three varnish proxies and the nginx-rtmp server as ‘clients’, and since the VM now has far less load, the stream it provides to the ‘proxy-servers’ doesn’t get ‘chopped’ from time to time, as it did previously when it served hundreds of clients.
While each wowza streamer previously needed 6Gb of RAM to serve around 500-600Mbit of traffic, varnish needs <1Gb and can easily serve 900Mbit. Our nginx-rtmp server also uses <1Gb of RAM. So we’re actually using fewer resources to serve more (happier) clients!

This setup gives us a lot of flexibility and extensibility. We can easily scale it horizontally when we want to just by adding more varnish or nginx-rtmp servers.

With this setup we were able to achieve 3.55Gbps and serve more than 6000 clients last Sunday (10/11/2013), that’s double of our previous record!

Here are the graphs:
traffic.parliament.20131110.type

traffic.parliament.20131110.dc

New gpg key

I’ve decided to change my old gpg key with a new RSA 4096bits.

My new gpg key id is 0x7011E02C or if you prefer the longer version 0x897C03177011E02C

Transition statement

Date: 11/11/2013

For a number of reasons[0], I've recently set up a new OpenPGP key,
and will be transitioning away from my old one.

The old key will continue to be valid for some time, but I prefer all
future correspondence to come to the new one.  I would also like this
new key to be re-integrated into the web of trust.  This message is
signed by both keys to certify the transition.

the old key was:

pub   1024D/0x4A0A1BC8E4F4FFE6 2008-03-19 [expires: 2014-03-18]
      Key fingerprint = 9EB8 31BE C618 07CE 1B51  818D 4A0A 1BC8 E4F4 FFE6

And the new key is:

pub   4096R/0x897C03177011E02C 2013-11-11
      Key fingerprint = 79B1 9198 B8F6 803B EC37  5638 897C 0317 7011 E02C

To fetch the new key, you can get it with:

  wget -q -O- https://void.gr/kargig/gpg/0x897C03177011E02C_pub.asc | gpg --import -

Or, to fetch my new key from a public key server, you can simply do:

  gpg --keyserver keys.gnupg.net --recv-key 0x897C03177011E02C

If you already know my old key, you can now verify that the new key is
signed by the old one:

  gpg --check-sigs 0x897C03177011E02C

If you don't already know my old key, or you just want to be double
extra paranoid, you can check the fingerprint against the one above:

  gpg --fingerprint 0x897C03177011E02C

George Kargiotakis

0. https://www.debian-administration.org/users/dkg/weblog/48

You can find the above text here, signed by my old key and my new key.

Another day another hacked website

Yesterday morning, phone rings to notify my of a new sms. Someone could not access his website on some server that I am root/administer.
I tried to ping the server and got 1 reply every 10-15 packets so my initial thought was that the hosting provider had fucked up. I pinged other machines in the “neighborhood”, they replied just fine. So the problem lied in my server. I got console access through IPMI, you know…the ones with the cipher zero bug, and I managed to login. An apache2 process was constantly using 100% of a core and the machine sent gazillion packets towards a certain destination.

Since I wanted to investigate what exactly this process did, I put an iptables entry in my OUTPUT chain to block packets towards that destination. The machine became responsive again, though the apache process still ran at 100%. Since I run my vhosts using apache2 mpm_itk module, I knew through the apache2 PIDs’ username which site had been hacked. I grepped the logs for any POST, but I couldn’t see anything. Unfortunately the logs only go back 2 days (NOT my policy! and a very bad one actually…but anyway).

strace -p PID did not yield anything interesting, just the process trying to create sockets to send packets towards the destination.

socket(PF_NETLINK, SOCK_RAW, 0) = 417
bind(417, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(417, {sa_family=AF_NETLINK, pid=11398, groups=00000000}, [12]) = 0
sendto(417, "\24\0\0\0\26\0\1\3\233\323\354Q\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
recvmsg(417, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"0\0\0\0\24\0\2\0\233\323\354Q\206,\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 588
recvmsg(417, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"@\0\0\0\24\0\2\0\233\323\354Q\206,\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(417, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0\233\323\354Q\206,\0\0\0\0\0\0\1\0\0\0\24\0\1\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
close(417) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 417
fcntl(417, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(417, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(417, {sa_family=AF_INET, sin_port=htons(4883), sin_addr=inet_addr("X.Y.Z.W")}, 16) = 0
fcntl(417, F_SETFL, O_RDWR) = 0
sendto(417, "\207\25\312P\322t\0#\317}jf\2(W\374\375\232h\213\220\31\355\277)\320[\255\273\276\221\374"..., 8192, MSG_DONTWAIT, NULL, 0) = -1 EPERM (Operation not permitted)
close(417) = 0

lsof -n -p PID output had hundreds of open log files and a few connections. Grepping out the logs I noticed one that was quite interesting, it went towards another server at port 5555.
apache2 11398 XXXXXXX 416u IPv4 831501972 0t0 TCP A.B.C.D:59210->B.C.D.E:5555 (CLOSE_WAIT)

I run tcpdump there, and of course it was an irc connection. I started capturing everything.

lsof also revealed this:
apache2 11398 XXXXXXX cwd DIR 8,7 4096 2474373 /var/www/vhosts/XXXXXXX/httpdocs/libraries/phpgacl
which I could have have also seen it doing ls /proc/PID/cwd/ …but anyway.

Looking inside that dir I found a file named gacl_db.php. It was base64 encoded. Well actually it was multiple times base64 encoded and obfsuscated by using character substitutions, so I had to de-obfuscate it. It was quite easy using php and some bash scripting.

This is the original base64 encoded/obfuscated file: Original gacl_db.php
This is the final result: Deobfuscated gacl_db.php
(I have removed the irc server details from the deobfuscated file, it’s still there in the original file for whoever wants it though)

It’s just an IRC bot containing a perl reverse shell as well. It has commands to flood other servers, and that’s what my server was doing.

I joined the IRC server and at that time there were more than 90 bots inside. Right now that I’m writing this blog post there are less than 50. Every bot joining the channel outputs a text like this:

[uname!]: FreeBSD a.b.c.d 8.1-RELEASE-p5 FreeBSD 8.1-RELEASE-p5 #10: Fri Sep 30 14:45:56 MSK 2011 root@a.b.c.d:/path/to/to/to/sth pl#27 amd64 (safe: off)
[vuln!]: http://www.a-vhost-name.TLD/libraries/phpgacl/gacl_db.php
[uname!]: Linux x.y.z.w 3.2.0-43-generic #68-Ubuntu SMP Wed May 15 03:33:33 UTC 2013 x86_64 (safe: off)
[vuln!]: http://www.another-vhost-name.another-TLD/libraries/phpgacl/gacl_db.php

So if you run servers or websites, do a locate gacl_db.php.

Since all the bot/servers entering post a [vuln!] message about phpgacl, my guess is that the original vulnerability that allowed the attacker to gain access is right there. I haven’t had time to look into it yet, but I’ve warned my clients to remove this library from their websites as a precaution. You should probably do the same.

Greek PGP Web of Trust 2012 edition

I’ve very glad for hosting this guest post. Dorothea put some real effort into it. So…enjoy!

—————————————————————————————————————–
In 2008 Patroklos Argyroudis created the first visualization of the greek PGP web of trust, based on information supplied mostly by people who attended a keysigning party at Thessaloniki. You can read his related posts at sysc.tl/tag/web-of-trust/ [0]
In 2012, during the second cryptoparty [1] at hackerspace.gr [2], George Kargiotakis suggested if someone wanted to update the network. I decided to undertake the task and you can see some of the visualizations below.

Visualizations:
1. Venn of persons that have signed others and of persons that have been signed by others
2. Greek PGP network for 2012
3. Trust in the 2012 Greek PGP network
4. Highlighting the persons who have signed more people
5. Do people trust more persons than they are trusted by?
6. Geolocation of individuals (globally)
7. Geolocation of individuals (in Greece)
8. Gender percentages
9. Educational and research institutes in the PGP network
10. Animation: Formation through time of associations that were active in 2012
11. Communities and the ten most important positions in the 2012 Greek PGP network according to Eigen value centrality

Additional sections:
12. Outline of methodology
13. Keyserver & keys used
14. Notes on methodology
15. Software and visualization notes
16. Problems encountered and how you can help
17. Future plans
18. Web references
19. Synopsis
20. Communication
21. Thanks
(more…)

How Vodafone Greece degrades my Internet experience

The title may sound a bit pompous, but please read on and you’ll see how certain decisions can cripple, or totally disrupt modern Internet services and communications as these are offered(?) by Vodafone’s mobile Internet solutions.

== The situation ==
I’ve bought a mobile Internet package from Vodafone Greece in order to be able to have 3G access in places where I don’t have access to wifi or ethernet. I am also using a local caching resolver on my laptop (Debian Linux), running unbound software, to both speed up my connections and to have mandatory DNSSEC validation for all my queries. Many of you might ask why do I need DNSSEC validation of all my queries since only very few domains are currently using DNSSEC, well I don’t have a reply that applies to everyone, let’s just say for now that I like to experiment with new things. After all, this is the only way to learn new things, experiment with them. Let’s not forget though that many TLDs are now signed, so there are definitely a few records to play with. Mandatory DNSSEC validation has led me in the past to identify and investigate a couple other problems, mostly having to do with broken DNSSEC records of various domains and more importantly dig deeper into IPv6 and fragmentation issues of various networks. This last topic is so big that it needs a blog post, or even a series of posts, of it’s own. It’s my job after all to find and solve problems, that’s what system or network administrators do (or should do).

== My setup ==
When you connect your 3G dongle with Vodafone Greece, they sent you 2 DNS servers (two out of 213.249.17.10, 213.249.17.11, 213.249.39.29) through ipcp (ppp). In my setup though, I discard them and I just keep “nameserver 127.0.0.1” in my /etc/resolv.conf in order to use my local unbound. In unbound’s configuration I have set up 2 forwarders for my queries, actually when I know I am inside an IPv6 network I use 4 addresses, 2 IPv4 and 2 IPv6 for the same 2 forwarders. These forwarders are hosted where I work (GRNET NOC) and I have also set them up to do mandatory DNSSEC validation themselves.
So my local resolver, which does DNSSEC validation, is contacting 2 other servers who also do DNSSEC validation. My queries carry the DNS protocol flag that asks for DNSSEC validation and I expect them to validate every response possible.

As you can see in the following screenshot, here’s what happens when I want to visit a website. I ask my local caching resolver, and that resolver asks one of it’s forwarders adding the necessary DNSSEC flags in the query.
The response might have the “ad” (authenticated) DNSSEC flag, depending whether the domain I’m visiting is DNSSEC signed or not.

[Screenshot of DNS queries]
dnssec_query

== The problem ==
What I noticed was that using this setup, I couldn’t visit any sites at all when I connected with my 3G dongle on Vodafone’s network. When I changed my /etc/resolv.conf to use Vodafone’s DNS servers directly, everything seemed work as normal, at least for browsing. But then I tried to query for DNSSEC related information on various domains manually using dig, Vodafone’s resolvers never sent me back any DNSSEC related information. Well actually they never sent me back any packet at all when I asked them for DNSSEC data.

Here’s an example of what happens with and without asking for DNSSEC data. The first query is without requesting DNSSEC information and I get a normal reply, but upon asking for the extra DNSSEC data, I get nothing back.
[Screenshot of ripe.net +dnssec query through Vodafone’s servers]
no_dnssec_replies_by_vodafone

== Experimentation ==
Obviously changing my forwarders configuration in unbound to the Vodafone DNS servers did not work because Vodafone’s DNS servers never send me back any DNSSEC information at all. Since my unbound is trying to do DNSSEC validation of everything, obviously including the root (.) zone, I need to get back packets that contain these records. Else everything fails. I could get unbound working with my previous forwarders or with Vodafone’s servers as forwarders, only by disabling the DNSSEC validation, that is commenting out the auto-trust-anchor-file option.

Then I started doing tests on my original forwarders that I had in my configuration (and are managed by me). I could see that my query packets arrived at the server and the server always sent back the proper replies. But whenever the reply contained DNSSEC data, that packet was not forwarded to my computer through Vodafone’s 3G network.

More tests were to follow and obviously my first choice were Google’s public resolvers, 8.8.8.8 and 8.8.4.4. Surprise, surprise! I could get any DNSSEC related information I wanted. The exact same result I got upon testing with OpenDNS resolvers, 208.67.222.222 and 208.67.220.220. From a list of “fairly known” public DNS servers that I found here, only ScrubIT servers seems to be currently blocked by Vodafone Greece. Comodo DNS, Norton DNS, and public Verizon DNS all work flawlessly.

My last step was to try and get DNSSEC data over tcp instead of udp packets. Surprise, surprise again, well not at all any more… I could get back responses containing the DNSSEC information I wanted.

== Conclusion ==
Vodafone Greece for some strange reason (I have a few ideas, starting with…disabling skype) seems to “dislike” large UDP responses, among which are obviously DNS replies carrying DNSSEC information. These responses can sometimes be even bigger than 1500bytes. My guess is that in order to minimize hassle for their telephone support, they have whitelisted a bunch of “known” DNS servers. Obviously the thought of breaking DNSSEC and every DNSSEC signed domain for their customers hasn’t crossed their minds yet. What I don’t understand though is why their own DNS servers are not whitelisted. Since they trust other organizations’ servers to send big udp packets, why don’t they allow DNSSEC from their own servers? Misconfiguration? Ignorance? On purpose?

The same behavior can (sometimes -> further investigation needed here) be seen while trying to use OpenVPN over udp. Over tcp with the same servers, everything works fine. That reminds me I really need to test ocserv soon…

== Solution ==
I won’t even try to contact Vodafone’s support and try to convince their telephone helpdesk to connect me to one of their network/infrastructure engineers. I think that would be completely futile. If any of you readers though, know anyone working at Vodafone Greece in _any_ technical department, please send them a link to this blog post. You will do a huge favor to all Vodafone Greece mobile Internet users and to the Internet itself.

The Internet is not just for HTTP stuff, many of us use it in various other ways. It is unacceptable for any ISP to block, disrupt, interrupt or get in the middle of such communications.
Each one of us users should be able to use DNSSEC without having to send all our queries to Google, OpenDNS or any other information harvesting organization.

== Downloads ==
I’m uploading some pcaps here for anyone who wants to take a look. Use wireshark/tcpdump to read them.

A. tcpdump querying for a non-DNSSEC signed domain over 3G. One query without asking for DNSSEC and two queries asking for DNSSEC, all queries go to DNS server 194.177.210.10. All queries arrived back. The tcpdump was created on 194.177.210.10.
vf_non-dnssec_domain_query.pcap

B. tcpdump querying for a DNSSEC signed domain over 3G. One query without asking for DNSSEC and three queries asking for DNSSEC, all queries go to DNS server 194.177.210.10. The last three queries never arrived back at my computer. The tcpdump was created on 194.177.210.10.
vf_dnssec_domain_query.pcap

C. tcpdump querying for a DNSSEC signed domain over 3G. One query without asking for DNSSEC and another one asking for DNSSEC, all queries go to DNS Server 8.8.8.8. All queries arrived back. The tcpdump was created on my computer using the PPP interface.
vf_ripe_google_dns.pcap

Linux kernel handling of IPv6 temporary addresses – CVE-2013-0343

I reported this bug on November 2012 but as of February 2013 it still hasn’t been fixed.

My initial report on oss-security and kernel netdev mailing lists reported it as an ‘information disclosure’ problem but then I found out that the issue is more severe and it can lead to the complete corruption of Linux kernel’s IPv6 stack until reboot. My second report wasn’t public, I thought it would be better not to make any public disclosure until the kernel people had enough time to respond, and was only sent to a number of kernel developers but I’m making it public now since the CVE is already out.

If someone wants to read all the publicly exchanged emails the best resource is probably this: http://marc.info/?t=135291265200001&r=1&w=2

Here’s the initial description of the problem:

Due to the way the Linux kernel handles the creation of IPv6 temporary addresses a malicious LAN user can remotely disable them altogether which may lead to privacy violations and information disclosure.

By default the Linux kernel uses the ‘ipv6.max_addresses’ option to specify how many IPv6 addresses an interface may have. The ‘ipv6.regen_max_retry’ option specifies how many times the kernel will try to create a new address.

Currently, in net/ipv6/addrconf.c,lines 898-910, there is no distinction between the events of reaching max_addresses for an interface and failing to generate a new address. Upon reaching any of the above conditions the following error is emitted by the kernel times ‘regen_max_retry’ (default value 3):

[183.793393] ipv6_create_tempaddr(): retry temporary address regeneration
[183.793405] ipv6_create_tempaddr(): retry temporary address regeneration
[183.793411] ipv6_create_tempaddr(): retry temporary address regeneration

After ‘regen_max_retry’ is reached the kernel completely disables temporary address generation for that interface.

[183.793413] ipv6_create_tempaddr(): regeneration time exceeded - disabled temporary address support

RFC4941 3.3.7 specifies that disabling temp_addresses MUST happen upon failure to create non-unique addresses which is not the above case. Addresses would have been created if the kernel had a higher
‘ipv6.max_addresses’ limit.

A malicious LAN user can send a limited amount of RA prefixes and thus disable IPv6 temporary address creation for any Linux host. Recent distributions which enable the IPv6 Privacy extensions by default, like Ubuntu 12.04 and 12.10, are vulnerable to such attacks.

Due to the kernel’s default values for valid (604800) and preferred (86400) lifetimes, this scenario may even occur under normal usage when a Router sends both a public and a ULA prefix, which is not an uncommon
scenario for IPv6. 16 addresses are not enough with the current default timers when more than 1 prefix is advertised.

The kernel should at least differentiate between the two cases of reaching max_addresses and being unable to create new addresses, due to DAD conflicts for example.

And here’s the second, more severe report about the corruption of the IPv6 stack:

I had previously informed this list about the issue of the linux kernel losing IPv6 privacy extensions by a local LAN attacker. Recently I’ve found that there’s actually another, more serious in my
opinion, issue that follows the previous one. If the user tries to disconnect/reconnect the network device/connection for whatever reason (e.g. thinking he might gain back privacy extensions), then the device gets IPs from SLAAC that have the “tentative” flag and never loses that. That means that IPv6 functionality for that device is from then on completely lost. I haven’t been able to bring back the kernel to a working IPv6 state without a reboot.

This is definitely a DoS situation and it needs fixing.

Here are the steps to reproduce:


== Step 1. Boot Ubuntu 12.10 (kernel 3.5.0-17-generic) ==
ubuntu@ubuntu:~$ ip a ls dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:8b:99:5d brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.96/24 brd 192.168.1.255 scope global eth0
    inet6 2001:db8:f00:f00:ad1f:9166:93d4:fd6d/64 scope global temporary dynamic 
       valid_lft 86379sec preferred_lft 3579sec
    inet6 2001:db8:f00:f00:5054:ff:fe8b:995d/64 scope global dynamic 
       valid_lft 86379sec preferred_lft 3579sec
    inet6 fdbb:aaaa:bbbb:cccc:ad1f:9166:93d4:fd6d/64 scope global temporary dynamic 
       valid_lft 86379sec preferred_lft 3579sec
    inet6 fdbb:aaaa:bbbb:cccc:5054:ff:fe8b:995d/64 scope global dynamic 
       valid_lft 86379sec preferred_lft 3579sec
    inet6 fe80::5054:ff:fe8b:995d/64 scope link 
       valid_lft forever preferred_lft forever

ubuntu@ubuntu:~$ sysctl -a | grep use_tempaddr
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.eth0.use_tempaddr = 2
net.ipv6.conf.lo.use_tempaddr = 2

ubuntu@ubuntu:~$ nmcli con status
NAME                      UUID                                   DEVICES    DEFAULT  VPN   MASTER-PATH
Wired connection 1        923e6729-74a7-4389-9dbd-43ed7db3d1b8   eth0       yes      no    --
ubuntu@ubuntu:~$ nmcli dev status
DEVICE     TYPE              STATE
eth0       802-3-ethernet    connected

//ping6 2a00:1450:4002:800::100e  while in another terminal: tcpdump -ni eth0 ip6

ubuntu@ubuntu:~$ ping6 2a00:1450:4002:800::100e -c1
PING 2a00:1450:4002:800::100e(2a00:1450:4002:800::100e) 56 data bytes
64 bytes from 2a00:1450:4002:800::100e: icmp_seq=1 ttl=53 time=70.9 ms

--- 2a00:1450:4002:800::100e ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 70.994/70.994/70.994/0.000 ms

# tcpdump -ni eth0 host 2a00:1450:4002:800::100e
17:57:37.784658 IP6 2001:db8:f00:f00:ad1f:9166:93d4:fd6d > 2a00:1450:4002:800::100e: ICMP6, echo request, seq 1, length 64
17:57:37.855257 IP6 2a00:1450:4002:800::100e > 2001:db8:f00:f00:ad1f:9166:93d4:fd6d: ICMP6, echo reply, seq 1, length 64

== Step 2. flood RAs on the LAN ==

$ dmesg | tail
[ 1093.642053] IPv6: ipv6_create_tempaddr: retry temporary address regeneration
[ 1093.642062] IPv6: ipv6_create_tempaddr: retry temporary address regeneration
[ 1093.642065] IPv6: ipv6_create_tempaddr: retry temporary address regeneration
[ 1093.642067] IPv6: ipv6_create_tempaddr: regeneration time exceeded - disabled temporary address support

ubuntu@ubuntu:~$ sysctl -a | grep use_tempaddr
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
net.ipv6.conf.eth0.use_tempaddr = -1
net.ipv6.conf.lo.use_tempaddr = 2

//ping6 2a00:1450:4002:800::100e  while in another terminal: tcpdump -ni eth0 ip6

ubuntu@ubuntu:~$ ping6 2a00:1450:4002:800::100e -c1
PING 2a00:1450:4002:800::100e(2a00:1450:4002:800::100e) 56 data bytes
64 bytes from 2a00:1450:4002:800::100e: icmp_seq=1 ttl=53 time=77.5 ms

--- 2a00:1450:4002:800::100e ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 77.568/77.568/77.568/0.000 ms

# tcpdump -ni eth0 host 2a00:1450:4002:800::100e
17:59:38.204173 IP6 2001:db8:f00:f00:5054:ff:fe8b:995d > 2a00:1450:4002:800::100e: ICMP6, echo request, seq 1, length 64
17:59:38.281437 IP6 2a00:1450:4002:800::100e > 2001:db8:f00:f00:5054:ff:fe8b:995d: ICMP6, echo reply, seq 1, length 64

//notice the change of IPv6 address to the one not using privacy extensions even after the flooding has finished long ago.

== Step 3. Disconnect/Reconnect connection  ==
// restoring net.ipv6.conf.eth0.use_tempaddr to value '2' makes no difference at all for the rest of the process

# nmcli dev disconnect iface eth0
# nmcli con up uuid 923e6729-74a7-4389-9dbd-43ed7db3d1b8

ubuntu@ubuntu:~$ ip a ls dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:8b:99:5d brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.96/24 brd 192.168.1.255 scope global eth0
    inet6 2001:db8:f00:f00:5054:ff:fe8b:995d/64 scope global tentative dynamic 
       valid_lft 86400sec preferred_lft 3600sec
    inet6 fdbb:aaaa:bbbb:cccc:5054:ff:fe8b:995d/64 scope global tentative dynamic 
       valid_lft 86400sec preferred_lft 3600sec
    inet6 fe80::5054:ff:fe8b:995d/64 scope link tentative 
       valid_lft forever preferred_lft forever

//Notice the "tentative" flag of the IPs on the device

//ping6 2a00:1450:4002:800::100e  while in another terminal: tcpdump -ni eth0 ip6

ubuntu@ubuntu:~$ ping6 2a00:1450:4002:800::100e -c1
PING 2a00:1450:4002:800::100e(2a00:1450:4002:800::100e) 56 data bytes
^C
--- 2a00:1450:4002:800::100e ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

# tcpdump -ni eth0 host 2a00:1450:4002:800::100e
18:01:45.264194 IP6 ::1 > 2a00:1450:4002:800::100e: ICMP6, echo request, seq 1, length 64

Summary:
Before flooding it uses IP: 2001:db8:f00:f00:ad1f:9166:93d4:fd6d
After flooding it uses IP: 2001:db8:f00:f00:5054:ff:fe8b:995d –> it has lost privacy extensions
After disconnect/reconnect it tries to use IP: ::1 –> it has lost IPv6 connectivity

The problem currently affects all Linux kernels (including the latest 3.8), that have IPv6 Privacy Extensions enabled. The only distribution that has IPv6 Privacy Extensions enabled by default is Ubuntu starting from version 12.04. So Ubuntu 12.04 and 12.10 are currently vulnerable to this attack and can have their IPv6 stack corrupted/disabled by a remote attacker in an untrusted network.

Kernel developers and people from RedHat Security Team are trying to fix the issue which in my opinion involves changing parts of the logic of IPv6 addressing algorithms in the Linux kernel.

No mitigation currently exists apart from disabling IPv6 Privacy Extensions.

You can play with this bug using flood_router26 tool from THC-IPv6 toolkit v2.1.
Usage: # ./flood_router26 -A iface

P.S. I can’t tell if the stack corruption could also lead to other kernel problems, that would probably need some professional security researchers to look into it.

mitigating wordpress xmlrpc attack using ossec

I’ve created some local rules for ossec to mitigate some of the effects of the wordpress xmlrpc attack presented here: WordPress Pingback Portscanner – Metasploit Module.

They seem to work for me, use at your own risk of getting flooded with tons of alerts. Obviously you need to set the alert level of the second rule to something that will trigger your active-response. Feel free to tweak the alert level, frequency and timeframe. Before you change frequency to something else please read the following thread though: setting ossec frequency level


   <rule id="100167" level="1">
    <if_sid>31108</if_sid>
    <url>xmlrpc.php</url>
    <match>POST</match>
    <description>WordPress xmlrpc attempt.</description>
  </rule>

  <rule id="100168" level="10" frequency="2" timeframe="600">
    <if_matched_sid>100167</if_matched_sid>
    <same_source_ip />
    <description>WordPress xmlrpc attack.</description>
    <group>attack,</group>
   </rule>

btw, if you don’t want xmlrpc.php accessible at all, you can block it through a simple mod_rewrite rule:


<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/PATH/TO/xmlrpc.php [NC]
RewriteRule ^(.*)$ - [F,L]

or you can try any of the other numerous ways to accomplish the same thing as presented here.

You’ll lose pingback functionality though…oh well.