<- SL: Proxy - Indice Generale - Copertina - AGORA': Intro ->

Sistemi Liberi


Linux: Un router per condividere l'accesso a Internet

di Giuseppe Lucente


L'articolo...

In questo articolo vedremo come sia possibile configurare una macchina che presenta Hardware datato affinché funga da Router e quindi consenta di condividere l'accesso in Internet su una rete composta da più Client; tutto questo a conferma del fatto che le potenzialità dei sistemi GNU/Linux spaziano davvero in tantissimi campi.



Indice


Introduzione: Linux molto più di un Router!

Che il nostro caro ed amato pinguino fosse particolarmente adatto per funzionare come Server lo si sapeva già! In particolar modo con il fiorire di nuove tipologie di reti e connessioni ad alta velocità, il concetto di LAN (Local Area Network) si sta diffondendo sempre di più non solo nell'ambito di attività produttive ma anche in ambienti prettamente casalinghi... eccolo, ancora una volta il nostro fedele amico Tux sempre al passo con i tempi ci viene incontro rendendoci la vita più funzionale.

Questo breve ma spero essenziale HOW-TO spiega come configurare un sistema basso costo, altamente scalabile, basato su linux, per condividere l'accesso ad Internet su una rete costituita da più client.
Soffermiamoci un attimo su quest'ultimo punto prima di introdurre l'articolo vero e proprio cercando di capire fino in fondo quali possano essere i vantaggi e/o svantaggi che ne possiamo trarre:

Vantaggi:

Sistema a basso costo:
Visto il lavoro che deve svolgere è facilmente intuibile che non abbiamo bisogno di una supermacchina, paradossalmente può andar benissimo anche il vecchio 486 abbandonato nel dimenticatoio :)
Aggiungerei inoltre il notevole vantaggio dal punto di vista economico (il portafoglio ringrazia) non dovendo attrezzare ogni singolo client di un modem dedicato per l'accesso in rete o non dovendo acquistare svariate licenze per l'uso di un'apparecchiatura apposita.
Elevata Scalabilità:
Si può facilmente pianificare un upgrade del Server qualora le prestazioni non fossero più adeguate o in previsione di un allargamento della rete. Molto probabilmente la mera sostituzione del processore può bastare per riottenere un sistema perfettamente funzionante.
Centralizzazione e controllo rete:
Anche se questo discorso non rientra nell'argomento merita quantomeno di esser menzionato: centralizzare tutti gli accessi magari adottando sistemi quali Proxy Server o altre tipologie di Firewall presenta numerosi vantaggi, si possono ottenere soluzioni molto flessibili e allo stesso tempo professionali; ne risulta un maggiore controllo della rete, e la possibilità di lavorare in un ambiente sicuro.

Svantaggi:

Per quanto riguarda questi ultimi credo che ci sia poco da dire se non che bisogna attrezzarsi di una ulteriore macchina e che la stessa deve comunque essere sempre accessa per garantire in qualsiasi momento la navigazione in rete.



Tipologia di configurazione: DHCP o MANUALE?

Dopo questa introduzione è arrivata l'ora di metterci al lavoro!
La prima cosa da fare è decidere per quale tipo di configurazione optare; per quanto riguarda questo discorso la scelta verrà dettata da chiare preferenze personali, in ogni caso chiariamo rapidamente le due tipologie. DHCP non è altro che un Server in ascolto sul sistema che riserva un certo range di indirizzi liberi da distribuire ai client man mano che essi ne fanno richiesta. La configurazione Manuale è invece un po' più lunga e complessa rispetto alla precedente soprattutto nel caso di reti molto grandi, in quanto ci obbliga a configurare tutti i client singolarmente.
Tuttavia per questo articolo scegliamo la configurazione Manuale, tanto per rendere più chiari alcuni concetti di rete e per essere consapevoli fino in fondo di ciò che stiamo facendo!
Per chi fosse interessato anche a DHCP può comunque leggere " DHCP mini-HOWTO " disponibile sul sito del Pluto - www.pluto.linux.it
A questo punto ipotizziamo di avere una rete composta da tre PC, 2 client e un gateway (il nostro linux-router). Inoltre consideriamo che quest'ultimo abbia già un accesso alla rete esterna mediante un modem seriale/USB o ethernet:

Con uno schema chiaro e definito in mano abbiamo tutto quello che ci occorre ....

IP Address & hostname...

Il primo passo da fare sarà quello di assegnare ad ogni host un indirizzo univoco (IP Address) che lo contraddistingue all'interno della rete. Ci viene in aiuto l'utilità "ifconfig" che permette di attivare e configurare qualsiasi interfaccia presente sul sistema.
Viste le dimensioni contenute della rete optiamo per l'assegnazione di tre indirizzi di "Classe C":

ifconfig eth0 192.168.1.1 up netmask 255.255.255.0  -------> sul Gateway
ifconfig eth0 192.168.1.2 up netmask 255.255.255.0  -------> sul Client A
ifconfig eth0 192.168.1.3 up netmask 255.255.255.0  -------> sul Client B

Rapidamente la sintassi di questo comando: con l'attributo " UP " abbiamo detto a ifconfig di attivare l'interfaccia "eth0" assegnandole come indirizzo IP "192.168.1.xxx"
Nota di Percorso: l'attributo Netmask si può anche omettere in quanto il sistema riconosce il tipo di classe IP assegnata e la imposta automaticamente.

Se abbiamo fatto tutto in maniera corretta le nostre schede di rete dovrebbero essere pronte a rispondere ad una nostra eventuale richiesta. Possiamo provare un semplice ping o meglio ancora chiedere nuovamente aiuto a ifconfig affinché ci metta a disposizione un'istantanea di tutte le interfaccie di rete presenti sul sistema:

[xxxx:]ifconfig
eth0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 b)  TX bytes:240 (240.0 b)
          Interrupt:11 Base address:0x6000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1076 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1076 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:107856 (105.3 Kb)  TX bytes:107856 (105.3 Kb)

Dal risultato ottenuto emerge chiaramente che la scheda di rete è stata configurata correttamente, il flag "inet addr" ci conferma che l'indirizzo da noi scelto è impostato(l'interfaccia di loopback per il momento non ci interessa).
Nota di percorso: l'output di ifconfig è meravigliosamente dettagliato, oltre ai vari indirizzi di rete rilascia numerose informazioni quali pacchetti ricevuti, inviati e scartati (vedi le voci in azzurro), insomma l'asso nella manica ideale quando si hanno problemi di rete..... Tenetelo bene a mente! Comunque per evitare spiacevoli sorprese consiglio di provare il comando sopra descritto su tutti gli Host.

Manca ancora qualcosa: assegnare ai vari host un nome oltre che un indirizzo IP; più correttamente "hostname".
Questo passo è a mio avviso fondamentale in quanto permette di creare una linea di separazione fra i client più decisa ed evita inutili confusioni!

Detto fatto .... la sintassi del comando è piuttosto semplice da ricordare:

hostname [name]

        Quindi procediamo concretamente inserendo i vari nomi:

hostname server -----> sul Gateway
hostname pippo  -----> sul client A
hostname pluto  -----> sul client B

Anche in questo caso come ulteriore conferma possiamo controllare che il sistema ci fornisca il nome da noi impostato. Digitiamo solamente il comando " hostname " e diamo INVIO:

[xxxx:]hostname
pippo

ATTENZIONE: la procedura qui sopra riportata ha validità generale, cioè la si può applicare tranquillamente a tutte le distro in circolazione. Nella realta dei fatti la cosa non è sempre del tutto vera, ad esempio in sistemi RedHat un comando "hostname" imposta il nome corretto ma solo per la sessione attuale. Al successivo riavvio il comando dovrà essere rilanciato oppure bisognerà ricorrere a procedure che fissano in maniera definitiva questo parametro. Consiglio quindi di chiarire immediatamente quale sia la procedura migliore in base alla distribuzione usata.

/etc/hosts : risoluzione dei nomi!

Bene! è giunta l'ora di fondere tutto il lavoro fin qui fatto: uniamo assieme gli Indirizzi Ip e gli hostname in un unico file ( /etc/hosts ) permettendo così al sistema di effettuare localmente la risoluzione dei nomi.
In sostanza dobbiamo rendere consapevole il sistema che all'indirizzo 192.168.1.xxx equivale la macchina di nome [pippo/pluto/server].

Spostiamoci quindi nella directory "/etc" e modifichiamo con il nostro editor preferito il sopraindicato file specificando i vari host con la sintassi [IPADRESS] [HOSTNAME].
Per chiarire le idee riassumiamo il dafarsi nella tabella sottostante:

[xxxx]cd /etc
[xxxx]vi /etc/hosts
127.0.0.1		localhost localhost.localdomain
192.168.1.1		server                                  # la procedura va svolta su tutti gli host
192.168.1.2		pippo
192.168.1.3             pluto

Salviamo e usciamo!

Bene, con la procedura appena vista abbiamo messo appunto la risoluzione locale, ma ciò non è sufficiente! E' nostro compito assicurarci anche della risoluzione dei nomi in Internet, impostando all'interno del file /etc/resolv.conf di tutte le macchine l'indirizzo Ip di uno o più domain name server (DNS), dati generalmente forniti dal provider.
Anche questa operazione, come la precedente, si dimostra alquanto facile da portare a termine, basterà un semplice

[xxxx] echo nameserver ip_dns_provider >> /etc/resolv.conf

oppure per chi preferisse è possibile editare direttamente il resolv.conf e aggiungere gli indirizzi seguento la sintassi vista sopra ... a voi la scelta!

Modifica della tabella di routing

A questo punto siamo pronti per completare la configurazione della rete. L'ultima cosa che ci rimane da fare prima di introdurre l'ultima parte dell'articolo è modificare la tabella di Routing che si occupa di instradare i pacchetti all'interno della rete; in pratica, dobbiamo dire ai vari host da dove passare per raggiungere i computer che non appartengono alla stessa sottorete. Vista la complessità dell'argomento e il fatto che rientra limitatamente nel nostro caso non ci addentriamo nel discorso che meriterebbe sicuramente un articolo a sé stante. Ci limitiamo solamente a spiegare i passi fondamentali per permetterci di proseguire in questa lunga avventura. Chiunque fosse interessato ad approfondire l'argomento può trovare svariata documentazione in rete.
Anche in questo caso il nostro caro Pinguino ci fornisce tutti gli strumenti necessari per il lavoro... in particolar modo "route" è l'utilità che utilizzeremo per modificare la "routing table", quindi non perdiamo altro tempo, apriamo un terminale e digitiamo:

[xxxx]route add -net 192.168.1.0 netmask 255.255.255.0 eth0      # la procedura va svolta su tutti gli host

Vediamo di chiarire le idee spiegando in pratica cosa abbiamo fatto!
Abbiamo attivato l'instradamento dei pacchetti appartenenti alla rete 192.168.1.0 attraverso l'interfaccia eth0. Detto così sembra non dica assolutamente niente.
In parole più semplici tutto il traffico generato dalla rete 192.168.1.0 (che comprende quindi le macchine server, pippo, pluto) deve passare per l'interfaccia eth0!

A questo punto la tabella di routing è stata modificata. Tuttavia dobbiamo metterci mano ancora un'ultima volta per effettuare l'operazione cuore di tutto l'argomento, cioè configurare pippo e pluto affinché considerino l'host "server" come il "DEFAULT GATEWAY" della rete. In sostanza si tratta di una sorta di riorganizzazione gerarchica. Vediamo concretamente come fare:

[xxxx]route add default gw 192.168.1.1                             # solo sugli host 'pippo' e 'pluto'!

Direi di spendere due parole per riassumere ed eventualmente chiarire che cosa abbiamo fatto. Lanciamo dal nostro fidato terminale (non dal server) il comando "route" seguito dal flag "-n". L'output mostrato dovrebbe apparire simile a quello riportato qui sotto:

[xxxx]:route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 ppp0

In prima riga appare l'instradamento di tutta la nostra rete attraverso l'interfaccia eth0.
Analogo il discorso per la seconda riga: tutto il traffico della rete 127.0.0.0 passerà per l'interfaccia di loopback.
La terza riga, la più interessante è il frutto dell'ultima operazione fatta! Essa definisce infatti l'instradamento del client in questione verso il Gateway. Si nota infatti che l'indirizzo Ip di quest'ultimo appare sotto la colonna "GATEWAY".

Bene, abbiamo concluso la configurazione della rete, è giunta l'ora di provare se effettivamente le macchine riescono a comunicare tra di loro; proviamo con l'utilità ping:

[xxxx]:ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) from 192.168.1.1 : 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=0 ttl=255 time=544 usec
64 bytes from 192.168.1.2: icmp_seq=1 ttl=255 time=471 usec
64 bytes from 192.168.1.2: icmp_seq=2 ttl=255 time=520 usec
64 bytes from 192.168.1.2: icmp_seq=3 ttl=255 time=449 usec
64 bytes from 192.168.1.2: icmp_seq=4 ttl=255 time=487 usec

--- 192.168.10.2 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/mdev = 0.449/0.494/0.544/0.036 ms

Perfetto, tutti gli sforzi compiuti sono stati premiati, la nostra rete è finalmente configurata. Ribadisco comunque il concetto di prima: al fine di evitare spiacevoli sorprese non accontetatevi solamente di un risultato se pur positivo, effettuate controlli in maniera incrociata su tutte le macchine.

NAT: ...mascheriamo la nostra Rete!

Con quest'ultima parte di articolo vediamo di introdurre brevemente il discorso del NAT ( Network Address Translation ) cercando di capire in che modo esso possa tornarci utile per terminare il nostro lavoro.
Il Nat è una forma molto particolare di modifica dei pacchetti. In generale senza addentraci troppo nel discorso ci consente di modificare i pacchetti prima che siano trasmetti in rete (SourceNAT / SNAT) o di modificarne la loro destinazione (DestinationNAT / DNAT). Facciamo dunque un passo indietro: durante il processo di configurazione della rete (ved. capitolo precedente) una delle prime operazioni eseguite era stata configurare le interfaccie di rete "eth0" assegnando loro un indirizzo IP, valido però solamente all'interno della nostra rete. Il problema nasce qualora tentiamo un collegamento all'esterno utilizzando un indirizzo IP di questo tipo: di fatto non avrebbe nessun successo. Ecco a questo punto chiarito il motivo di tutto il discorso: dobbiamo mascherare i nostri client 'pippo' e 'pluto' dietro ad un indirizzo IP valido, che risulta essere quello assegnato dal provider al nostro gateway durante la connessione in Internet. Per rendere questa procedura possibile utilizzeremo una forma particolare di SNAT chiamata "MASQUERADE" che viene appunto utilizzata solamente nel caso di connessioni dial-up. Aggiungerei inoltre che l'intero processo di mascheramento della rete verrà affidato all'impeccabile Netfilter, un efficace sistema di filtraggio dei pacchetti integrato nel kernel, sfruttando iptables, tool user-level per la modifica delle catene di filtraggio; tutto questo ci consentirà di mettere in tutta sicurezza la nostra rete.
Riguardo a Netfilter, chiunque fosse interessato ad approfondire le problematiche di sicurezza rete può approfondire il discorso "firewall" leggendo l'articolo Teoria del Firewall pubblicato nella scorsa edizione del PJ che introduce le diverse tipologie di firewall annunciando così una lunga serie di articoli dedicati alla sicurezza.

Dopo questo rapido tour vediamo di mettere in pratica tutto. Apriamo il nostro editor preferito e prepariamo il nostro script di configurazione; le righe contenenti il cancelletto le utilizzeremo per commentare ciò che stiamo facendo:
N.B: per non dilungarci troppo vedremo solamente le righe necessarie al nostro scopo!

#!/bin/sh

iptables="/sbin/iptables"
# poco importante: indica solamente il percorso dell'eseguibile!

echo '0' > /proc/sys/net/ipv4/ip_forward
# Finché tutto non è in ordine, niente forwarding

modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp ip_nat_ftp
modprobe iptable_nat
modprobe ipt_MASQUERADE
# Carichiamo i moduli più importanti! (attenzione NAT e MASQUERADE sono essenziali x il nostro scopo)
.....
.....

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# Aggiungiamo una regola alla catena di postrouting:
# tutti i pacchetti in uscita attraverso l'interfaccia "ppp0"
# dovranno essere mascherati

iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# accettiamo tutti i pacchetti appartenenti a connessioni già iniziate o cmq correlati ad esse

iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
# accettiamo il traffico generato dalla rete interna

iptables -A FORWARD -j DROP
# tutto il resto è scartato

echo '1' > /proc/sys/net/ipv4/ip_forward
# Adesso che siamo in sicurezza, abilitiamo il passaggio dei pacchetti (forwarding)


Nota: Anche se potrebbe sembrare ovvio è meglio specificare; sia 'iptables' sia 'lo script' devono risiedere sul gateway!
Salviamo il lavoro e rendiamolo eseguibile ....:

chown root.root /sbin/personal_script
chmod 755 /sbin/personal_script

.... Potete anche aggiungerlo in /etc/rc.d/rc.local in modo che lo script venga avviato automaticamente ad ogni boot del sistema.

A questo punto il nostro lavoro è definitivamente concluso. Non dobbiamo fare altro che collegarci mediante un client ad Internet e provare le capacità del nostro nuovo fiammante serverino!

Conclusioni...

Con quest'ultima parte dedicata al NAT si conclude ahimè anche il nostro articolo.
Abbiamo visto che configurare un server Linux per fargli svolgere operazioni delicate come il mascheramento dei client e l'inoltro dei pacchetti risulta essere una operazione tutto sommato semplice; fortunatamente tutti gli strumenti a nostra disposizione, benché semplici nel loro utilizzo, sono estremamente potenti. Sono altresì consapevole di non essere stato completamente esauriente, non sarebbe stato possibile trattare in maniera completa l'argomentazione vista la moltitudine di sfaccettature che presenta, l'unico auspicio che rimane è quello di aver contribuito ad avvicinare ulteriormente tutti coloro che nutrono ancora titubanze verso questo straordinario sistema. Non mi rimane che augurare ... BUONA NAVIGATA A TUTTI!



L'autore
Giuseppe Lucente alias Beppe è un utente casalingo con tanta passione per tutto quello che ruota attorno al mondo dell'informatica.
È fuggito appena in tempo nel 1999 da un regime dittatoriale governato da sistemi CloseSource per (e)migrare verso un regime più democratico: Linux, che gli ha concesso di ampliare le proprie capacità.
Amante degli animali, ha deciso di intraprendere una dura lotta per la salvaguardia dei pinguini :)


<- SL: Proxy - Indice Generale - Copertina - AGORA': Intro ->