To σισύφιο έργο της ρύθμισης του DNS στο Linux Μέρος ΙΙ

Στο σημείωμα αυτό θα δούμε πως κάνει αναζήτηση DNS το Linux. Κάτι τόσο απλό έτσι δεν είναι; Μέγα λάθος, υπάρχει μια πολυπλοκότητα σε αυτό, κάθε διανομή θα κάνει τα πράγματα ελαφρά διαφορετικά και η ρύθμιση του DNS (αλλά και του δικτύου) έχει μαι πολυπλοκότητα, που δεν είναι επαρκώς τεκμηριωμένη. Είναι μια συνέχεια και ένα συμπλήρωμα αυτού του άρθρου για όσους χρήστες ή διαχειριστές συστημάτων θέλουν να ξέρουν τι υπάρχει κάτω από το καπάκι.

Μια καλά ρυθμισμένη διανομή, απλά θα δουλέψει χωρίς ο χρήστης να κάνει τίποτα πέραν του να συνδέσει ένα καλώδιο δικτύου ή να δώσει τους κωδικούς για κάποιο ασύρματο WiFi. Αλλά σε επαγγελματικά περιβάλλοντα, σε servers και docker containers θέλεις ένα καλύτερο έλεγχο και μια καλύτερη κατανόηση.

Αν δεν θέλεις να κάνεις κάτι ποιο πολύπλοκο, σταμάτα να διαβάζεις τώρα!

Πως ένα πρόγραμμα κάνει DNS Resolve

Το DNS είναι μια υπηρεσία του δικτύου και δεν ξέρει για αυτό ο πυρήνας. Δεν υπάρχει κάποια κλήση συστήματος. Υπάρχει μια κλήση της τυπικής βιβλιοθήκης getaddrinfo(3) της C, αλλά δεν της κάνουν χρήση όλα τα προγράμματα. Κάποια άλλα προγράμματα θα χρησιμοποιήσουν την παλιά και υπό κατάργηση gethostbyname(3).

Μπορούμε να δούμε τι κλήσεις συστήματος χρησιμοποιεί μια εντολή με την εντολή strace(1) . Θα την χρησιμοποιήσουμε για να διερευνήσουμε ποια αρχεία ανοίγει ένα πρόγραμμα όταν τρέχει και να κοιτάξουμε για την open(2) ή την openat(2) για παράδειγμα

strace -e trace=open,openat  host google.com

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

openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY) = 6
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 5

Αυτά τα δυο αρχεία είναι μια καλή αρχή για να ξεκινήσουμε την διερεύνηση.

NSSwitch

Ας ξεκινήσουμε με αυτό και το αρχείο nsswitch.conf(5). Εκεί μέσα θα βρούμε μια γραμμή που στην διανομή μου είναι:

hosts:          files mdns4_minimal [NOTFOUND=return] dns

Το αρχείο περιέχει πολλές άλλες καταχωρήσεις σχετικά με τις διάφορες “βάσεις δεδομένων” του συστήματος. Για παράδειγμα που θα βρει τους χρήστες ή πως θα κάνει DNS.

Μια ιστορία από το μακρινό παρελθόν. Δούλευα σε ένα μικρό τοπικό ISP και είχαμε πρόβλημα στο πως γράφονταν ένας χρήστης στο σύστημα. Θυμάστε αυτά το CD εγγραφής; Δουλεία μου ήταν να φτιάξω ένα τέτοιο. Θέλαμε τους χρήστες σε μια βάση δεδομένων SQL συνδεμένη και με το λογιστήριο. Αφού ο διαχειριστής είχε προσπαθούσε επί 3 εβδομάδες να πατσάρει υπηρεσίες τελικά έψαξα το πως γίνετε (δεν υπήρχε πολύ πληροφορία τότε) και το έλυσα με μια γραμμή εκεί. Ήταν μια φοβερή λύση.

Τι ακριβώς σημαίνει αυτό; Είναι μια λίστα με τις “βάσεις δεδομένων” που θα κοιτάξει το σύστημα για να βρει μια διεύθυνση dns. Υπάρχουν 3 βάσεις. Η πρώτη είναι η files που θα συμβουλευτεί πρώτα. Αυτή θα συμβουλευτεί το αρχείο ‘/etc/hosts hosts(5). Η δεύτερη βάση κάνει χρήση του Multicast DNS - Wikipedia και θα αναζητήσει το όνομα με βάση κάποιον DNS server. Η διαφορά από το dns είναι πως θα κοιτάξει και για συσκευές στο τοπικό δίκτυο με την κατάληξη ‘*.local’. Η τελευταία dns δεν ξέρει για τοπικά ονόματα, αλλά δεν υπάρχει λόγος να χρησιμοποιηθεί, εξου και το ’ [NOTFOUND=return]'. Στο δικό σας σύστημα ίσως να είναι διαφορετικό. Αν ναι γράψτε το στα σχόλια.

Οπότε υπάρχουν διαφορετικοί τρόποι ανάλογα με το είδος του ονόματος. Οι τολμηροί ας παίξουν σκαλίζοντας το αρχείο και δοκιμάζοντας διαφορετική σειρά ή σβήνοντας κάποιες “βάσεις”.

image

Το πρόγραμμα που θα κάνει αναζήτηση DNS θα καλέσει αυτόν τον μηχανισμό μέσα από την libc. Σίγουρα τον υποστηρίζει η GNU libc, αλλά δεν ξέρω αν οι εναλλακτικές υλοποιήσεις (όπως η musl) τον χρησιμοποιούν. Αν έχετε κάποιο τέτοιο σύστημα πείτε μας το στα σχόλια.

Υπάρχει κόσμος που συγκρίνει τις libc μόνο με βάση το μέγεθος του κώδικα. Αλλά ο παραπάνω κώδικας υπάρχει εκεί για κάποιο λόγο, αυτός είναι ένας από αυτούς.

Το αρχείο ‘/etc/resolv.conf

Αυτό το αρχείο (που συνήθως είναι ένας συμβολικός δεσμός κάπου άλλου) περιέχει τον συγκεκριμένο nameserver που θα χρησιμοποιηθεί. Η μάχη για το ποιο πρόγραμμα θα τον ενημερώσει περιγράφετε εδώ: To σισύφιο έργο της ρύθμισης του DNS στο Linux, Μέρος Ι.

Στο σύστημα μου το αρχείο αυτό το φτιάχνει το systemd-resolved.service(8) αλλά πως ακριβώς; Η λύση είναι στο αρχείο ‘/lib/systemd/system/networking.service’. Ας δούμε τι περιέχει και πως βρίσκουμε την τοποθεσία του:

systemctl status networking.service
cat /lib/systemd/system/networking.service

ή με μια εντολή:

systemctl cat networking.service

Μέσα στο unit θα βρούμε τις γραμμές

[Service]
Type=oneshot
EnvironmentFile=-/etc/default/networking
ExecStart=/sbin/ifup -a --read-environment
ExecStop=/sbin/ifdown -a --read-environment --exclude=lo
RemainAfterExit=true
TimeoutStartSec=5min

Τι μας λένε; Πως την ρύθμιση θα την κάνει η εντολή /sbin/ifup χρησιμοποιώντας ρυθμίσεις από το αρχείο ‘/etc/default/networking’. Επόμενο βήμα ο φάκελος '/etc/network/ ’ και οι υποφακέλοι του που περιέχουν πολύπλοκα scripts για να κάνουν την ρύθμιση. Ρίξτε μια ματιά και προσπαθήστε να καταλάβετε τι συμβαίνει :innocent:.

NetworkManager, systemd-networkd, netplan, dnsmasq, avahi, dhclient

Κάποιες διανομές θα χρησιμοποιήσουν τον NetworkManager και κάποιες άλλες το καινούργιο systemd-networkd για την ρύθμιση του δικτύου. To καθένα έχει τους τρόπους του και δεν θα περιγράψω κανέναν εδώ. Στο Ubuntu :ubuntu: και στις διανομές βασισμένες σε αυτό πρόσφατα μπήκε το netplan που είναι ένα σύστημα που φτιάχνει τα αρχεία ρυθμίσεων αυτών των δυο, με χρήση απλών αρχείων YAML.

Το dnsmasq συνήθως θα ξεκινήσει και είναι ένας τοπικό DNS server που ακούει στην πόρτα 53. Εδώ μπορεί να έχουμε τα αρχεία ρυθμίσεων να λένε πως το χρησιμοποιούν, αλλά να μην είναι κατ ανάγκη εγκατεστημένο :joy:. Αυτό που κάνει είναι να λειτουργεί σαν ένα επίπεδο caching, ώστε να μην κάνουμε την αναζήτηση ενός ονόματος ξανά και ξανά. Μια καλή εναλλακτική είναι το unbound, για περισσότερα δείτε εδώ:

Το dhclient σε κάποιες διανομές ρυθμίζει την διεύθυνση IP και ενημερώνει τον DNS server αυτόματα χρησιμοποιώντας κάποιον DHCP server, συνήθως τον ρούτερ.

Τέλος μπορεί να τρέχετε το avahi. Αυτό μεταξύ άλλων ενημερώνει τις διευθύνσεις τύπου ‘*.local’.

Περισσότερες ερωτήσεις παρά απαντήσεις;

Πιθανά αυτό το σημείωμα σας άφησε με περισσότερες ερωτήσεις παρά απαντήσεις. 'Ισως να είπατε στον εαυτό σας “Νόμιζα πως κάτι ήξερα, αλλά τελικά δεν ξέρω τίποτα!”. Αυτή αγαπητέ είναι η αρχή της γνώσης: Dunning–Kruger effect - Wikipedia.

image

Και δεν καλύψαμε παρά τα βασικά για το DNS. Ελπίζω πάντως να βοήθησε να ξεκαθαρίσουμε όλοι τα υποσυστήματα και πως εμπλέκονται μεταξύ τους και να είναι μια αφετηρία αν προκύψει κάποιο πρόβλημα και δεν ξέρεις από που να ξεκινήσεις. Ο συγγραφέας δεν είναι επίσης κάποιος βαθύς γνώστης του DNS ή του πως μια μοντέρνα διανομή ρυθμίζει το δίκτυο. Προσθέστε ελεύθερα επιπλέον πληροφορίες και επισημάνετε τα λάθη και τις παρανοήσεις μου, που σίγουρα υπάρχουν. Ουδείς άσφαλτος :grin:.

Γιατί αυτή η πολυπλοκότητα και πως μπορεί να διορθωθεί; Εν μέρη υπάρχει για ιστορικούς λόγους, αλλά και για την εσφαλμένη ιστορική πεποίθηση (μεγάλη κουβέντα αυτό) πως πάντα στο UNIX μπορούμε να τρέχουμε ότι θέλουμε και να ρυθμίσουμε το σύστημα όπως θέλουμε. Δεν μπορείς να έχεις το ένα χωρίς το άλλο. Διάλεξε :innocent:.

Σε μια μοντέρνα διανομή Linux υπάρχει μια αυξημένη πολυπλοκότητα σε σχέση με ένα παραδοσιακό UNIX — υπάρχουν πολλοί καλοί λόγοι για αυτό — υπάρχει μια συνεχής αναζήτηση για καλύτερες λύσεις για τα καινούργια προβλήματα που προκύπτουν. Αυτή την στιγμή δεν έχουν καταλήξει όλες οι διανομές σε ένα τρόπο, και έχουμε και πάντα το πρόβλημα της συμβατότητας προς τα πίσω. Ακόμα χειρότερα κάποιες διανομές δεν έχουν καταλάβει την πολυπλοκότητα που απαιτούν οι μοντέρνες ανάγκες και κάνουν βήματα προς τα πίσω. Εγώ λέω αντί να γκρινιάζουμε και να αναπολούμε το παρελθόν (τότε που το κεφάλι μας μπορεί να είχε ακόμα τρίχες) πως είναι καλύτερο να προσπαθήσουμε να καταλάβουμε αυτές τις ανάγκες και να μάθουμε ή τουλάχιστον να ενημερωθούμε για τα νέα συστήματα. Δυστυχώς στην εποχή του clickbait δεν υπάρχει πάντα εύκολα προσβάσιμη αυτή η πληροφορία.

Διαβάστε

Την παρακάτω σειρά άρθρων στα οποία βασίστηκε το κείμενο

Ένα μικρό script για πειράματα

Την πολύ καλή σειρά του Delta Hacker