Χαζές λύσεις για χαζά προβλήματα (Firewalls, NATs και scripts)

Εισαγωγή: VDSL woes

Κάποια στιγμή έκανα κι εγώ το βήμα, και αναβάθμισα το σπίτι μας σε σύνδεση 100/10 VDSL.

Γενικά είμαι ευχαριστημένος – δεν θα κάνω συγκρίσεις με την dial-up εποχή, που ένα τραγούδι τυχαίο αρχείο μεγέθους 3.5mb ήθελε 15 λεπτά να κατέβει στον υπολογιστή, ή που το διαβόητο βίντεο του Λεβέντη έκανε μια βδομάδα να έρθει, αν δούλευε σωστά ο download manager και δεν έσπαγε το download, και να πρέπει να ξεκινήσει ξανά από την αρχή.

Αλλά ακόμα και με το απλό ADSL της 9/1 (πραγματικής) ταχύτητας η διαφορά είναι χαοτική. Το θέμα όμως είναι ότι πλέον η γραμμή είναι πολύ ευαίσθητη στο θόρυβο. Τον πρώτο καιρό μάλιστα είχαμε αποσυνδέσεις πολλές φορές τη βδομάδα, ενώ 3 και 4 σε μια μέρα δεν ήταν σπάνιο.

Ο πάροχος, προφανώς, είπε το θέμα είναι στην πλευρά μου, και εν μέρει ήταν. Αφαιρώντας όλες τις διακλαδώσεις του χαλκού, βάζοντας ένα πιο αξιοπρεπές modem, και ξαναμιλώντας με τον πάροχο, που “κάτι έκανε”, η γραμμή πλέον πέφτει 1 με 2 φορές την βδομάδα περίπου, κάτι ανεκτό για μένα.

Ευκαιρία να κάνουμε ένα script

Επειδή όμως η διαδικασία του troubleshooting κράτησε πολύ καιρό, είπα να φτιάξω ένα σκριπτάκι που να μου “χαρτογραφεί” τις αστάθειες της γραμμής. Δυστυχώς το modem, ενώ έχει snmp και telnet, δεν δίνει την ip μέσα από αυτά τα interfaces, οπότε χάριν ευκολίας, απλά pollάρω την διεύθυνση μου από το internet. Όταν βλέπω αλλαγή στην διεύθυνση, μου στέλνω ένα tweet με τη νέα διεύθυνση, και κάνω update ένα διάγραμμα το οποίο έχω φτιάξει με το πολύ εύκολο στη χρήση canvasJS.

Ποιο είναι το χαζό πρόβλημα όμως;

Λοιπόν, το σπίτι έχει δυο wifi δίκτυα. Ένα δικό μας, της οικογένειας, κι ένα guest, τα οποία είναι απομονωμένα. Τι γίνεται όμως αν θες να δώσεις πρόσβαση σε ένα service που βρίσκεται στο private δίκτυο, σε ενα client που βρίσκεται στο guest δίκτυο, και το modem δεν δίνει τη δυνατότητα τόσο λεπτών ρυθμίσεων;

Η λύση που βρήκα είναι αρκετά χοντροκομμένη, και είναι η εξής:

Βήμα πρώτο:

Βάζουμε το service που θέλουμε να μοιράσουμε στα NAT/Port forwarding settings του modem. Παρανοϊκό, ναι το ξέρω, αλλά bear with me, έχει και συνέχεια.

Βήμα δεύτερο:

Εξασφαλίζουμε ότι ξέρουμε την internet ip του modem, ή (αρκετά πιο εύκολο) έχουμε γραφτεί σε μια dynamic dns υπηρεσία.

Βήμα τρίτο:

Ρυθμίζουμε το firewall στο μηχάνημα που έχει το service, ώστε να δέχεται συνδέσεις μόνο από διευθύνσεις του LAN και από την internet ip του modem.

Βήμα τέταρτο:

Ο client, όντας συνδεδεμένος στο guest δίκτυο, κάνει access το service όχι με τη LAN address του host, αλλά με την internet ip/url του modem. Το modem κάνει forward τη σύνδεση στο host με source address τη δικιά του ip, η σύνδεση περνάει το firewall, και τα καταφέραμε!

Βήμα πεμπτο:

profit!!!

Και πού κολλάει η εισαγωγή με το VDSL που πέφτει;

Έχοντας λοιπόν ένα σκριπτ που ήδη κάνει monitor τη σύνδεση στο internet, και ξέρει αν έπεσε και άλλαξε η διεύθυνση μας, μπορούμε να το κάνουμε extend, ώστε να φτιάχνει και τους κανόνες του firewall!

Ιδού το τέρας τελικό αποτέλεσμα!

#!/bin/bash

myip=""
let err=0
let tweet=0

tweets=( "no tweet" "New IP" "Same IP" )

cd ~/dropouts

#accept connections to port 9080 from the local network and VPN
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 9080 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 10.7.0.0/24 --dport 9080 -j ACCEPT

while [ 1 ]
do
    res=`curl https://ipinfo.io/ip 2>/dev/null`
    if [ $? -ne 0 ]
    then
        echo error
        let err=$err+1
        continue
    fi

    if [ "$myip" == "" ]
    then
        #first result after startup, add iptables rule
        sudo iptables -A INPUT -p tcp -s $res --dport 9080 -j ACCEPT
        #and reject all other connections
        sudo iptables -A INPUT -p tcp  --dport 9080 -j REJECT

        let tweet=1
        myip=$res
    else
        if [ "$myip" == "$res" ]
        then
            if [ $err -gt 0 ]
            then
                let tweet=2
            fi
        else
            #connection was reset
            #new ip, delete old iptable rules and add new
            sudo iptables -D INPUT -p tcp -s $myip --dport 9080 -j ACCEPT
            sudo iptables -D INPUT -p tcp  --dport 9080 -j REJECT
 
            sudo iptables -A INPUT -p tcp -s $res --dport 9080 -j ACCEPT
            sudo iptables -A INPUT -p tcp  --dport 9080 -j REJECT

            myip=$res
            let tweet=1

            ./chartmaker.sh >> maker.log
        fi
    fi

    if [ $tweet -gt 0 ]
    then
        tstamp=`date +%Y-%m-%d`
        ~/bin/RaspBot.py "$tstamp ${tweets[$tweet]}: $myip, errors: $err"

        let err=0
        let tweet=0
    fi

    sleep 300
done
Δημοσιεύθηκε την
Κατηγοριοποιημένα ως technology Με ετικέτα:

Γράψτε ένα σχόλιο

Η ηλ. διεύθυνση σας δεν δημοσιεύεται.

Αυτός ο ιστότοπος χρησιμοποιεί το Akismet για να μειώσει τα ανεπιθύμητα σχόλια. Μάθετε πώς υφίστανται επεξεργασία τα δεδομένα των σχολίων σας.