Εγκατάσταση και ρύθμιση Squid Proxy Server

Σε αυτό το άρθρο, θα δούμε πως μπορούμε να ρυθμίσουμε αλλά και να επαληθεύσουμε ότι λειτουργεί ο Squid proxy server μας.

egkatastasi-rithmisi-squid-proxy

 

Εισαγωγή στον Squid Proxy Server

Το squid και το squidGuard είναι δύο εφαρμογές που δουλεύουν παράλληλα με σκοπό να ελέγξουν την πρόσβαση που έχουν οι χρήστες μέσα από τον browser. Χρησιμοποιούν ‘Access Control Lists’, οι οποίες είναι δεν είναι τίποτα περισσότερο από ένα αρχείο κειμένου το οποίο περιέχει μία σειρά από κανόνες (Access List rules) που ξεκινάνε με την λέξη ‘ACL’ (στην αρχή της πρότασης). Μέσα από αυτές, λέμε στον squid proxy server, τι είδους περιορισμό και έλεγχο θέλουμε να εφαρμόσει στους clients που χρησιμοποιούν τον proxy server μας. Όπως καταλαβαίνετε λοιπόν, η όλη φάση με τις ACLs είναι κάπως έτσι:

  • ‘deny’ αυτό
  • ‘allow’ το άλλο

… ανάλογα πάντα με το τι θέλουμε να πετύχουμε και πρόσβαση θέλουμε να δώσουμε στους χρήστες μας.

Να τονίσω ότι αν και οι παρακάτω εντολές έχουν δοκιμαστεί σε openSUSE Leap η εγκατάσταση του Squid Server δεν διαφέρει σε άλλες διανομές όπως π.χ. Ubuntu, Linux Mint, Debian κλπ. Σε openSUSE είναι απαραίτητα τα παρακάτω:

  • squid: ο proxy server
  • yast2-squid: για να το ρυθμίζουμε μέσω του YaST
  • squidGuard: για την εγκατάσταση μίας λίστας που θα μας επιτρέψει να περιορίσουμε την πρόσβαση σε κάποια sites)
zypper in squid squidGuard yast2-squid

 

Η σειρά των κανόνων

Εκεί που την πατάνε συνήθως οι περισσότεροι, είναι το γεγονός ότι παίζει ρόλο η σειρά με την οποία ταξινομείτε τους κανόνες. Ο λόγος είναι ότι οι Access Lists διαβάζονται από πάνω προς τα κάτω.

Ο daemon βλέπει τους κανόνες σαν μία σειρά από tests, δηλαδή για κάθε γραμμή που έχετε γράψει, εφαρμόζει εκείνη την στιγμή έναν έλεγχο και τσεκάρει αν ισχύει ή όχι. Αν ισχύει, τότε εφαρμόζει τον κανόνα και σταματάει να διαβάζει την συνέχεια του αρχείου.

Αυτό έρχεται σε αντίθεση με τα κλασσικά *.conf αρχεία, όπου εκεί γίνεται ολοκληρωμένο parsing και όχι ένα μέρος αυτού. Η λογική λοιπόν είναι να ξεκινήσετε να γράφετε τους κανόνες σας, από τον πιο γενικό προς τον πιο ειδικό, είτε το ανάποδο (ανάλογα τι θέλετε να πετύχετε).

Ρύθμιση του Squid Server

Το βασικό configuration file για το squid είναι λίγο … μεγάλο … και όπως όλα, έχει και αυτό ένα κάρο πράγματα που δεν χρειαζόμαστε — τουλάχιστον όχι τώρα. Οπότε αυτό που θα κάνω, είναι να διαγράψω αρκετά από αυτά.

Πάω λοιπόν στο ‘/etc/squid’ directory

cd /etc/squid

και εκεί θα δούμε τα conf αρχεία που σχετίζονται με το squid μας. Αυτό που μας απασχολεί για την ώρα είναι ένα και μόνο ένα: squid.conf.

hellblazer:~ # cd /etc/squid/

hellblazer:/etc/squid # ll
total 300
-rw-r--r-- 1 root root 419 Dec 17 2014 cachemgr.conf
-rw-r--r-- 1 root root 419 Dec 17 2014 cachemgr.conf.default
-rw-r--r-- 1 root root 1547 Dec 17 2014 errorpage.css
-rw-r--r-- 1 root root 1547 Dec 17 2014 errorpage.css.default
lrwxrwxrwx 1 root root 26 Jan 11 12:06 errors -> /usr/share/squid/errors/de
-rw-r--r-- 1 root root 11954 Dec 17 2014 mime.conf
-rw-r--r-- 1 root root 421 Dec 17 2014 msntauth.conf
-rw-r--r-- 1 root root 421 Dec 17 2014 msntauth.conf.default
-rw-r--r-- 1 root root 2362 Dec 17 2014 squid.conf /etc/squid/squid.conf

Επειδή το configuration αρχείο είναι τεράστιο και χαοτικό, θέλω με την παρακάτω εντολή να φτιάξω μια καθαρή έκδοσή του χωρίς σχόλια, οπότε και πετάω ότι ξεκινάει με # και τις εντολές $ :

grep -Eiv '(^#|^$)' /etc/squid/squid.conf > /etc/squid/squid.conf

Αν θέλετε να δείτε την διαφορά μεταξύ πριν και μετά, ώστε να πάρετε μία γεύση κατά πόσο μικρύναμε το συγκεκριμένο αρχείο, χρησιμοποιείστε το εργαλείο wc -l:

hellblazer:/etc/squid # wc -l squid.conf.backup
75 squid.conf.backup

hellblazer:/etc/squid # wc -l squid.conf
30 squid.conf

Και πλέον ήρθε η στιγμή να το επεξεργαστούμε, ανοίγω λοιπόν τον vi (εσείς ανοίξτε όποιον θέλετε προφανώς)

hellblazer:/etc/squid #vi squid.conf

Εδώ θέλω να σας μιλήσω για 2 πράγματα:

Όσοι θα χρησιμοποιήσουν τον squid proxy server μας, θα πρέπει να συνδεθούν μαζί του στο port 3126. Αυτό είναι το default port που κάνει listening o squid για proxy connections. Όπως είπαμε και στην αρχή, αυτό που κάνει ο proxy είναι να σας δείχνει το internet (http, https) μέσα από την δική του ματιά.

http_port 3128

Προφανώς λοιπόν, αφού οι clients θα κοιτάνε με τα μάτια του squid, τότε το internet δεν θα βλέπει αυτούς, αλλά τον squid. Δηλαδή η IP με την οποία θα κάνουν web browsing δεν θα είναι η δική τους, αλλά αυτή του squid proxy server. Οπότε με αυτόν τον τρόπο, οι clients δεν κάνουν expose την πραγματική τους ταυτότητα, και μένουν κρυφοί προς τον υπόλοιπο κόσμο.

Με απλά λόγια λοιπόν, μπορούμε να πούμε ότι ένας proxy server, είναι ουσιαστικά ένας web anonymizer. Ακριβώς αυτό! Κρύβει την IP του client χρησιμοποιώντας την δική του, παρεμβάλοντας τον εαυτό του ανάμεσα στην επικοινωνία μεταξύ του client και του web. Οπότε στην μία περίπτωση δέχεται και προωθεί τα http requests του client προς το web, και στην άλλη δέχεται και επιστρέφει πίσω την απάντηση από το web προς τον client.

client —-> squid —-> web server
client <—- squid <—- web server

Ένα τυπικό σενάριο είναι να έχουμε 500 χρήστες, δηλαδή 500 browsers, δηλαδή 500 διαφορετικές IP, οι οποίοι όλοι τους χρησιμοποιούν τον δικό μου proxy server. Έτσι, όλες αυτές οι συνδέσεις και όλα αυτά τα requests που πηγαινo-έρχονται προς-και-από το web, θα φαίνονται σαν να γίνονται μόνο από έναν χρήστη: εμένα!

Γιατί; Μα αφού εγώ τους παρέχω την δυνατότητα να χρησιμοποιούν τον squid proxy server μου με αντάλλαγμα 1 ευρώ το μήνα, δηλαδή 500 ευρώ😛 Anyway, πάμε λίγο παρακάτω …

Σε άλλες διανομές πρέπει ίσως να δώσετε:

acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 128.0.0.0/8 0.0.0.0/32 ::1

Αλλά στο openSUSE Leap, οι κανόνες:

  • ACLs all,
  • manager,
  • localhost,
  • και to_localhost είναι ήδη predefined.

Οπότε, πρώτα από όλα, θα δώσουμε έναν κανόνα που μας επιτρέπει να έχουμε πρόσβαση στον proxy server από το τοπικό μας δίκτυο. Το configuration που προ-υπάρχει ήδη έτοιμο, είναι πολύ πιθανό να περιλαμβάνει ήδη το δίκτυο σας.

acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16 <--- το πιο πιθανό είναι ότι σας καλύπτει αυτό
acl localnet src fc00::/7
acl localnet src fe80::/10

Αν θυμάμαι καλά, οι περισσότεροι ελληνικοί ISP δίνουν routers που φτιάχνουν default δίκτυο 192.168.1.0/24. Σε αυτό την περίπτωση είστε ήδη μέσα στο 192.168.0.0/16. Εγώ που έχω γερμανικό ISP, ρουτεράκι μου, έχει τοπικό δίκτυο 192.168.178.0/24 το οποίο και αυτό είναι πάλι μέσα στο 192.168.0.0/16.

Ο λόγος που έχει ήδη έτοιμα κάποια δίκτυα, είναι για να μην κάνει την ζωή δύσκολη σε κάποιον που θέλει απλά να πατήσει ‘systemctl start squid’ και να ξεκινήσει. Οκ, δεκτό, αλλά bad security practice, για αυτό και εγώ θα αλλάξω αυτά που γράφει εκεί και θα τα προσαρμόσω στο τοπικό μου δίκτυο όπως δείχνω παρακάτω

Χρησιμοποιώ:

Ref-host IPv4
-------------
Network: 10.161.224.0/19
Broadcast: 10.161.255.255
Range: 10.161.224.1 - 10.161.255.254
My IP: 10.161.225.83

Ref-host IPv6
-------------
link-local unicast: fe80::5054:ff:fe03:8ed0/64
link-local network: fe80::/64
loopback: ::1/128

Οπότε σβήνω τις έτοιμες παραπάνω γραμμές και δίνω:

acl localnet src 10.161.224.0/19 # το δικό μου IPv4 internal network
acl localnet src fe80::/64 # το προσωπικό μου IPv6 link-local

Αυτό που λέω στον squid είναι:

Αν δεις να σου ζητάει να συνδεθεί μαζί σου ένας τύπος που έρχεται από το δίκτυο 10.161.224.0/19, τότε δώσε του HTTP πρόσβαση.

Ρύθμιση της Access List στον Squid Server

Πάμε τώρα να δούμε την Access List που λέγαμε νωρίτερα (ναι, η σειρά παίζει ρόλο). Αρχικά λοιπόν βλέπουμε ότι το squid επιτρέπει την πρόσβαση στον localhost manager, δηλαδή εμένα (αυτό έλειπε…).

http_access allow localhost manager

επίσης δίνει πρόσβαση στο localnet (δηλαδή στην 10.161.224.0 που έκανα define νωρίτερα) :

http_access allow localnet

και τέλος δίνουμε και πρόσβαση στο 127.0.0.1 :

http_access allow localhost

Όλα τα υπόλοιπα τα κάνει denied, και έτσι θα το αφήσω κ εγώ:

http_access deny all

Θυμάστε που είπα πριν ότι η σειρά παίζει ρόλο; Αν πάτε και βάλετε πρώτο access list rule το http_access deny all τότε θα φάτε πόρτα με το ‘καλημέρα’.

Αφού είδαμε τα βασικά, ας ρίξουμε και μία ματιά πιο κάτω, όπως για παράδειγμα εδώ:

and we also see some other definitions, such as the port and the coredump.

http_port 3128
coredump_dir /var/cache/squid

Βλέπουμε την port που θα κάνει listening ο daemon και το coredump dir (για να ξέρουμε που να ψάξουμε σε περίπτωση κρασαρίσματος).

Τέλος, υπάρχουν και κάποιοι άλλοι τύποι συνδέσεων, που δεν έχω ιδέα τι κάνουν, απλά τα αφήνω έτσι ως έχουν:

refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320

Πολύ σημαντικό είναι επίσης να δούμε ποιες ports θα γίνονται αποδεκτές από το squid. Οι παρακάτω πόρτες θα γίνουν redirect:

acl SSL_ports port 443 # https (SSL)
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http

και προφανώς μπορείτε να προσθέσετε τις δικές σας (π.χ. την port του game server που χρησιμοποιείτε). Τελειώσαμε λοιπόν με το configuration. Save and Exit.

Αυτό ήταν. Όπως διαπιστώσετε, δεν χρειάζεται ουσιαστικά να κάνετε τίποτα, ακόμα και αυτά που άλλαξα, μπορούσα να μην τα αλλάξω και δεν θα είχα κανένα πρόβλημα. Απλά ήθελα να κάνουμε ένα ‘πέρασμα’ για ‘νιώσετε’ πιο βολικά με αυτά που θα ακολουθήσουν στην συνέχεια.

Εκκίνηση του Squid Proxy

Ξεκινήστε τον squid proxy server χρησιμοποιώντας την αντίστοιχη εντολή, είτε systemd είτε sysv, αναλόγως τι προτιμάτε και ξέρετε να χειρίζεστε:

hellblazer:/etc/squid # systemctl start squid.service

επαληθεύουμε ότι ξεκίνησε χωρίς πρόβλημα:

hellblazer:/etc/squid # systemctl status squid.service
squid.service - Squid caching proxy
Loaded: loaded (/usr/lib/systemd/system/squid.service; disabled)
Active: active (running) since Mon 2016-01-11 14:49:53 CET; 1s ago
Process: 30709 ExecStart=/usr/sbin/squid -F $SQUID_START_OPTIONS -f /etc/squid/squid.conf (code=exited, status=0/SUCCESS)
Process: 30703 ExecStartPre=/bin/sh -c test -d "`sed -n 's/^cache_dir \+[[:alnum:]]\+ \+\([[:graph:]\/]\+\) .*/\1/p' /etc/squid/squid.conf | sed '1 q'`/00" || /usr/sbin/squid -z -F -N -S -f /etc/squid/squid.conf (code=exited, status=0/SUCCESS)
Main PID: 30714 (squid)
CGroup: /system.slice/squid.service
├─30712 /usr/sbin/squid -F -sY -f /etc/squid/squid.conf
├─30714 (squid-1) -F -sY -f /etc/squid/squid.conf
└─30715 (logfile-daemon) /var/log/squid/access.log <------------ αυτό είναι το log file

Jan 11 14:49:53 hellblazer squid[30714]: Using Least Load store dir selection
Jan 11 14:49:53 hellblazer squid[30714]: Set Current Directory to /var/cache/squid
Jan 11 14:49:53 hellblazer squid[30714]: Loaded Icons.
Jan 11 14:49:53 hellblazer squid[30714]: HTCP Disabled.
Jan 11 14:49:53 hellblazer squid[30714]: Pinger socket opened on FD 14
Jan 11 14:49:53 hellblazer squid[30714]: Squid plugin modules loaded: 0
Jan 11 14:49:53 hellblazer squid[30714]: Adaptation support is off.
Jan 11 14:49:53 hellblazer squid[30714]: Accepting HTTP Socket connections at local=[::]:3128 remote=[::] FD 12 flags=9
Jan 11 14:49:53 hellblazer systemd[1]: squid.service: Supervising process 30714 which is not our child. We'll most likely not notice when it exits.
Jan 11 14:49:54 hellblazer squid[30714]: storeLateRelease: released 0 objects

Ας ρίξουμε και μία ματιά στο log file:

hellblazer:/etc/squid # tail -f /var/log/squid/cache.log

2016/01/11 15:06:36 kid1| Squid plugin modules loaded: 0
2016/01/11 15:06:36 kid1| Adaptation support is off.
2016/01/11 15:06:36 kid1| Accepting HTTP Socket connections at local=[::]:3128 remote=[::] FD 12 flags=9
2016/01/11 15:06:36| pinger: Initialising ICMP pinger ...
2016/01/11 15:06:36| icmp_sock: (1) Operation not permitted
2016/01/11 15:06:36| pinger: Unable to start ICMP pinger.
2016/01/11 15:06:36| icmp_sock: (1) Operation not permitted
2016/01/11 15:06:36| pinger: Unable to start ICMPv6 pinger.
2016/01/11 15:06:36| FATAL: pinger: Unable to open any ICMP sockets.
2016/01/11 15:06:37 kid1| storeLateRelease: released 0 objects

Χμ, φαίνεται ότι έχουμε ένα μικρό προβληματάκι εδώ, το οποίο συμβαίνει την στιγμή που το squid προσπαθεί να χρησιμοποιήσει ένα δικό του utility που λέγεται pinger, το οποίο βρίσκεται στο /usr/sbin/pinger. Σας θυμίζει κάτι;

Σε αυτό το $PATH μόνο ο root μπορεί να το τρέξει, σε αντίθεση με το ping που βρίσκεται στο /usr/bin/ping το οποίο μπορούν όλοι να το τρέξουν. Άρα έχουμε permission πρόβλημα, το οποίο δεν θα βρίσκαμε ποτέ αν δεν κοιτούσαμε τα logs.

Αναφορά σφάλματος

Ας πάμε λοιπόν στο bugzilla να φτιάξουμε ένα bug, ώστε να διορθωθεί το παρακάτω πρόβλημα. Καλό θα είναι, να πούμε στον developer/maintainer πώς μπορεί να αναπαράγει το πρόβλημα:

  • Login σαν απλό χρήστης (στην περίπτωση μου είναι ‘tux’).
# su tux
  • Κάνε ping στο loopback interface χρησιμοποιώντας το ‘ping’.
$ ping 127.0.0.1

Αναμενόμενη συμπεριφορά: Λειτουργεί.
Πραγματική συμπεριφορά: Λειτουργεί.

  • Τώρα κάνε ping χρησιμοποιώντας το pinger utility
$ /usr/sbin/pinger 127.0.0.1

Αναμενόμενη συμπεριφορά: Λειτουργεί
Πραγματική συμπεριφορά: αποτυγχάνει λόγω permissions
Logs:

2016/01/11 15:21:17| pinger: Initialising ICMP pinger ...
2016/01/11 15:21:17| icmp_sock: (1) Operation not permitted
2016/01/11 15:21:17| pinger: Unable to start ICMP pinger.
2016/01/11 15:21:17| icmp_sock: (1) Operation not permitted
2016/01/11 15:21:17| pinger: Unable to start ICMPv6 pinger.
2016/01/11 15:21:17| FATAL: pinger: Unable to open any ICMP sockets.

Αυτό το σφάλμα συμβαίνει επειδή το pinger προσπαθεί να ανοίξει socket files και επίσης να ανοίξει ports με σκοπό να στείλει/λάβει IP πακέτα από/προς τον απομακρυσμένο web server που στείλουμε το request.

Όμως οι κανονικοί χρήστες δεν έχουν άδεια να πειράζουν sockets ή ports. Οπότε θα ήταν λάθος να φτιάξουμε το πρόβλημα με το να τους δώσουμε πρόσβαση. Άλλωστε δεν είναι δική μας δουλειά να το φτιάξουμε, αρκεί και μόνο το γεγονός ότι κάναμε bug report, ειδοποιώντας έτσι τον developer.

 

Προσωρινή παράκαμψη σφάλματος

Για την ώρα όμως και τις συνθήκες του άρθρου, θα πρέπει να σκεφτώ ένα workaround για να προχωρήσουμε παραπέρα… αυτό που θα κάνω λοιπόν είναι να θέσω το SUID bit σε αυτή την εντολή/αρχείο, οπότε οποιοσδήποτε τρέξει αυτή την εντολή δεν θα έχει πλέον πρόβλημα να ανοίξει τα απαιτούμενα socket files και ports.

Προσοχή: αυτό δεν είναι ασφαλές, οπότε να περιμένετε για το επίσημο bug fix και μην υλοποιήσετε το quick hack που μόλις σας περιέγραψα.

Ας το κάνω λοιπόν, για να μπορέσουμε να πάμε παρακάτω :

hellblazer:/etc/squid # ls -l /usr/sbin/pinger
-rwxr-xr-x 1 root root 68448 Dec 17 2014 /usr/sbin/pinger

hellblazer:/etc/squid # chmod u+s /usr/sbin/pinger

hellblazer:/etc/squid # ls -l /usr/sbin/pinger
-rwsr-xr-x 1 root root 68448 Dec 17 2014 /usr/sbin/pinger /usr/sbin/pinger 127.0.0.1
2016/01/11 15:29:04| pinger: Initialising ICMP pinger ...
2016/01/11 15:29:04| pinger: ICMP socket opened.
2016/01/11 15:29:04| pinger: ICMPv6 socket opened

Χμ, φαίνεται να λειτουργεί. Ας κάνουμε ένα restart το squid και να βεβαιωθούμε ότι φτιάχτηκε:

hellblazer:/etc/squid # systemctl restart squid.service

hellblazer:/etc/squid # tail -f /var/log/squid/cache.log
2016/01/11 15:29:48 kid1| Loaded Icons.
2016/01/11 15:29:48 kid1| HTCP Disabled.
2016/01/11 15:29:48 kid1| Pinger socket opened on FD 14
2016/01/11 15:29:48 kid1| Squid plugin modules loaded: 0
2016/01/11 15:29:48 kid1| Adaptation support is off.
2016/01/11 15:29:48 kid1| Accepting HTTP Socket connections at local=[::]:3128 remote=[::] FD 12 flags=9
2016/01/11 15:29:48| pinger: Initialising ICMP pinger ...
2016/01/11 15:29:48| pinger: ICMP socket opened.
2016/01/11 15:29:48| pinger: ICMPv6 socket opened
2016/01/11 15:29:49 kid1| storeLateRelease: released 0 objects

Οκ, φτιάχτηκε, πολύ ωραία, μπορώ να προχωρήσω με αυτό το άρθρο (για καλή μου τύχη). Με την ευκαιρία όμως, γίνατε μάρτυρες μιας κατάστασης που δείχνει πόσο σημαντικό είναι να κοιτάτε τα logs. Είναι πολύ πιθανό να έχετε αντίστοιχο πρόβλημα στη διανομή σας, οπότε κάντε μια αναφορά και συνεισφέρετε στην βελτίωση του λογισμικού !😉

Ενεργοποίηση πρόσθετων στο Squid Server

Μιας που πιάσαμε τα logs, ας δούμε κάτι εξίσου χρήσιμο. Στην περίπτωση που θέλετε να επαληθεύσετε ότι κάποιο feature του squid είναι ενεργοποιημένο ή όχι, δηλαδή αυτό που διαβάζετε καμιά φορά στο internet, πχ σας λένε: «τσέκαρε αν έχεις ενεργοποιημένο το SSL support» δηλαδή αν έχεις κάνει built το squid με την συγκεκριμένη flag κατά το –configure’.

Προφανώς εγώ δεν έκανα κανένα built, αλλά κάποιος άλλος έκανε και εμένα μου έδωσε το τελικό πακέτο το οποίο και εγκατέστησα με το zypper. Οπότε δεν έχω ιδέα τι flags χρησιμοποίησε ο τύπος κατά το compile του squid. No worries though, απλά ξεκινήστε το quid με την verbosity flag (v), και κάντε grep για ‘ssl’

squid -v | grep ssl

Αν είναι ενεργοποιημένο θα δείτε κάτι σαν κ αυτό: `–enable-ssl`

Και μιας που το έφερε η κουβέντα, ας δούμε ακριβώς τον τρόπο που το squid κάνει parse to configuration file:

squid -k parse 2>&1

Αν θέλετε απλά να βεβαιωθείτε ότι δεν έχετε κάνει κανένα τυπογραφικό λάθος στο configuration file, ελέγξτε το ως εξής:

squid -k check

Τώρα θα μου πεις, είναι δυνατόν να έχω κάνει ορθογραφικό λάθος και να ξεκινήσει το squid; Δεν ξέρω, εξαρτάται από τον τρόπο με τον οποίο ξεκινάει το service το systemd. Για παράδειγμα ο Apache ξέρω ότι διαμαρτύρεται έντονα αν του γράψεις πράγματα που δεν καταλαβαίνει στο conf του. Αντίθετα με το squid, που αν ανατρέξετε λίγο πιο πάνω που το ξεκίνησα, θα δείτε ότι το systemd του ξεκίνησε ως εξής /usr/sbin/squid -F -sY -f /etc/squid/squid.conf, όπου δεν βλέπω κάποια -k flag. Οπότε καλό είναι να τσεκάρετε και αυτό from time to time.

 

Ρύθμιση Πιστοποίησης στο Squid Server

Στήσαμε λοιπόν (τρομερά δύσκολο, ένα start κάναμε) το squid proxy server, στον οποίο έχουν πρόσβαση όλοι όσοι βρίσκονται στο τοπικό μου δίκτυο. Ας το περιορίσουμε λίγο αυτό.

Διαβάζω λοιπόν στο google ότι υποστηρίζει ncsa auth σαν basic level πιστοποίησης. Δεν έχω όμως ιδέα ποιο αρχείο πρέπει να σκαλίσω, οπότε κάτσε να κάνω σε πρώτη φάση ένα list με όλα τα αρχεία που περιέχονται στο πακέτο squid και να κάνω ‘grep’ για κάτι σχετικό, μπας και …

rpm -ql squid | grep ncsa
--> /usr/sbin/basic_ncsa_auth

Αχα, το βρήκαμε! Ακολουθεί βασικό configuration του παραπάνω αρχείου /usr/sbin/basic_ncsa_auth :

auth_param basic program /usr/sbin/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated

http_port 3128

Πάμε να φτιάξουμε έναν χρήστη panos για να το τεστάρουμε τώρα:

htpasswd -c /etc/squid/passwords panos
New password: (suse) <--- ειναι το password που πάτησα
Re-Type password: (suse) <-- ξανά το ίδιο προφανώς
Adding password for user panos

Επαληθεύω ότι δημιουργήθηκε στο σχετικό αρχείο passwords και έχει το username του χρήστη, αλλά και το password υπό την μορφή hash.

hellblazer:/etc/squid # cat /etc/squid/passwords
panos:$apr1$lF/aBSzu$BKYLidISwBJxtm/WoPYo2.

Κάνουμε επανεκκίνηση το squid προκειμένου να εφαρμοστούν οι αλλαγές που μόλις κάναμε ώστε να επαληθεύσουμε αν κάναμε τίποτα ή όχι.

systemctl restart squid.service

Ανοίγω τα logs: /var/log/squid/cache.log:

2016/01/20 15:34:45 kid1| storeLateRelease: released 0 objects
2016/01/20 15:34:59 kid1| Starting new basicauthenticator helpers...
2016/01/20 15:34:59 kid1| helperOpenServers: Starting 1/20 'basic_ncsa_auth' processes

Οκ, βλέπω ότι έγινε εκκίνηση του basic_ncsa_auth helper (ό,τι κι αν σημαίνει αυτό). Πάμε όμως να διαπιστώσουμε όντως ότι δουλεύει αυτό το πράγμα.

Δοκιμή σύνδεσης με password/username

Για το τεστ αυτό θα χρησιμοποιήσω το αγαπημένο μου ‘wget’, όπου θα του πω να προσπαθήσει να κατεβάσει το html από ένα website, χρησιμοποιώντας τον proxy server μου, που βρίσκεται σε ένα από τα Virtual Machines μου, με hostname: ‘hellblazer.qam.suse.de’. Επίσης θα του δώσω τις παραμέτρους username (panos) και password (suse) προκειμένου να τεστάρω αν δουλεύει το basic authentication που ρυθμίσαμε νωρίτερα.

Το τελευταίο όρισμα, είναι το site που θέλω να επισκεφτώ, στην δική μου περίπτωση επέλεξα το cerebrux.net.

Ανοίγω λοιπόν ένα VM, (αν και μπορώ κάλλιστα να παραμείνω στον hellblazer), απλά και μόνο για να εξομοιώσω καλύτερα το σενάριο client-server.

root@nasa:/ # wget -e use_proxy=yes -e http_proxy=http://hellblazer.qam.suse.de:3128 --proxy-user=panos --proxy-password="suse" www.cerebrux.net

Output:

--2016-01-20 15:43:51-- http://www.cerebrux.net/
Resolving hellblazer.qam.suse.de (hellblazer.qam.suse.de)... 10.161.225.83
Connecting to hellblazer.qam.suse.de (hellblazer.qam.suse.de)|10.161.225.83|:3128... connected.
Proxy request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html’

[ ] 96,673 168KB/s in 0.6s

2016-01-20 15:43:53 (168 KB/s) - ‘index.html’ saved [96673]

Βλέπουμε λοιπόν ότι:

  1. η σύνδεση με τον proxy πέτυχε (ο client μου ‘nasa’ βρίσκεται στο ίδιο τοπικό δίκτυο με τον ‘hellblazer’).
  2. Το authentication λειτούργησε.
  3. Ανοίγω και επαληθεύω ότι το ‘index.html’ είναι όντως κάτι αποδεκτό, και όχι κάποιο μήνυμα του τύπου: proxy failed blah blah κλπ.

Δοκιμή σύνδεσης με λάθος password

Σε αυτό το σενάριο, έστω ότι κάποιος τρίτος, που βρίσκεται στο ίδιο δίκτυο με εμένα (άρα βλέπει τον squid proxy μου) θέλει να τον χρησιμοποιήσει για να βγει στο internet μέσω αυτού. Αν και εσείς μπορείτε να χρησιμοποιήσετε το ίδιο σύστημα για την δοκιμή, εγώ θα πάω ξανά σε ένα άλλο virtual machine (ναι έχω πολλά).

travis:/tmp/panos # wget -e use_proxy=yes -e http_proxy=http://hellblazer.qam.suse.de:3128 --proxy-user=alex --proxy-password="xazos" www.cerebrux.net

(προσέξτε ότι αντί για το σωστό password ‘suse’, έδωσα επίτηδες ένα λάθος ‘xazos’).

Output:

--2016-01-20 15:46:30-- http://www.cerebrux.net/
Resolving hellblazer.qam.suse.de (hellblazer.qam.suse.de)... 10.161.225.83
Connecting to hellblazer.qam.suse.de (hellblazer.qam.suse.de)|10.161.225.83|:3128... connected.
Proxy request sent, awaiting response... 407 Proxy Authentication Required
2016-01-20 15:46:30 ERROR 407: Proxy Authentication Required.

Βλέπουμε λοιπόν πολύ σωστά, ότι ο squid server μου, μου απαγόρευσε την χρήση του!
Αν πάω λοιπόν στο VM που τρέχει ο squid server και ανοίξω τα logs /var/log/squid/access.log τότε θα δω ότι έχει καταγράψει την παραπάνω ενέργεια:

1453300673.437 0 10.161.225.82 TCP_DENIED/407 3751 GET http://www.cerebrux.net/ alex HIER_NONE/- text/html

Άρα, μπορείτε πολύ ωραία και απλά να γράψετε ένα script που να ελέγχει το παραπάνω αρχείο για ‘TCP_DENIED/407’ και αν βρει τέτοιο πράγμα, τότε να σας στέλνει ένα e-mail λέγοντας σου ότι η ‘τάδε IP’ προσπάθησε να αποκτήσει πρόσβαση στον squid proxy σου, αλλά δεν τα κατάφερε.

Αλλάξτε το password χωρίς να κάνετε restart το squid service

Σε αυτό το σενάριο, θέλουμε απλά να μάθουμε περισσότερα για το πως λειτουργεί το σύστημά μας. Είμαστε απλά περίεργοι, ψάχνουμε να βρούμε πιθανά προβλήματα, πιθανά bugs. Κάτι που σκέφτηκα λοιπόν είναι να αλλάξω το password, αλλά μην κάνω restart το squid. Θέλω να δω λοιπόν τι θα κάνει το squid τότε:

  • Αν δώσω το καινούριο password
  • Aν δώσω το παλιό password
hellblazer:/etc/squid # htpasswd -c /etc/squid/passwords panos

New password: (redhat)
Re-type new password: (redhat)
Adding password for user panos

Δοκιμάζουμε με το νέο (redhat) password:

vis:/tmp/panos # wget -e use_proxy=yes -e http_proxy=http://hellblazer.qam.suse.de:3128 --proxy-user=panos --proxy-password="redhat" www.cerebrux.net

output:

--2016-01-20 15:57:50-- http://www.cerebrux.net/
Resolving hellblazer.qam.suse.de (hellblazer.qam.suse.de)... 10.161.225.83
Connecting to hellblazer.qam.suse.de (hellblazer.qam.suse.de)|10.161.225.83|:3128... connected.
Proxy request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘index.html.6’

Λειτούργησε! Παρόλο που δεν έκανα restart ή reload, το squid δέχτηκε το καινούριο μου password. To παραπάνω είναι wanted behavior και δεν αποτελεί bug, το σχεδίασαν επίτηδες έτσι, επειδή θέλουν να μπορούν να προσθέτους/αφαιρούν χρήστες χωρίς να απαιτείται επανεκκίνηση του server. Και ναι, μόλις το διασταυρώσαμε🙂

Δοκιμάζουμε με το παλιό(suse) password:

travis:/tmp/panos # wget -e use_proxy=yes -e http_proxy=http://hellblazer.qam.suse.de:3128 --proxy-user=panos --proxy-password="suse" www.cerebrux.net
--2016-01-20 15:58:51-- http://www.cerebrux.net/
Resolving hellblazer.qam.suse.de (hellblazer.qam.suse.de)... 10.161.225.83
Connecting to hellblazer.qam.suse.de (hellblazer.qam.suse.de)|10.161.225.83|:3128... connected.
Proxy request sent, awaiting response... 407 Proxy Authentication Required
2016-01-20 15:58:51 ERROR 407: Proxy Authentication Required.

Βλέπουμε ότι πλέον δεν δέχεται το παλιό password, καθώς το έχει αντικαταστήσει πλέον με το παλιό.

Περισσότερος πειραματισμός

Αφήστε την φαντασία σας να οργιάσει και σκεφτείτε διάφορα test cases, τα οποία θα σας κάνουν να μάθετε καλύτερα το squid και ίσως να ανακαλύψετε και κάποια bugs στην πορεία. Στο παραπάνω σενάριο είδαμε τι συμβαίνει όταν αλλάξω το password χωρίς να κάνω restart, και συγκεκριμένα είδαμε το σενάριο:

  • Πρώτα login με το καινούριο password (success=expected), μετά login το παλιό (failed=expected)

Σαν προτείνω να δοκιμάσετε το ανάποδο:

  • Πρώτα login με το παλιό password ( ??? ), μετά login με το καινούριο ( ??? )

επίσης, για όσους γουστάρουν να ψάχνονται ακόμα περισσότερο:

  • Παλιό (???), μετά (καινούριο), τέλος με παλιό (???)

… είμαι σίγουρος ότι θα βρείτε ενδιαφέρονται πράγματα, και μέσα από όλη αυτή την διαδικασία μαθαίνετε το Linux καλύτερα, καθώς αναπτύσσετε troubleshooting skills.

Πιστοποίηση χρήστη στο Squid Server με DIGEST

Καλό το παραπάνω authetication, αλλά γράφει ότι είναι basic, που σημαίνει ότι ίσως υπάρχει και κάτι άλλο, πιο advanced ίσως… Ψάχνοντας λοιπόν βρήκα, ότι υπάρχει και μία ακόμα authetication method, που ονομάζεται ‘digest’.

Πρώτα ορίζουμε κάτι που το ονομάζει realm, προφανώς σε αυτό το realm μπορούν να δηλωθούν κι άλλοι users, οπότε φαντάζομαι ότι είναι κάτι σαν group για να λες:

το τάδε γραφείο με αυτούς τους υπαλλήλους ανοίκει στο τάδε ‘realm’ και θα έχουν αυτό τον κωδικό, το άλλο γραφείο με τους άλλους υπαλλήλους θα ανήκει στο άλλο ‘realm’ κλπ κλπ.

Οπότε το φαντάζομαι ότι είναι κάποιου είδους ομαδοποίηση.

htdigest -c /etc/squid/users MyRealm username

Σημειώστε ότι το htdigest είναι binary που ανήκει στο πακέτο apache2-utils (και όχι στο squid). Θα μου πείτε: ‘και πως το ξέρεις;’ . Καταρχάς είχα την περιέργεια να δω τι είναι αυτή η εντολή, και όποιος ψάχνει βρίσκει. Αρκεί βέβαια να ξέρει τα βασικά για packet managing στο σύστημά του. Στο δικό μου η εντολή για να βρω από ποιο πακέτο προέρχεται το συγκεκριμένο binary είναι:

rpm -qf $(which htdigest)

Τέλος πάντων, απλά ήθελα να το αναφέρω, ότι για την δημιουργία αυτού του password δεν είναι υπεύθυνο το squid, αλλά το ‘apache2-utils’. Αυτό το δημιουργεί, και το squid απλώς το διαβάζει. Ετσι, για να ξεκαθαρίσουμε τα πράγματα, όποτε ξέρουμε που να κοιτάξουμε αν κάτι πάει στραβά…

hellblazer:/etc/squid # htdigest -c /etc/squid/digest_passwords MyRealm panagiotis
Adding password for panagiotis in realm MyRealm.
New password: (paok)
Re-type new password: (paok)

Επαληθεύουμε ότι φτιάχτηκε το αρχείο και περιέχει τις σχετικές πληροφορίες:

hellblazer:/etc/squid # cat /etc/squid/digest_passwords
panagiotis:MyRealm:4f59c41fcf9914f477bc328e031acb46

Η διαφορά εδώ, τουλάχιστον αυτό που μαντεύω είναι ότι το παραπάνω password έγινε MD5 hash χρησιμοποιώντας πληροφορίες από το username (panagiotis), το passwrd (paok), και το realm (MyRealm).

 

Επαλήθευση ότι δουλεύει το digest

Όπως πήραμε πρέφα πριν, αυτό το digest authentication δεν είναι κάτι που υποστηρίζει εσωτερικά το squid, αλλά κάτι που το φτιάχνουμε με εργαλεία ενός τρίτου (βλ. apache2-utils). Οπότε σε πρώτη φάση θα τεστάρω ότι λειτουργεί το digest authentication σαν οντότητα, και στην συνέχεια αν όλα πάνε καλά, τότε θα πω στο squid να το χρησιμοποιήσει στο configuration του.

Με αυτόν τον τρόπο, θα γλυτώσουμε από πιθανούς μελλοντικούς πονοκεφάλους, καθώς δεν θα ξέρουμε αν φταίει το squid ή το αρχείο που έκανε generate το apache2-utils. Προκείμενου να γίνει digest authentication από το squid, κάνει pipe το username και το realm σε ένα άλλο binary, κι αν το άλλο binary τα γνωρίζει, επιστρέφει το MD5 hash. Στην περίπτωση του openSUSE, η όλη αυτή φάση λέγεται file-based authentication:

hellblazer:/etc/squid # rpm -ql squid | grep digest
/usr/sbin/digest_edirectory_auth
/usr/sbin/digest_file_auth θα μπείτε με την δική σας κανονική IP
http://example.gr --> θα μπείτε με την IP του proxy

Έτσι γίνεται, δεν είναι κανένα μαγικό. Αλλά ας πάμε στο θέμα μας.

Πώς θα σετάρουμε έναν client να χρησιμοποιεί πάντα τον proxy μας;

Αρχικά θυμόμαστε ότι ο proxy squid server τρέχει στο VM hellblazer.qam.suse.de που έχει την τοπική IP 10.161.225.83

Αυτό που θα κάνω είναι να ρυθμίσω τον Firefox, επειδή είναι πανεύκολο να το κάνω απευθείας στον browser, αφού έτσι αλλιώς αυτόν χρησιμοποιώ για web browsing.

Firefox > Preference > Advanced Tab > Network > Settings >

[ ] No Proxy
[ ] Audo-detect proxy settings for this network <– αυτό θα το ενεργοποιούσατε μόνο αν κάναμε broadcast τον squid proxy server στο δίκτυο.
[ ] Use system proxy settings <— αυτό θα το βάζατε αν χρησιμοποιούσατε την ENV μεταβλητή που χρησιμοποιεί το Linux για proxy.
[x] Manual proxy connection: <— Αυτό είναι που θα χρησιμοποιήσω εγώ

HTTP Proxy: 10.161.225.82 Port: 3128
[x] Use this proxy server for all protocols

Μπορούμε επίσης να επιλέξουμε «[ ] Remote DNS» μόνο εφόσον θέλουμε να κάνουμε απομακρυσμένα dns queries. Δεν έχω σετάρει κανένα bind server, οπότε το αφήνω για την ώρα.

Τώρα πάτε στο ‘google.com’. Αν όλα πήγαν καλά θα πρέπει να βλέπετε το google χωρίς κανένα πρόβλημα. Η IP που βλέπει το google δεν είναι η IP του client (10.161.225.82) αλλά η IP του proxy server (10.161.225.83).

Βέβαια, αν θέλετε να το εξακριβώσετε, δεν έχετε παρά να σηκώσετε ένα webserver και να τον επισκεφτείτε. Δυστυχώς θα βγω αρκετά off topic αν το περιγράψω και αυτό, οπότε το αφήνω στην καλή θέληση του καθενός, να το τεστάρει μόνος του. Απλά θα σηκώσετε ένα τοπικο apache και θα δείτε τα logs του.

Για την ώρα, θα αρκεστώ βλέποντας τα log files του proxy server. Πάω λοιπόν στο /var/log/ και εκεί βλέπω τον squid φάκελο. Αυτό με ενδιαφέρει κυρίως είναι το ‘access.log’ :

hellblazer:/var/log/squid # ls -l
total 24
-rw-r----- 1 squid nogroup 5011 Jan 11 16:37 access.log <-- αυτό εδώ
-rw-r----- 1 squid nogroup 16155 Jan 11 16:09 cache.log
-rw-r----- 1 squid nogroup 0 Jan 11 16:09 netdb.state

Βλέπουμε εδώ ότι όλα τα ‘GET’ και ‘POST’ methods που σχετίζονται με το google προέρχονται από την IP του client 10:161:225:82

hellblazer:/var/log/squid # cat access.log | grep 'google'

1452526527.490 519 10.161.225.82 TCP_MISS/302 634 GET http://google.com/ - HIER_DIRECT/216.58.217.206 text/html
1452526528.019 528 10.161.225.82 TCP_MISS/302 1158 GET http://www.google.de/? - HIER_DIRECT/216.58.218.195 text/html
1452526584.523 58433 10.161.225.82 TCP_MISS/200 34758 CONNECT ajax.googleapis.com:443 - HIER_DIRECT/74.125.133.95 -
1452526585.830 59418 10.161.225.82 TCP_MISS/200 9037 CONNECT www.googleadservices.com:443 - HIER_DIRECT/74.125.224.141 -
1452526587.634 59480 10.161.225.82 TCP_MISS/200 5060 CONNECT googleads.g.doubleclick.net:443 - HIER_DIRECT/216.58.208.194 -
1452526587.634 59514 10.161.225.82 TCP_MISS/200 27118 CONNECT www.googletagmanager.com:443 - HIER_DIRECT/173.194.45.62 -
1452526588.718 59897 10.161.225.82 TCP_MISS/200 4837 CONNECT www.google.com:443 - HIER_DIRECT/173.194.115.52 -
1452526589.748 60012 10.161.225.82 TCP_MISS/200 4561 CONNECT www.google.de:443 - HIER_DIRECT/216.58.218.195 -
1452526589.748 59745 10.161.225.82 TCP_MISS/200 4743 CONNECT www.google.com:443 - HIER_DIRECT/173.194.115.52 -
1452526590.738 59864 10.161.225.82 TCP_MISS/200 54720 CONNECT apis.google.com:443 - HIER_DIRECT/216.58.217.206 -
1452526591.621 63832 10.161.225.82 TCP_MISS/200 16303 CONNECT www.google-analytics.com:443 - HIER_DIRECT/173.194.45.38 -
1452526591.730 63707 10.161.225.82 TCP_MISS/200 253948 CONNECT www.google.de:443 - HIER_DIRECT/216.58.218.195 -

Αν μπορούσαμε να δούμε τα log files της Google (ή πιο απλά σηκώστε έναν webserver και επισκεφτείτε τον) θα βλέπαμε ότι όλα τα request έρχονται από την external IP του proxy server και δεν θα υπήρχε ίχνος για την external IP του client. Συνεπώς, η Google δεν μπορεί να βρει την πραγματική ταυτότητα του client που έκανε το request, διότι βρίσκεται κρυμμένος και μόνο ο proxy server γνωρίζει την ταυτότητά του.

Τι θα γίνει όμως στην περίπτωση που ο proxy server είναι μη διαθέσιμος (πχ offline) ; Για να εξομοιώσουμε αυτό το σενάριο απλά κλείστε τον squid server, μην πειράξετε το configuration. Θέλω απλά να δείτε τι βλέπει ο client όταν

systemctl stop squid.service

Ίσως χρειαστεί να περιμένετε λίγο, διότι το squid κάνει flushing ότι έχει στην μνήμη cache.

Τώρα πάτε πίσω στον client, ανοίξτε πάλι τον Firefox και δοκιμάστε να πάτε πάλι στο google. Θα δείτε λοιπόν ένα μήνυμα που θα λέει:

«The proxy server is refusing connections»
«Firefox is configured to use a proxy that is refusing connections».

Για να το φτιάξετε, δεν πρέπει να χρησιμοποιήσετε τον proxy, οπότε πάτε πάλι πίσω στα preferences και επιλέξτε:

[x] No Proxy

Τότε θα επαναφέρετε την σύνδεση με το http, και θα λειτουργήσει ξανά ο browser, μόνο που τώρα δεν χρησιμοποιείτε τον proxy server. Αν για παράδειγμα επισκεφτείτε κάποιο website τότε θα καταγραφεί η πραγματική εξωτερική IP σας, και όχι αυτή του proxy server.

Οπότε με αυτά και μ’αυτά τελειώσαμε τον configuration του HTTP Client (Firefox). Έτσι είδαμε πως καταφέραμε να κρύψουμε την IP μας από τον έξω κόσμο, και γλυτώσαμε από τα πιθανά cookies.

 

Περιορισμός πρόσβασης στον Squid Server

Είδαμε παραπάνω ότι το αρχικό configuration του proxy περιλαμβάνει πρόσβαση σε όλο το τοπικό μου δίκτυο. Τι γίνεται όμως αν εγώ θέλω να αποτρέψω ένα συγκεκριμένο μηχάνημα από το να χρησιμοποιεί τον proxy μου;

Αν πάμε πάλι πίσω στο squid.conf θα δούμε ότι αρχικά έχω κάνει define το τοπικό μου δίκτυο (localnet) :

acl localnet src 10.161.224.0/19 # το δίκτυο μου

και στην συνέχεια αποφάσισα αν θα κάνω ‘allow’ ή ‘deny’ σε αυτό, με την εξής σειρά:

http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all

Στην περίπτωση λοιπόν που θέλουμε να αποτρέψουμε την πρόσβαση από μία συγκεκριμένη IP (συνήθως είναι ένα δίκτυο, αλλά ας πούμε μια συγκεκριμένη IP για να φανεί καλύτερα στο παράδειγμα), θ απρέπει πρώτα να την κάνουμε define και στην συνέχεια να γράψουμε μία access list για αυτήν.

Αυτό που θα κάνω είναι restrict την IP του client. Έτσι, τα υπόλοιπα μηχανήματα στο δίκτυο θα συνεχίζουν να απολαμβάνουν τις υπηρεσίες του squid, ενώ ένας συγκεκριμένος client θα βλέπει την πόρτα.

Κάνω deny το δίκτυο ή την IP που θέλω να μπλοκάρω

acl localnet src 10.161.224.0/19 # το δίκτυό μου
# Εδω γράφετε την IP που θέλετε να μπλοκάρετε[/code"]

Όπως όλες οι access list rules, έτσι κι αυτή πρέπει να ξεκινάει με την λέξη <strong>acl</strong>. Στην συνέχεια βάζουμε όποιο όνομα θέλουμε (θα τον πω 'noThisGuy' ) και στην συνέχεια δηλώνω την προέλευση αυτής (src), δηλαδή την IP του client που θέλω να μπλοκάρω (10.161.225.82).

Προκειμένου να ορίσουμε μία συγκεκριμένη IP, πρέπει να αναφερθούμε σε ένα δίκτυο, χωρίς hosts, και αυτό γίνεται με την μάσκα υποδικτύου 255.255.255.255 (ή με άλλα λόγια /32 bitmask).

acl noThisGuy src 10.161.225.82/32 # διεύθυνση client που θα μπλοκάρω

Ξανά, το '/32' σημαίνει ότι θα μπλοκάρω μόνο την συγκεκριμένη IP. Aν δεν το καταλαβαίνετε, διαβάστε στο internet για IPv4 subnetting.

Οπότε μέχρι τώρα, έχω κάτι τέτοιο:

acl localnet src 10.161.224.0/19 # το δίκτυό μου
acl noThisGuy src 10.161.225.82 # διεύθυνση client που θα μπλοκάρω

Θα αφήσω στην άκρη το IPv6, αλλά καλό θα είναι να το μπλοκάρετε και αυτό για να είστε σίγουροι στην περίπτωση που επιτρέπετε τα IPv6 default networks:

acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/64 # RFC 4291 link-local (directly plugged) machines

τότε ο client, αν και εφόσον χρησιμοποιεί IPv6, θα μπορεί πάλι να συνδεθεί.

Οπότε το μόνο που μένει τώρα είναι να προσθέσουμε τις οδηγίες προς την ACL. Το 'localnet' υπάρχει ήδη, οπότε απλά θα χρησιμοποιήσω τον συμβολισμό του θαυμαστικού (!) που σημαίνει 'εκτός από'. Οπότε αυτό που θα κάνω είναι να πω στο squid: 'Επέτρεψε όλο το localnet (10.161.224.0/19) εκτός από τον noThisGuy (10.161.225.82)

http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet !noThisGuy <------- εδώ είμαστε
http_access allow localhost
http_access deny all

Οπότε, κάνουμε restart τον squid proxy server για να εφαρμοστούν οι αλλαγές μας, και να προσπαθήσουμε ξανά να συνδεθούμε στο Google. Αν έχετε απορυθμίσει τον client να χρησιμοποιεί τον proxy, ξανά ρυθμίστε τον.

Αυτό που βλέπει τώρα ο client ένα μήνυμα που του λέει ότι του απαγορεύτηκε η πρόσβαση.

Access Denied.
Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect

Θυμηθείτε ότι αυτό είναι διαφορετικό μήνυμα από το προηγούμενο, όπου ο proxy ήταν down. Άρα, αναλόγως το μήνυμα μπορείτε να γνωρίζετε αν ο proxy server είναι offline ή αν μπλόκαραν μεμονωμένα την πρόσβαση προς το μηχάνημά σας.

Πάμε όμως να δούμε και τι καταγράφτηκε τα logs του server και πιο συγκεκριμένο στο 'access.log':

1452530224.883 0 10.161.225.82 TCP_DENIED/403 3915 GET http://google.com/ - HIER_NONE/- text/html
1452530224.929 0 10.161.225.82 TCP_DENIED/403 3834 GET http://www.squid-cache.org/Artwork/SN.png - HIER_NONE/- text/html

Οπότε βλέπουμε ότι ο συγκεκριμένος τύπος που μπλοκάραμε πριν, προσπάθησε να συνδεθεί, αλλά απέτυχε. Συνεπώς επαληθεύουμε ότι το configuration που κάναμε δουλεύει. Κατά την ίδια λογική, εφαρμόζουμε αντίστοιχους κανόνες σε διάφορα δίκτυα (πχ Guests) και προσαρμόζουμε την πρόσβαση μόνο σε αυτούς που θέλουμε.

So we see that this guy tried to access our proxy server and the connection was successfully rejected thanks to our
latest configuration.

 

Δημιουργία BLACKLIST

Επειδή μπορούμε να προωθούμε τα HTTP requests του client, μπορούμε να τα φιλτράρουμε, να βλέπουμε δηλαδή ποιο site θέλει να επισκεφτεί, και μετά να αποφασίσουμε αν θέλουμε να τον αφήσουμε να δει το περιεχόμενό του ή όχι. Για αυτή την δουλειά, χρησιμοποιούμε κάτι έτοιμο, το οποίο λέγεται squidGuard και μας παρέχει διάφορα επίπεδα ελέγχου, σχετικά με το φιλτράρισμα ή το blacklisting συγκεκριμένων, domains, websites, URLs, για συγκεκριμένες ώρες, ημέρες, και γενικά πολλές πολλές επιλογές.

Το configuration βρίσκεται εδώ:

/etc/squidguard.conf

The location of the blacklists: dbhome /var/lib/squidGuard/db
The location of the logfiles : logdir /var/log/squidGuard

The definition of a category :

dest porn { <---- /var/lib/squidGuard/db/porn/
domainlist porn/domains <---- /var/lib/squidGuard/db/porn/domains
urllist porn/urls <---- /var/lib/squidGuard/db/porn/urls
}

Για να το τεστάρουμε, πάτε στην τοποθεσία με τα blacklists και προσθέστε τα δικά σας.

cd /var/lib/squidGuard/db/

Θα φτιάξω έναν φάκελο 'testdomain' στον οποίο θα βάλω μέσα όλα τα σχετικά αρχεία (domain list, url list, expressions κλπ).

mkdir /var/lib/squidGuard/db/testdomains

Σε πρώτη φάση, φτιάχνω ένα αρχείο που λέγεται 'domains' και πληκτρολογώ τα websites για οποία θέλω να μπλοκάρω την πρόσβαση προς αυτά.

vi /var/lib/squidGuard/db/testdomains/testdomain

www.olapaokre.gr
olapaokre.com

Αλλάζω επίσης τον κάτοχο του φακέλου και του αρχείου, έτσι ώστε το squid να μπορεί να τα διαχειριστεί κατά το δοκούν.

chown -R squid:root /var/lib/squidGuard/db/testdomains

παρακαλώ, επιβεβαιώστε ότι λειτούργησε η παραπάνω εντολή:

drwxr-xr-x 2 squid root 21 Jan 12 12:11 /var/lib/squidGuard/db/testdomains/
-rw-r--r-- 1 squid root 20 Jan 12 12:07 domains

Και τώρα, μπορείτε να πείτε στο squidGuard να κάνει build μία βάση δεδομένων (*.db) χρησιμοποιώντας τα αρχεία από αυτή την λίστα (ναι μόνο αυτά τα 2 domains). Για να το κάνουμε αυτό, πρέπει να πούμε στο squidGuard να κοιτάξει στο παραπάνω φάκελο:

vi /etc/squidguard.conf

βρείτε εκεί που λέει 'dest' και προσθέστε τα εξής:

dest testdomains {
domainlist testdomains/domains
'/var/lib/squidGuard/db/testdomains/domains' file
}

αφαιρέστε όλα τα υπόλοιπα (κάντε ένα backup πρώτα) που αναγράφονται στην κατηγορία με τα ACLs, και βάλτε αυτά που θέλετε εσείς για το 'testdomain' που φτιάξαμε παραπάνω:

acl {
default {
pass !testdomains all
redirect http://www.google.com
}
}

Στο παραπάνω παράδειγμα, αν κάποιος προσπαθήσει να επισκεφτεί τα websites που βρίσκονται στην database, τότε το squidGuard θα αλλάξει το IP Header του request και θα το κάνει redirect στο google.com. Χρησιμοποιώ την default class γιατί θέλω να κρατήσω το tutorial απλό. Εδώ μπορείτε να ορίσετε ένα κάρο πράγματα και να έχετε συνθήκες ελέγχου, αλλά αν πάρετε την βασική ιδέα πως δουλεύει το σύστημα, μετά είναι στο χέρι σας να ψάξετε όσο θέλετε.

Προαιρετικές αλλαγές

Χωρίζω την πρόσβαση ανάμεσα στα γραφεία, τα οποία βρίσκονται σε διαφορετικά υποδίκτυα προφανώς και ανάλογα μπλοκάρω ή φιλτράρω την κίνηση προς συγκεκριμένες σελίδες. Επίσης μπορώ να εφαρμόσω ελέγχους σχετικούς με την ώρα που θα προσπαθήσει κάποιος να συνδεθεί κάπου.

src bad_offices {
ip 192.168.0.0/24 # Replace this with your subnet
}

acl {
bad_offices {
pass !testdomains all
redirect http://www.lds.org
}
default {
pass !testdomains all
redirect http://www.google.com
}
}

Σε αυτό το παράδειγμα, όλοι οι clients στα 'bad_offices' θα σταλθούν στο
'www.lds.org' αντί του 'www.google.com'.

Παράδειγμα με ώρα και μέρα

Αντί για την 'default' class, μπορείτε να φτιάξετε μία δική σας πχ 'time workhours'.

time workhours {
weekly mtwhf 08:00 - 16:30
date *-*-01 08:00 - 16:30
}

Σε αυτή την περίπτωση λέω πως οι τύποι που κάθονται στα 'bad_offices' και προσπαθήσουν να μπουν σε κάποιο από τα απαγορευμένα websites που βρίσκονται στην database (κατά τις ώρες λειτουργίας του γραφείου, από τις 08:00 ως τις 16:30) τότε θα μεταφερθούν στο 'www.lds.org'. Αν το προσπαθήσουν μετά, τότε θα τους δώσουμε πρόσβαση κανονικά:

bad_offices within workhours {
pass !testdomains all
} else {
pass any
}

Τέλος πάντων, ας μην αρχίσω να απαριθμώ σενάρια γιατί δεν θα τελειώσουμε πουθενά. Κάντε save και reload την database:

squidGuard -C all

Επεξήγηση : -C file|all : create new .db files from urls/domain files specified in "file".

Σαν αποτέλεσμα θα δημιουργηθεί ένα καινούριο 'testdomains.db'. Το οποιο το επιβεβαιώνουμε ξανά από το logfile:

# tail -f /var/log/squidGuard/squidGuard.log

2016-01-12 12:17:06 [3191] Added User: root
2016-01-12 12:17:06 [3191] Added User: foo
2016-01-12 12:17:06 [3191] Added User: bar
2016-01-12 12:17:06 [3191] destblock good missing active content, set inactive
2016-01-12 12:17:06 [3191] destblock local missing active content, set inactive
2016-01-12 12:17:06 [3191] init domainlist /var/lib/squidGuard/db/testdomains/domains <--------
2016-01-12 12:17:06 [3191] create new dbfile /var/lib/squidGuard/db/testdomains/domains.db <--------
2016-01-12 12:17:06 [3191] squidGuard 1.4 started (1452597426.547)
2016-01-12 12:17:06 [3191] db update done
2016-01-12 12:17:06 [3191] squidGuard stopped (1452597426.552)

Για να επιβεβαιώσουμε ότι λειτουργεί το blacklisting, ας δοκιμάσουμε ένα 'dry-run':

echo "http://www.olapaokre.gr - - GET" | squidGuard -d

Το αναμενόμενο αποτέλεσμα εδώ είναι να μας κάνει redirect στο Google:

2016-01-12 12:36:04 [3903] squidGuard ready for requests (1452598564.003)
http://google.com -/- - GET <------- πράγματι
2016-01-12 12:36:04 [3903] squidGuard stopped (1452598564.003)

Οπότε μέχρι στιγμής, επιβεβαιώσαμε ότι το squidGuard λειτουργεί σωστά. Τώρα το μόνο που μένει είναι να πούμε στον squid proxy server να λαμβάνει υπόψη του το squidGuard, προσθέτοντας μία γραμμή με την τοποθεσία του binary του squidGuard αλλά και του configuration του:

vi /etc/squid/squid.conf

url_rewrite_program /usr/sbin/squidGuard –c /etc/squidguard.conf

Στην συνέχεια, κάντε επανεκκίνηση το squid:

systemctl restart squid.service

και προσπαθήστε να μπείτε στο 'olapaokre.gr' πχ με τον Firefox. Θα δείτε λοιπόν ότι θα σας μεταφέρει στο Google🙂

Σημείωση: Όταν και αν επαναφέρεται πίσω αυτό το redirect, μην ξεχάσετε να καθαρίσετε την cache του browser, γιατί θα συνεχίσει να σας στέλνει στο google.com

 

Σχετικά με το Squid Cache

Μιας που αναφέραμε το θέμα της cache, μία ερώτηση θα ήταν τι συμβαίνει με την cache του proxy; Αν διαβάσετε το changelog θα δείτε ότι το squid έχει την δική του cache και μάλιστα την υλοποιεί εξολοκλήρου στην μνήμη RAM.

Παλαιότερρα, συνίθιζε να χησιμοποιηεί κομμάτι του δίσκου, για να αποθηκεύει τα αρχεία, πράγμα που το έκανε αρκετά πιο αργό κατά την επανεκκίνηση του service. Ωστόσο, αν για κάποιο λόγο θέλετε να τεστάρατε ότι η cache λειτουργεί, μπορείτε να το ενεργοποίησετε για να το δοκιμάσετε:

Θα κάνετε χρήση του unsquid.pl

unsquid dumps Squid cache files specified on the command line into directories reflecting their original URLs, hence preserving the original site layouts for off-line browsing

για να το ενεργοποιήσετε, βγάλτε το σχόλιο στην αρχή της παρακάτω εντολής:

cache_dir aufs /var/cache/squid 100 16 256

Στην συνέχεια κάνω επανεκκίνηση το squid και ελέγχω αν ενεργοποιήθηκε:

squid -k parse 2>&1
...
2016/01/21 15:15:43| Processing: cache_dir aufs /var/cache/squid 100 16 256
2016/01/21 15:15:43| Processing: coredump_dir /var/cache/squid
...

Ανοίξτε τον browser και επισκεφτείτε μερικά sites. Αυτό θα έχει σαν συνέπεια να δημιουργηθεί μία cache στον δίσκο και συγκεκριμένα εδώ:

find /var/cache/squid/??/ -type f -print | xargs /usr/share/doc/packages/squid/contrib/unsquid.pl -t 'image/.*' -d /tmp/squid/

hellblazer:/tmp/squid # ls
http: ???

--> There is a new folder 'http:'

hellblazer:/tmp/squid # cd http\:/
hellblazer:/tmp/squid/http: # ls
i2.wp.com cerebrux.net s0.2mdn.net www.gravatar.com www.gstatic.com

Αυτό είναι απόδειξη ότι η cache λειτουργεί, οπότε το επαληθεύσαμε κ αυτό🙂

Ρύθμιση Squid με Local SSL Cert

Τελευταίο θέμα για αυτό το άρθρο που πιστεύω ότι πρέπει να ξέρει κάποιος, είναι πως να κάνει το squid να χρησιμοποιεί το δικό του SSL Certificate. Αυτό για το οποίο πληρώνετε επιπλέον όταν ζητάτε SSL Proxy Server.

Φτιάξτε ένα SSL certificate:

hellblazer:/tmp/squid/http: # cd /etc/squid/

hellblazer:/etc/squid # openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout myCA.pem -out myCA.pem

Generating a 2048 bit RSA private key
..................................+++
....................+++
writing new private key to 'myCA.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Germany
Locality Name (eg, city) []:Nuremberg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:SUSE
Organizational Unit Name (eg, section) []:QAM
Common Name (e.g. server FQDN or YOUR name) []:hellblazer.qam.suse.de
Email Address []:root@hellblazer.qam.suse.de

Αυτό θα δημιουργήσει το 'myCA.pem' αρχείο, δηλαδή το Certificate Authority.

hellblazer:/etc/squid # ls -lrt /etc/squid/myCA.pem

-rw-r--r-- 1 root root 3172 Jan 21 17:04 myCA.pem

Ας πούμε τώρα στο squid να χρησιμοποιεί το myCA.pem. Αντικαθιστούμε λοιπόν την port:

  • http_port 3128

με αυτό:

http_port 3128 ssl-bump cert=/etc/squid/myCA.pem generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

στην συνέχεια κάνουμε restart το squid και επαληθεύουμε την σύνδεση. Πώς; Ε κάντε και κάτι μόνοι σας ...

Have fun🙂

Απορίες, παρατηρήσεις, ιδέες... Ελεύθερα ! Πες την άποψή σου... έστω και Ανώνυμα:

Εισάγετε τα παρακάτω στοιχεία ή επιλέξτε ένα εικονίδιο για να συνδεθείτε:

Λογότυπο WordPress.com

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό WordPress.com. Αποσύνδεση / Αλλαγή )

Φωτογραφία Twitter

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Twitter. Αποσύνδεση / Αλλαγή )

Φωτογραφία Facebook

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Facebook. Αποσύνδεση / Αλλαγή )

Φωτογραφία Google+

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Google+. Αποσύνδεση / Αλλαγή )

Σύνδεση με %s