Archivi tag: ubuntu

Ubuntu: analisi e debug di un’interfaccia di rete malfunzionante

Di recente, analizzando i log di uno dei server che gestisco, mi sono accorto che una delle sue interfacce di rete continuava a generare tutta una serie di eventi del tipo:

root@linux-box:~$ dmesg | grep eth0
[  184.348573] 8139too 00:40:f4:44:68:8e: eth0: link up
[  190.271409] 8139too 00:40:f4:44:68:8e: eth0: link up
[  196.374125] 8139too 00:40:f4:44:68:8e: eth0: link up
[  201.823936] 8139too 00:40:f4:44:68:8e: eth0: link up
[  208.089862] 8139too 00:40:f4:44:68:8e: eth0: link up
[  212.200536] 8139too 00:40:f4:44:68:8e: eth0: link up
[  216.950829] 8139too 00:40:f4:44:68:8e: eth0: link up
[  221.071493] 8139too 00:40:f4:44:68:8e: eth0: link up
[  226.731134] 8139too 00:40:f4:44:68:8e: eth0: link up
[  230.778527] 8139too 00:40:f4:44:68:8e: eth0: link up
[  234.126353] 8139too 00:40:f4:44:68:8e: eth0: link up
[  238.936576] 8139too 00:40:f4:44:68:8e: eth0: link up
[  244.859427] 8139too 00:40:f4:44:68:8e: eth0: link up
[  250.845563] 8139too 00:40:f4:44:68:8e: eth0: link up
[  256.831661] 8139too 00:40:f4:44:68:8e: eth0: link up
[  262.458027] 8139too 00:40:f4:44:68:8e: eth0: link up
[  266.428794] 8139too 00:40:f4:44:68:8e: eth0: link up
[  271.305659] 8139too 00:40:f4:44:68:8e: eth0: link up
[  277.091885] 8139too 00:40:f4:44:68:8e: eth0: link up
[  282.768241] 8139too 00:40:f4:44:68:8e: eth0: link up
[  287.102103] 8139too 00:40:f4:44:68:8e: eth0: link up
[  290.866316] 8139too 00:40:f4:44:68:8e: eth0: link up
[  294.267496] 8139too 00:40:f4:44:68:8e: eth0: link up

ubuntu

In più, essa risultava completamente “sorda”, nel senso che anche sniffando il traffico mediante tcpdump, non vi era evidenza di frame/pacchetti di alcun genere, nonostante fosse collegata ad un segmento di rete piuttosto popolato.

Alla luce di ciò, le cause del suddetto malfunzionamento sarebbero potute essere 2:

1) guasto hardware;
2) aggiornamento che ha compromesso i driver del kernel che si interfacciano con la scheda (leggasi moduli), rendendola inutilizzabile.

Prima di procedere con l’analisi, però, è opportuno capire come avviene il riconoscimento dell’interfaccia di rete da parte del sistema operativo durante la fase di boot.

Chipset e moduli del kernel

Durante l’accesione (boot) della macchina, il sistema operativo riconosce la scheda di rete “dialongando” con il chipset di cui è dotata. Per individuarlo è sufficiente lanciare il seguente comando (con relativo output):

root@linux-box:~# lspci | grep Ethernet

04:01.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)

Nella fattispecie, il chipset utilizzato dalla scheda è Realtek.

Il modulo del kernel in grado di interfacciarsi con essa prende il nome di r8139too e deve essere caricato in fase di avvio. Per verificare che il suddetto modulo sia effettivamente up è sufficiente lanciare il comando:

root@linux-box:~$ lsmod | grep 8139

il cui output sarà simile al seguente:

8139too                32177  0
8139cp                 27360  0

Udev e nomenclatura

Se il modulo è stato correttamente caricato, la scheda di rete può essere effettivamente “riconosciuta” come tale ed il sistema operativo sarà in grado di assegnarle un nome.

Durante tale fase entra in gioco il demone udev, che “leggerà” il contenuto del file di configurazione dedicato alle interfacce di rete, ovvero /etc/udev/rules.d/70-persistent-net.rules:

root@linux-box:~$ cat /etc/udev/rules.d/70-persistent-net.rules

# PCI device 0x10ec:/sys/devices/pci0000:00/0000:00:1e.0/0000:04:01.0 (8139too)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:40:f4:44:68:8e", ATTR{dev_id}=="0x0", ATTR{type}=="1", NAME="eth0"

La suddetta regola di esempio parla chiaro: appena viene identificata una scheda di rete recante come indirizzo MAC 00:40:f4:44:68:8e, come id 0x0 e come tipo 1, le dovrà essere assegnato come nome eth0.

Configurazione

A questo punto la scheda è pronta per essere configurata, secondo quanto definito all’interno del file /etc/network/interfaces:

auto eth0
iface eth0 inet static
address 192.168.11.1
netmask 255.255.255.0

Comandi di diagnostica

Se tutto è filato per il verso giusto, lanciando un semplice ifconfig, la suddetta scheda di rete sarà tra quelle disponibili:

root@linux-box:~$ ifconfig eth0
eth0      Link encap:Ethernet  IndirizzoHW 00:40:f4:44:68:8e
          indirizzo inet:192.168.1.1  Bcast:192.168.11.255  Maschera:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1989751 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3500430 errors:0 dropped:0 overruns:0 carrier:0
          collisioni:0 txqueuelen:1000
          Byte RX:339007498 (339.0 MB)  Byte TX:3756299292 (3.7 GB)
          Interrupt:16 Indirizzo base:0xe800

Inoltre, è possibile visualizzare il modulo in uso per interfacciarsi con la suddetta scheda, avvalendosi di ethtool con l’opzione -k:

root@linux-box:~$ ethtool -i eth0

il cui output sarà simile al seguente:

driver: 8139too
version: 0.9.28
firmware-version:
bus-info: 0000:04:01.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no

Per identificare, invece, alcuni dei suoi parametri di funzionamento, quali autonegoziazione, velocità, duplex, ecc., è sufficiente lanciare il comando:

root@linux-box:~# ethtool eth0

che ci darà un risultato simile al seguente:

Settings for eth0:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Supported pause frame use: No
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Link partner advertised link modes:  10baseT/Half 10baseT/Full
                                             100baseT/Half 100baseT/Full
        Link partner advertised pause frame use: Symmetric
        Link partner advertised auto-negotiation: Yes
        Speed: 100Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 32
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: pumbg
        Wake-on: g
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes

In alternativa, si possono ottenere delle informazioni più sintetiche utilizzando il più datato (e meno completo) mii-tool:

root@linux-box:~$ mii-tool eth0
eth0: negotiated 100baseTx-FD, link ok

Identificazione della causa

A valle delle riflessioni fatte fin’ora, tutto ciò che riguarda la scheda risulta coerente e conforme con quanto ci si aspettava, per cui è stato facile intuire, andando per esclusione, che si trattava, banalmente, di un guasto hardware.

Una volta sostituita la scheda, infatti, tutto ha ripreso a funzionare correttamente.

Alla prossima.

dnsmasq ed Ubuntu: configurare un server DNS/DHCP per ambienti SOHO

Premesso che per mettere in piedi un nameserver locale si possono utilizzare diverse soluzioni open source, anche di tipo enterprise (una su tutte è rappresentata da bind/named), ho deciso di installare dnsmasq su un server Ubuntu per 2 motivi:

1) la rete aveva dimensioni estremamente ridotte (un server, qualche workstation e 3 stampanti), quindi rientrava nell’ambito delle infrastrutture SOHO (Small Office Home Office);

2) vi era la necessità di tirar su anche un servizio di DHCP, configurabile direttamente sull’applicativo in questione (che quindi può svolgere, contemporaneamente, sia il ruolo di nameserver che quello di DHCP server).

dnsmasq

Configurazione del DHCP server

Fare in modo che dnsmasq svolga le funzioni tipiche di un server DHCP è un’operazione abbastanza banale. Infatti, è sufficiente editare la configurazione del demone in questione (operando sul file /etc/dnsmasq.conf), aggiungendo le seguenti direttive:

no-dhcp-interface=eth1

dhcp-range=eth1,192.168.0.100,192.168.0.199,8h

In particolare, ho messo in ascolto il server DHCP sulla sola interfaccia eth0 (dato che si tratta di una macchina dual homed, in cui la scheda eth1 è collegata ad Internet mediante uno screened router). Inoltre, ho definito il pool di indirizzi che possono assere assegnati ai client che ne fanno richiesta, con relativo lease time (8h).

Configurazione del nameserver

Tale configurazione è un po’ più complessa rispetto alla precedente ma risulta comunque abbordabile.

Diciamo che dnsmasq è un nameserver “giocattolo”, in cui molti record DNS devono essere definiti all’interno di un file “piatto”, quale, ad esempio, /etc/hosts (anche se è possibile definire un file ad hoc per tale scopo), senza che vi sia quindi la necessità di creare una specifica zona DNS (cosa che invece risulta essere mandatoria con altri nameserver “un po’ più seri”).

I record di tipo A presenti nel file /etc/hosts avevano un formato simile al seguente:

192.168.0.2     proxy
192.168.0.4     server1
192.168.0.5     PC1
192.168.0.6     stampante1
192.168.0.7     stampante2
192.168.0.9     stampante3
192.168.0.10    PC2

Per quanto riguarda, invece, la configurazione del servizio DNS, ho abilitato le seguenti direttive (all’interno del file /etc/dnsmasq.conf):

interface=eth0
except-interface=eth1
listen-address=192.168.0.2

expand-hosts

domain=soho.loc

Le prime 3 servono a mettere in ascolto il server solo ed esclusivamente sull’interfaccia rivolta verso la LAN. Con expand-hosts e domain=soho.loc, invece,  ho fatto in modo che le query DNS vadano a buon fine anche nel caso in cui venga fornito il solo hostname della macchina di cui si vuole conoscere l’indirizzo IP.

Poichè il suddetto nameserver deve risolvere solo ed esclusivamente gli indirizzi locali, ho dovuto definire i forwarder (o nameserver di upstream) a cui inviare le query per tutte le zone DNS pubbliche. La direttive che ho utilizzato sono le seguenti:

resolv-file=/etc/resolv.dnsmasq
strict-order

dove il contenuto del file /etc/resolv.dnsmasq era il seguente:

nameserver 8.8.8.8
nameserver 208.67.222.222
nameserver 8.8.4.4
nameserver 208.67.220.220

La direttiva strict-order faceva in modo che i forwarder venissero contattati seguendo  l’ordine con cui sono stati definiti all’interno del suddetto file (il secondo nameserver viene contattato solo nel caso in cui il primo non sia raggiungibile, ergo, per ottenere una maggiore ridondanza, ho deciso di alternare ai nameserver di Google quelli di OpenDNS).

Per avere un maggiore controllo sulle query inoltrate al nameserver locale, ho deciso di loggarle su un apposito file di testo grazie ai seguenti parametri di configurazione:

log-queries
log-facility=/var/log/dnsmasq/query.log

Ho anche configurato la rotazione dei log mediante il file dnsmasq posto all’interno della directory /etc/logrotate.d:

/var/log/dnsmasq/query.log {
        rotate 7
        weekly
        compress
        missingok
        notifempty
}

Infine, affinchè i client della LAN riuscissero a “riconoscere” i record DNSSEC (garantendo loro una maggiore sicurezza durante la navigazione su Internet), ho fatto in modo che dnsmasq girasse le query DNSSEC ai forwarder (demandando loro il ruolo di validator).

La direttiva che mi ha consentito di fare ciò è la seguente:

proxy-dnssec

Il fatto che il nameserver primario di Google (8.8.8.8) sia il primo della lista dei forwarder non è certamente un caso. Infatti, esso garantisce dei tempi di risposta più brevi rispetto a quelli di OpenDNS, oltre ad essere anche DNSSEC compliant (cosa che OpenDNS non è).

In definitiva, la configurazione di dnsmasq (in base alle mie esigenze) si è rivelata essere la seguente:

no-dhcp-interface=eth1

dhcp-range=eth1,192.168.0.100,192.168.0.199,8h

interface=eth0
except-interface=eth1
listen-address=192.168.0.2

expand-hosts

domain=soho.loc

resolv-file=/etc/resolv.dnsmasq
strict-order

log-queries
log-facility=/var/log/dnsmasq/query.log

proxy-dnssec

Dopo aver effettuato un controllo sintattico della suddetta configurazione mediante il comando:

root@ubuntubox:~# dnsmasq --test

ed aver riavviato il demone:

root@ubuntubox:~# service dnsmasq restart

sono passato ai test funzionali mediante dig. Per prima cosa ho effettuato una query di tipo A per il record proxy, utilizzando dapprima il solo hostname:

root@fw-scar:~# dig @localhost proxy

; <<>> DiG 9.8.1-P1 <<>> @localhost proxy
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3216
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;proxy.                         IN      A

;; ANSWER SECTION:
proxy.                  0       IN      A       192.168.0.2

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:50:11 2016
;; MSG SIZE  rcvd: 39

e successivamente l’intero FQDN:

 root@fw-scar:~# dig @localhost proxy.soho.loc

; <<>> DiG 9.8.1-P1 <<>> @localhost proxy.soho.loc
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30251
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;proxy.soho.loc.                        IN      A

;; ANSWER SECTION:
proxy.soho.loc.         0       IN      A       192.168.0.2

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:52:15 2016
;; MSG SIZE  rcvd: 48

Successivamente mi sono concentrato sui tempi di risposta per i domini pubblici (da parte dei forwarder), ottenendo i seguenti tempi pre-cashing:

root@fw-scar:~# dig @localhost repubblica.it | grep "Query time"
;; Query time: 50 msec

e post caching:

root@fw-scar:~# dig @localhost repubblica.it | grep "Query time"
;; Query time: 0 msec

Infine, ho testato la risoluzione dei record DNSSEC, utilizzando il comando:

root@fw-scar:~# dig @localhost pir.org +dnssec +multi

; <<>> DiG 9.8.1-P1 <<>> @localhost pir.org +dnssec +multi
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35285
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;pir.org.               IN A

;; ANSWER SECTION:
pir.org.                299 IN A 97.107.141.235
pir.org.                299 IN RRSIG A 5 2 300 20160602204000 (
                                20160519204000 58424 pir.org.
                                cJwr7HlIMA+DyQ8vqqmkNtHRAqsGVdKWTQkJeP/a5698
                                UTyK/cF08uYhH8xMk9I0RMWqtkJDM8od8hWmYUZgidzi
                                7Fh26m1FQYGAcN/PMw2/6wEnNh4ErWZtXe2fXRAS8btx
                                I+nyRPOCoAHR3CjC0cjKqtniUoWHt5x/51iEBw4= )

;; Query time: 86 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:57:36 2016
;; MSG SIZE  rcvd: 219

ricevendo come risposta sia il record A che il relativo RRSIG.

Alla fine della fiera ho messo in piedi un server DNS/DHCP funzionante e funzionale.

Alla prossima.