%%
%% Dispense Amministrazione di rete
%% Sezione intermedia, i servizi principali
%%
%% Copyright (C) 2003-2018 Simone Piccardi and Truelite Srl. 
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%%
%% S. Piccardi Feb. 2003
%%
%% netinter.tex: 
%%
\chapter{La gestione dei servizi di base}
\label{cha:networks_base_services}


\section{I programmi di ausilio alla gestione dei servizi di base}
\label{sec:net_servizi}

Tratteremo in questa sezione alcuni programmi di ausilio per la gestione dei
servizi di rete più semplici, ed in particolare l'uso di un cosiddetto
``\textsl{super-demone}'' per gestire servizi usati occasionalmente, e l'uso
dei \textit{TCP wrappers} per fornire un meccanismo elementare di controllo
degli accessi anche a quei programmi che non ne hanno uno al loro interno.



\subsection{I servizi elementari e i super-demoni}
\label{sec:net_superdaemons}

Fino a qualche tempo fa nell'installazione di un sistema di tipo Unix venivano
di norma attivati una serie di servizi di rete elementari, usabili a scopo di
test, come \texttt{echo} o \texttt{discard}, a cui si potevano aggiungere
altri servizi minori, mantenuti attivi in previsione di un possibile futuro
utilizzo. Ma mantenere perennemente in esecuzione dei demoni per fornire dei
servizi usati solo in maniera occasionale (come potevano essere
\texttt{telnet} o \texttt{ftp}), veniva a costituire, specie nelle prime
versioni di Unix, uno spreco di risorse non accettabile.

Per questo motivo venne introdotto il concetto di \textsl{super-demone}, un
demone speciale che facesse da intermediario mettendosi in ascolto sulle varie
porte interessate, per poi smistare le richieste ai programmi che implementano
il servizio richiesto.  Oggi le esigenze di prestazioni non sussistono più, ed
inoltre una buona norma di sicurezza prevede di non lasciare servizi attivi se
questi non sono in uso, ma per fornire servizi minori l'uso di un
\textsl{super-demone} resta l'opzione più utilizzata.

In sostanza un \textsl{super-demone} svolge quello che è il lavoro di un
centralinista, che riceve le telefonate sul centralino e poi passa ciascuna di
esse all'ufficio competente. Nel caso specifico il programma riceve le
connessioni su una certa porta e poi lancia automaticamente il relativo
programma di risposta. In questo modo non c'è bisogno di mantenere sempre in
esecuzione tanti programmi diversi, ma li si possono lanciare solo quando
servono.

Inoltre, come avviene per il centralinista che ti può dire direttamente
l'orario degli uffici, un \textsl{super-demone} è in genere in grado di
rispondere direttamente per alcuni servizi elementari (come \texttt{echo} o
\texttt{discard}), per i quali non necessita di invocare nessun programma
esterno.

Infine una caratteristica comune dei \textsl{super-demoni} è che sono in grado
di associare alla connessione ad una porta l'esecuzione di un programma
qualunque. È possibile cioè, in occasione di una connessione ad una porta,
lanciare un programma collegando il socket della connessione allo
\textit{standard input} e allo \textit{standard output} del programma stesso.
Così ad esempio si potrà attivare il servizio di rete \texttt{netstat} sulla
porta 15, usando l'omonimo programma visto in sez.~\ref{sec:net_netstat}.

Di norma i servizi più importanti, come il web, la posta, il DNS, o SSH non
vengono utilizzati in questo modo, perché questa interposizione di un altro
programma avrebbe effetti negativi sulle prestazioni, anche se in molti casi
l'importanza del servizio (ad esempio quella di un server web o di posta
elettronica) va commisurata con l'uso che se ne fa: per una macchina client
tenere sempre attivo Apache per fornire delle pagine locali consultate ogni
tanto può effettivamente essere eccessivo.

Tradizionalmente il programma utilizzato per svolgere questo compito è
\texttt{inetd}, che fino a qualche anno fa veniva installato di default da
tutte le distribuzioni; \texttt{inetd} però presenta numerosi limiti, ed oggi
tende ad essere sostituito con il più recente \texttt{xinetd}, se non ad
essere eliminato del tutto. In generale infatti l'utilità di un
\textsl{super-demone} sta venendo meno, considerato che il costo sempre minore
delle risorse ne rende meno vantaggioso l'utilizzo.


\subsection{Il super-demone \texttt{inetd}}
\label{sec:net_inetd}

Come appena accennato la gestione dei servizi di base a lungo è stata
effettuata tramite il programma \index{demone!\texttt{inetd}} \texttt{inetd},
che ancor oggi viene usato da alcune distribuzioni.  Il programma viene
lanciato dagli script di avvio, ma al solito si può avviare e fermare il
demone manualmente con il relativo script, che di norma è
\texttt{/etc/init.d/inetd}.

In caso di necessità si può eseguire \texttt{inetd} anche direttamente a riga
di comando, nel qual caso si può usare l'opzione \texttt{-d} per farlo partire
in modalità di debug, in cui non si distacca dal terminale. Il comando prende
come argomento un file di configurazione alternativo, altrimenti utilizza il
default. Per le altre opzioni ed i dettagli del funzionamento si faccia
riferimento come al solito alla pagina di manuale.

Il file di configurazione di default di \texttt{inetd} è
\index{configurazione!\texttt{/etc/inetd.conf}} \texttt{/etc/inetd.conf}, ed è
qui che si specifica su quali porte il demone deve porsi in attesa e quali
programmi lanciare. Un esempio di questo file è il seguente:
\begin{FileExample}[label=/etc/inetd.conf]
# /etc/inetd.conf:  see inetd(8) for further informations.
#
# Internet server configuration database
#
# <service_name> <sock_type> <proto> <flags> <user> <server_path> <args>
#
#:INTERNAL: Internal services
#echo           stream  tcp     nowait  root    internal
#echo           dgram   udp     wait    root    internal
#chargen        stream  tcp     nowait  root    internal
#chargen        dgram   udp     wait    root    internal
#discard        stream  tcp     nowait  root    internal
#discard        dgram   udp     wait    root    internal
#daytime        stream  tcp     nowait  root    internal
#daytime        dgram   udp     wait    root    internal
#time           stream  tcp     nowait  root    internal
#time           dgram   udp     wait    root    internal
#:MAIL: Mail, news and uucp services.
nntp            stream  tcp     nowait  news    /usr/sbin/tcpd  /usr/sbin/leafnode
#:INFO: Info services
ident           stream  tcp     wait    identd  /usr/sbin/identd        identd
\end{FileExample}
come si vede il formato è relativamente semplice: una tabella in cui ogni riga
è relativa ad un servizio da lanciare, ed i cui campi sono separati da spazi o
tabulatori. Al solito righe vuote e inizianti con ``\texttt{\#}'' sono
ignorate.

Il servizio da fornire, o meglio la porta su cui porsi in ascolto, è
identificato dal primo campo tramite il nome simbolico di
\texttt{/etc/services}. Il successivo campo indica il tipo di socket: i due
tipi più comuni sono \texttt{stream} o \texttt{dgram}, ma si possono usare
tutti i tipi di socket supportati con Linux, (come \texttt{raw}, \texttt{rdm},
o \texttt{seqpacket}). Il terzo campo indica il protocollo usato: di norma si
tratta di \texttt{tcp} o \texttt{udp},\footnote{in realtà si può specificare
  un qualunque altro protocollo col nome riportato in \texttt{/etc/protocols},
  ma benché sia possibile usare il demone con qualunque tipo di socket e
  protocollo di rete, in pratica sono questi due gli unici che vengono
  utilizzati.} che corrispondono rispettivamente ai tipi \texttt{stream} e
\texttt{dgram}.

Il quarto campo indica come \texttt{inetd} deve gestire la porta
nell'esecuzione del programma. I casi sono due, se il server lanciato resta in
esecuzione trattando direttamente eventuali connessioni multiple si deve usare
\texttt{wait}, in tal caso \texttt{inetd} attenderà che il programma termini
prima di rimettersi in ascolto sulla porta. Se invece il programma lanciato
gestisce la singola connessione, è necessario che \texttt{inetd} si rimetta in
ascolto sulla porta e lanci un'altra istanza in caso di nuovo collegamento, in
tal caso occorre usare \texttt{nowait}.

In genere per i socket di tipo \texttt{dgram} si usa \texttt{wait} perché non
esistendo le connessioni i programmi hanno la necessità di trattare tutti i
pacchetti che arrivano sulla stessa porta, e si dovrà aspettare la fine del
processo corrente, che indica la fine del flusso di dati, prima di rilanciare
un'altra istanza.  Se questo non è necessario, come avviene in genere per i
socket di tipo \texttt{stream}, in cui si passa al programma il socket della
connessione su cui esso fornisce una risposta, deve essere usato il valore
\texttt{nowait}. Benché questi siano i casi più comuni, ma non esiste una
regola specifica attinente al protocollo, e tutto dipende dal funzionamento
del programma lanciato.

Il quinto campo indica l'utente per conto del quale viene eseguito il
programma; se si vuole specificare anche un gruppo diverso dal gruppo
principale dell'utente, lo si può fare scrivendo il campo nella forma
\texttt{user.group}.  Il sesto campo deve indicare il pathname completo del
comando che verrà eseguito in caso di connessione, o la parola chiave
\texttt{internal} se quel servizio è fornito direttamente da \texttt{inetd},
come accennato infatti \texttt{inetd} è in grado di fornire direttamente
alcuni servizi elementari come \texttt{echo}, \texttt{discard} o
\texttt{daytime}, per i quali non è necessario lanciare nessun programma a
parte.

Eventuali argomenti dovranno essere specificati di seguito; dato però che
\texttt{inetd} usa direttamente il resto della linea per invocare la funzione
\texttt{exec}, questi non potranno essere specificati normalmente, riprendendo
quanto si scriverebbe sulla shell, ma dovranno essere preceduti dall'argomento
iniziale che indica il nome del programma lanciato. Sulla riga di comando
infatti è la shell che costruisce automaticamente questo argomento usando il
nome del programma invocato, in questo caso deve essere fatto esplicitamente.

Come si può notare nell'esempio sono abilitati solo due servizi, il primo è un
server news gestito tramite il programma \texttt{leafnode}, il secondo è il
servizio \textit{ident}, definito
dall'\href{http://www.ietf.org/rfc/rfc1413.txt}{RFC~1413}, che permette di
identificare l'utente proprietario del processo che ha creato una certa
connessione.  Si noti anche come nel caso di \texttt{leafnode} questo non sia
stato lanciato direttamente ma invocato attraverso \texttt{tcpd}, un utile
programma di sicurezza che permette di controllare gli accessi ai servizi di
rete, come vedremo in sez.~\ref{sec:net_TCP_wrappers}.  

Se si vuole abilitare un nuovo servizio \texttt{netstat}, che fornisca via
rete i dati delle connessioni presenti sulla nostra macchina utilizzando il
programma omonimo trattato in sez.~\ref{sec:net_netstat}, basterà aggiungere
al file una riga del tipo:
\begin{Example}
netstat    stream  tcp   nowait  nobody     /bin/netstat netstat -ant
\end{Example}
e si noti come si sia ripetuto, prima dei parametri \texttt{-ant}, il nome del
programma \texttt{netstat}. Senza questa ripetizione il risultato sarebbe
stato che all'esecuzione di \texttt{/bin/netstat} il nome del processo sarebbe
risultato \texttt{-ant}, mentre le opzioni sarebbero state
perse.\footnote{cosa che si può osservare direttamente eseguendo \texttt{ps},
  posto di essere così veloci e fortunati da riuscire a lanciarlo mentre
  \texttt{netstat} sta ancora girando.}

Fatta l'aggiunta citata, dopo aver riavviato \texttt{inetd} per fargli
prendere le modifiche effettuate alla configurazione, si potrà verificare il
funzionamento del nuovo servizio usando \texttt{telnet} per collegarsi verso
di esso, con qualcosa come:
\begin{Console}
piccardi@gont~:$ \textbf{telnet localhost netstat}
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:15              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.1:53          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:631             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.1:32777       195.110.124.18:993      ESTABLISHED
tcp        0      0 127.0.0.1:32944         127.0.0.1:15            ESTABLISHED
tcp        0      0 192.168.1.1:32778       62.177.1.107:5223       ESTABLISHED
tcp        0      0 192.168.1.1:32772       192.168.1.168:5901      ESTABLISHED
tcp        0      0 127.0.0.1:15            127.0.0.1:32944         ESTABLISHED
Connection closed by foreign host.
\end{Console}
%$
\noindent ottenendo il risultato del comando \texttt{netstat} eseguito sulla
macchina remota in cui compare, nell'ultima riga, anche la connessione su cui
lo stiamo leggendo.

Il precedente esempio funziona perché quando lancia un programma,
\texttt{inetd} fa sì che \textit{standard input}, \textit{standard output} e
\textit{standard error} siano associati al socket su cui è stata aperta la
connessione. Si può così eseguire un programma qualsiasi, e questo accetterà i
dati in ingresso dal socket e su di esso scriverà le sue risposte; in generale
è sempre compito del programma messo in esecuzione gestire opportunamente la
connessione di rete, fornendo il servizio richiesto.

Nell'esempio appena mostrato quello che è successo è che il programma
\texttt{netstat} è stato eseguito sul server remoto (il fatto che si sia usato
\texttt{localhost} è stato solo per comodità) e ha prodotto la lista dei
socket attivi scrivendola sullo \textit{standard output}, per poi terminare.
Questo ha fatto sì che noi la ricevessimo all'altro capo del socket creato
dalla connessione effettuata con \texttt{telnet}, che è stato automaticamente
chiuso alla terminazione del processo. La stessa procedura è applicabile in
generale a qualunque comando di shell, per cui potremmo definire un servizio
di rete \texttt{ps} (assegnandogli una porta in \texttt{/etc/services}) che ci
fornisca l'elenco dei processi, ed in generale potremmo anche crearci un
servizio ad hoc usando degli script.


\subsection{Il super-demone \texttt{xinetd}}
\label{sec:net_xinetd}

Il programma \index{demone!\texttt{xinetd}} \texttt{xinetd} nasce come
riscrittura di \texttt{inetd} per eseguire lo stesso compito: far partire i
server appropriati in caso di connessione al relativo servizio, evitando di
lanciare e tenere in memoria dei programmi che resterebbero dormienti per la
gran parte del tempo.

Rispetto ad \texttt{inetd} esso supporta nativamente il controllo di accesso
con i \textit{TCP wrappers} (vedi sez.~\ref{sec:net_TCP_wrappers}), ma oltre a
questo ha una serie di funzionalità ulteriori come la possibilità di mettere a
disposizione i servizi in orari determinati, dei meccanismi di redirezione
delle connessioni, delle capacità di registrazione degli eventi più estese,
dei meccanismi di protezione nei confronti delle scansioni delle porte, e la
capacità di limitare il numero di istanze del server lanciate per resistere ad
attacchi di \textit{denial of service}.

Le maggiori funzionalità comportano ovviamente il prezzo di una maggiore
complessità di configurazione, comunque il comando supporta una opzione,
\texttt{-inetd\_compat}, che gli permette di operare in modalità di
compatibilità con \texttt{inetd}. In tal caso infatti il programma prima legge
i suoi file di configurazione, e poi \texttt{/etc/inetd.conf} facendo partire
i servizi definiti in quest'ultimo.

Il file principale di configurazione di \texttt{xinetd} è
\index{configurazione!\texttt{/etc/xinetd.conf}} \texttt{/etc/xinetd.conf}, un
esempio del suo contenuto che illustra le principali direttive generiche, è il
seguente (preso dal default installato su una Debian Wheezy senza le righe di
commento):
\begin{FileExample}[label=/etc/xinetd.conf]
# Simple configuration file for xinetd
defaults
{
        instances   = 25
        log_type    =  SYSLOG auth 
        log_on_success = HOST PID
        log_on_failure = HOST RECORD
        per_source  = 5
}
includedir /etc/xinetd.d
\end{FileExample}
\noindent in questo caso nel file è presente soltanto la sezione speciale
\texttt{defaults} che contiene i valori di default delle opzioni, da applicare
per tutti i servizi per i quali essi non sono stati esplicitamente
specificati.

La riga finale con la direttiva \texttt{includedir} richiede poi di includere
automaticamente nella configurazione il contenuto di tutti i file contenuti
nella directory specificata (di norma, come nel caso, si usa
\texttt{/etc/xinetd.d}), cosa che permette di attivare in maniera indipendente
un servizio, con la semplice installazione di un file in tale directory.

Al solito le righe vuote e il cui primo carattere è ``\texttt{\#}'' vengono
ignorate; per il resto per ciascun servizio che si vuole attivare è necessario
specificare una voce (nel caso basterà scrivere un file che la contenga in
\texttt{/etc/xinetd.d}) che inizia con la direttiva \texttt{service}; la
sintassi generica di tale voce è del tipo:
\begin{Example}
service <nome_servizio>
{
      <attributo> <operatore> <valore> <valore> ...
      ...
}
\end{Example}
\noindent dove \texttt{<nome\_servizio>} indica il servizio che si vuole
fornire, mentre gli attributi permettono di specificarne le caratteristiche,
con un operatore di assegnazione che nella gran parte dei casi è
``\texttt{=}'', con significato ovvio. L'operatore però può essere anche
``\texttt{+=}'' o ``\texttt{-=}'', rispettivamente per aggiungere o togliere
valori, anche se solo alcuni attributi supportano questa sintassi.

Come mostrato nell'esempio precedente, anche la direttiva \texttt{defaults}
prende degli attributi; in genere questi sono attributi generali che possono a
loro volta essere rispecificati in maniera diversa per i singoli
servizi. Nell'esempio il primo attributo è \texttt{instances} che permette di
porre un limite massimo al numero di istanze dello stesso programma server che
il programma può lanciare, mentre il secondo attributo è \texttt{log\_type},
che permette di specificare le modalità con cui viene effettuata la
registrazione dei dati delle connessioni.  Queste possono essere \texttt{FILE}
per specificare a seguire un file su cui salvare direttamente i dati, o
\texttt{SYSLOG} per specificare l'uso del \textit{syslog} (vedi
sez.~\ref{sec:syslog.conf}), indicando poi con l'ulteriore parametro (nel caso
\texttt{auth}) quale \textit{facility} utilizzare; è possibile anche
specificare di seguito una \textit{priority}, se diversa dal default che è
\texttt{info}.

I due attributi successivi, \texttt{log\_on\_success} e
\texttt{log\_on\_failure}, permettono di specificare cosa scrivere nei log in
caso rispettivamente di successo e fallimento di una connessione. Le
indicazioni \texttt{HOST} e \texttt{USERID} sono comuni ad entrambi e
permettono di registrare rispettivamente l'IP e l'utente (se è disponibile il
servizio \texttt{identd} secondo l'\href{http://www.ietf.org/rfc/}{RFC~1413})
relativi alla connessione da remoto; \texttt{log\_on\_success} permette anche
di registrare lo stato di uscita del server (con \texttt{EXIT}), la durata
della connessione (con \texttt{DURATION}) ed il numero identificativo del
processo (con \texttt{PID}).

Infine l'ultimo attributo, \texttt{per\_source}, permette di stabilire un
numero massimo per le connessioni da un singolo IP, una misura di protezione
per limitare eventuali \textit{denial of service}. Un elenco dei principali
attributi che possono essere specificati nella sezione \texttt{defaults}, con
la relativa descrizione, è riportato in
tab.~\ref{tab:net_xinetd_attribute_default}, l'elenco completo può essere
trovato nelle pagine di manuale, accessibili con \texttt{man xinetd.conf}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Attributo} &\textbf{Descrizione}\\
    \hline
    \hline
     \texttt{instances}       & numero massimo di processi lanciati per ogni
                                servizio; prende un valore intero.\\
     \texttt{log\_type}       & metodologia di registrazione dei log, su file
                                o tramite \textit{syslog}; prende i valori 
                                \texttt{FILE} (seguito dal nome del file su cui
                                vengono aggiunti i messaggi) o \texttt{SYSLOG}
                                seguito dalla \textit{facility} da usare ed
                                opzionalmente dalla priorità.\\
     \texttt{log\_on\_success}& cosa registrare per le connessioni
                                riuscite; prende uno o più fra \texttt{PID},
                                \texttt{HOST}, \texttt{USERID}, \texttt{EXIT},
                                \texttt{DURATION}.\\
     \texttt{log\_on\_failure}& cosa registrare per le connessioni
                                fallite, prende uno o più fra \texttt{HOST},
                                \texttt{USERID}, \texttt{ATTEMPT}. \\
     \texttt{per\_source}     & numero massimo di connessioni per singolo IP 
                                sorgente; prende un valore intero. \\
     \texttt{only\_from}      & lista delle macchine da cui è possibile
                                accedere; prende indirizzi IP in forma dotted
                                decimal, CIDR o nomi a dominio.\\
     \texttt{no\_access}      & lista delle macchine da cui è impossibile 
                                accedere; prende indirizzi IP in forma dotted
                                decimal, CIDR o nomi a dominio.\\
     \texttt{access\_times}   & orario nel quale è possibile
                                accedere ai servizi, prende un intervallo
                                temporale specificato nella forma
                                \texttt{HH:MM-HH:MM}.\\ 
     \texttt{cps}             & rate massimo di accesso; prende un valore
                                decimale per indicare il limite sulle
                                connessioni al secondo, ed un valore intero
                                per specificare il numero di secondi da
                                aspettare prima di accettare nuove connessioni
                                una volta superato il limite.\\
     \texttt{nice}            & valore di \textit{nice} (vedi
                                sez.~\ref{sec:struct_priority}) da applicare
                                ai demoni lanciati; prende un valore intero.\\
     \texttt{max\_load}       & carico massimo oltre il quale la macchina
                                smette di accettare connessioni; prende un
                                valore decimale.\\ 
    \hline    
  \end{tabular}
  \caption{Attributi specificabili in generale per tutti i servizi gestiti
    attraverso il super-demone \texttt{xinetd}.}
  \label{tab:net_xinetd_attribute_default}
\end{table}

Come accennato il programma è in grado sia di implementare direttamente dei
controlli di accesso, che di utilizzare quelli eventualmente specificati
tramite i file di controllo dei \textit{TCP wrappers} (vedi
sez.~\ref{sec:net_TCP_wrappers}). Si tenga presente che l'uso dei \textit{TCP
  wrappers} ha di norma la precedenza sul controllo interno, per cui se si
abilita l'accesso con queste direttive, ma esso è negato dai TCP wrappers,
questi ultimi avranno la meglio. I due attributi \texttt{only\_from} e
\texttt{no\_access} sono in grado di specificare direttamente le stesse
condizioni all'interno del file di configurazione di \texttt{xinetd}. In
questo caso le sintassi supportate sono sia le forme dotted decimal
(interpretando gli zeri finali come indirizzi di rete), che quelle CIDR, sia
quelle espresse con nomi a dominio.

Come già accennato ciascun servizio che si vuol lanciare con \texttt{xinetd}
deve essere specificato con la direttiva \texttt{service} seguita dal nome
dello stesso (che specifica anche la porta che verrà utilizzata, come
risultante in \texttt{/etc/services}) mentre le direttive che vi si applicano
vanno specificate successivamente fra parentesi graffe. Se il nome non è
presente in \texttt{/etc/services} (ad esempio se si usa una porta arbitraria
per un servizio proprio) si deve dichiarare il servizio come \texttt{UNLISTED}
con l'attributo \texttt{type} (e si dovrà definire la porta con l'attributo
\texttt{port}). Un possibile esempio di configurazione è il seguente:
\begin{FileExample}[label=xinetd.conf]
service time
{
        disable = yes
        type            = INTERNAL
        id              = time-stream
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no
}
service time
{
        disable         = yes
        type            = INTERNAL
        id              = time-dgram
        socket_type     = dgram
        protocol        = udp
        user            = root
        wait            = yes
}
service nntp
{
        socket_type = stream
        wait        = no
        user        = news
        server      = /usr/sbin/leafnode
        server_args = -v
        only_from   = 192.168.0.0/24
        access_times = 08:00-17:00
}
\end{FileExample}

In questo caso si sono definiti due servizi gestiti direttamente da
\texttt{xinetd}, e cioè il servizio \textit{time} su TCP e UDP, entrambi sono
disabilitati, avendo \texttt{disable} impostato su \texttt{yes}. Si noti come
siano stati differenziati attraverso la presenza di un argomento \texttt{id}.
Inoltre con \texttt{socket\_type} si è specificato il tipo di socket da usare,
e con \texttt{protocol} il relativo protocollo. Il campo \texttt{type} dice
che il servizio è fornito internamente, mentre \texttt{user} indica che verrà
eseguito per conto dell'utente \textit{root}. Infine il campo \texttt{wait}
indica, con lo stesso significato che ha per \texttt{inetd}, se
\texttt{xinetd} deve attendere la conclusione del programma lanciato,
lasciando gestire a lui ulteriori connessioni, o se deve mantenere il
controllo della porta lanciando altre istanze in caso di nuove connessioni.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Attributo} &\textbf{Descrizione}\\
    \hline
    \hline
     \texttt{socket\_type}& tipo di socket; prende gli stessi valori
                            (\texttt{stream}, \texttt{dgram}, ecc.)
                            dell'analogo parametro in \texttt{inetd.conf}. \\ 
     \texttt{user}        & utente per conto del quale è lanciato il
                            servizio; deve essere presente in
                            \texttt{/etc/passwd}, si può specificare un
                            eventuale gruppo con l'attributo \texttt{group}.\\ 
     \texttt{server}      & pathname del programma server da lanciare; deve essere
                            sempre specificato se il servizio non è gestito 
                            internamente. \\ 
     \texttt{wait}        & indica se si deve attendere o meno la conclusione
                            del server per lanciare un'altra istanza
                            mantenendo o meno il controllo della porta; è 
                            l'analogo dello stesso parametro in
                            \texttt{inetd.conf} e prende i valori \texttt{yes}
                            e \texttt{no}.\\ 
     \texttt{protocol}    & protocollo usato (analogo di \texttt{tcp} ed
                            \texttt{udp} per \texttt{inetd.conf}); deve
                            essere un nome valido in
                            \texttt{/etc/protocols}.\\
     \texttt{port}        & porta su cui ascoltare le connessioni; deve essere
                            specificata se si è specificato un servizio non
                            riportato in \texttt{/etc/services} (nel caso di
                            uso di servizi di tipo \texttt{UNLISTED}).  \\
     \texttt{type}        & tipo di servizio; può assumere i valori 
                            \texttt{INTERNAL} (per servizi gestiti
                            internamente), \texttt{RPC} per indicare che si
                            userà un servizio RPC (vedi
                            sez.~\ref{sec:net_rpc_services}), \texttt{UNLISTED}
                            per servizi non presenti in \texttt{/etc/services}
                            o \texttt{/etc/rpc}.\\
     \texttt{server\_args}& eventuali argomenti da passare al programma server
                            quando viene lanciato; al contrario di 
                            \texttt{inetd} non necessita di specificare
                            il nome del comando come argomento iniziale.\\ 
     \texttt{disable}     & indica se attivare il servizio, il default è
                            disattivo; può assumere i valori \texttt{yes}
                            e \texttt{no}. \\
     \texttt{id}          & identificatore aggiuntivo qualora si tratti di
                            servizi diversi con lo stesso nome. \\
     \texttt{bind}        & consente di specificare l'interfaccia su cui
                            fornire il servizio; prende l'indirizzo IP ad essa
                            associato.\\
     \texttt{redirect}    & consente di redirigere il servizio ad un'altra
                            macchina; prende l'indirizzo IP e la porta verso
                            quale redirigere tutto il traffico separati da uno
                            spazio.\\
     \texttt{umask}       & imposta la \textit{umask} ereditata
                            dal processo mandato in esecuzione.\\
    \hline
  \end{tabular}
  \caption{Attributi specificabili per un servizio gestito attraverso il
     super-demone \texttt{xinetd}.}
  \label{tab:net_xinetd_attribute_service}
\end{table}

Oltre ai due servizi interni si è abilitato anche il servizio di news; in
questo caso restano specificati con lo stesso significato precedente gli
argomenti \texttt{wait}, \texttt{socket\_type} e \texttt{user} (anche se per
quest'ultimo si è usato l'utente \texttt{news}), mentre non esistendo il
servizio \texttt{news} su UDP non è stato necessario impostare
\texttt{protocol}. Si è invece specificato il programma da usare come server
con \texttt{server}, passando i relativi argomenti con \texttt{server\_args}.
Inoltre nel caso si è ristretto l'accesso al servizio alle macchine della
sottorete \texttt{192.168.0.0/24} con \texttt{only\_from} e negli orari di
ufficio usando \texttt{access\_times}.

Oltre a quelli appena illustrati, si sono riportati i principali attributi
utilizzabili in tab.~\ref{tab:net_xinetd_attribute_service}. Si ricordi che
anche i precedenti attributi di tab.~\ref{tab:net_xinetd_attribute_default}
possono essere utilizzati, e saranno applicati solo al servizio in questione.
Al solito nella pagina di manuale di \texttt{xinetd.conf} è riportato un
elenco completo di tutti gli argomenti presenti e la descrizione dettagliata
di ciascuno di essi.

Anche con \texttt{xinetd} è possibile creare un proprio servizio usando i
comandi di shell; ripeteremo allora quanto visto con \texttt{inetd} definendo
un nuovo servizio \texttt{netstat}. Dato che il servizio è previsto in
\texttt{/etc/services} solo per TCP possiamo attivarlo creando in
\texttt{/etc/xinetd.d} un nuovo file con un contenuto del tipo di: 
\begin{FileExample}[label=/etc/xinetd.d/netstat]
service netstat
{
        disable         = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /bin/netstat
        server_args     = -ant
}
\end{FileExample}
e, una volta riavviato \texttt{xinetd}, potremo verificarne come prima il
funzionamento, con un \texttt{telnet} sulla porta 15.

Una delle caratteristiche più utili di \texttt{xinetd} è quella che consente
di utilizzarlo per redirigere le connessioni ad una porta verso un'altra
macchina ed eventualmente un'altra porta. Benché questo sia possibile anche
utilizzando le funzionalità del \textit{netfilter} di Linux con
\texttt{iptables},\footnote{per una trattazione approfondita dello stesso si
  consulti il cap.~2 di \cite{SGL}.} quando la redirezione deve essere fatta
verso un server esterno (il caso più comune è lo spostamento di un servizio
presso un diverso provider) la cosa può risultare abbastanza complessa. 

Si supponga allora che si sia spostato il proprio server di posta presso uno
diverso provider, e sia in corso la propagazione dei DNS (vedi
sez.~\ref{sec:net_DNS_intro}) per il nuovo indirizzo IP, in tal caso chi sta
ancora utilizzando il vecchio indirizzo contatterà la vecchia macchina. Per
garantire una continuità nell'accesso si potranno redirigere tutte le
connessioni da questa al nuovo server con \texttt{xinetd} utilizzando le
funzionalità di redirezione; in questo caso basterà installare una
configurazione del tipo:
\begin{FileExample}[label=/etc/xinetd.d/popredir]
service pop3
{
        disable         = no
        socket_type     = stream
        wait            = no
        user            = root
	redirect	= IP.DEL.NUOVO.SERVER 110
}
\end{FileExample}

Con questa configurazione, una volta riavviato il servizio, le connessioni
al servizio POP3 verranno ricevute da \texttt{xinetd} che le girerà, in
maniera trasparente per l'utente, al nuovo server, reinviando al client le
risposte. Così sarà possibile fornire accesso, usando il nuovo server, anche a
coloro che non hanno ancora ottenuto il nuovo indirizzo. 


\subsection{Il servizio NTP}
\label{sec:net_NTP}

Abbiamo già accennato in sez.~\ref{sec:cmd_time} come sia possibile usare il
comando \texttt{ntpdate} per rimettere l'orologio di una macchina, andando ad
interrogare un server esterno che fornisce il servizio di \textsl{ora esatta}
attraverso il protocollo NTP.\footnote{il \textit{Network Time Protocol} è uno
  dei più complessi disponibili su Internet e consente una sincronizzazione
  dei tempi molto precisa (dell'ordine dei ms in locale e delle decine di ms
  in remoto) nonostante tutte le incertezze che si possono avere nella
  trasmissione dei pacchetti;
  l'\href{http://www.ietf.org/rfc/rfc1305.txt}{RFC~1305} che descrive la
  versione 3 del protocollo supera il centinaio di pagine, la versione
  quattro, che è pienamente supportata da \texttt{ntpd}, è descritta
  dall'\href{http://www.ietf.org/rfc/rfc5905.txt}{RFC~5905} ed è stata
  standardizzata (\href{http://www.ietf.org/rfc/rfc2020.txt}{RFC~2030}) una
  versione semplificata del protocollo, SNTP, utilizzata quando non è
  necessaria la precisione del protocollo completo.} Si può però anche tenere
costantemente aggiornato l'orologio installando direttamente un server NTP.

Il servizio NTP usa la porta 123 UDP, e prevede una organizzazione gerarchica
dei server in \textsl{strati} con precisione decrescente dei tempi. La
gerarchia parte dai dispositivi di strato 0, che sono quelli collegati
direttamente ad una fonte primaria della misura esatta del tempo (e possono
essere orologi atomici, orologi GPS o radio). Ogni volta che un server NTP
viene sincronizzato su un altro server NTP, la convenzione vuole che il suo
numero di strato venga aumentato di 1, per questo lo strato 0 indica la
connessione diretta ad una fonte di tempo.

In genere server pubblici di strato 0 (a meno di non utilizzare un propria
fonte di tempo) non sono disponibili direttamente all'utente finale, e vengono
invece utilizzati dei server di strato 1, che formano quelli che più
comunemente si chiamano \textit{Time Server}.  Un gruppo di questi server è
fornito all'indirizzo \texttt{pool.ntp.org}; l'indirizzo viene risolto dal DNS
in una serie diversa di server di strato 1, per cui si possono avere diverse
fonti. Un server NTP italiano, sincronizzato sull'orologio atomico
dell'Istituto Galileo Ferraris di Torino, è raggiungibile all'indirizzo
\texttt{tempo.ien.it}.

In genere quando si installa un server NTP su una rete si crea un server di
strato 2, che fa riferimento ad uno o più server di strato 1 per ottenere la
fonte di misura dei tempi. Si può poi anche installare il servizio sulle
singole macchine, nel qual caso è opportuno che queste facciano riferimento al
precedente server di strato 2, e si avrebbero a quel punto server di strato 3.

In tal caso infatti, a parte il fatto di non generare inutilmente traffico di
rete verso l'esterno per rivolgersi in più macchine ad un server di strato 1,
è prevalente l'interesse di avere una migliore coerenza fra i tempi degli
orologi delle macchine (cosa ottenibile rivolgendosi ad un server sulla
propria rete), piuttosto che una maggiore ``\textsl{esattezza media}'' delle
ore dei vari orologi.  L'operazione si potrebbe ripetere creando eventuali
server di strato 4 e così via fino ad un massimo di 16 strati, ma con scarsa
utilità pratica.

L'utilizzo di un server NTP rispetto all'invocazione periodica di
\texttt{ntpdate} ha il vantaggio che il demone è in grado di raccogliere
informazioni riguardo alla deriva dell'orologio di sistema, e fornire allo
stesso le necessarie informazioni per mantenere corretta l'ora in maniera
costante (facendolo accelerare o rallentare per compensare le differenze
rilevate), senza che diventi necessaria un sincronizzazione periodica.

Il server \index{demone!\texttt{ntpd}} \texttt{ntpd} fornisce una
implementazione completa della versione 4 del protocollo, pur mantenendo la
compatibilità con la versione 3. Benché si possano effettuare alcune
impostazioni di base direttamente con le opzioni a riga di comando, in genere
il comando viene lanciato dagli script di avvio, e legge la sua configurazione
da \index{configurazione!\texttt{/etc/ntp.conf}} \texttt{/etc/ntp.conf} (o dal
file specificato con l'opzione \texttt{-c}).  Qualora si avessero problemi si
può lanciare direttamente il server in modalità di debug con l'opzione
\texttt{-d},\footnote{sempre che il relativo supporto sia stato abilitato
  nella compilazione del programma, nel qual caso si può ripetere l'opzione
  più volte per avere messaggi di debug più dettagliati.} in tal caso il
programma non si distaccherà dal terminale e stamperà tutti i messaggi.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|c|p{10cm}|} 
    \hline
    \textbf{Direttiva}&\textbf{Opzione}& \textbf{Significato} \\
    \hline
    \hline
    \texttt{driftfile}&\texttt{-f}& prende come parametro il file dove
                                    verranno scritte le informazioni relative
                                    alla deriva dell'orologio di sistema,
                                    usate per le relative correzioni.\\
    \texttt{statsdir} &\texttt{-s}& indica la directory su cui vengono salvate
                                    le informazioni statistiche.\\
    \texttt{server}   &--& indica un server di riferimento da cui ottenere la
                           sincronizzazione, passato come argomento per nome a
                           dominio o indirizzo IP, la direttiva può essere
                           ripetuta più volte per indicare più server. \\
    \texttt{restrict} &--& imposta le regole di accesso al server, prende come
                           primo parametro un indirizzo IP di una macchina o
                           di una rete (nel qual caso deve essere seguita
                           dalla sottodirettiva \texttt{mask} e dalla relativa
                           \textit{netmask}) cui seguono le restrizioni da
                           applicare. Deve essere specificata almeno una volta
                           per indicare una regola di default (in tal caso si
                           può usare la parola chiave \texttt{default} al
                           posto dell'indirizzo).\\ 
    \hline
\end{tabular}
\caption{Le principali direttive di configurazione di \texttt{ntp.conf} ed
  eventuali corrispondenti opzioni di \texttt{ntpd}.}
\label{tab:ntpd_confoptions}
\end{table}

Il formato del file prevede la solita convenzione di ignorare righe vuote o
inizianti per ``\texttt{\#}'', ogni riga è costituita da una direttiva seguita
da uno o più argomenti, separati da spazi, e non si può proseguire sulla riga
successiva. La direttiva più importante, ed in genere l'unica che serve
modificare, è \texttt{server}, usata per indicare a quali server di strato
superiore ci si deve rivolgere per ottenere la sincronizzazione.

Una seconda direttiva, da utilizzare quando si intende impostare un server NTP
locale ad uso di altre macchine, è \texttt{restrict}, che consente di indicare
a quali IP il server può rispondere per le richieste di sincronizzazione.  Le
altre principali direttive di configurazione di \texttt{/etc/ntp.conf} sono
riportate in tab.~\ref{tab:ntpd_confoptions}, insieme alle opzioni che
permettono di impostare il valore di alcune di esse se si lancia il demone a
riga di comando.

Un estratto del file di configurazione installato su una Debian Sarge per un
server di strato 2 è il seguente, dove si è indicato un server di strato 1 da
usare come riferimento e si è abilitato l'accesso dalla propria rete locale:
\begin{FileExample}[label=/etc/ntp.conf]
driftfile /var/lib/ntp/ntp.drift
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server pool.ntp.org
restrict default kod notrap nomodify nopeer noquery
restrict 127.0.0.1 nomodify
restrict 192.168.1.0  mask  255.255.255.0 nomodify notrap
\end{FileExample}

La documentazione delle varie opzioni e delle principali direttive di
configurazione del server è disponibile nella pagina di manuale, accessibile
con \texttt{man ntpd}, ma per la documentazione completa occorre fare
riferimento al sito del progetto, su
\url{http://www.ntp.org/documentation.html}.

Una volta installato un server NTP se ne può controllare il funzionamento con
il comando \index{comando!\texttt{ntpq}} \texttt{ntpq}. Se eseguito senza
argomenti il comando fornisce una interfaccia testuale ed opera in modalità
interattiva, nella quale si possono scrivere direttamente i vari comandi
interni che interrogano il server NTP, che possono essere invece forniti sulla
riga di comando come parametri per l'opzione \texttt{-c}. Di default il
comando si collega al server NTP su \texttt{localhost}, ma si può indicare un
server diverso passandogli l'indirizzo come argomento.  

In genere l'uso più comune del comando è invocarlo con l'opzione \texttt{-p}
che richiede la stampa dei server a cui si sta facendo riferimento, in modo da
verificare che la sincronizzazione stia funzionando. Si può usare poi
l'opzione \texttt{-n} per evitare la risoluzione inversa degli indirizzi
IP. In tal caso il comando stampa un elenco dei server che sono stati
contattati con qualcosa del tipo:
\begin{Console}
root@monk:~# \textbf{ntpq -np}
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+5.249.146.81    193.11.166.36    2 u  264 1024  377   43.117    0.586   2.716
-85.18.189.242   62.48.53.90      3 u  563 1024  337   47.407   63.370  64.227
*212.45.144.3    193.204.114.232  2 u   11 1024  377   31.621   -0.626   0.604
+146.48.81.102   193.204.114.233  2 u  963 1024  375   47.269    0.366   0.883
\end{Console}
\noindent che ci mostra come siano stati contattati 4 server fino ad un
massimo di 963 secondi fa (la colonna \texttt{when} indica l'ultima
interrogazione), di questi viene marcato con un ``\texttt{*}'' iniziale il
server usato al momento come riferimento primario, mentre con un
``\texttt{+}'' si indicano i candidati ad essere ulteriori riferimenti e con
``\texttt{-}'' quelli scartati. 

%TODO trattare ntptrace


\subsection{I TCP wrappers}
\label{sec:net_TCP_wrappers}

Per molto tempo gran parte dei servizi di rete, nati in un periodo in cui
Internet era una rete costituita principalmente da istituzioni ed enti di
ricerca, ed in cui il numero delle persone che potevano utilizzarla era molto
limitato e facilmente controllabile, non sono stati forniti di nessun tipo di
controllo degli accessi, permettendo a chiunque di collegarsi ad essi,
qualunque fosse la sua macchina o il suo indirizzo IP.

Con l'espandersi della rete e la possibilità di accessi non voluti o
\textsl{maliziosi}, è diventato sempre più importante poter effettuare un
controllo degli accessi. Per questo Wietse Wenema, un esperto di sicurezza, ha
creato un insieme di librerie e programmi, chiamati \textit{TCP wrappers}, che
consentono di realizzare un controllo degli accessi permettendo il
collegamento ai servizi da essi protetti solo da parte di certi indirizzi o
reti.\footnote{in sostanza questi programmi leggono dal socket associato ad
  una connessione l'indirizzo sorgente da cui essa è stata effettuata, ed
  applicano delle restrizioni sui possibili valori di quest'ultimo.}

Le modalità con cui si possono utilizzare le capacità di filtraggio dei
\textit{TCP wrappers} sono sostanzialmente due. La prima è quella più semplice
che vede l'uso del programma \index{comando!\texttt{tcpd}} \texttt{tcpd}, che
fa da ``\textsl{involucro}'' (in inglese \textit{wrapper}, da cui il nome)
all'esecuzione di altri programmi.  Esso viene di norma utilizzato attraverso
il demone \texttt{inetd} come illustrato in sez.~\ref{sec:net_inetd} per
lanciare altri programmi. Il comando infatti effettua un controllo sul socket
associato alla connessione e se l'accesso è consentito lancia il demone
specificato come argomento; in questo modo è possibile realizzare un controllo
di accesso anche per programmi che non hanno alcun supporto per questa
funzionalità.

La seconda modalità è quella che prevede l'uso, direttamente all'interno del
demone che fornisce il servizio, delle librerie di controllo dei \textit{TCP
  wrappers}, in questo modo è il programma stesso che diventa in grado di
usarne le funzionalità senza dover essere lanciato da un programma esterno.
Alcuni demoni che fanno uso di questa modalità sono quelli relativi a servizi
come SSH, LDAP o NFS. In entrambi i casi le connessioni ai servizi controllati
con i \textit{TCP wrappers} vengono registrate sul sistema del
\textit{syslog}, in modo da lasciare traccia di eventuali tentativi di accesso
non autorizzati, dopo di che vengono eseguiti i vari controlli che sono stati
richiesti.

Il controllo di accesso dei \textit{TCP wrappers} è gestito attraverso due
file, \index{configurazione!\texttt{/etc/hosts.allow}}
\texttt{/etc/hosts.allow} ed \index{configurazione!\texttt{/etc/hosts.deny}}
\texttt{/etc/hosts.deny}, che contengono le regole di accesso.  Il primo file,
come suggerisce il nome, elenca le regole che consentono l'accesso, il secondo
quelle che lo negano.

Si tenga presente che il funzionamento dei \textit{TCP wrappers} è tale che
prima viene controllato \texttt{hosts.allow}, e se una regola corrisponde
l'accesso è garantito e la procedura di controllo finisce immediatamente.
Altrimenti viene controllato \texttt{hosts.deny} e se una regola corrisponde
l'accesso è negato. Se non si trova nessuna corrispondenza (o entrambi i file
sono vuoti o non esistono), l'accesso è consentito.

Dato che è buona norma in una politica di sicurezza bloccare tutto per default
per poi consentire soltanto quanto necessario, in genere quello che si fa è
negare tutti gli accessi in \texttt{hosts.deny} e garantire poi solo quelli
effettivamente voluti in \texttt{hosts.allow}.  Per questo un esempio tipico
del contenuto di \texttt{hosts.deny} è il seguente:
\begin{FileExample}[label=/etc/hosts.deny]
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
#                  See the manual pages hosts_access(5), hosts_options(5)
#                  and /usr/doc/netbase/portmapper.txt.gz
#
ALL: ALL
\end{FileExample}
in cui si blocca l'accesso a tutti i servizi da qualunque provenienza.

La sintassi delle regole da utilizzare in questi file già si intravede da
questo primo esempio; al solito righe vuote e tutto quello che segue un
\texttt{\#} viene ignorato, mentre ogni riga non vuota deve avere la forma
generica:
\begin{Example}
lista dei server: lista dei client : comando shell
\end{Example}
con tre campi di configurazione separati dal carattere ``\texttt{:}'', di
questi il terzo è opzionale e può essere omesso (ed in effetti è scarsamente
utilizzato). I primi due campi, come riportato, consentono l'uso di una lista
di valori, da specificare separati da spazi.

Per capire meglio la sintassi prendiamo un secondo esempio, più significativo
del precedente, per un possibile contenuto di \texttt{hosts.allow} che, una
volta bloccato tutto con il precedente \texttt{hosts.deny}, consenta comunque
di accedere ad alcuni servizi:
\begin{FileExample}[label=/etc/hosts.allow]
# /etc/hosts.allow: list of hosts that are allowed to access the system.
#                   See the manual pages hosts_access(5), hosts_options(5)
#                   and /usr/doc/netbase/portmapper.txt.gz
#
sshd:     ALL
leafnode: 127.0.0.1
portmap:  127.0.0.1 192.168.0.
mountd:   127.0.0.1 192.168.0.
statd:    127.0.0.1 192.168.0.
lockd:    127.0.0.1 192.168.0.
rquotad:  127.0.0.1 192.168.0.
\end{FileExample}

L'esempio riporta alcuni criteri di accesso per diversi servizi: il primo
concerne l'uso di SSH (che tratteremo in sez.~\ref{sec:net_ssh}) per l'accesso
da remoto alla riga di comando, che viene gestito dal programma \texttt{sshd};
il secondo è il servizio che permette di tenere un server di news in locale,
gli altri sono i vari server necessari al funzionamento di NFS (si veda
sez.~\ref{sec:net_NFS_server}). L'esempio consente l'accesso generico ad SSH
da qualunque indirizzo IP, l'accesso a NFS solo dalla rete locale, e l'uso del
server di news solo dalla macchina stessa.

In generale per il primo campo serve ad indicare il nome (o i nomi, se sono
più di uno) del programma che gestisce il servizio sui cui si vuole applicare
il controllo di accesso. Occorre fare attenzione, perché nelle versioni meno
recenti dei \textit{TCP wrapper} il nome da indicare nella prima colonna è
proprio quello del programma che fornisce il servizio, e non quello della
porta che si usa invece in \texttt{inetd.conf}; le versioni più recenti
consentono anche di utilizzare il nome del servizio (o il relativo numero di
porta).

Nella secondo campo si indicano invece gli indirizzi IP o le reti a cui si
vuole consentire l'accesso. Per le reti in genere si può usare sia la
notazione numerica che quella dei nomi a dominio, e si può usare il carattere
``\texttt{*}'' per raggruppare indirizzi; si può anche specificare una
maschera di rete con un indirizzo del tipo:
\begin{Example}
131.155.72.0/255.255.254.0
\end{Example}
e specificare la lista degli indirizzi usando un file, dando il pathname
assoluto dello stesso.

Il formato e la lista completa delle funzionalità che sono controllabili
tramite questi due file è riportato nella pagina di manuale ad essi associata,
accessibile con \texttt{man 5 hosts\_access}. Si tenga comunque conto che
alcuni servizi supportano solo un sottoinsieme delle funzionalità definite in
generale, come accade ad esempio per il server NFS del kernel, ci sono infatti
casi in cui questi file vengono utilizzati direttamente, in maniera
indipendente dalle librerie dei \textit{TCP wrapper}, con un sottoinsieme
delle capacità di queste ultime.

Per una migliore gestione dei \textit{TCP wrapper} col relativo pacchetto
vengono forniti anche dei programmi di utilità che permettono di verificare la
configurazione ed effettuare dei controlli di accesso.  Il primo programma è
\index{comando!\texttt{tcpdchk}} \texttt{tcpdchk} che esegue un controllo
delle regole di accesso impostate con \texttt{hosts.allow} e
\texttt{hosts.deny}, confrontandole anche con i servizi attivati in
\texttt{inetd.conf}. Il comando riporta tutti gli eventuali problemi rilevati,
a partire da un uso scorretto di wildcard e indirizzi, servizi che non sono
riconosciuti, argomenti o opzioni non validi, ecc. Così ad esempio potremo
avere:
\begin{Console}
root@gont:~# \textbf{tcpdchk}
warning: /etc/hosts.allow, line 15: apt-proxy: no such process name in /etc/inetd.conf
\end{Console}
\noindent in corrispondenza ad una regola di accesso rimasta aperta per un
servizio che in seguito è stato rimosso.

Il comando permette di controllare i file \texttt{hosts.allow} e
\texttt{hosts.deny} nella directory corrente invece che sotto \texttt{/etc}
usando l'opzione \texttt{-d}, mentre si può specificare un diverso file per 
\texttt{inetd.conf} con l'opzione \texttt{-i}, la documentazione completa è al
solito disponibile con \texttt{man tcpdchk}.

Il secondo comando di controllo è \index{comando!\texttt{tcpdmatch}}
\texttt{tcpdmatch} che permette di verificare il comportamento dei TCP wrapper
per una specifica richiesta da un servizio. Il comando richiede due parametri,
il primo che specifichi il servizio che si vuole controllare ed il secondo la
stazione da cui si intende effettuare l'accesso.  Il comando eseguirà una
scansione delle regole e riporterà i risultati. Ad esempio potremo richiedere:
\begin{Console}
root@gont:~# \textbf{tcpdmatch sshd oppish}
warning: sshd: no such process name in /etc/inetd.conf
warning: oppish: hostname alias
warning: (official name: oppish.earthsea.ea)
client:   hostname oppish.earthsea.ea
client:   address  192.168.168.11
server:   process  sshd
matched:  /etc/hosts.allow line 5
access:   granted
\end{Console}
\noindent che controlla l'accesso al servizio SSH (si noti che si deve
specificare il nome del programma che esegue il servizio) da parte della
macchina \texttt{oppish}, trovando che questo è consentito dalla riga 5 del
file \texttt{hosts.allow}. Il comando rileva anche che il servizio non è
lanciato attraverso \texttt{inetd} e quale è l'IP effettivo della macchina.



\section{L'assegnazione dinamica degli indirizzi IP}
\label{sec:net_DHCP}

In questa sezione tratteremo vari protocolli (ed i relativi programmi di
utilizzo) che vengono usati per l'assegnazione automatica degli indirizzi IP
all'interno di una rete locale. Il primo, il RARP è stato il primo protocollo
usato a questo scopo, ed è sostanzialmente in disuso essendo sostituito dagli
altri due. Il secondo, il BOOTP, nasce per distribuire via rete immagini di
avvio, mentre l'ultimo, il DHCP, ricomprende tutte queste esigenze all'interno
di un unico servizio, e lo tratteremo con maggiori dettagli.


\subsection{I protocolli RARP, BOOTP e DHCP}
\label{sec:net_RARP}

Il protocollo RARP (sigla che sta per \textit{Reverse Address Resolution
  Protocol}), è un protocollo elementare, definito
nell'\href{http://www.ietf.org/rfc/rfc0903.txt}{RFC~903} che, come il nome
stesso indica, esegue il compito inverso rispetto al protocollo ARP già visto
in sez.~\ref{sec:net_arp}. Il protocollo è implementato direttamente a livello
di collegamento fisico (cioè nella maggior parte dei casi su ethernet) e serve
ad ottenere, dato un \textit{MAC address} sulla rete, l'indirizzo IP ad esso
associato.

Lo scopo del protocollo era principalmente quello di fornire un meccanismo
automatico per l'assegnazione di un indirizzo IP ad una macchina in fase di
avvio; questa esegue (posto che il kernel disponga del relativo supporto, che
su Linux deve essere opportunamente abilitato) una richiesta RARP su ethernet
ed utilizza l'indirizzo IP fornito come risposta per configurare l'interfaccia
di rete da cui ha eseguito la richiesta; la cosa presuppone ovviamente la
presenza nel suddetto tratto di rete di un server che fornisca la risposta.

Tutto ciò oggi, in presenza di altri protocolli più sofisticati in grado di
eseguire sia questo che altri compiti, ha solo interesse storico (considerato
anche che sono assai pochi ormai i sistemi operativi che lo supportano). Per
chi si trovasse in situazioni in cui per compatibilità con vecchi sistemi
viene ancora usato questo metodo per l'assegnazione degli indirizzi, ci
limitiamo a citare la possibilità di compilare il kernel per utilizzare questo
supporto.

Il protocollo BOOTP (il nome sta per \textit{Bootstrap Protocol}), è definito
nell'\href{http://www.ietf.org/rfc/rfc0951.txt}{RFC~951} e nasce come
protocollo per gestire l'avvio automatico delle macchine. Rispetto al
precedente RARP è basato su IP e UDP (e non direttamente sul collegamento
fisico) e non si limita alla ricerca di un indirizzo IP da assegnare
automaticamente ad una scheda di rete, ma prevede anche l'invio delle
informazioni necessarie ad ottenere un file da usare come immagine del sistema
operativo per l'avvio e l'indirizzo di una macchina a cui richiedere
quest'ultimo.

Il protocollo BOOTP nasce principalmente per fornire un meccanismo con cui
macchine senza disco possono eseguire un avvio del sistema operativo via rete,
ottenendo quest'ultimo, (cioè i vari file contenenti i dati necessari, nel
caso di Linux l'immagine del kernel ed un eventuale \textit{ramdisk}) da un
opportuno server. In genere il trasferimento dei dati avviene tramite il
protocollo TFTP,\footnote{il \textit{Trivial File Transfer Protocol} è un
  protocollo elementare per il trasferimento di file basato su UDP, che è
  utilizzabile in programmi estremamente semplificati come quelli che sono
  contenuti nel BIOS di una macchina.} ma in teoria possono essere utilizzati
anche altri protocolli.  In questo caso è compito del BIOS della macchina
implementare la parte client del protocollo (sia di BOOTP che di TFTP, se poi
viene usato quest'ultimo) in modo da ottenere poi l'immagine del sistema che
verrà caricata in memoria ed eseguita.

Come sottoinsieme delle funzionalità del protocollo BOOTP c'è ovviamente anche
quella della assegnazione automatica di un indirizzo IP dato che il
trasferimento dell'immagine del sistema avviene sempre con un altro protocollo
che necessita di IP. Per questo motivo il protocollo può essere usato per
distribuire gli indirizzi su una rete.  Di nuovo qualora questa funzionalità
fosse necessaria per l'avvio, ad esempio per l'avvio di un sistema con la
directory radice su NFS, occorrerà compilare il kernel con il relativo
supporto, analogamente a quanto si farebbe per l'uso di RARP.

Il supporto per la parte server del protocollo è disponibile con il programma
\index{demone!\texttt{bootpd}} \texttt{bootpd} (su Debian il pacchetto è
\texttt{bootp}) che implementa tutte le funzionalità definite
nell'\href{http://www.ietf.org/rfc/rfc0951.txt}{RFC~951} e pure le estensioni
dei successivi \href{http://www.ietf.org/rfc/rfc1532.txt}{RFC~1532} e
\href{http://www.ietf.org/rfc/rfc1533.txt}{RFC~1533}. In genere il servizio
viene avviato tramite \texttt{inetd}, ma può essere eseguito anche in modalità
\textit{standalone}.

Il comando prevede come argomento il file da cui leggere le impostazioni, che
può essere omesso, nel qual caso verrà utilizzato il default che è
\index{configurazione!\texttt{/etc/bootptab}} \texttt{/etc/bootptab};
quest'ultimo contiene tutte le definizioni dei vari parametri da usare per
ciascun client nella forma:
\begin{Example}
hostname:tg=value... :tg=value... :tg=value. ...
\end{Example}
dove \texttt{hostname} indica il nome associato ad un client cui seguono le
assegnazioni dei parametri che sono identificati da una etichetta di due
caratteri, separata con l'uso del carattere ``\texttt{:}''.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Tag} &\textbf{Descrizione}\\
    \hline
    \hline
    \texttt{bf} & file di avvio. \\
    \texttt{dn} & nome del dominio.\\
    \texttt{ds} & lista dei server DNS. \\
    \texttt{gw} & lista dei gateway. \\
    \texttt{ha} & indirizzo fisico (\textit{MAC address}) della macchina. \\
    \texttt{hd} & home directory per il file di avvio. \\
    \texttt{hn} & \textit{hostname} da inviare al client. \\
    \texttt{ip} & indirizzo IP da assegnare. \\
    \texttt{rp} & pathname della directory da montare come radice. \\
    \texttt{sa} & indirizzo del server TFTP da usare. \\
    \texttt{sm} & maschera di rete della macchina. \\
    \texttt{td} & directory radice per il server TFTP.\\
    \hline    
  \end{tabular}
  \caption{Etichette dei parametri assegnabili in \texttt{bootptab}.}
  \label{tab:net_bootptab_tag}
\end{table}

Un elenco delle etichette dei principali parametri usati da \texttt{bootptab}
è riportato in tab.~\ref{tab:net_bootptab_tag}, al solito l'elenco completo e
tutti i dettagli sono nella relativa pagina di manuale, accessibile con
\texttt{man bootptab}.

Il protocollo più utilizzato per la configurazione automatica della rete è il
DHCP, sigla che sta per \textit{Dynamic Host Configuration Protocol}, che al
giorno d'oggi ha soppiantato in maniera praticamente completa sia RARP che
BOOTP.  Oltre ai servizi previsti dal precedente BOOTP, del quale implementa,
in maniera compatibile all'indietro, tutte le funzionalità, il protocollo
supporta anche l'assegnazione dinamica degli indirizzi.  La sua descrizione
completa è disponibile
nell'\href{http://www.ietf.org/rfc/rfc2131.txt}{RFC~2131}, che ne definisce
tutte le caratteristiche.

A differenza di BOOTP lo scopo principale di DHCP, come espresso dal nome
stesso, è quello della configurazione dinamica delle macchine in una rete
locale. Uno dei vantaggi di questo protocollo è che è in grado di fornire
parecchie informazioni in più rispetto a quelle elementari fornite da BOOTP,
rendendo possibile la configurazione automatica di tutte le funzionalità della
rete per le macchine di una LAN.

La peculiarità di DHCP è comunque il supporto per la gestione dinamica degli
indirizzi. Con BOOTP infatti l'assegnazione di un indirizzo IP è fatta
staticamente sul server dove per ogni client deve essere configurato un
indirizzo.  Il client si limita a fare una richiesta e configurare la rete in
base alla risposta (o fallisce se il server non risponde). Non viene gestito
il caso di una assegnazione temporanea all'interno di un pool di indirizzi,
cioè il caso tipico di quando al computer di un ospite in visita deve essere
assegnato un indirizzo temporaneo all'interno della propria rete.

Una assegnazione di questo tipo comporta ovviamente una serie di problemi in
più rispetto all'assegnazione statica, ed in particolare l'assegnazione degli
indirizzi si scontra con le problematiche relative alla presenza discontinua
od occasionale di macchine all'interno della rete, alla necessità di dover
gestire la riassegnazione di indirizzi usati in precedenza, di accorgersi
quando un indirizzo non è più in uso, e di evitare di assegnare lo stesso
indirizzo a macchine diverse.

Per risolvere questo tipo di problematiche DHCP prevede una comunicazione non
occasionale fra il client, che resta attivo anche dopo la configurazione
dell'indirizzo, ed il server e tre diverse modalità di assegnazione degli
indirizzi, dette rispettivamente \textsl{statica}, \textsl{automatica} e
\textsl{dinamica}.

La configurazione \textsl{statica} è sostanzialmente la stessa di BOOTP, in
cui si associa staticamente un indirizzo ad una specifica macchina sulla base
del \textit{MAC address} della stessa. Con la configurazione
\textsl{automatica} invece viene assegnato in maniera permanente un indirizzo
IP ad ogni macchina che ne fa richiesta, ma non è necessario che
l'amministratore imposti la corrispondenza come nel caso precedente. Questo
può andare bene nel caso di macchine sempre presenti sulla rete, ma non è
ovviamente adatto al caso di presenze occasionali.

Per questo la modalità che alla fine viene utilizzata di più è quella della
configurazione \textsl{dinamica}, in cui ad ogni assegnazione è associato
anche un tempo di permanenza, il cosiddetto \textit{lease}, passato il quale,
se il client non ha chiesto un prolungamento, l'assegnazione viene cancellata.
In questo modo diventa possibile gestire la presenza occasionale di macchine
sulla rete, assegnando un indirizzo libero che tornerà automaticamente
disponibile dopo un certo periodo di inutilizzo, o che potrà essere rilasciato
esplicitamente quando segnalato dal client stesso. 

Il protocollo DHCP prevede che sia sempre il client a contattare il server;
all'avvio il client invia dei pacchetti in \textit{broadcast} su
UDP,\footnote{ci si può chiedere come possa essere utilizzato UDP, che
  presuppone IP, prima che la macchina abbia un indirizzo IP con il quale
  contattarla; quello che accade è che i pacchetti vengono inviati con IP
  sorgente nullo (indirizzo \texttt{0.0.0.0} e porta 68), ed in
  \textit{broadcast} come IP di destinazione (indirizzo
  \texttt{255.255.255.255} e porta 67) con al loro interno il \textit{MAC
    address} del richiedente, che così può essere raggiunto dal server.} e
alla ricezione di una richiesta il server invia un pacchetto di risposta
contenente le varie informazioni di configurazione,\footnote{in realtà il
  meccanismo è più complesso, il protocollo prevede che il client invii un
  pacchetto di tipo \textit{dhcp discovery}, che in sostanza chiede se esiste
  un server DHCP disponibile; a questo i server presenti risponderanno con dei
  pacchetti di offerta (di tipo \textit{dhcp offer}) con una proposta di
  indirizzo IP e di \textit{lease}, ed il client potrà scegliere quello che
  preferisce (in genere in base alla maggior durata del \textit{lease})
  rispondendo con un pacchetto di tipo \textit{dhcp request}; la negoziazione
  si chiude alla risposta del server con un pacchetto \textit{dhcp ack}, senza
  il quale il procedimento ricomincia da capo.}  che prevedono l'indirizzo IP
da assumere, quello del \textit{default gateway}, l'indirizzo di eventuali
server DNS ed altre informazioni relative alla rete, ma soprattutto, qualora
si usi la configurazione dinamica, il periodo di \textit{lease} per il quale
l'assegnazione dell'indirizzo sarà considerata valida.


\subsection{Uso del servizio DHCP dal lato client}
\label{sec:net_DHCP_client}

Per poter usufruire dei servizi di un server DHCP esistono vari programmi; i
più comuni e diffusi sono \texttt{pump} e \texttt{dhclient}, di quest'ultimo
esistono poi due versioni, a seconda che si usi la versione 2 o la versione 3
del protocollo, anche se ormai in uso resta praticamente solo quest'ultimo.

Il programma \index{comando!\texttt{pump}} \texttt{pump} è un client sia per
DHCP che per BOOTP. Il suo uso è immediato, basta invocarlo specificando
l'interfaccia che si vuole configurare in maniera automatica con l'opzione
\texttt{-i}, una invocazione tipica è qualcosa del tipo:
\begin{Example}
pump -i eth0
\end{Example}
anche il programma può essere lanciato automaticamente all'avvio del sistema,
quando si configura la rete per eseguire la configurazione tramite DHCP.

Il comando prende una serie di altre opzioni che consentono di scartare le
informazioni ottenute dal server (come i DNS o il \textit{default gateway}) o
controllare lo stato del servizio, al solito per i dettagli si può fare
riferimento alla pagina di manuale. Il programma può anche essere controllato
tramite un file di configurazione, \texttt{/etc/pump.conf}, il cui formato è
descritto nella relativa pagina di manuale, accessibile con \texttt{man pump}.

Una volta ricevuta risposta da un server, il comando utilizza le informazioni
ricevute per configurare la rete. Queste in genere comprendono, oltre
l'indirizzo IP da assegnare, anche il dominio locale, gli indirizzi dei server
DNS e quello del \textit{default gateway}, pertanto il comando non si limiterà
ad assegnare un indirizzo all'interfaccia specificata, ma creerà anche un
opportuno \texttt{resolv.conf} ed inserirà la \textit{default route} nella
tabella di routing.  Qualora il server non dia nessuna risposta invece il
comando fallirà, così come la configurazione automatica della rete.

Il secondo programma che viene utilizzato come client per la configurazione
automatica della rete è \index{comando!\texttt{dhclient}} \texttt{dhclient}.
Questo è parte della implementazione di riferimento del protocollo DHCP fatta
dall'Internet Software Consortium, ed ad oggi viene utilizzato nella versione
3, anche se su alcune distribuzioni molto vecchie si può ancora trovare la
versione 2 del programma.

L'invocazione manuale del programma è analoga a quella di \texttt{pump}, ma
non è necessario specificare una opzione per indicare una interfaccia.  Se non
si passano argomenti il programma esamina le interfacce presenti, scarta
quelle che non supportano il \textit{broadcast}, e poi cerca di configurarle
tutte; altrimenti si può specificare la lista delle interfacce da configurare
con qualcosa del tipo:
\begin{Example}
dhclient eth1 eth2
\end{Example}
il comando supporta tre opzioni, \texttt{-p} consente di specificare l'uso di
una porta diversa da quella standard, \texttt{-d} che esegue il programma in
modalità di debug mantenendolo agganciato al terminale (si tenga presente che
anche il client DHCP lavora come demone, dovendo gestire la scadenza dei
\textit{lease}) e \texttt{-e} che causa l'uscita del programma se questo non
riesce a configurare l'interfaccia entro un certo tempo.

Il comportamento di \texttt{dhclient} è controllato dal file
\index{configurazione!\texttt{/etc/dhcp/dhclient.conf}} \texttt{dhclient.conf}
(che a seconda delle versioni può essere installato sotto \texttt{/etc/dhcp3/}
o sotto \texttt{/etc/dhcp/}) riguardo ad aspetti come le temporizzazioni, le
informazioni richieste al server, la presenza di valori che devono
sovrascrivere o essere aggiunti a quelli presenti in eventuali risposte o
utilizzati come default qualora questo non risponda.

Il formato del file prevede al solito che le righe vuote e tutto quanto segue
il carattere ``\texttt{\#}'' venga ignorato. Le direttive sono di due tipi,
quelle elementari, che specificano delle caratteristiche singole, hanno la
forma di una parola chiave seguita da uno o più valori e sono terminate dal
carattere ``\texttt{;}''. Quelle complesse possono specificare più
caratteristiche e prevedono una parola chiave seguita da un eventuale
parametro e da un blocco di ulteriori direttive semplici (nella forma
precedente) che viene delimitato da parentesi graffe. In generale spaziature e
ritorni a capo vengono ignorati, ed i nomi delle direttive sono \textit{case
  insensitive}.

Un esempio di \texttt{dhclient.conf}, preso dalla versione installata su una
Debian Squeeze (nella versione 3 del client) è il seguente estratto, dove come
si può notare la maggior parte delle direttive sono commentate:
\begin{FileExample}[label=dhclient.conf]
# Configuration file for /sbin/dhclient, which is included in Debian's
#       dhcp3-client package.
#
# This is a sample configuration file for dhclient. See dhclient.conf's
#       man page for more information about the syntax of this file
#       and a more comprehensive list of the parameters understood by
#       dhclient.
#
# Normally, if the DHCP server provides reasonable information and does
#       not leave anything out (like the domain name, for example), then
#       few changes must be made to this file, if any.
#

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

#send host-name "andare.fugue.com";
#send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
#send dhcp-lease-time 3600;
#supersede domain-name "fugue.com home.vix.com";
#prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, domain-search, host-name,
        netbios-name-servers, netbios-scope, interface-mtu,
        rfc3442-classless-static-routes, ntp-servers;
#require subnet-mask, domain-name-servers;
#timeout 60;
#retry 60;
#reboot 10;
#select-timeout 5;
#initial-interval 2;
#script "/etc/dhcp3/dhclient-script";
#media "-link0 -link1 -link2", "link0 link1";
#reject 192.33.137.209;
...
\end{FileExample}

In genere non è necessario modificare questo file, che può anche essere
lasciato vuoto. Nell'esempio precedente la principale direttiva utilizzata è
\texttt{request} che serve ad indicare quale informazioni si richiedono al
server DHCP. Un'altra direttiva che può essere utilizzata è \texttt{send} che
consente di inviare informazioni al server, come ad esempio
l'\textit{hostname} (vedi sez.~\ref{sec:net_hosts}) che può essere utilizzato
da quest'ultimo per aggiornare la lista delle macchine presenti sulla rete.
Un elenco delle principali direttive è riportato in
tab.~\ref{tab:net_dhclient_conf}, l'elenco completo è al solito disponibile
sulla pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato} \\
    \hline
    \hline
     \texttt{request}  & elenca la lista delle opzioni DHCP (vedi
                         tab.~\ref{tab:net_dhcp_options}) che il client
                         richiede al server.\\
     \texttt{timeout}  & indica il tempo massimo oltre il quale il client
                         stabilisce che non ci sono server raggiungibili.\\
%     \texttt{retry}    & .\\
%     \texttt{reboot}   & .\\
%     \texttt{option}   & .\\
     \texttt{send}     & indica una opzione DHCP (vedi
                         tab.~\ref{tab:net_dhcp_options}) ed il relativo
                         valore che il client invia al server.\\
     \texttt{script}   & specifica lo script usato dal client per
                         configurare l'interfaccia, di default viene usato
                         \texttt{/etc/dhcp3/dhclient-script}.\\
     \texttt{reject}   & specifica l'indirizzo IP di un server da cui non
                         devono essere accettate risposte.\\
     \texttt{interface}& permette di impostare direttive di configurazione
                         specifiche per una interfaccia; richiede come
                         argomento il nome della interfaccia in questione ed a
                         seguire il blocco delle direttive da applicare.\\
    \hline    
  \end{tabular}
  \caption{Principali direttive del file \texttt{dhclient.conf}.}
  \label{tab:net_dhclient_conf}
\end{table}

Si tenga presente che le operazioni di \texttt{dhclient} non sono limitate
alla configurazione iniziale della rete; il protocollo infatti prevede che il
client debba ricontattare periodicamente il server per prolungare un
\textit{lease} che sta scadendo, mantenendo l'associazione con il relativo
indirizzo IP, o per riacquisire le informazioni di configurazione, o per
notificare la cessazione dell'uso di un indirizzo IP in caso di uscita.

Per la gestione della assegnazione dinamica degli indirizzi \texttt{dhclient}
mantiene una lista dei \textit{lease} ottenuti nel file
\texttt{dhclient.leases} (in genere questo file si trova sotto
\texttt{/var/lib/dhcp/}) in modo da tenerne traccia anche se si sono
effettuati riavvii del sistema o se il server ha avuto un crash. Il formato
del file è descritto nella relativa pagina di manuale, accessibile con
\texttt{man dhclient.leases}. Anche questo file viene letto all'avvio ed i
suoi dati vengono utilizzati qualora un server DHCP sia irraggiungibile.

In questo caso quando il server torna disponibile i vecchi \textit{lease} non
ancora scaduti vengono ricontrollati e, se trovati validi, riutilizzati.  Il
client si cura inoltre di aggiornare \texttt{dhclient.leases} tutte le volte
che ottiene una nuova associazione con un nuovo \textit{lease}, e per evitare
che il file cresca indefinitamente crea periodicamente una nuova versione del
file contenente solo i \textit{lease} attivi al momento, salvando la vecchia
come \texttt{dhclient.leases\tild}.



\subsection{La configurazione di un server DHCP}
\label{sec:net_DHCP_server}

Sul lato server il protocollo DHCP viene realizzato tramite un apposito
demone, \index{demone!\texttt{dhcpd}} \texttt{dhcpd}, che si incarica di
ricevere le richieste e fornire le risposte. Il server viene lanciato dal
relativo script di avvio (che dipende dalla distribuzione), ma può anche
essere avviato a mano. In quel caso si può usare l'opzione \texttt{-d} per
eseguire il server interattivamente in modalità di debug. Un'altra opzione è
\texttt{-p} che permette di usare una porta diversa da quella di default (la
67 su UDP); per le altre opzioni si può fare riferimento alla pagina di
manuale.

Come il client anche il server mantiene una lista delle assegnazioni
effettuate e dei relativi \textit{lease} in un apposito file,
\texttt{dhcpd.leases} (sempre sotto \texttt{/var/lib/dhcp/}), così da poter
tenere traccia dello stato del sistema anche in caso di riavvio, anche il
formato di questo file è descritto nella pagina di manuale accessibile con
\texttt{man dhcpd.leases}.  Il server scrive in questo file ogni nuovo
\textit{lease} assegnato e ne cura la rotazione periodica come fa
\texttt{dhclient} per \texttt{dhclient.leases}.

Il funzionamento del server è controllato da un file di configurazione che è
\index{configurazione!\texttt{/etc/dhcp/dhcpd.conf}} \texttt{dhcpd.conf} (che
di nuovo può essere installato sotto \texttt{/etc/dhcp/} o
\texttt{/etc/dhcp3/}). Un esempio del contenuto di questo file è il seguente:
\label{sec:net_DHCP_conf}
\begin{FileExample}[label=dhcpd.conf]
#
# Sample configuration file for ISC dhcpd for Debian
#

# option definitions common to all supported networks...
option domain-name "earthsea.ea";
option domain-name-servers havnor.earthsea.ea;

option subnet-mask 255.255.255.0;
default-lease-time 600;
max-lease-time 7200;

subnet 192.168.0.0 netmask 255.255.255.0 {
  range 192.168.0.32 192.168.0.63;
  option broadcast-address 192.168.0.255;
  option routers roke.earthsea.ea;
}

host lorbaner {
  hardware ethernet 08:00:07:26:c0:a5;
  fixed-address lorbaner.earthsea.ea;
}
\end{FileExample}

Il formato del file è identico a quello di \texttt{dhclient.conf} e come per
questo il contenuto è divisibile sommariamente in due categorie di direttive,
quelle che prevedono la specificazione di semplici parametri e quelle più
complesse, dette dichiarazioni, che contengono blocchi di altre direttive. In
generale il file prevede una serie di direttive iniziali, che servono ad
impostare i valori che vengono utilizzati come default. Questi possono essere
modificati a valori diversi all'interno di dichiarazioni più specifiche.

Un esempio di direttive semplici sono le righe iniziali del precedente esempio
che nel caso sono state utilizzate per impostare alcune opzioni DHCP a livello
generale, come il dominio di riferimento, il server DNS, o la maschera di
rete. In questo caso si usa la direttiva \texttt{option}, seguito dal nome
dell'opzione DHCP che si intende impostare (le principali sono riportate in
tab.~\ref{tab:net_dhcp_options}) e dal relativo valore.

Altre due direttive semplici sono \texttt{default-lease-time}, che imposta il
valore di default (nel caso 600 secondi) del \textit{lease} delle risposte, e
\texttt{max-lease-time} che imposta valore massimo che può essere assegnato ad
un \textit{lease}.  Un elenco delle principali direttive per la dichiarazione
di parametri è illustrato in tab.~\ref{tab:net_dhcpd_conf}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{option}        & imposta il valore di una opzione DHCP, prende
                             come argomento il nome dell'opzione (vedi
                             tab.~\ref{tab:net_dhcp_options}), seguito dagli
                             eventuali valori.\\     
    \texttt{default-lease-time} & imposta il valore di default del tempo di
                                  \textit{lease} inviato a un client se questo non
                                  ha fatto una richiesta specifica.\\
    \texttt{max-lease-time}& imposta il valore massimo del tempo di
                             \textit{lease} che può essere inviato ad un
                             client, indipendentemente da quanto esso possa
                             avere richiesto.\\
    \texttt{range}         & imposta un intervallo di indirizzi da assegnare
                             dinamicamente.\\
    \texttt{fixed-address} & imposta un indirizzo (o più) da assegnare
                             staticamente, viene in genere utilizzato 
                             all'interno di una dichiarazione \texttt{host} 
                             insieme a \texttt{hardware address}.\\
    \texttt{hardware address}&indica l'indirizzo hardware (in genere un
                               \textit{MAC address}) cui
                               assegnare un indirizzo statico.\\
    \texttt{include}       & legge il contenuto di un altro file come se
                             questo fosse stato incluso nella configurazione.\\
    \texttt{filename}      & specifica il nome del file da caricare come
                             sistema operativo (deve essere riconosciuto come
                             nome valido dal protocollo, in genere TFTP, usato
                             dal client per caricarlo).\\
    \texttt{next-server}   & specifica il server da cui scaricare il file per
                             il boot del sistema (indicato dalla precedente
                             \texttt{filename}).\\
    \hline    
  \end{tabular}
  \caption{Principali direttive del file \texttt{dhcpd.conf}.}
  \label{tab:net_dhcpd_conf}
\end{table}

In generale il DHCP consente di suddividere gli IP restituiti alle stazioni in
diverse sotto-reti, anche se nel nostro esempio ne viene usata una
soltanto. Questo è fatto tramite la direttiva \texttt{subnet}, che serve a
dichiarare una sottorete; essa è seguita dall'indirizzo della rete e dalla
specificazione della relativa \textit{netmask} preceduta dalla parola chiave
\texttt{netmask}. All'interno della dichiarazione si potrà poi indicare l'uso
di una assegnazione dinamica specificando l'intervallo di indirizzi con la
direttiva \texttt{range}, oltre ai tempi di \textit{lease} e alle altre
opzioni DHCP da usare per quella sottorete.

Un'altra dichiarazione utile è quella che consente di configurare una stazione
singola (analoga dell'assegnazione statica di BOOTP), anch'essa mostrata
nell'esempio in sez.~\ref{sec:net_DHCP_conf}. Questo viene fatto tramite la
direttiva \texttt{host} seguita dal nome della macchina, quest'ultima sarà
identificata dal \textit{MAC address} specificato dalla direttiva
\texttt{hardware ethernet}, mentre l'indirizzo fisso da assegnare verrà
specificato dalla direttiva \texttt{fixed-address}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{subnet} & dichiara una sottorete, ad essa deve seguire
                      l'indirizzo IP della sottorete e la relativa maschera
                      introdotta dalla parola chiave \texttt{netmask}; il
                      corpo della dichiarazione conterrà i parametri da
                      applicare alla suddetta sottorete.\\
    \texttt{host}   & dichiara una macchina singola, ad essa deve seguire il 
                      nome della stessa; il corpo della dichiarazione conterrà
                      i parametri da applicare alla suddetta macchina.\\
    \texttt{group}  & dichiara un gruppo di macchine, ad essa deve seguire il
                      nome del gruppo; il corpo della dichiarazione  conterrà
                      i parametri da applicare alle macchine del gruppo
                      identificate attraverso ulteriori dichiarazioni di tipo
                      \texttt{host}.\\
%    \texttt{} & .\\
%    \texttt{} & .\\
    \hline    
  \end{tabular}
  \caption{Principali direttive di dichiarazione del file \texttt{dhcpd.conf}.}
  \label{tab:net_dhcpd_conf_declar}
\end{table}


Si noti come in entrambi questi esempi di dichiarazioni si sono dovute poi
specificare i valori dei parametri da applicare con una serie di altre
direttive semplici poste all'interno di un blocco delimitato da parentesi
graffe.  Un elenco delle principali direttive di dichiarazione è illustrato in
tab.~\ref{tab:net_dhcpd_conf_declar}. Per una lista completa dei parametri si
può fare riferimento alla pagina di manuale del file di configurazione
accessibile con \texttt{man dhcpd.conf}.

Una parte essenziale della configurazione del server è quella relativa alle
opzioni DHCP, che costituiscono il contenuto delle risposte che il server
fornisce ai client. È attraverso queste opzioni che si inviano ai client le
varie informazioni sulla rete che ne permettono la configurazione automatica.
Come già visto esse possono essere inserite sia direttamente nel corpo
principale di \texttt{dhcpd.conf}, dove assumeranno il ruolo di valore di
default, che all'interno di singole dichiarazioni per sotto-reti o macchine
singole. 

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{domain-name}         & specifica il nome di dominio in cui ci si 
                                   trova (ad uso dell'impostazione automatica 
                                   di \texttt{resolv.conf}). \\
    \texttt{domain-name-servers} & specifica una lista di server DNS (anche
                                   questo per l'impostazione automatica dei
                                   relativi campi in \texttt{resolv.conf}). \\
    \texttt{subnet-mask}         & specifica la \textit{netmask} per la
                                   rete associata all'indirizzo assegnato. \\
    \texttt{broadcast-address}   & specifica l'indirizzo di \textit{broadcast}
                                   per la rete associata all'indirizzo
                                   assegnato. \\
    \texttt{routers}             & specifica il \textit{default gateway} per
                                   la rete associata all'indirizzo assegnato.\\
    \texttt{host-name}           & specifica il nome della macchina.\\
    \texttt{netbios-name-servers}& specifica l'indirizzo di un server WINS
                                   (usato dalle macchine Windows).\\
%    \texttt{netbios-scope}       & .\\
%    \texttt{time-offset}         & .\\
    \hline    
  \end{tabular}
  \caption{Principali opzioni del protocollo DHCP.}
  \label{tab:net_dhcp_options}
\end{table}

Le opzioni vengono sempre impostate da una direttiva nella forma
\texttt{option \textsl{nome-opzione} \textsl{valore-opzione};} ed una lista
dei nomi delle principali opzioni utilizzate per la configurazione automatica
delle macchine è riportata in tab.~\ref{tab:net_dhcp_options}. Al solito
l'elenco completo è disponibile sulla relativa pagina di manuale, accessibile
con \texttt{man dhcp-options}.


\subsection{La configurazione automatica della rete con IPv6}
\label{sec:net_ndp_radvd}

A differenza di IPv4, con IPv6 l'assegnazione automatica degli indirizzi, ed
anche una buona parte della autoconfigurazione della rete, è stata prevista
direttamente fin dalle basi del protocollo. Come accennato in
sez.~\ref{sec:net_ip_addr} ad ogni interfaccia di rete su cui si è abilitato
IPv6 viene automaticamente assegnato un indirizzo \textit{link-local} nella
classe \texttt{fe80::/10}, inserendo il nei bit meno significativi
dell'indirizzo il \textit{MAC address} della scheda in formato EUI-64.

Questo consente ad IPv6 di realizzare all'interno del protocollo una serie di
servizi che con IPv4 venivano demandati a protocolli ausiliari; in
particolare, come accennatto in sez.~\ref{sec:net_ip_addr}, con IPv6 è
prevista la cosiddetta \itindex{Stateless Address Autoconfiguration (SLAAC)}
\textit{Stateless Address Autoconfiguration} (SLAAC) che consente di assegnare
automaticamente un indirizzo IPv6 (non \textit{link-local}, e quindi
instradabile) senza dover ricorrerere ad un server DHCP. Oltre a questo,
sempre grazie al \itindex{Neighbor Discovery Protocol (NDP)} \textit{Neighbor
  Discovery Protocol} che è parte di ICMPv6, si ha la possibilità di ottenere
automaticamente l'indirizzo del gateway e la propria sottorete.

In genere l'indirizzo IP, una volta ottenuta la sottorete su cui si è posti,
viene costruito automaticamente, sfruttando la disponibilità di 64 bit per
ogni rete, o dal \textit{MAC address} dell'interfaccia di rete, o con una
generazione di un numero casuale. Dato però che entrambi i metodi non si
possono escludere in maniera assoluta che non ci possano essere indirizzi
duplicati (anche se il \textit{MAC address} è unico, qualcuno potrebbe aver
assegnato lo stesso indirizzo in maniera statica), NDP supporta anche, sempre
all'interno della \textit{Stateless Address Autoconfiguration}, un meccanismo
di scoperta di eventuali indirizzi duplicati, correggendo eventualmente
l'assegnazione per tenerne conto.

Tutto questo è possibile perché grazie alla assegnazione automatica degli
indirizzi \textit{link-local}, si può utilizzare immediatamente ICMPv6 usando
uno dei pacchetti previsti da NDP (il \textit{Router Solicitation}) per
contattare l'indirizzo di \textit{multicast} \texttt{ff02::2} che riunisce
tutti i router presenti sulla propria rete, ed ottenere da questi, una
risposta di \textit{Router Advertisement} (altro pacchetto di NDP) con il
proprio prefisso di rete e l'indirizzo del relativo gateway. 

Questo meccanismo fa si che con IPv6 la configurazione automatica possa essere
effettuata in buona parte senza far ricorso ad un server DHCP, considerato
anche che esistono ulteriori estensioni che consentono di fornire anche
l'elenco dei server DNS e dei domini locali (che non sono però ancora
supportate interamente da tutti i sistemi operativi). Per poterle usare però è
necessario che il router fornisca le risposte previste da NDP. Nel caso di un
router basato su Linux questo può essere ottenuto con un apposito demone, il
\textit{Router Advertisement Daemon} \index{demone!\texttt{radvd}}
\texttt{radvd}. Il programma deve essere installato sul router che fa da
default gateway (su Debian e CentOS basta installare il pacchetto
\texttt{radvd}) ed è controllato dal file
\index{configurazione!\texttt{/etc/radvd.conf}} \texttt{/etc/radvd.conf}, un
esempio di configurazione è il seguente:

\begin{FileExample}[label=radvd.conf]
interface eth0 {
   AdvSendAdvert on;
   prefix 2001:db8::/64 {};
};
\end{FileExample}

La sintassi del file è analoga a quella usata da \texttt{dhcpd}, con delle
direttive semplici, cui segue la specificazione di un parametro, o direttive
contenitore che possono prevedere blocchi di ulteriori direttive fra parentesi
graffe. Ogni direttiva (contenitore o meno) deve essere conclusa con un
``\texttt{;}'' posto o dopo il parametro o dopo il blocco. Alla radice del
file di configurazione stanno una o più direttive \texttt{interface}, che
consentono di indicare su quali interfacce la macchina agisce da router e su
cui attivare il \textit{Router Advertisement}. Questa direttiva richiede che
si indichi come argomento il nome dell'interfaccia, seguita da un blocco con
le relative impostazioni.

Con i default del programma le impostazioni illustrate nell'esempio precedente
sono già sufficienti al funzionamento dell'autoconfigurazione degli indirizzi:
con \texttt{AdvSendAdvert} si indica di inviare periodicamente dei
\textit{Router Advertisement} a tutte le macchine presenti su
quell'interfaccia (usando l'indirizzo di \textit{multicast} \texttt{FF02::1}),
mentre con la successiva \texttt{prefix} si indica il prefisso di rete che i
client dovranno usare per l'autoconfigurazione (l'indirizzo che viene inviato
come gateway è sempre quello del router stesso). 

Altre direttive contenitore che si possono utilizzare all'interno della
definizione di una interfaccia sono RDNSS e e DNSSL che attivano
rispettivamente l'\textit{advertisement} per i server DNS da usare (RDDNS sta
per \texttt{Recursive DNS Server}) e per i domini su cui effettuare una
ricerca (DNSSL sta per \textit{DNS Search List}), per cui si possono
sostituire le opzioni \texttt{domain-name-servers} e \texttt{domain-name} di
un server DHCP con una configurazione di \texttt{radvd} analoga alla seguente:

\begin{FileExample}[label=radvd.conf]
interface eth0 {
   AdvSendAdvert on;
   prefix 2001:db8::/64 {};
   RDNSS 2001:db8::ab {};
   DNSSL earthsea.ea {};
};
\end{FileExample}

Dato che l'autoconfigurazione del DNS e del dominio non è detto sia
universalmente supportata, può comunque essere necessario delegare la
configurazione di queste informazioni ad un server DHCP (usando la versione
IPv6 del relativo protocollo). In tal caso occorrerà indicare ai client che
essi devono richiedere queste ulteriori informazioni, aggiungendo nella
sezione di configurazione dell'interfaccia la direttiva
\texttt{AdvOtherConfigFlag on}. L'uso di un server DHCP potrebbe comunque
risultare utile per fornire anche ulteriori informazioni alle macchine (ad
esempio i server NTP) che non sono supportate da \texttt{radvd}.

Inoltre per esigenze di gestione (ad esempio per tenere traccia di quale
indirizzo si assegna a quale macchina) si può volere evitare del tutto SLAAC e
passare a quella che viene chiamata una configurazione \texttt{stateful} in
cui anche l'assegnazione degli indirizzi IP viene gestita dal DHCP. In tal
caso resta comunque necessario l'uso di \texttt{radvd} perché le informazioni
relative al suffisso di rete ed al default gateway con IPv6 vengono comunque
gestite attraverso NDP e il \textit{router advertising}. Qualora si abbia
questa esigenza \texttt{radvd} dovrà indicare esplicitamente ai client di
evitare l'autoconfigurazione degli indirizzi, cosa che si ottiene inserendo
all'interno di \texttt{prefix} la direttiva \texttt{AdvAutonomous off}, poi si
dovrà indicare all'interno di \texttt{interface} che anche gli indirizzi
devono essere richiesti al DHCP, con la direttiva \texttt{AdvManagedFlag on}
(che attiva anche la precedente \texttt{AdvOtherConfigFlag}). In un caso come
questo la configurazione risultante dovrebbe essere qualcosa del tipo:

\begin{FileExample}[label=radvd.conf]
interface eth0 {
   AdvSendAdvert on;
   AdvManagedFlag on;
   prefix 2001:db8::/64 {
     AdvAutonomous off;
   };
};
\end{FileExample}

Qualora si decida di ricorrere all'uso di DHCP occorrerà poi configurare anche
il relativo server, per questo si può usare lo stesso \texttt{dhcpd}, che se
lanciato con l'opzione \texttt{-6} fornisce il supporto per DHCPv6. Il server
però non è in grado di gestire in contemporanea sia IPv4 che IPv6, pertanto se
entrambi i protocolli sono necessari, occorrerà eseguire una seconda istanza,
usando un file di configurazione distinto, ad esempio
\texttt{/etc/dhcp/dhcpd6.conf}. Le direttive per indicare una sottorete o un
intervallo di indirizi su IPv6 sono analoghe a quelle di IPv4, con aggiunto un
6 in coda, mentre le opzioni devono essere indicate apponendo un
\texttt{dhcp6.} alle analoghe di IPv4; pertanto un esempio di configurazione
potrebbbe essere il seguente:

\begin{FileExample}[label=dhcpd6.conf]
subnet6 2001:db8::/64 {
    option dhcp6.name-servers 2001:db8::ab;
    option dhcp6.domain-search "earthsea.ea";
    range6 2001:db8::1:0000 2001:db8::1:ffff;
}
\end{FileExample}





\section{Amministrazione remota con SSH}
\label{sec:net_ssh}

Un tempo parlare di amministrazione remota di un computer significava parlare
del comando \texttt{telnet}. Come accennato in sez.~\ref{sec:net_telnet} però
questo comando esegue tutte le sue comunicazioni in chiaro, password comprese,
che così sono estremamente facili da intercettare. Per questo oggi parlare di
amministrazione remota significa parlare di SSH, sigla che sta per
\textit{\textbf{s}ecure \textbf{sh}ell},\footnote{il nome origina in realtà da
  un altro programma, \texttt{rsh}, parte dei cosiddetti \texttt{r-command} di
  Sun, che consentiva di eseguire una shell remota; gli \texttt{r-command}, in
  cui la ``\texttt{r}'' sta per \textit{remote}, erano un insieme di
  \textsl{duplicati} dei comandi unix (\texttt{rsh}, \texttt{rcp},
  \texttt{rlogin}) che eseguivano lo stesso compito degli analoghi senza la
  ``\texttt{r}'' su una macchina remota; il problema è che questo veniva fatto
  senza nessuna cifratura della comunicazione e consentendo l'esecuzione sulla
  base dell'indirizzo IP da cui i comandi venivano lanciati, in maniera cioè
  totalmente insicura.} ed identifica un protocollo di comunicazione che
permette di creare un canale cifrato con una macchina remota.  Benché sia
possibile utilizzare il canale in maniera generica, l'uso principale di SSH è
quello di fornire una shell, consentendo così l'amministrazione remota; da
questo origina il nome del servizio.


\subsection{La configurazione del server SSH}
\label{sec:SSHD_server}

Come buona parte dei protocolli di rete, SSH è realizzato con una architettura
client-server; quando si vuole poter effettuare l'amministrazione da remoto di
una macchina occorre installare su di essa la parte server del protocollo che
viene fornita dal demone \index{demone!\texttt{sshd}} \texttt{sshd}. È questo
demone che si incarica di rispondere alle richieste dei client e di realizzare
tutte le fasi necessarie alla creazione di una canale cifrato su cui sia
possibile inviare in maniera sicura le informazioni, per poi eseguire sulla
macchina i vari comandi richiesti, restituendone i risultati.

Nel nostro caso faremo riferimento alla implementazione del protocollo
realizzata dal progetto \textit{OpenSSH}, il programma originale infatti, dopo
essere stato rilasciato per un certo tempo con licenza libera, è diventato
proprietario, ma un gruppo di programmatori indipendente\footnote{il progetto
  OpenSSH è portato avanti dagli stessi sviluppatori del sistema operativo
  OpenBSD, una versione di BSD il cui sviluppo è centrato sulla massima
  attenzione alle problematiche di sicurezza.} è riuscito, partendo dalla
ultima versione libera disponibile, a ricreare una implementazione completa
del protocollo, che nel frattempo è stato anche standardizzato.

Il demone può essere lanciato direttamente dalla linea di comando ed andrà
automaticamente in background sganciandosi dal terminale. Il servizio ascolta
di default sulla porta 22, ma può essere impostato su una porta diversa usando
l'opzione \texttt{-p}. Con l'opzione \texttt{-D} lo si può eseguire in
modalità di debug, mantenendolo agganciato al terminale, l'uso dell'opzione
\texttt{-d}, ripetuta fino ad un massimo di tre volte, fa sì che esso generi
messaggi di controllo sempre più dettagliati.

Nelle normali operazioni però, come gli altri demoni, anche \texttt{sshd}
viene di norma lanciato automaticamente dagli script di avvio.\footnote{su
  Debian lo script è \texttt{/etc/init.d/ssh}, altre distribuzioni usano
  \texttt{sshd}; si tenga presente che alcune distribuzioni recenti installano
  di default soltanto il client, il server viene fornito a parte (ad esempio
  su Debian a partire da \textit{Etch} deve essere installato il pacchetto
  \texttt{openssh-server}).} Il comportamento del demone (ad esempio anche la
porta da utilizzare) è comunque controllato dal rispettivo file di
configurazione; tutti i file di configurazione attinenti a SSH vengono
normalmente mantenuti nella directory \texttt{/etc/ssh/}; di default la
configurazione del server è posta nel file
\index{configurazione!\texttt{/etc/ssh/sshd\_config}} \texttt{sshd\_config},
ma se ne può specificare un altro con l'opzione \texttt{-f}. Per un elenco
completo delle opzioni di \texttt{sshd} si può fare riferimento alla pagina di
manuale.

Come consuetudine il file di configurazione è in formato testo con una
direttiva per linea, questa viene identificata da una parola chiave e seguita
da uno o più argomenti separati da spazi o tabulazioni; righe vuote e tutto
ciò che segue il carattere ``\texttt{\#}'' al solito viene ignorato.  Le
principali direttive ed il relativo significato sono riportate in
tab.~\ref{tab:sshd_options}; si sono descritte solo quelle che è più probabile
che un amministratore si trovi a dover modificare. I valori delle altre sono
di norma preimpostati a quanto specificato dal file di configurazione
installato con il pacchetto. Al solito per una descrizione completa delle
varie direttive si può fare riferimento alla pagina di manuale, accessibile
con \texttt{man sshd\_config}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|p{2.9cm}|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{AcceptEnv}       & indica le variabili di ambiente inviate dal
                               client che possono essere inserite
                               nell'ambiente della sessione di lavoro.\\
    \texttt{AllowTCPForwarding}& abilita l'inoltro di connessioni TCP sul
                                 canale cifrato (vedi
                                 sez/~\ref{sec:ssh_forwarding}).\\  
    \texttt{AllowAgentForwarding}& abilita l'inoltro delle connessioni
                               all'agent (vedi
                               sez.~\ref{sec:net_ssh_key}); prende come 
                               argomento i valori \texttt{yes} o \texttt{no},
                               di default è abilitato.\\ 
    \texttt{AllowGroups}, \texttt{DenyGroup} & abilita/disabilita l'accesso
                               agli utenti che fanno parte della lista di gruppi
                               (specificata dai rispettivi nomi separati da
                               spazi) passata come argomento; accetta anche i
                               caratteri ``\texttt{?}'' e ``\texttt{*}'' come
                               \textit{wildcard} per i nomi dei gruppi.\\
    \texttt{AllowUsers}, \texttt{DenyUsers}& abilita/disabilita l'accesso agli
                               utenti che fanno parte della lista passata come
                               argomento; accetta ``\texttt{?}'' e
                               ``\texttt{*}'' come \textit{wildcard}.\\
    \texttt{Banner}          & invia al client il contenuto del file passato 
                               come argomento per poterlo stampare come avviso
                               prima di passare alla procedura di
                               autenticazione, il default è \texttt{none} che
                               non invia nulla.\\  
    \texttt{HostKey}         & indica quali sono i file contenenti le chiavi
                               crittografiche usate dal server.\\
    \texttt{ListenAddress}   & permette di indicare un indirizzo specifico su
                               cui mettersi in ascolto (nella forma
                               \texttt{indirizzo:porta}); il default è
                               ascoltare su tutti gli indirizzi locali.\\
    \texttt{PasswordAuthentication}& abilita la ordinaria autenticazione a
                               password, prende i valori \texttt{yes} o
                               \texttt{no} e di default è abilitata.\\
    \texttt{PermitRootLogin} & permette il login diretto all'amministratore;
                               prende come argomento i valori \texttt{yes} o
                               \texttt{no}; le versioni più recenti supportano
                               anche \texttt{without-password} che consente
                               l'accesso solo con una autenticazione diversa
                               dalle password.\\ 
    \texttt{Port}            & specifica la porta su cui mettersi in ascolto
                               (di default è la 22).\\
    \texttt{Protocol}        & indica la versione del protocollo e deve essere
                               impostato a 2 in quanto le precedenti versioni
                               sono insicure; è possibile abilitare versioni
                               inferiori solo a fine di compatibilità, ma si
                               consiglia energicamente di aggiornare i 
                               client.\footnotemark\\ 
    \texttt{PubkeyAuthentication}& abilita l'autenticazione a chiavi (vedi
                               sez.~\ref{sec:net_ssh_key}), prende i valori
                               \texttt{yes} o \texttt{no} e di default è
                               abilitata.\\
    \texttt{Subsystem}       & configura un sottoprogramma, e richiede come
                               argomenti il nome dello stesso seguito dal
                               pathname al programma che lo realizza; viene
                               in genere utilizzato solo per abilitare SFTP,
                               un protocollo di trasferimento file con una
                               sintassi identica a quella di FTP, con il
                               sottosistema denominato \texttt{sftp} ed il
                               programma \texttt{sftp-server}.\\
    \texttt{X11DisplayOffset}& assegna un valore di partenza per il numero di
                               \textit{display} (vedi sez.~\ref{sec:X_client})
                               usato dalle sessioni \textit{X Window} 
                               inoltrate sul canale cifrato.\\
    \texttt{X11Forwarding}   & abilita l'\textsl{inoltro} delle sessioni
                               X11 (vedi sez.~\ref{sec:ssh_forwarding});
                               prende come argomento i valori \texttt{yes} o
                               \texttt{no} e di default è disabilitato. \\
    \hline    
  \end{tabular}
  \caption{Principali direttive di configurazione per il demone \texttt{sshd}
    usate nel file \texttt{sshd\_config}.}
  \label{tab:sshd_options}
\end{table}
\footnotetext{che è il motivo per cui non descriveremo il formato di questa
  direttiva; chi vuole esporsi al rischio si legga attentamente le pagine di
  manuale.}

Al solito per una descrizione completa delle varie direttive si può fare
riferimento alla pagina di manuale, accessibile con \texttt{man sshd\_config}.
Un estratto del file di configurazione di \texttt{sshd} installato su una
Debian Wheezy è riportato di seguito:
\begin{FileExample}[label=sshd\_config]
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
#Privilege Separation is turned on for security
...
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile	%h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
...
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes
\end{FileExample}

Data la delicatezza delle operazioni svolte dal demone, tramite il quale
diventa possibile eseguire un qualunque comando su una macchina remota, è
stata posta la massima attenzione ai requisiti di sicurezza. Ad esempio di
default l'accesso remoto all'utente di amministrazione è disabilitato, e può
essere abilitato solo con la direttiva \texttt{PermitRootLogin} impostata al
valore \texttt{yes}; senza di essa occorre prima collegarsi come un utente
normale e poi usare \texttt{su}.

Si tenga presente che \texttt{sshd} onora sia la presenza del file
\texttt{/etc/nologin} non consentendo, quando esso esiste, la connessione ad
utenti che non siano l'amministratore, che l'utilizzo dei \textit{TCP
  wrappers}, obbedendo alle restrizioni poste nei file \texttt{hosts.allow} e
\texttt{hosts.deny} (vedi sez.~\ref{sec:net_TCP_wrappers}). Inoltre con le
direttive \texttt{AllowGroups}, \texttt{AllowUsers}, \texttt{DenyGroups},
\texttt{DenyUsers} si può restringere l'accesso ad utenti e gruppi
specificati. Si tenga presente però che utilizzando sia \texttt{AllowUsers}
che \texttt{AllowGroups} devono essere soddisfatte entrambe le condizioni, per
cui se non c'è almeno uno degli utenti indicati che fa parte di uno dei gruppi
indicati, nessuno potrà più collegarsi.

Se l'utente è fra quelli permessi il server ne eseguirà l'autenticazione;
\texttt{sshd} supporta molti meccanismi di autenticazione, ciascuno dei quali
può essere abilitato o meno in maniera indipendente tramite una opportuna
direttiva nella forma \texttt{\textsl{Meccanismo}Authentication} (per l'elenco
completo si rimanda alla pagina di manuale) impostata a \texttt{yes} o a
\texttt{no}. Il default è la richiesta della password dell'utente, controllato
dalla direttiva \texttt{PasswordAuthentication}; in tal caso normalmente
\texttt{sshd} si appoggia a PAM, con tutte le funzionalità viste in
sez.~\ref{sec:cfg_user_PAM}, ma una alternativa molto più valida (su cui
torneremo in sez.~\ref{sec:net_ssh_key}) è l'autenticazione a chiavi,
controllata dalla direttiva \texttt{PubkeyAuthentication}. 

Infine una ulteriore serie di direttive (per cui di nuovo si rimanda alla
pagina di manuale) consentono di controllare i dettagli della cifratura del
canale (ad esempio gli algoritmi crittografici utilizzabili), SSH infatti usa
la crittografia a chiave asimmetrica,\footnote{per una introduzione ai
  concetti su cui si basa la crittografia a chiave asimmetrica, e la relativa
  nomenclatura, si rimanda alla sezione 1.2 di \cite{SGL}.}  ed in particolare
la direttiva \texttt{HostKey} consente di indicare quali chiavi devono essere
utilizzate dal server.  In genere queste sono mantenute nella directory
\texttt{/etc/ssh/} insieme ai file di configurazione, in una serie di file
\texttt{ssh\_host\_*\_key} per le chiavi private e
\texttt{ssh\_host\_*\_key.pub} per le chiavi pubbliche, dove l'asterisco sta
ad indicare il tipo di chiave (che può essere \texttt{dsa}, \texttt{ecdsa} o
\texttt{rsa}).

Queste chiavi vengono usate dal server per essere identificato dai client e
per generare le chiavi di sessione con cui sono cifrati le singole
connessioni.\footnote{il protocollo prevede che ogni connessione sia cifrata
  in maniera indipendente con una \textsl{chiave di sessione}, rinnovata
  periodicamente, che viene creata tramite queste chiavi.}  Questi file
vengono generati automaticamente all'installazione del pacchetto (anche se è
possibile generarli a mano, vedi sez.~\ref{sec:net_ssh_key}) ed in particolare
quelli contenenti le chiavi private devono essere conservati con la massima
cura in quanto costituiscono le credenziali che attestano l'identità del
server.

Se l'autenticazione ha successo il server mette a disposizione del client un
canale cifrato su cui eseguire una trasmissione sicura dei dati. L'uso più
comune è quello di realizzare una sessione di lavoro in cui eseguire i
programmi richiesti dal client (in genere una shell) facendo passare tutte le
comunicazioni attraverso il canale cifrato. In tal caso la direttiva
\texttt{AcceptEnv} indica quali fra le eventuali variabili d'ambiente
richieste dal client potranno essere copiate da quest'ultimo alla sessione
creata sul server. 

Vedremo poi in sez.~\ref{sec:ssh_forwarding} come l'uso di SSH non si limiti
all'esecuzione di comandi in remoto, ma consenta anche di eseguire
l'\textsl{inoltro} sul canale cifrato di altre tipologie di dati. Ad esempio è
possibile avere una sessione grafica remota, lanciando sul server programmi
che usano l'interfaccia grafica di X11 ed ottenendo attraverso SSH le finestre
sul client, per cui si potranno eseguire compiti di amministrazione remota
anche attraverso programmi ad interfaccia grafica.


\subsection{L'utilizzo di SSH come client}
\label{sec:net_SSH_client}

Prima di entrare nei dettagli dei vari comandi che utilizzano SSH dal lato
client occorre precisare che anche questi sono controllati da un file di
configurazione generale, \index{configurazione!\texttt{/etc/ssh/ssh\_config}}
\texttt{/etc/ssh/ssh\_config}, la cui struttura è analoga a quella di
\texttt{sshd\_config}, con una direttiva per linea. In questo caso però la
direttiva \texttt{Host} ha un ruolo speciale, essa infatti permette di
indicare un insieme di macchine (identificate per indirizzo IP o nome a
dominio) cui si applicano tutte le direttive seguenti fino ad una eventuale
successiva direttiva \texttt{Host}.

In sostanza una direttiva \texttt{Host} definisce una sezione del file
contente le configurazioni da usare con tutte le macchine da essa definite.
L'amministratore può così imporre delle restrizioni nell'accesso a certe
macchine, ad esempio si può disabilitare di default la possibilità di far
eseguire al client reinoltro delle sessioni X (vedi
sez.~\ref{sec:ssh_forwarding}) o richiedere specifici default per i parametri
delle connessioni.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{CheckHostIP} & controlla se la macchina verso cui ci si collega è
                           conosciuta (se cioè è presente nel file
                           \texttt{known\_hosts}) verificando se le chiavi
                           pubbliche sono cambiate in modo da prevenire
                           attacchi di tipo \textit{man in the middle}; di
                           default è impostata a \texttt{yes}.\\  
    \texttt{Compression} & specifica se comprimere il traffico, il valore può
                           essere \texttt{yes} o \texttt{no} (il default).\\
    \texttt{CompressionLevel}& se si è abilitata la compressione permette di
                           specificarne il livello,\footnotemark prende un
                           valore numerico, ed il default è 6.\\
    \texttt{ForwardAgent}& consente il reinoltro della connessione all'agent
                           sulla macchina remota a cui ci si collega, in questo
                           modo si può usare l'\textit{agent} presente sulla
                           propria  macchina per ulteriori connessioni SSH
                           partenti dalla macchina remota, senza dovere
                           ripetere l'immissione di password; prende come
                           argomento i valori \texttt{yes} o \texttt{no}.\\ 
    \texttt{ForwardX11}  & consente l'inoltro della sessione X (vedi
                           sez.~\ref{sec:ssh_forwarding}); prende come
                           argomento i valori \texttt{yes} o \texttt{no}.\\
    \texttt{HashKnownHosts}& richiede che i nomi delle macchine a cui ci si è
                           già collegati salvati in \texttt{known\_hosts}
                           vengano salvati con un hash invece che in chiaro.\\
    \texttt{Host}        & restringe l'applicazione delle direttive seguenti ai
                           collegamenti effettuati verso le macchine
                           specificate; prende come argomento sia nomi a
                           dominio che indirizzi IP, e supporta l'uso dei
                           caratteri jolly ``\texttt{*}'' e ``\texttt{?}'';
                           l'uso del solo ``\texttt{*}'' permette di definire
                           i valori di default da applicare a qualunque
                           macchina remota.\\
    \texttt{Port}        & specifica la porta di destinazione da usare come
                           default; è preimpostato a 22.\\
    \texttt{Protocol}    & indica le versioni del protocollo da utilizzare,
                           deve essere sempre uguale a 2.\\
    \texttt{SendEnv}     & specifica quali variabili di ambiente presenti dal
                           lato client devono essere passate al server, che
                           deve comunque accettarle con la direttiva
                           \texttt{AcceptEnv}.\\
    \texttt{ServerAliveCountMax}& imposta il numero di messaggi di
                           \textit{keepalive} senza risposta dopo i quali
                           viene abbattuta la connessione.\\ 
    \texttt{ServerAliveInterval}& imposta il tempo (in secondi) senza traffico
                           sulla connessione dopo il quale il client invia un
                           messaggio di \textit{keepalive} al server, oltre a
                           rilevare le connessioni terminate, consente anche di
                           mantenere attivi i collegamenti verso quelle
                           macchine poste dietro firewall mal configurati che
                           perdono le connessioni su cui non passa traffico
                           per un certo intervallo di tempo.\\
    \texttt{StrictHostKeyChecking}& definisce l'accuratezza con cui vengono
                           controllate le macchine note, con \texttt{yes} 
                           \texttt{known\_hosts} non viene mai aggiornato e le
                           connessioni verso macchine con chiavi pubbliche
                           cambiate sono bloccate; con \texttt{ask} (il
                           default) le nuove macchine vengono aggiunte a
                           \texttt{known\_hosts} previa conferma esplicita da
                           dare alla prima connessione, con \texttt{no} le
                           connessioni verso macchine con chiavi pubbliche
                           cambiate non vengono bloccate.\\ 
    % \texttt{TCPKeepAlive}& invia messaggi di \textit{keepalive} sulla
    %                        connessione per accorgersi se questa è rimasta
    %                        attiva prende come argomenti \texttt{no} o
    %                        \texttt{yes} (il default).\\
    \hline    
  \end{tabular}
  \caption{Principali direttive di configurazione del file
    \texttt{ssh\_config} per i client SSH.}
  \label{tab:net_ssh_config}
\end{table}

\footnotetext{la compressione è effettuata tramite il programma \texttt{gzip},
  ed il livello di compressione impostato da questa direttiva è quello usato
  da detto programma, che prevede la possibilità di scegliere una maggiore
  compressione a scapito di maggiore tempo per eseguirla, o viceversa; i
  valori vanno da 1 (veloce) a 9 (lenta); la scelta del valore ottimale
  dipende in maniera essenziale dalle caratteristiche della macchina e della
  rete, su una macchina lenta con connessione veloce una compressione alta può
  ridurre le prestazioni per il tempo perso ad eseguirla.}

Le principali direttive ed il relativo significato sono illustrate in
tab.~\ref{tab:net_ssh_config}; al solito l'elenco completo, la spiegazione
dettagliata delle stesse e i loro possibili valori sono riportati nella pagina
di manuale, accessibile con \texttt{man ssh\_config}. Gli utenti possono
inserire le proprie configurazioni personali nel file \texttt{\tild
  /.ssh/config}, che, come tutte le configurazioni personali di SSH relative
un utente (sia per il lato client che per quello server) vengono mantenute
nella directory \texttt{.ssh} della sua home. Un esempio di
\texttt{/etc/ssh/ssh\_config} (estratto della versione installata da Debian
Wheezy) è il seguente:
\begin{FileExample}[label=ssh\_config]
...
Host *
#   ForwardAgent no
#   ForwardX11 no
#   RhostsAuthentication no
#   RhostsRSAAuthentication no
#   RSAAuthentication yes
#   PasswordAuthentication yes
...
    SendEnv LANG LC_*
    HashKnownHosts yes
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials no
\end{FileExample}
\label{fig:net_ssh_conf}



Si tenga presente che nell'uso dei comandi client le configurazioni applicate
vengono determinate esaminando prima le opzioni date sulla riga di comando,
poi (se presente) il file di configurazione personale in \texttt{\tild
  /.ssh/config} ed infine il file di configurazione generale. Il primo valore
ottenuto è quello che viene usato, questo vuol dire che le opzioni a riga di
comando hanno la precedenza sulle impostazioni personali, che a loro volta
hanno la precedenza su quelle di \texttt{/etc/ssh/ssh\_config}.  Inoltre se ci
sono più corrispondenze per diverse sezioni \texttt{Host} verrà ovviamente
utilizzata la prima, questo significa che è opportuno mettere le
configurazioni più specifiche in testa al file, e che qualunque altra sezione
venga messa dopo una sezione \texttt{Host *} non avrà nessun effetto.

I due comandi principali di utilizzo di SSH dal lato client sono \texttt{ssh}
e \texttt{scp} utilizzati rispettivamente per l'amministrazione remota e per
la copia dei file.  Il comando più importante resta comunque
\index{comando!\texttt{ssh}} \texttt{ssh} anche se buona parte di quello che
diremo nella trattazione seguente (in particolare quanto riguarda la creazione
del canale cifrato e l'autenticazione) resta valido anche per tutti gli altri
comandi che operano come client rispetto a \texttt{sshd}.

Se lanciato senza argomenti, \texttt{ssh} stampa un messaggio di aiuto, il
comando infatti richiede che si specifichi almeno un argomento, che indica la
macchina a cui collegarsi. Se presente il secondo argomento indica il
programma da eseguire sulla macchina remota nella sessione di collegamento; in
questo caso la connessione sarà automaticamente chiusa una volta conclusa
l'esecuzione del comando indicato. Utilizzando un solo argomento sarà invece
eseguita una shell. 

Se non si specifica niente il collegamento con la macchina remota viene sempre
eseguito per conto dell'utente che esegue \texttt{ssh}; se si desidera
utilizzare un utente diverso se ne può specificare l'username con l'opzione
\texttt{-l} o usare una indicazione del tipo \texttt{utente@macchina} per
specificare il server a cui ci si vuole connettere. Alla fine la forma più
semplice di invocazione del comando è:
\begin{Example}
ssh [-l nome_login] nome_macchina | nome_login@nome_macchina [comando]
\end{Example}

Una volta messo in esecuzione per prima cosa \texttt{ssh} si collega al server
per creare il canale cifrato. Il protocollo prevede che il server invii la sua
chiave pubblica che verrà confrontata con quella presente nell'elenco dei
server noti. Questo viene mantenuto nel file \texttt{known\_hosts} della
directory \texttt{.ssh} dell'utente; se il server a cui ci si rivolge è già
presente in \texttt{known\_hosts} verrà verificato che la chiave pubblica sia
uguale a quella ivi registrata, comportamento che si ottiene dalla
configurazione di default dalle direttive \texttt{CheckHostIP} e
\texttt{StrictHostKeyChecking}, e se questo avviene si passa alla fase di
autenticazione. Altrimenti la connessione verrà rifiutata con un avviso in cui
viene riportata la riga di \texttt{known\_hosts} che contiene il valore non
corrispondente.

Se invece la macchina a cui ci si collega non è presente nell'elenco di
\texttt{known\_hosts} verrà stampata la fingerprint della sua chiave pubblica,
così che la si possa verificare in maniera indipendente, e verrà chiesto se
aggiungerla all'elenco. Solo una volta che si sia data conferma dell'aggiunta
il procedimento passerà alla fase di autenticazione.  Questa procedura è
essenziale per accorgersi di eventuali attacchi di interposizione (i
cosiddetti \textit{man in the middle}) in cui un malintenzionato si spaccia
per il server a cui ci si vuole collegare, in modo da poter intercettare il
traffico verso di esso.

Una volta riconosciuta opportunamente la macchina remota, viene creato un
canale di comunicazione cifrato, e se previsto il server invia al client il
contenuto del file specificato dalla direttiva \texttt{Banner} di
tab.~\ref{tab:sshd_options}, che consente di replicare sulle sessioni SSH il
funzionamento del file \texttt{/etc/issue}; poi viene eseguita la fase di
autenticazione. Questa, come già detto in sez.~\ref{sec:SSHD_server}, prevede
diversi meccanismi (ne vedremo uno specifico in sez.~\ref{sec:net_ssh_key}),
ma normalmente consiste semplicemente nel replicare la procedura di login che
si fa sulla console con la richiesta della password dell'utente con cui ci si
è collegati; sarà compito di \texttt{sshd} autenticare l'utente sul server
usando l'username avuto dal client.

Una volta completata l'autenticazione il server provvederà a collegare il
canale cifrato ad un terminale virtuale sul quale saranno eseguiti i comandi
(con i privilegi dell'utente con cui ci si è connessi), connettendolo al
terminale su cui è eseguito \texttt{ssh}, così che da esso si possano inviare
dati ed ottenere risposte. Questo avviene soltanto quando non si specifica
l'esecuzione di un comando e deve essere allocato un terminale ad uso della
shell; se si richiede un singolo comando questo viene semplicemente eseguito
con lo \textit{standard input} e lo \textit{standard output} collegati al
canale cifrato, ed in tal caso per forzare l'allocazione di un terminale
(necessario per certi comandi) occorre usare l'opzione \texttt{-t}.

Nella modalità standard in cui si usa \texttt{ssh} per invocare una shell
remota il server eseguirà anche delle inizializzazioni
specifiche;\footnote{per la descrizione completa delle operazioni compiute dal
  server prima di arrivare al prompt della riga di comando remota si legga la
  pagina di manuale di \texttt{sshd}.} in particolare prima di lanciare la
shell verranno eseguite le istruzioni presenti nel file
\index{configurazione!\texttt{/etc/ssh/sshrc}} \texttt{/etc/ssh/sshrc} o, se
questo esiste, nel file \texttt{.ssh/rc} dell'utente (quello della macchina
remota, non quello da cui si usa \texttt{ssh}). In questo modo è possibile
effettuare delle impostazioni specifiche (ad esempio attivare dei limiti)
tramite questi file che sono gli analoghi di \texttt{/etc/profile} per le
connessioni SSH.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{-A} & abilita l'inoltro della connessione all'agente di
                  autenticazione.\\ 
    \texttt{-a} & disabilita l'inoltro della connessione all'agente di
                  autenticazione.\\ 
    \texttt{-i} & specifica la chiave da usare per l'autenticazione (vedi
                  sez.~\ref{sec:net_ssh_key}).\\
    \texttt{-L} & abilita il \textit{port forwarding} locale (vedi
                  sez.~\ref{sec:ssh_forwarding}).\\ 
    \texttt{-l} & specifica l'utente con cui collegarsi al server.\\
    \texttt{-p} & specifica la porta a cui collegarsi sul server.\\
    \texttt{-R} & abilita il \textit{port forwarding} remoto (vedi
                  sez.~\ref{sec:ssh_forwarding}).\\
    \texttt{-t} & forza l'allocazione di un terminale virtuale, così da
                  consentire anche l'esecuzione di comandi che ne richiedono
                  la presenza.\\
    \texttt{-v} & attiva la modalità di controllo in cui vengono stampati
                  avvisi progressivi nella fase di connessione, può
                  essere invocata fino a tre volte per aumentare la
                  \textsl{prolissità}.\\ 
    \texttt{-X} & attiva l'inoltro della sessione X11 (vedi
                  sez.~\ref{sec:ssh_forwarding}).\\
    \texttt{-x} & disattiva l'inoltro della sessione X11 (vedi
                  sez.~\ref{sec:ssh_forwarding}).\\
%    \texttt{} & .\\
    \hline    
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{ssh}.}
  \label{tab:ssh_options}
\end{table}

Una delle opzioni principali di \texttt{ssh} è \texttt{-X}, che, se il server
lo consente, attiva l'inoltro della sessione X11 (vedi
sez.~\ref{sec:ssh_forwarding}); questo può essere disabilitato (qualora
abilitato per default in \texttt{ssh\_config}) con l'opzione
\texttt{-x}. Analogamente si può abilitare o disabilitare l'inoltro verso
l'agente di autenticazione (che tratteremo in sez.~\ref{sec:net_ssh_key})
rispettivamente con le opzioni \texttt{-A} e \texttt{-a}. Nel
caso il server sia stato posto in ascolto su una porta diversa da quella
standard se ne può specificare esplicitamente una con l'opzione \texttt{-p}.
Le altre opzioni più comuni sono illustrate in tab.~\ref{tab:ssh_options}, per
un elenco completo e tutti i dettagli si rimanda al solito alla pagina di
manuale del comando che è accessibile con \texttt{man ssh}.

L'altro comando client più utilizzato è \index{comando!\texttt{scp}}
\texttt{scp} che permette di copiare file via rete in maniera sicura,
trasmettendoli attraverso un canale cifrato con SSH. La sintassi è analoga a
quella del comando \texttt{cp}, e prevede l'indicazione di uno o più file (o
directory) di origine da copiare su una destinazione. Solo che in questo caso
l'indicazione può essere effettuata con una espressione generalizzata che
consente di indicare anche una origine o una destinazione
remota,\footnote{strettamente o l'origine o la destinazione, \texttt{scp} crea
  una connessione SSH verso una singola macchina e quindi non può supportare
  la copia da una macchina remota ad un'altra.} da scrivere nella forma:
\begin{Example}
utente@macchina:/percorso/al/file
\end{Example}
dove \texttt{macchina} indica l'indirizzo (numerico o simbolico) della
macchina remota su cui si trova il file, \texttt{utente} è l'username con il
quale ci si vuole collegare alla macchina remota (lo si può omettere se
corrisponde a quello con cui si sta lavorando), e \texttt{/percorso/al/file}
il pathname del file sulla macchina remota; se quest'ultimo viene specificato
in forma relativa viene considerato a partire dalla home dell'utente che si sta
usando.

Un esempio di uso del comando potrebbe essere il seguente:
\begin{Example}
scp piccardi@gapil.gnulinux.it:gapil.pdf .
\end{Example}
che copia il file \texttt{gapil.pdf} dalla home dell'utente su un server
remoto alla directory corrente, mentre per effettuare un trasferimento in
direzione opposta di una intera directory si potrà usare il comando:
\begin{Example}
scp -r gapil piccardi@gapil.gnulinux.it:public_html/
\end{Example}
che copia ricorsivamente il contenuto della directory \texttt{gapil} nella
directory \texttt{public\_html} della home del server.

Il comando richiede la stessa procedura di autenticazione usata da
\texttt{ssh}, che normalmente comporta l'immissione da terminale delle
password relative agli utenti delle macchine a cui ci si collega. L'opzione
\texttt{-p} permette di preservare i tempi ed i permessi del file originale,
mentre l'opzione \texttt{-r} esegue una copia ricorsiva di intere directory.
Le altre principali opzioni sono in tab.~\ref{tab:scp_options}, al solito per
i dettagli su tutte le altre opzioni si può fare riferimento alla pagina di
manuale accessibile con \texttt{man scp}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{-C} & abilita la compressione della connessione.\\
    \texttt{-i} & specifica la chiave da usare per l'autenticazione (vedi
                  sez.~\ref{sec:net_ssh_key}).\\
    \texttt{-l} & imposta una limitazione nell'uso della banda, da esprimersi
                  in Kbit/s.\\ 
    \texttt{-P} & specifica la porta a cui collegarsi sul server.\\
    \texttt{-p} & preserva tempi e permessi dei file che si copiano.\\
    \texttt{-r} & esegue una copia ricorsiva delle directory.\\
    \texttt{-v} & attiva la modalità di controllo in cui vengono stampati
                  avvisi progressivi nella fase di connessione, può
                  essere invocata fino a tre volte per aumentare la
                  \textsl{prolissità}.\\ 
%    \texttt{} & .\\
    \hline    
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{scp}.}
  \label{tab:scp_options}
\end{table}

Infine per effettuare trasferimenti di file è disponibile come alternativa a
\texttt{scp} anche una interfaccia che riproduce quella del protocollo FTP,
utilizzabile attraverso il comando \texttt{sftp}. Nell'uso più comune questo
comando prende come argomento l'indirizzo di una macchina remota a cui
collegarsi e crea una sessione di lavoro da cui si possono inviare i comandi
di tab.~\ref{tab:net_FTP_commands}, con sintassi del tutto analoga a quella di
un client FTP, per cui sono disponibili operazioni più complesse del semplice
trasferimento di un file (ad esempio ottenere una lista dei file presenti in
remoto). Resta comunque possibile trasferire i file in maniera immediata
usando la sintassi di \texttt{scp}. Inoltre si può specificare con l'opzione
\texttt{-b} un \textit{batch file} da cui prendere i comandi per una
esecuzione non interattiva.

Un primo vantaggio di \texttt{sftp} è che tutto quello che occorre sul lato
server è una installazione di \texttt{sshd} che abbia abilitato il supporto
relativo (questo viene fatto di default in tutte le installazioni standard) e
non è necessario installare un demone a parte.  Inoltre tutti i vantaggi di
SSH restano a disposizione, dalla cifratura dei dati alla possibilità di avere
metodi di autenticazione avanzata come quello che vedremo in
sez.~\ref{sec:net_ssh_key}.

Se a questo si aggiunge il fatto che questa interfaccia è stata standardizzata
con il nome di SFTP, ed è disponibile come estensione per molti client FTP e
programmi che girano anche sotto Windows come Filezilla e WinSCP, si può
tranquillamente affermare che al giorno d'oggi non esistono più ragioni valide
per installare un server FTP.

\subsection{La autenticazione a chiavi}
\label{sec:net_ssh_key}

Una delle caratteristiche più importanti di SSH è quella di avere, rispetto
alla classica autenticazione con username e password, la possibilità di
utilizzare diverse modalità di autenticazione e fra queste la più interessante
è quella basata sulle chiavi crittografiche.  Questa modalità di
autenticazione permette, caso quasi unico nel suo genere, di aumentare la
sicurezza ottenendo anche una maggiore facilità d'uso, ad esempio diventa
possibile avere delle sessioni di lavoro in cui una volta effettuato un
accesso iniziale non è più necessario ripetere l'immissione di una password di
autenticazione tutte le volte che si utilizza uno dei comandi \texttt{ssh} o
\texttt{scp}.

Questa modalità di autenticazione si basa sulla crittografia a chiave
asimmetrica alla base del protocollo, sfruttando l'uso di una coppia di chiavi
personali dell'utente. Una delle caratteristiche della crittografia a chiave
asimmetrica infatti è che è possibile effettuare il riconoscimento univoco di
un utente, una volta che questo dimostri di essere in possesso della chiave
privata associata alla chiave pubblica che il server utilizza per
identificarlo (di nuovo per una trattazione più dettagliata dei concetti
relativi alla crittografia a chiave asimmetrica si rimanda la sezione 1.2 di
\cite{SGL}).

Nel caso di autenticazione a chiave, invece di mandare la password dell'utente
sul canale cifrato per farla verificare, viene usata una procedura di
\textit{challenge and response}: il server invia al client un segreto (la
\textsl{sfida}) cifrato con la chiave pubblica dell'utente a cui si vuole
garantire l'accesso, solo il reinvio del segreto decifrato (la
\textsl{risposta}) è garanzia che il client conosce la chiave privata, ed è
questo che garantisce l'identità dell'utente.

Questa modalità di autenticazione è molto più sicura di quella basata su
username e password perché anche se il server venisse compromesso non
riceverebbe comunque le credenziali personali di un utente: nel primo caso
otterrebbe la password, qui invece la chiave privata resta sempre sul
client. Inoltre in questo modo si possono rendere del tutto inutili gli
attacchi a dizionario (di cui abbiamo già parlato in
sez.~\ref{sec:cfg_user_db}) anche nel caso in cui un utente avesse scelto una
password debole, dato che l'uso delle password può essere completamente
escluso.

Per poter utilizzare questa modalità di autenticazione occorre anzitutto
generare una coppia di chiavi; il pacchetto \textit{OpenSSH} mette a
disposizione un apposito programma per la creazione e la gestione delle
chiavi,\index{comando!\texttt{ssh-keygen}} \texttt{ssh-keygen}.  Se invocato
senza nessuna opzione \texttt{ssh-keygen} predispone la creazione di una
chiave RSA, chiedendo su quale file salvarla e proponendo il default di
\texttt{id\_rsa} nella solita directory \texttt{.ssh} nella home
dell'utente. Viene poi richiesta una \textit{passphrase}, da indicare due
volte, che serve a proteggere l'accesso alla chiave privata, che non può
essere utilizzata senza di essa.

Si può indicare un diverso formato per la chiave con l'opzione \texttt{-t}
seguita da un parametro che indica il tipo di chiave i cui possibili valori
sono tre: \texttt{rsa} per chiavi RSA di default, \texttt{dsa} per chiavi DSA
e \texttt{ecdsa} per le chiavi ECDSA.\footnote{in realtà è possibile usare
  anche \texttt{rsa1} per ottenere il formato di chiavi RSA usato nella
  vecchia versione protocollo, ma queste sono comunque da evitare per
  l'insicurezza dello stesso.} Le chiavi private vengono salvate, a meno di
non indicare in fase di creazione un file diverso, sempre sotto \texttt{.ssh}
nella home dell'utente rispettivamente nei file \texttt{id\_rsa},
\texttt{id\_dsa} e \texttt{id\_ecdsa}, le corrispondenti chiavi pubbliche sono
salvate sempre su un file con lo stesso nome della chiave privata esteso con
un \texttt{.pub}.  Si può inoltre specificare il nome direttamente sulla riga
di comando, usandolo come parametro per l'opzione \texttt{-f}.

Una volta completato il processo di generazione, che con macchine lente e per
chiavi di grandi dimensioni può essere anche molto lungo, il comando salva la
chiave privata cifrata con la \textit{passphrase} fornita.  Se si vuole
cambiare la \textit{passphrase} in un secondo tempo si può chiamare il comando
con l'opzione \texttt{-p}: verrà richiesta la vecchia \textit{passphrase} per
accedere alla chiave privata, e poi la nuova, che andrà ripetuta due volte per
conferma. Alle chiavi è pure associato un commento, che non ha nessun uso nel
protocollo, ma serve da identificativo della chiave; esso viene di solito
inizializzato alla stringa \texttt{utente@hostname} e può essere cambiato con
l'opzione \texttt{-c}.

Infine con l'opzione \texttt{-l} si può stampare l'\textsl{impronta digitale}
(la cosiddetta \textit{fingerprint}) della chiave a scopo di verifica, mentre
l'opzione \texttt{-b} permette di specificare la lunghezza della chiave in
bit. Il valore di default, 1024, è in genere adeguato, lunghezze maggiori
aumentano la sicurezza, ma richiedono molto più tempo per la generazione e
l'uso. I dettagli sul funzionamento del comando e le restanti opzioni sono
accessibili nella pagina di manuale con \texttt{man ssh-keygen}.

Una volta creata la coppia di chiavi diventa possibile utilizzarla per
l'autenticazione. Il meccanismo prevede che quando un utente invoca
\texttt{ssh}, se c'è una chiave nella directory \texttt{.ssh} (nella home
dell'utente che effettua il collegamento, quindi dalla parte del client) la
parte pubblica venga inviata al server. Quando \texttt{sshd} riceve una
richiesta di connessione in questa modalità va a verificare la presenza del
file \texttt{.ssh/authorized\_keys} nella home dell'utente per conto del quale
si vuole accedere (cioè dalla parte del server, dove l'utente può essere anche
completamente diverso) e se in esso è presente la chiave pubblica ricevuta
viene eseguita la procedura di \textit{challenge and response} illustrata in
precedenza; a questo punto \texttt{ssh} richiederà la \textit{passphrase} per
sbloccare la chiave privata e rispondere alla sfida.

Per quanto appena detto quello che si deve fare per abilitare l'accesso con
l'autenticazione a chiavi è inserire sulla macchina remota la chiave pubblica
della persona a cui si vuole dare l'accesso. Questa deve essere aggiunta al
file \texttt{authorized\_keys} nella directory \texttt{.ssh} dell'utente per
conto del quale si vuole dare accesso. Se si è trasferita la chiave pubblica
sul server basterà un comando del tipo:
\begin{Example}
cat id_dsa.pub >> .ssh/authorized_keys
\end{Example}
dove nel caso \texttt{id\_dsa.pub} è la chiave pubblica dell'utente che deve
poter accedere.

Si noti l'uso della redirezione in \textit{append}, il file
\texttt{authorized\_keys} infatti può contenere più chiavi pubbliche, le
chiavi infatti sono mantenute una per riga in formato codificato ASCII, per
cui le singole righe del file sono di norma molto lunghe. Se si fosse
semplicemente sovrascritto il file si sarebbero cancellate quelle di eventuali
altri utenti.

Si noti anche che non è necessario che chi accede con l'autenticazione a
chiavi conosca la password dell'utente sulla macchina remota, basta che la sua
chiave sia fra quelle autorizzate. In questo modo diventa possibile dare
accesso anche a più persone senza che queste debbano condividere la conoscenza
di una unica password, cosa che ne aumenterebbe il rischio di scoperta o
perdita.  In questo caso infatti l'autenticazione viene fatta solo sulla base
della corrispondenza fra una chiave pubblica ed una chiave privata e tutto
quello che serve è la presenza della coppia di chiavi. Ancora una volta si è
ottenuta maggior sicurezza ed una semplificazione nell'uso non essendo più
necessario ricordarsi una password diversa per ciascun server a cui ci si deve
collegare, ma solo quella della propria chiave.

Dato che il procedimento manuale di inserimento della chiave può essere
macchinoso (richiede la copia del file della chiave pubblica, e poi il
collegamento sulla macchina per inserirla) con il pacchetto di SSH viene
fornito un apposito comando, \index{comando!\texttt{ssh-copy-id}}
\texttt{ssh-copy-id}, che permette di automatizzare l'operazione aggiungendo
la chiave pubblica dell'utente che lo invoca all'\texttt{authorized\_keys} di
una macchina di destinazione. Un esempio di uso del comando è il seguente:
\begin{Example}
ssh-copy-id piccardi@oppish.truelite.it
\end{Example}
dato il quale si dovrà immettere la password dell'utente remoto.

Le vecchie versioni del comando richiedono l'uso esplicito dell'opzione
\texttt{-i} per indicare quale è il file della chiave da usare, si tenga conto
che in questo caso va indicato il file della chiave privata (a trovare quello
della chiave pubblica ci pensa il comando). Nelle versioni recenti, se si sta
utilizzando l'agente di autenticazione \texttt{ssh-agent} (che tratteremo a
breve), la chiave viene presa direttamente da lui.

Ovviamente quando si usa questo metodo di autenticazione la protezione della
propria chiave privata è fondamentale, chiunque ne venga in possesso e possa
utilizzarla ottiene immediatamente tutti gli accessi a cui essa è abilitata, e
questo è il motivo per cui essa viene protetta con una
\textit{passphrase}\footnote{la \textit{passphrase} viene a sostituire il
  ruolo della password, ed è bene sceglierla con molta cura, in quanto è
  l'unica protezione contro l'abuso della nostra chiave privata; per questo
  motivo si parla di \textit{passphrase} e non di password; è quindi il caso
  di usare una frase lunga e complicata, e non una singola parola.} che deve
essere fornita tutte le volte che la si deve usare. Essa comunque deve essere
protetta sia da lettura che da scrittura da parte di estranei.  Questo è
imposto dal comando \texttt{ssh} stesso, che si rifiuta di usare, stampando un
clamoroso avvertimento, una chiave privata che sia leggibile da altri oltre al
proprietario.

A questo punto però ci si potrebbe chiedere l'utilità di tutto questo
armamentario, dato che invece di una password per il login bisogna comunque
inserire una \textit{passphrase} per sbloccare la chiave privata, che si
richiede tra l'altro essere lunga e difficile. L'utilità sta nel fatto che è
possibile usare un altro programma, l'agente di autenticazione
\index{demone!\texttt{ssh-agent}} \texttt{ssh-agent}, che permette di
sbloccare la chiave una sola volta, all'inizio di una sessione di lavoro, e
poi mantiene la chiave privata sbloccata in memoria, permettendone il
successivo riutilizzo senza che sia necessario fornire di nuovo la
\textit{passphrase}.

L'idea è che \texttt{ssh-agent} venga lanciato all'inizio di una sessione di
lavoro, in modo che tutti i comandi lanciati successivamente possano farvi
riferimento, interrogandolo tutte le volte che è necessario compiere una
operazione con la propria chiave privata. Il programma svolge il ruolo di
intermediario, per questo si parla di agente: infatti è sempre
\texttt{ssh-agent} ad eseguire le operazioni di autenticazione, fornendo ai
richiedenti i risultati ottenuti, in modo da non dover mai comunicare verso
l'esterno la chiave privata.

Di norma \texttt{ssh-agent} viene lanciato automaticamente all'avvio delle
sessioni grafiche, mentre lo si deve lanciare esplicitamente nel caso di
collegamento da terminale.  Si tenga presente che all'avvio l'agente non
dispone di nessuna chiave privata e perché possa funzionare occorre
consegnargli la propria chiave. Questo viene fatto con il comando
\index{comando!\texttt{ssh-add}} \texttt{ssh-add},\footnote{in caso di
  sessioni grafiche esistono vari programmi alternativi, come
  \texttt{ssh-askpass}, che possono essere utilizzati per eseguire lo stesso
  compito.} che chiederà la \textit{passphrase} della chiave privata, la
sbloccherà, e la invierà all'agente, che da quel momento in poi potrà
utilizzarla.  Sempre con \texttt{ssh-add} si potrà rimuovere la propria chiave
dall'agente con l'opzione \texttt{-d}, o richiedere la rimozione di tutte le
chiavi presenti con \texttt{-D}. Il comando consente inoltre di verificare le
chiavi in possesso dell'agente con l'opzione \texttt{-l} (per le altre opzioni
si consulti la pagina di manuale).

Per poter comunicare con l'agente i vari programmi che ne hanno bisogno usano
la variabile di ambiente
\index{variabili!di~ambiente!\texttt{SSH\_AUTH\_SOCK}}
\texttt{SSH\_AUTH\_SOCK} che identifica il socket locale su cui esso è in
ascolto.  Se non è definita anche se il programma è attivo l'autenticazione a
chiavi non funzionerà, e si passerà direttamente all'autenticazione
normale. La variabile viene definita dallo stesso \texttt{ssh-agent} quando
viene lanciato, che la scrive anche sullo \textit{standard output}. Si ricordi però che
le variabili di ambiente definite da un processo vengono viste soltanto nei
processi figli, pertanto quando si lancia \texttt{ssh-agent} in
\textit{console}, questo resterà attivo in background, ma fintanto che non si
inserisce manualmente la variabile \texttt{SSH\_AUTH\_SOCK} nel proprio
ambiente, non potrà essere utilizzato.

Una funzionalità ancora più interessante dell'uso di \texttt{ssh-agent} è che
\texttt{ssh} supporta anche il reinoltro della connessione che ha verso di
lui. Se il server \texttt{sshd} a cui ci si collega consente di usare questa
funzionalità (il default è di farlo) una volta che ci si è collegati ad esso
la variabile \texttt{SSH\_AUTH\_SOCK} viene automaticamente definita, ed
\texttt{sshd} reinvierà all'indietro le richieste di autenticazione fatte sul
server remoto. Il risultato è che si potrà usare \texttt{ssh} con
l'autenticazione a chiavi anche sul server remoto, usando le chiavi che si
stanno gestendo con il proprio agente di autenticazione locale senza che
queste abbandonino la propria macchina.

Per utilizzare questa funzionalità occorre usare l'opzione \texttt{-A} (o
inserire nel proprio \texttt{.ssh/config} la direttiva \texttt{ForwardAgent
  yes}). Il risultato è la capacità di usare \texttt{ssh} in maniera sicura
con l'autenticazione a chiavi senza dover reimmettere le password non soltanto
quando lo si esegue sulla propria macchina, ma anche quando lo si esegue sulle
macchine su cui ci si è collegati a partire dalla propria (il salto però
funziona una sola volta).

Questa funzionalità non viene abilitata di default perché espone al rischio
che l'amministratore del server remoto possa utilizzare la connessione
reinoltrata per sfruttare l'agente e, fintanto che si resta collegati,
autenticarsi verso tutte le altre macchine per cui la propria chiave è
abilitata. Ovviamente questo è un rischio significativo, si tenga presente
però che se non ci si può fidare dell'amministratore di un server remoto,
usarlo per connessioni verso altre macchine non è comunque una buona idea in
generale visto che qualunque cosa facciamo può essere intercettata, comprese
le password inserite in una normale chiamata a \texttt{ssh}. In questo caso
l'unica soluzione sicura è di non collegarsi mai ad una macchina remota
attraverso un'altra.


\subsection{Le funzionalità di reinoltro del traffico}
\label{sec:ssh_forwarding}

Una delle caratteristiche più interessanti di SSH, già abbondantemente citata,
è la capacità di utilizzare la presenza di un canale cifrato per mettere a
disposizione delle funzionalità di comunicazione che vanno ben al di là della
semplice realizzazione di una sessione di lavoro remota.

La prima di queste funzionalità è quella dell'inoltro delle sessioni \textit{X
  Window}, che consente di eseguire da remoto anche applicazioni con
interfaccia grafica. La trasparenza sulla rete del protocollo di \textit{X
  Window} già consentiva questo anche con una sessione fatta con
\texttt{telnet}. Come spiegato in sez.~\ref{sec:X_client} infatti basta
definire sulla macchina remota la variabile d'ambiente \texttt{DISPLAY} con
l'indirizzo IP della macchina su cui si vogliono ricevere le finestre, ed
abilitare su di essa l'accesso al server X via rete con il comando
\texttt{xhost}, per avere anche la trasmissione remota delle finestre.

Il problema resta quello che \textit{X Window} non prevede nessuna cifratura
dei dati, per cui una volta che si sia consentito un accesso da remoto al
server X gli si potrà far fare di tutto, ed ovviamente questo è un grosso
problema per la sicurezza. Ad esempio è relativamente semplice (ed è stato
fatto) scrivere un programma che crea una finestra trasparente a tutto schermo
messa in primo piano il cui solo scopo è quello di intercettare tutti i tasti
premuti, ottenendo così un perfetto \textit{keylogger} in grado di leggere
tutte le password che vengono immesse, anche al di fuori della sessione X
remota.

Con SSH invece si può ottenere l'inoltro della sessione X in maniera sicura,
facendo transitare tutto il traffico sul canale cifrato, e senza la necessità
di consentire l'accesso da remoto al server X, cosa che tra l'altro sulle
distribuzioni più attente alle questioni di sicurezza, è disabilitata di
default, per cui anche volendo non sarebbe possibile farlo, a meno di non
cambiare la configurazione del server X e riavviarlo.

Dal lato server si può attivare l'inoltro della sessione X11 attraverso l'uso
delle direttive \texttt{X11Forwarding} e \texttt{X11DisplayOffset} di
\texttt{sshd\_config}.  La prima direttiva abilita l'inoltro della sessione
X11; di default questo è disabilitato (anche se molte distribuzioni installano
un \texttt{sshd\_config} che lo riabilita), in quanto si tratta di una
funzionalità aggiuntiva che è il caso di usare solo se necessario: se ad
esempio la macchina remota è un server sul quale non devono girare programmi
con interfaccia grafica è assolutamente inutile (e quindi dannoso dal punto di
vista della sicurezza) attivare questa funzionalità. 

Nell'esempio di configurazione mostrato in precedenza si è attivata
esplicitamente questa opzione.  La seconda direttiva,
\texttt{X11DisplayOffset}, consente di impostare il valore minimo del
\textit{display} (si ricordi quanto detto in sez.~\ref{sec:cfg_xserver_start})
usato come destinazione per la sessione X11. Questo in genere viene impostato
al valore di 10, così da non creare conflitti con altri \textit{display}
eventualmente presenti in locale.

Quando si eseguono queste impostazioni quello che accade è che per ogni
sessione SSH sulla macchina remota viene automaticamente definita la variabile
\texttt{DISPLAY} al valore \texttt{localhost:\textsl{NN}} (con
\texttt{\textsl{NN}} a partire da 10), così che le applicazioni lanciate nella
sessione inviino i dati del protocollo X11 su un socket\footnote{viene usato
  un socket messo in ascolto su \texttt{localhost} sulla porta
  \texttt{6000+\textsl{NN}} dato che le porte standard usate dalle sessioni di
  rete del protocollo X11 sono date da 6000 più il numero di display.} su cui
si pone in ascolto \texttt{sshd}.  A questo punto il server trasferirà questi
dati attraverso il canale cifrato al client, e quest'ultimo si incaricherà di
inviarli al server X locale che disegnerà le finestre dell'applicazione
remota.

Un'altra funzionalità avanzata messa a disposizione da \texttt{ssh} è quella
del cosiddetto \textsl{reinoltro delle porte} (il \textit{port forwarding}),
che consente di far passare sul canale cifrato delle connessioni TCP
generiche. Questa modalità può essere utilizzata in due modi, ma il più comune
è quello in cui si inoltra tutto il traffico diretto ad una porta locale verso
una qualunque porta posta su una qualunque macchina raggiungibile dalla
macchina remota a cui ci si collega con SSH.

Questa prima modalità, in cui si inoltra il traffico a partire dalla macchina
locale, viene attivata lanciando il comando \texttt{ssh} con l'opzione
\texttt{-L} a cui deve seguire una terna indicante rispettivamente la porta
locale su cui porsi in ascolto,\footnote{in questa forma la porta locale sarà
  messa in ascolto soltanto su \textit{localhost}, se si vuole utilizzare un
  altro indirizzo locale, lo si può specificare aggiungendolo prima della
  porta locale, seguito dal carattere di separazione ``\texttt{:}'' e dagli
  altri tre valori, ma questa forma è poco utilizzata.}  l'indirizzo IP della
macchina remota e la porta remota cui verrà inoltrato il traffico ricevuto
sulla porta locale.  Queste informazioni devono essere separate dal carattere
``\texttt{:}'' e si possono usare sia valori numerici che simbolici; un
esempio di utilizzo di questa opzione è il seguente:
\begin{Example}
ssh -L 1631:localhost:631 piccardi@davis.truelite.it
\end{Example}

Nell'esempio si è collegato il traffico diretto verso la porta 1631 del
\textit{localhost} della macchina locale alla porta 631 del \textit{localhost}
della macchina remota (il \texttt{localhost} del comando è risolto sulla
macchina remota).  Questo consentirà di accedere sulla macchina locale
all'interfaccia di configurazione di CUPS della macchina remota, nonostante
questa sia posta in ascolto soltanto sul \textit{localhost} di quest'ultima.
Dato questo comando basterà puntare un browser sulla macchina locale alla
porta 1631 del proprio \textit{localhost} per ottenere la connessione alle
pagine di CUPS della macchina remota.  Si noti inoltre che come si è raggiunto
\texttt{localhost}, si potrà anche raggiungere qualunque altro indirizzo
visibile dalla macchina remota, ad esempio tutti quelli di una rete privata su
cui essa si affacci.

La seconda modalità del \textit{port forwarding} è quella in cui si inoltra il
traffico a partire dalla macchina remota, che si attiva con l'opzione
\texttt{-R}. In questo caso si può inoltrare tutto il traffico diretto ad una
porta della macchina remota verso una porta di una macchina raggiungibile
dalla macchina locale. Come prima all'opzione deve seguire una terna analoga
in cui si indicano nell'ordine: la porta su cui porsi in ascolto sulla
macchina remota, l'indirizzo IP e la porta della macchina raggiungibile
localmente a cui inoltrare il traffico inviato alla porta remota. Un esempio
di questa modalità potrebbe essere il seguente:
\begin{Example}
ssh -R 20022:localhost:22 servizio@holland.truelite.it
\end{Example}

In questo caso si consente a chi lavora sulla macchina remota
\texttt{holland.truelite.it} di accedere in SSH, collegandosi localmente alla
porta 20022, alla macchina da cui è stato lanciato questo comando.  Diventa
cioè possibile in generale consentire una connessione partente dalla macchina
a cui ci si collega verso le macchine che stanno nella rete della macchina da
cui si lancia il comando, anche se queste sono su una rete privata e non sono
direttamente raggiungibili da Internet. Si tratta di una funzionalità che
risulta molto comoda quando si devono raggiungere macchine dietro un firewall
che possono soltanto uscire su Internet.

Si tenga presente che in entrambe le modalità quando ci si vuole mettere in
ascolto su una porta privilegiata, occorre rispettivamente che l'utente che
esegue il comando (nel caso di \texttt{-L}) o quello per conto del quale ci si
collega (nel caso di \texttt{-R}) abbia i privilegi di amministratore,
altrimenti la connessione SSH riuscirà ma senza il reinoltro del traffico.


\section{La condivisione dei file sulla rete}
\label{sec:net_file_sharing}

Tratteremo in questa sezione i protocolli per la condivisione dei file via
rete, concentrandoci in particolare sul protocollo più usato nei sistemi
unix-like, cioè NFS. Tratteremo comunque, anche se in maniera estremamente
superficiale, anche la condivisione dei file con i protocolli utilizzati in
ambiente Windows attraverso l'utilizzo di Samba.


\subsection{Il protocollo ed il server NFS}
\label{sec:net_NFS_server}

Il protocollo NFS, sigla che sta a significare \textit{Network File System}, è
stato creato da Sun per permettere di montare il contenuto di dischi che
stanno su stazioni remote come se fossero presenti sulla macchina locale. In
questo modo si può assicurare un accesso trasparente ai file, e si può
utilizzare un filesystem anche su una macchina senza dischi,\footnote{in
  questo caso la configurazione è più complessa, in quanto occorre abilitare
  il kernel stesso a montare la directory radice su NFS.} passando solo
attraverso la rete.

In genere tutte le distribuzioni prevedono i pacchetti per l'installazione di
un server NFS. La sola scelta che si può dover fare è fra l'uso del supporto
del protocollo direttamente a livello del kernel o l'uso di una
implementazione realizzata completamente in user-space.  Date le peggiori
prestazioni, quest'ultima soluzione in genere viene evitata, e per questo in
genere si deve utilizzare un kernel per cui sia stato abilitato il supporto
per NFS, cosa che accade per i kernel standard installati da qualunque
distribuzione.\footnote{le opzioni necessarie in caso di compilazione in
  proprio sono accessibili con \texttt{make menuconfig} sotto la voce
  \texttt{File system}, nella sotto voce \texttt{Network File System}.}

% ; qualora si ricompili un kernel da soli
% (si ricordi quanto illustrato in sez.~\ref{sec:kernel_compile}) occorrerà
% invece verificare che siano abilitate in \texttt{.config} le seguenti opzioni:
% \begin{Verbatim}
% CONFIG_NFS_FS=m
% CONFIG_NFS_V3=y
% CONFIG_NFSD=m
% CONFIG_NFSD_V3=y
% \end{Verbatim}
% queste opzioni sono accessibili con \texttt{make menuconfig} sotto la voce
% \texttt{File system}, nella sotto voce \texttt{Network File System}.

Il protocollo NFS è piuttosto complesso, nasce come protocollo
\textit{stateless} in cui ogni richiesta e successiva risposta è indipendente
dalle altre e non esiste nessuna sessione stabilita fra client e server. Il
protocollo usava inizialmente soltanto pacchetti UDP (che si adattano bene al
modello di richiesta/risposta indipendenti) ed è basato sul sistema delle RPC
di cui abbiamo fatto una panoramica in sez.~\ref{sec:net_rpc_services}. Questo
significa che al funzionamento di NFS, oltre a \texttt{portmap}, concorrono
ben altri cinque demoni:
\begin{basedescript}{\desclabelwidth{2.2cm}}
\item[\texttt{rpc.nfsd}] è il demone che svolge la gran parte del lavoro,
  realizzando le funzioni di accesso al contenuto dei file. Deve essere
  lanciato dopo che è stato attivato \texttt{portmap}.
\item[\texttt{rpc.statd}] è il demone che gestisce le caratteristiche dei file
  come tempi di accesso, permessi, ecc. Deve essere lanciato dopo che è stato
  attivato \texttt{portmap}.
\item[\texttt{rpc.lockd}] è il demone che gestisce, quando questo è abilitato,
  il \textit{file locking}.\footnote{il \textit{file locking} è la capacità di
    bloccare ad altri processi l'accesso ad un file, per una descrizione
    dettagliata si veda il capitolo 11 di \cite{GaPiL}.}  Di norma viene
  lanciato da \texttt{rpc.nfsd} in caso di necessità.
\item[\texttt{rpc.mountd}] è il demone che gestisce le richieste di montaggio
  del filesystem. Deve essere lanciato dopo che sono stati attivati
  \texttt{rpc.nfsd} e \texttt{rpc.statd}.
\item[\texttt{rpc.rquotad}] è il demone che permette, quando sono attivate, di
  gestire le quote sul filesystem di rete. Deve essere lanciato dopo che sono
  stati attivati \texttt{rpc.nfsd} e \texttt{rpc.statd}.
\end{basedescript}

Del protocollo esistono diverse versioni, conseguenza dell'evoluzione subita
nel tempo. La prima versione utilizzata è stata NFSv2 in quanto NFSv1 non è
sostanzialmente mai uscita dai laboratori della SUN, questa presenta numerose
limitazioni (fra cui una dimensione massima di 2Gb per i file) che sono state
superate con NFSv3. Con la versione 4 sono state introdotte funzionalità di
autenticazione forte, ed il protocollo è diventato \textit{stateful} e
richiede l'uso di TCP, ma sono state introdotte anche varie differenze nella
configurazione, pertanto il passagggio a questa nuova versione non è
indolore.

% TODO trattare meglio nfs4, in particolare la necessità di ridefinire gli
% export a partire da una unica directory radice e l'uso dei bind mount.

Benché complicato da descrivere dal punto di vista funzionale fino alla
versione 3 un server NFS è in genere molto semplice da configurare. Infatti di
norma il servizio viene avviato automaticamente dagli script di avvio
installati dai pacchetti, e tutto quello che c'è da configurare è il file
\index{configurazione!\texttt{/etc/exports}} \texttt{/etc/exports} che
definisce su ciascuna macchina quali sono le directory da \textsl{esportare}
verso l'esterno e quali sono le altre macchine che hanno la facoltà di
utilizzarle; un esempio di questo file è il seguente:
\begin{FileExample}[label=/etc/exports]
# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
/home/piccardi/share   192.168.1.0/255.255.255.0(rw)
\end{FileExample}

Il file prevede una serie di campi separati da spazi o tabulazioni; il primo
campo specifica la directory sul server che verrà condivisa, i campi
successivi definiscono chi e come può utilizzarla e si può specificare sia una
singola stazione che una rete. Qualora si indichi una rete occorre
specificarne il numero di bit (in notazione CIDR) o la maschera (in notazione
\textit{dotted decimal}) dopo il carattere ``\texttt{/}''.  Bisogna però stare
attenti perché non tutti i server supportano l'uso della notazione CIDR. Si
possono usare anche indirizzi simbolici, che devono poter essere risolti, nel
qual caso si possono usare i caratteri \textit{wildcard} ``\texttt{*}'' e
``\texttt{?}'' per esprimere i nomi.

Per ciascuna riga di \texttt{exports} si possono indicare più macchine o reti
separandoli con degli spazi, per ciascuna macchina e rete poi si potranno
specificare delle modalità di accesso e delle opzioni di funzionamento del
protocollo indicandole fra parentesi tonde. Si faccia attenzione a non
specificare le opzioni inserendo uno spazio fra il nome della macchina e le
parentesi che le delimitano (è un errore comune); in tal caso infatti le
opzioni verrebbero prese come l'indirizzo di una nuova macchina, con effetti
fra l'imprevedibile ed il rischioso.  Se si usano più opzioni queste devono
essere separate da virgole; il formato generico di una riga del file
\texttt{exports} sarà pertanto qualcosa del tipo:
\begin{Example}
/path/to/directory net1/mask1(option11,option12) machine2(option21,option22)
\end{Example}

Le opzioni sono suddivise in due gruppi: quelle generali, relative al
funzionamento del server e quelle di mappatura degli utenti. Le opzioni
principali riguardanti il comportamento del server sono quelle che permettono
di impostare le modalità di accesso ai file: \texttt{rw} e \texttt{ro}, che
indicano rispettivamente lettura/scrittura e sola lettura, e quelle che ne
governano la risposta in reazione a richieste di scrittura, come \texttt{sync}
che richiede che la scrittura dei dati su disco sia completata prima di
concludere una risposta, ed \texttt{async} che permette una risposta immediata
con una scrittura dei dati asincrona. Questa opzione è disabilitata di
default, in quanto in caso di crash del server le modifiche andrebbero perse;
il comando \texttt{exportfs} notifica se nessuna di queste due opzioni è stata
impostata, avvisando che sarà usata \texttt{sync} di default.  Le principali
opzioni ed il relativo significato sono riportati in
tab.~\ref{tab:net_exports_options}, l'elenco completo delle opzioni è
riportato nella pagina di manuale accessibile con \texttt{man exports}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
     \texttt{all\_squash} & mappa tutti gli UID e i GID.\\
     \texttt{anongid}     & imposta il GID usato per l'accesso anonimo.\\
     \texttt{anonuid}     & imposta l'UID usato per l'accesso anonimo.\\
     \texttt{async}       & abilita la scrittura asincrona sul server.\\
     \texttt{no\_root\_squash} & non rimappa l'UID ed il GID 0.\\
     \texttt{rw}          & accesso in lettura e scrittura.\\
     \texttt{ro}          & accesso in sola lettura.\\
     \texttt{root\_squash}& rimappa l'UID ed il GID 0.\\
     \texttt{sync}        & esegue le scritture in maniera sincrona.\\
%     \texttt{nohide} & mostra \\
    \hline
  \end{tabular}
  \caption{Possibili opzioni per le directory esportate tramite NFS nel file
    \texttt{/etc/exports}.}
  \label{tab:net_exports_options}
\end{table}

% TODO trattare nohide, crossmnt, fsid

Uno dei problemi principali che si deve affrontare quando si esporta una
directory con NFS è quello della titolarità dei file. Infatti il protocollo
associa i file agli utenti ed ai gruppi così come sono definiti sul server,
utilizzando i relativi UID e GID. Un utente sul client potrà avere accesso ai
\textsl{suoi} file condivisi solo se questi identificativi (questa volta come
definiti sul client) corrispondono; è necessario perciò tenere sincronizzati
UID e GID in modo che sia sui client che sul server essi corrispondano agli
stessi utenti e gruppi. Per fare questo si può ricorrere all'uso di LDAP per
la centralizzazione degli utenti (l'argomento è trattato in \cite{IS-LDAP}) o
utilizzare il servizio NIS.

In alcuni casi però occorrono delle eccezioni, ad esempio non è desiderabile
che l'amministratore di un client sia trattato come \textit{root} anche
nell'accesso ai file del server. Per questo motivo di default è attiva
l'opzione \texttt{root\_squash} che rimappa gli UID e GID 0 usati
dall'amministratore sul valore 65534 $(-2)$, corrispondente rispettivamente a
\texttt{nobody} e \texttt{nogroup}. 

Quello del controllo sull'accesso ai file in base al solo valore dell'UID è un
grosso problema di sicurezza di NFS; basta infatti collegarsi ad una rete con
un IP consentito per far essere in grado, una volta che ci si sia dati l'UID
corrispondente, di leggere i file di un qualunque utente; per questo motivo
dalla versione 4 del protocollo è possibile appoggiarsi ad un server Kerberos
per autenticare in maniera forte sia i client che gli utenti.

La presenza di una riga in \texttt{/etc/exports} non significa che la
directory ivi indicata sia resa disponibile automaticamente; per controllare i
filesystem che sono \textsl{esportati} è infatti necessario un apposito
comando \index{comando!\texttt{exportfs}} \texttt{exportfs}.  Di norma lo si
utilizza negli script di avvio per esportare tutti i filesystem elencati in
\texttt{/etc/exports} con \texttt{exportfs -a}. Qualora si modifichi
\texttt{/etc/exports} si può usare il comando \texttt{exportfs -r} per
sincronizzare la tabella dei filesystem esportati con i contenuti del file.
Infine con l'opzione \texttt{-u} si può rimuovere uno dei filesystem
esportati, mentre con \texttt{-o} si possono cambiare le opzioni. I dettagli
si trovano al solito nella pagina di manuale, accessibile con \texttt{man
  exportfs}.

Si tenga conto infine che i vari demoni che forniscono il servizio hanno il
supporto per i TCP wrapper, quindi onorano le restrizioni descritte in
sez.~\ref{sec:net_TCP_wrappers}. È buona norma, vista la delicatezza del
servizio fornito (che permette di accedere ai file degli utenti nelle
directory condivise), impostare sempre una politica di accesso negato di
default per tutti i demoni, per abilitare in \texttt{/etc/hosts.allow} gli
accessi alle stesse macchine riportate in \texttt{/etc/exports}.



\subsection{NFS sul lato client}
\label{sec:net_NFS_client}

Per poter utilizzare NFS sul lato client occorrerà avere il supporto nel
kernel, ed oltre a \texttt{portmap} dovranno essere attivi i due demoni
\texttt{rpc.statd} e \texttt{rpc.lockd}. Inoltre si deve avere una versione
sufficientemente recente del comando \texttt{mount} che sia in grado di
montare un filesystem NFS, ma al giorno d'oggi qualunque versione lo è.

Come per il lato server di norma l'utilizzo è molto semplice e si esaurisce
nel montare il filesystem remoto sulla directory prescelta, in quanto con
l'installazione dei relativi pacchetti tutte le distribuzioni si curano che
siano avviati tutti i servizi necessari.

Montare un filesystem NFS è comunque estremamente semplice, invece di indicare
un dispositivo basterà indicare l'indirizzo (simbolico o numerico) del server
seguito da ``\texttt{:}'' e dalla directory che si vuole montare, che dovrà
essere presente e accessibile nel file \texttt{/etc/exports} del server. Se si
vuole eseguire il comando a mano basterà eseguire \texttt{mount} con una
sintassi del tipo:
\begin{Example}
mount -t nfs indirizzoserver:/directory/esportata /mount/point
\end{Example}
e si può poi definire un \textit{mount point} permanente in
\texttt{/etc/fstab} aggiungendo una riga del tipo:
\begin{Example}
indirizzoserver:/directory/esportata /mount/point nfs user,exec,noauto 0 0
\end{Example}
dove la differenza con un filesystem su disco è l'uso di \texttt{nfs} come
\textit{filesystem type} e l'indirizzo della directory da montare al posto del
file di dispositivo. 

Nell'esempio si sono usate soltanto delle opzioni di montaggio generiche ma in
realtà NFS supporta una serie di opzioni specifiche che ne controllano il
funzionamento. Buona parte delle opzioni di NFS devono essere specificate
nella forma \texttt{opzione=valore}, fanno eccezione le opzioni che prendono
valori logici, che si specificano direttamente per attivarle, o con il
prefisso \texttt{no} per disattivarle.

Due opzioni, \texttt{hard} e \texttt{soft} controllano il comportamento del
client in assenza di connessione al server o di crollo di quest'ultimo; in
questo caso infatti si pone il problema di cosa fare per i processi che stanno
usando o cerchino di usare i file condivisi su una directory che è stata
montata via NFS.

Quello che succede normalmente è che in questo caso il processo viene posto in
stato \texttt{D} (\textit{uninterruptible sleep}, vedi
tab.~\ref{tab:proc_proc_states}) ed il client continua ad interrogare il
server fino a quando questo non ritorna disponibile e l'esecuzione riprende
(dal punto di vista del processo) come se niente fosse accaduto. Si tenga
presente che essendo in stato \texttt{D} non sarà possibile terminare i
processi rimasti bloccati; se si vuole poter uccidere i processi con
\texttt{kill} occorrerà usare l'opzione \texttt{intr}.

Con una directory montata con il valore di default, \texttt{hard}, il client
prosegue nel tentativo di riconnessione al server senza limiti di tempo ed i
processi restano bloccati indefinitamente, se invece si è usato \texttt{soft}
dopo un certo periodo di tempo di tentativi di riconnessione falliti, verrà
notificato al processo che ha eseguito l'accesso un errore di I/O su
disco. Questo intervallo di tempo, che viene detto un \textit{major timeout},
dipende dalle altre impostazioni di NFS, ed in particolare dalle opzioni di
montaggio \texttt{timeo} e \texttt{retrans}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
     \texttt{hard}  & in caso di crollo del server continua indefinitamente i
                      tentativi di riconnessione.\\
     \texttt{intr}  & permette di inviare segnali ai processi bloccati per un
                      crollo del server, con i kernel più recenti (posteriori
                      al 2.6.35) questa opzione viene ignorata ed occorre
                      usare semplicemente il segnale \texttt{SIGKILL}.\\
     \texttt{nolock}& disabilita il \textit{file locking} su NFS; viene usato
                      per compatibilità con alcuni vecchi server che non lo
                      supportano e non è utilizzabile con NFS4.\\ 
     \texttt{retrans}&il numero di tentativi di ritrasmissione che vengono
                      effettuati prima di generare un avviso, il default è tre
                      volte, e se si è usato \texttt{hard} il ciclo verrà
                      ripetuto indefinitamente, se si è usato \texttt{soft} il
                      client darà un errore definitivo.\\
     \texttt{rsize} & imposta le dimensioni del buffer di lettura, da indicare
                      in numero di byte, il default è 4096.\\
     \texttt{sec}    & specifica le modalità di autenticazione presso il
                       server, con \texttt{sys} (il default) vengono usati i
                       valori locali di UID e GID, con \texttt{krb5} viene
                       usato Kerberos per l'autenticazione.\\
     \texttt{soft}  & in caso di crollo del server i tentativi di
                      riconnessione vengono effettuati per un periodo limitato
                      di tempo e falliscono definitivamente dopo il numero di
                      tentativi fissato con \texttt{retrans}.\\
     \texttt{timeo} & il tempo (in decimi di secondo) atteso per una risposta
                      prima di effettuare la ritrasmissione di una richiesta,
                      è di 60 secondi per connessioni TCP e variabile a
                      seconda delle operazioni per UDP, viene aumentato ogni
                      volta che una ritrasmissione (raddoppiandolo) scade di
                      nuovo fino ad un massimo di 600 secondi per TCP e 60
                      secondi per UDP.\\
     \texttt{tcp}    & usa il protocollo TCP. \\
     \texttt{udp}    & usa il protocollo UDP (il default). \\
     \texttt{wsize} & identica a \texttt{rsize} ma per il buffer di
                      scrittura.\\
%     \texttt{} &  \\
    \hline    
  \end{tabular}
  \caption{Opzioni del comando \texttt{mount} specifiche per NFS.}
  \label{tab:net_NFS_mount}
\end{table}

Altre due opzioni importanti per le prestazioni sono \texttt{rsize} e
\texttt{wsize} che indicano le dimensioni (in byte) dei buffer di lettura e
scrittura. Il valore di default è di 4096 per entrambe, ma ovviamente più
ampio è il valore migliori saranno le prestazioni. Le altre opzioni principali
sono illustrate in tab.~\ref{tab:net_NFS_mount}. Per ulteriori dettagli e
l'elenco completo delle opzioni si può consultare la apposita pagina di
manuale, accessibile con \texttt{man nfs}.

Si ricordi infine, come accennato in sez.~\ref{sec:net_NFS_server}, che i
proprietari dei file sulle directory montate via NFS sono riconosciuti in base
ai valori di UID e GID definiti sul server. Pertanto se sul client l'utente
relativo non esiste o ha un UID diverso (cosa possibile, se non si sono creati
gli utenti nella stessa sequenza) la titolarità dei file non corrisponderà, e
si avranno problemi. 

Con la versione 4 di NFS è possibile appoggiarsi ad un server
Kerberos,\footnote{la trattazione di Kerberos va al di là dello scopo di
  questo testo, un buon libro sull'argomento è \cite{Kerberos}.} sia per
quanto riguarda l'identificazione e l'autenticazione di utenti e macchine, che
per la verifica e anche la cifratura del traffico NFS. Si tenga presente
infatti che di default il traffico dati di NFS non è né cifrato né
autenticato, ed è quindi poco sicuro; con NFS4 e Kerberos questi problemi
possono essere risolti, al prezzo di una maggiore complessità di
configurazione e prestazioni ovviamente inferiori.

% TODO trattare showmount, nfsstat



\subsection{La configurazione di base di Samba}
\label{sec:net_samba}

La suite Samba è un insieme di programmi che permette ad una macchina Unix di
utilizzare il protocollo CIFS (\textit{Common Internet File System}) usato dai
server Windows per la condivisione dei file. In realtà Samba permette di fare
molto di più, e può ad esempio sostituire un PDC (\textit{Primary Domain
  Controller}) Windows, ma qui noi ne tratteremo solo le caratteristiche di
base relative alla condivisione dei file.

Il nome Samba deriva dalla precedente denominazione di CIFS che veniva
chiamato in maniera non ufficiale SMB (\textit{Service Message Block}), e
l'autore originale racconta di aver scelto il nome eseguendo il comando
\texttt{grep s.m.b.}  sul file del dizionario. Nelle sue prime versioni il
servizio veniva fornito attraverso il protocollo proprietario \textit{NetBIOS}
usato da Windows come protocollo di trasporto; a questo livello il protocollo
ormai è in disuso, ed attualmente è disponibile direttamente su TCP/IP.

L'implementazione dei servizi SMB è realizzata da Samba attraverso due demoni,
\index{demone!\texttt{smbd}} \texttt{smbd} che implementa la condivisione dei
file e delle stampanti e \index{demone!\texttt{nmbd}} \texttt{nmbd} che
implementa i servizi NetBIOS (cioè il riconoscimento della presenza di server
sulla rete, la risoluzione dei nomi, ecc.). L'avvio del servizio è
generalmente curato dagli opportuni script; nel caso di Debian ad esempio
questa viene gestito da \texttt{/etc/init.d/samba} per entrambi i demoni,
altre distribuzioni usano due script separati.

Entrambi i demoni vengono controllati tramite un unico file di configurazione,
\index{configurazione!\texttt{/etc/samba/smb.conf}} \texttt{smb.conf}. La
sintassi è sempre analoga a quella dei file \texttt{.ini} di Windows che
abbiamo illustrato in sez.~\ref{sec:cfg_general}. Un estratto di questo file,
preso dalla installazione di default di una Scientific Linux, è il seguente:
\begin{FileExample}[label=/etc/samba/smb.conf]
[global]
	workgroup = MYGROUP
	server string = Samba Server Version %v
	log file = /var/log/samba/log.%m
	max log size = 50
	security = user
	passdb backend = tdbsam
	load printers = yes
	cups options = raw
[homes]
	comment = Home Directories
	browseable = no
	writable = yes
[printers]
	comment = All Printers
	path = /var/spool/samba
	browseable = no
	guest ok = no
	writable = no
	printable = yes
\end{FileExample}

Il file è diviso in sezioni distinte introdotte da un nome in parentesi
quadra, ciascuna delle quali descrive una risorsa condivisa attraverso SMB
(quello che viene chiamato uno \textit{share}).  Sono però previste tre
sezioni speciali, \texttt{[global]}, \texttt{[homes]}, e \texttt{[printers]}
che non corrispondono a degli \textit{share}, ma servono ad impostare alcune
funzionalità generiche. All'interno di una sezione i vari parametri sono
impostati con direttive del tipo \texttt{parola chiave = valore}.

La sezione \texttt{[global]} permette di impostare i parametri che si
applicano al server nel suo insieme. Le direttive fondamentali sono
\texttt{workgroup}, che definisce il nome del dominio NT in cui figurerà la
macchina, e \texttt{security}, che definisce le modalità di accesso al server
e può assumere i valori illustrati in tab.~\ref{tab:net_smb_conf_security}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Valore} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{ads}    &  gli utenti vengono autenticati presso un server
                       \textit{Active Directory}, la cosa richiede
                       installazione e configurazione locale di Kerberos oltre
                       all'unione della macchina al dominio \textit{Active
                         Directory} con l'appropriato uso del comando
                       \texttt{net}.\\
    \texttt{domain} &  gli utenti vengono autenticati presso un \textsl{server
                         di dominio} esterno, questo però richiede che si sia
                       effettuata una unione della propria macchina allo
                       stesso con l'appropriato uso del comando
                       \texttt{net}.\\
    \texttt{server} &  l'autenticazione viene dirottata verso un altro server
                       SMB (senza dominio) e se questa fallisce ricade nel
                       caso di \texttt{user}.\\
    \texttt{share}  &  opzione deprecata, utilizzabile in pratica solo quando
                       si vuole solo concedere un accesso anonimo (consente di
                       evitare l'invio della password da parte del client),
                       non funziona con le versioni recenti del protocollo
                       (SMB2).\\
    \texttt{user}   &  gli utenti devono autenticarsi presso il server, ed a
                       ciascuno di essi deve corrispondere un utente Unix,
                       questo comporta che gli utenti anonimi non
                       funzioneranno a meno di non impostare opportunamente la
                       direttiva \texttt{map to guest}.\\
    \hline    
  \end{tabular}
  \caption{Possibili valori della direttiva \texttt{security} in
    \texttt{/etc/samba/smb.conf}.} 
  \label{tab:net_smb_conf_security}
\end{table}


Di norma, a meno di non avere soltanto un accesso anonimo, nel qual caso si
può usare \texttt{share}, si utilizza come valore \texttt{user} che richiede
che esista un utente Unix per ciascun utente che si collega al server. I
valori \texttt{domain}, \texttt{server} e \texttt{ads} servono quando si vuole
dirottare la richiesta di autenticazione (caso che non tratteremo in questa
sede). In ogni caso Samba effettua gli accessi ai file per conto di un utente
UNIX locale, con i permessi associati a quest'ultimo, anche nel caso di
accesso anonimo, nel qual caso viene usato l'utente indicato dalla direttiva
\texttt{guest user}.

In tab.~\ref{tab:net_smb_global_parameter} sono riportati le altre direttive
principali.  L'elenco completo di tutti i parametri è descritto in dettaglio
nella sezione \texttt{PARAMETERS} della pagina di manuale di
\texttt{smb.conf}, di norma nel file fornito dai pacchetti di installazione,
vengono impostati valori ragionevoli adatti agli usi più comuni, la
trattazione dettagliata degli stessi va al di là dello scopo di questo testo,
ma per maggiori informazioni si può consultare il \textit{Samba-HOWTO},
inoltre tutti i dettagli delle direttive di configurazione sono documentati
nella pagina di manuale di \texttt{smb.conf}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
     \texttt{dns proxy}         & quando il server è usato per la risoluzione
                                  dei nomi, passa le richieste non risolte al
                                  DNS.\\
     \texttt{encrypt passwords} & utilizza una autenticazione basata su
                                  password cifrate, l'impostazione di
                                  default è \texttt{true} in quanto
                                  corrispondente al rispettivo default di
                                  Windows 98 e NT; se attivato necessita 
                                  la presenza dei dati di autenticazione in un
                                  opportuno supporto, in genere tramite
                                  \texttt{smbpasswd}.\\
     \texttt{guest account}     & specifica l'utente utilizzato per l'accesso
                                  \textsl{ospite} (cioè senza autenticazione);
                                  di norma si usa \texttt{nobody} che non ha
                                  nessun privilegio (in certi casi questo non
                                  consente l'uso delle stampanti).\\
     \texttt{map to guest}      & viene usato per indicare al servizio cosa
                                  fare quando viene fatta una richiesta per un
                                  utente che non è presente nel database (e
                                  quindi non ha un utente Unix corrispondente)
                                  o non può essere autenticato; prevede
                                  quattro valori: \texttt{never} in cui gli
                                  accessi vengono sempre rigettati (il default);
                                  \texttt{bad user} in cui viene rigettato
                                  l'accesso in caso di password sbagliata
                                  mentre gli utenti inesistenti vengono
                                  mappati sul \texttt{guest account};
                                  \texttt{bad password} in cui anche gli
                                  accessi con password sbagliata vengono
                                  mappati sul \texttt{guest account},
                                  \texttt{bad uid}, possibile solo con
                                  \texttt{security} impostato a \texttt{ads} o
                                  \texttt{domain} in cui gli accessi con
                                  utenti non riconosciuti nel dominio vengono
                                  mappati sul \texttt{guest account}.\\
     \texttt{passdb backend}    & specifica la lista dei supporti dove vengono 
                                  mantenute le password, il default è
                                  \texttt{tdbsam}, che indica un database
                                  binario, per usare un file testuale si usa
                                  \texttt{smbpasswd} mentre \texttt{ldapsam}
                                  ricava i dati da un server LDAP.\\
     \texttt{printing}          & indica come devono essere ricavate le
                                  informazioni riguardo le stampanti condivise
                                  da Samba, prevede diversi valori per i vari
                                  server di stampa, nel caso di Linux viene
                                  usato di default il valore \texttt{cups} che
                                  indica di appoggiarsi ad un server CUPS
                                  (vedi sez.~\ref{sec:print_CUPS}).\\
     \texttt{security}          & stabilisce le modalità di
                                  accesso al server, il valore di default è
                                  \texttt{user} che richiede un username ed
                                  una password per garantire
                                  l'accesso; è necessaria la presenza di un
                                  corrispondente utente sulla macchina.\\
     \texttt{socket options}    & specifica delle opzioni relative al
                                  comportamento del sistema nei confronti
                                  della rete.\\
     \texttt{unix password sync}& se specificato il server tenta di
                                  sincronizzare le password UNIX quando si è
                                  cambiata quella su Windows. \\
     \texttt{wins support}      & indica se supportare la risoluzione dei nomi
                                  \textit{NetBIOS} di NT.\\
     \texttt{wins server}       & indica un server per la risoluzione dei nomi
                                  \textit{NetBIOS} usati dal protocollo.\\
     \texttt{workgroup}         & definisce il gruppo di lavoro di cui il
                                  server farà parte (quello che è il nome di
                                  dominio NT, detto anche \textit{workgroup
                                    name}). \\ 
    \hline    
  \end{tabular}
  \caption{Significato delle principali direttive globali di Samba.}
  \label{tab:net_smb_global_parameter}
\end{table}

La sezione \texttt{[homes]} quando dichiarata permette di creare al volo degli
\textit{share} corrispondenti alle home degli utenti. In caso di connessione
prima vengono controllate le altre sezioni definite, e qualora non sia stata
trovata nessuna corrispondenza la sezione richiesta viene trattata se fatta
verso una condivisione di rete il cui nome corrisponde allo username
dell'utente.  Se l'utente esiste ed è stato correttamente autenticato
(torneremo su questo a breve) viene reso accessibile al volo il corrispondente
\textit{share} con le caratteristiche impostate in questa sezione.

La sezione \texttt{[printers]} ha lo stesso scopo della sezione
\texttt{[homes]}, ma vale per le stampanti, se non viene trovata una sezione
esplicita corrispondente alla stampante cercata, vengono esaminate le
informazioni relative alle stampanti (in modalità diverse a seconda di quanto
indicato con la direttiva \texttt{printing}) per verificare se esiste una
stampante con il nome richiesto, ed in caso positivo viene creato al volo il
relativo \textit{share}.

Per aggiungere uno \textit{share} è sufficiente definire una nuova sezione e
per creare un \textit{share} basterà inserire in coda al file mostrato in
precedenza una ulteriore sezione del tipo:
\begin{FileExample}[label=/etc/samba/smb.conf]
[foo]
path = /home/bar
browseable = yes
read only = no
\end{FileExample}
in questo modo gli utenti potranno accedere ad uno \textit{share} denominato
\texttt{foo} corrispondente al contenuto della directory \texttt{/home/bar}.

La direttiva principale in questo caso è \texttt{path}, usabile solo nella
dichiarazione di uno \textit{share}, che consente di indicare quale directory
della propria macchina verrà resa accessibile attraverso di esso.  Con la
configurazione indicata l'accesso richiederà sempre un username ed una
password, a meno che non si indichi in una ulteriore riga la direttiva
\texttt{guest ok = yes}, nel qual caso sarà consentito l'accesso anonimo senza
password, che avverrà per conto dell'utente specificato da \texttt{guest
  user}.

In ogni caso gli effettivi permessi disponibili sulla directory dello
\textit{share} (\texttt{/home/bar} nel caso dell'esempio) saranno quelli
previsti dal sistema per l'utente con il quale ci si è connessi al server;
Samba non può in nessun caso garantire maggiori permessi di quelli forniti dal
sistema, può invece ridurli, ad esempio impostando \texttt{read only = yes}
per consentire un accesso in sola lettura.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{browseable}& indica se lo \textit{share} deve essere pubblicato
                         sulla rete, prende i valori \texttt{yes} o
                         \texttt{no} (il default è \texttt{no}).\\
    \texttt{create mask}&maschera dei permessi per la creazione dei file, i
                         bit non indicati verranno rimossi, in genere si
                         indica con un valore ottale ed il suo default è
                         \texttt{0644}.\\
    \texttt{directory mask}& analoga di \texttt{create mask} per le directory.\\
    \texttt{host allow}& indica la lista delle stazioni da cui è possibile
                         connettersi al server: si possono usare sia
                         indirizzi IP che nomi a dominio, con notazione sia
                         CIDR che \textit{dotted decimal}; la direttiva si
                         può utilizzare anche globalmente e si applicherà a
                         tutti gli \textit{share}.\\ 
    \texttt{guest ok}  & indica se è consentito l'accesso anonimo, prende i
                         valori \texttt{yes} o \texttt{no} (il default è
                         \texttt{no}).\\
    \texttt{host deny} & analogo del precedente, indica la lista delle
                         stazioni da cui non è possibile connettersi al
                         server, in caso di conflitto con \texttt{host
                           allow} quest'ultimo ha la precedenza.\\ 
    \texttt{invalid users}& indica la lista degli utenti per conto dei
                         quali non si può utilizzare il servizio: di norma
                         si specifica sempre \textit{root} o gli altri utenti
                         di sistema e la si usa solo a livello globale ed ha
                         la precedenza su \texttt{valid users}.\\
    \texttt{read only} & indica se l'accesso è in sola lettura, prende i
                         valori \texttt{yes} o \texttt{no} (il default è
                         \texttt{yes}).\\
    \texttt{path}      & indica il pathname della directory in cui sono
                         contenuti i file dello \textit{share} (o la coda di
                         stampa per una stampante), si possono utilizzare
                         espressioni di sostituzione come \texttt{\%u} per il
                         nome dell'utente o \texttt{\%m} per il nome della
                         macchina e \texttt{\%S} per il nome dello
                         \textit{share}.\\
    \texttt{valid users}& indica la lista degli utenti che possono accedere al
                         servizio, per tutti gli altri sarà negato; si possono
                         indicare più nomi separati da spazi ed un nome
                         che inizia con ``\texttt{@}'' verrà interpretato come
                         nome di un gruppo e l'accesso sarà garantito a tutti
                         i suoi membri, il default è vuoto che indica
                         l'accesso a tutti gli utenti.\\
    \hline    
  \end{tabular}
  \caption{Le principali direttive di Samba per gli \textit{share}.}
  \label{tab:net_smb_share_parameter}
\end{table}

L'uso della direttiva \texttt{browseable = yes} permette di far apparire lo
\textit{share} nella lista pubblica mostrata dal cosiddetto \textit{Network
  Neighborhood} di Windows, cioè di farlo visualizzare quando si richiede di
``\textsl{sfogliare la rete}''. Le altre principali direttive utilizzabili
nella definizione di uno \textit{share} sono riportate in
tab.~\ref{tab:net_smb_share_parameter}, per i dettagli e l'elenco completo si
rimanda di nuovo alla documentazione ufficiale di Samba. Il pacchetto Samba
mette comunque a disposizione il comando \index{comando!\texttt{testparm}}
\texttt{testparm}, che esegue una analisi sommaria del file di configurazione
in grado di rilevare gli errori più macroscopici.

In generale per l'accesso ai servizi di condivisione forniti da Samba, che
siano definiti esplicitamente come appena visto, o implicitamente con la
sezione \texttt{[homes]}, è sempre necessaria l'autenticazione.  Il problema è
che Windows usa un meccanismo di autenticazione e gestione degli utenti
completamente diverso e non compatibile con quello nativo di Linux.

Il primo punto è che la procedura di autenticazione, dovendo passare sulla
rete, per avere un minimo di sicurezza non può prevedere il passaggio diretto
di credenziali che potrebbero essere intercettate, ed inoltre i client Windows
non sono in grado di inviare password in formato UNIX. Per questo non è
possibile eseguire un confronto diretto con il contenuto di
\texttt{/etc/passwd} come avviene per l'autenticazione locale.\footnote{in
  realtà la cosa è possibile usando la procedura di autenticazione obsoleta in
  cui la password viene inviata in chiaro ed il server potrebbe operare il
  confronto; questo è quello che avviene quando si forza il server a lavorare
  con le password trasmesse in chiaro ponendo il parametro \texttt{encrypt
    password} a \texttt{false}, ma questa modalità consente un uso limitato ed
  è comunque da evitare per gli ovvi problemi di sicurezza.}

Questo comporta che Samba deve essere in grado di effettuare autonomamente
l'autenticazione utilizzando lo stesso protocollo usato da Windows, da cui
segue automaticamente la necessità di mantenere un elenco di utenti e
password, queste ultime cifrate in maniera adeguata ai protocolli usati da
Windows, in maniera indipendente da quelle usate per gli utenti ordinari del
sistema ospite.

Il secondo punto è quello relativo al fatto che nel mondo Windows agli utenti
viene associato un identificativo unico, il cosiddetto \textit{SID}, che può
essere usato anche per gruppi e per macchine all'interno di quello che viene
chiamato un \textsl{dominio}. Su Unix utenti e gruppi sono separati e non
esiste il concetto di un account associato ad una macchina.\footnote{questo
  significa ad esempio che quando si usa Samba come \textit{Domain
    Controller}, cosa che non tratteremo in questa sede, per ciascuna macchina
  nel dominio deve essere disponibile un opportuno utente locale.} Dato che la
scelta fondamentale dell'architettura di Samba è che gli accessi ai file resi
accessibili su uno \textit{share} vengano sempre fatti per conto di un utente
della macchina, questo comporta che per gestire gli utenti Windows deve essere
creata una opportuna corrispondenza con utenti Unix.

In realtà le modalità con cui vengono gestiti gli utenti dipendono dalla
modalità in cui si sta utilizzando Samba, dato che, come accennato, è sempre
possibile delegare la procedura di autenticazione ad un'altra macchina. Qui
però prenderemo in considerazione solo il caso in cui gli utenti e
l'autenticazione vengono gestiti direttamente sul proprio server, supporremo
cioè che si stia usando Samba avendo impostato \texttt{security = user}.

I supporti usati da Samba per mantenere i dati di autenticazione e le
corrispondenze citati sono vari, il più semplice, rimasto a lungo il default,
è quello di registrarli su un file di testo analogo di
\texttt{/etc/passwd}. Questo viene abilitato specificando per il parametro di
configurazione \texttt{passdb backend} il valore \texttt{smbpasswd}, ed il
file da usare può essere specificato di seguito con il relativo pathname,
anche se di solito non si specifica niente e viene usato il default che è
\texttt{/var/lib/samba/smbpasswd}.

Questo file contiene gli \textit{hash} in formato Windows delle password di
ciascun utente. Il formato del file è analogo a quello di \texttt{passwd}, una
riga per ogni utente con campi separati dal carattere ``\texttt{:}'', il primo
campo specifica il nome utente ed il secondo il suo UID che devono
corrispondere agli analoghi in \texttt{passwd}.  Seguono due \textit{hash}
crittografici nel formato usato da Windows, poi dei flag per
l'\textit{account}, identificati da lettere fra parentesi quadra e infine la
data di ultima modifica della password. Il formato del file è descritto in
dettaglio nella pagina di manuale accessibile con \texttt{man 5 smbpasswd}.

Un secondo supporto, usato di default nelle versioni recenti di Samba, è
quello di \textit{tinydb} un piccolo database binario, che permette di
velocizzare notevolmente le operazioni di scansione. In tal caso si dovrà
indicare per \texttt{passdb backend} il valore \texttt{tdbsam} e i dati
verranno memorizzati nel file \texttt{/var/lib/samba/passdb.tdb}, a meno di
non aver specificato un pathname diverso come parametro opzionale di
\texttt{tdbsam}. È infine possibile usare come supporto un server LDAP, nel
qual caso il valore da usare è \texttt{ldapsam} seguito dalla URL che indica
il server da contattare.\footnote{questa configurazione è trattata con dovizia
  di particolari in sez.~2.2.4 di \cite{IS-LDAP}.}

In generale Samba supporta la gestione degli utenti attraverso il protocollo
CIFS utilizzando il comando \index{comando!\texttt{net}} \texttt{net} che
costituisce l'analogo dell'omonimo programma presente su Windows. Questa
modalità è completamente generica e consente di gestire gli utenti anche se
questi sono gestiti su un server remoto. Noi però non tratteremo questo
comando, ma quelli che operano localmente agendo direttamente sui supporti
citati.

Di norma la creazione dei dati per l'autenticazione degli utenti Windows deve
essere eseguita esplicitamente dall'amministratore, ed i singoli utenti devono
essere esplicitamente definiti per Samba. Non essendo infatti possibile
ricavare la password in chiaro degli utenti dagli \textit{hash} crittografici
mantenuti in \texttt{/etc/passwd} (o da qualunque altro supporto usato dal
\textit{Name Service Switch}) non esiste una modalità di
``\textsl{replicazione}'' automatica dei contenuti di quest'ultimo per
generare automaticamente gli utenti Windows da quelli Unix creando gli
\textit{hash} delle password nel formato usato da Samba. Si ricordi che
comunque per poter creare un utente Windows deve essere già definito nel
sistema l'utente Unix su cui questo verrà rimappato.

Per questo insieme al server viene fornito anche il comando
\index{comando!\texttt{smbpasswd}} \texttt{smbpasswd} che permette
l'inserimento dei dati di autenticazione all'interno del sistema utilizzato da
Samba; il comando userà quanto specificato con la direttiva \texttt{passdb
  backend}, e l'amministratore dovrà aggiungere i singoli utenti a mano con
qualcosa del tipo:
\begin{Example}
smbpasswd -a utente
\end{Example}
in questo caso verrà chiesta la password (due volte per evitare errori di
battitura) e l'utente, che in questo caso deve corrispondere ad uno già
presente nel sistema come utente Unix, verrà aggiunto all'interno
dell'opportuno supporto usato da Samba. 

Un utente normale può usare lo stesso comando sul suo username per modificare
la sua password, nel qual caso dovrà comunque fornire quella precedente.  Solo
l'amministratore può operare per conto di altri utenti; l'opzione \texttt{-a}
vista nell'esempio è quella che permette di aggiungere un utente, mentre
l'opzione \texttt{-x} permette di cancellarlo. Con le opzioni \texttt{-e} e
\texttt{-d} è invece possibile abilitare e disabilitare temporaneamente un
utente, mentre con \texttt{-n} si può impostare una password vuota.  Al solito
l'elenco completo delle opzioni è disponibile nella pagina di manuale del
comando, accessibile con \texttt{man smbpasswd}.

Oltre al server per fornire a client Windows i servizi di condivisione di una
macchina Unix, la suite di applicativi realizzata dal progetto Samba comprende
anche alcuni programmi che permettono di utilizzare lato client da un sistema
di tipo Unix i servizi presenti su un server Windows o su un altro server
Samba, anche se in quest'ultimo caso sarebbe più opportuno utilizzare le
applicazioni native Unix.

Il primo di questi programmi è \index{comando!\texttt{smbclient}}
\texttt{smbclient}, che permette di connettersi ad uno \textit{share} di un
server Windows con una interfaccia simile a quella di FTP. Il comando prende
come argomento il nome di un servizio Windows a cui collegarsi nella forma
generica:
\begin{Example}
//nome_server/nome_servizio
\end{Example}
dove \texttt{nome\_server} è il nome della macchina secondo il protocollo CIFS
(quello che viene chiamato \textit{NetBIOS name}) e \texttt{nome\_servizio} il
nome della condivisione (o della stampante) su quella macchina. Si noti come
il nome sia analogo a quello che viene usato da Windows, usando però il
carattere di separazione ``\texttt{/}'' al posto di ``\texttt{\bslash}'', ma è
possibile usare anche quest'ultimo, solo che si deve tener conto che la shell
lo interpreta, per cui nella riga di comando deve essere specificato due
volte, rendendo le cose meno leggibili.

L'opzione principale è \texttt{-U} che permette di specificare il nome utente
(relativo al server) con il quale ci si vuole connettere al servizio, se non
lo si specifica viene usato il proprio username. La password può essere
scritta direttamente sulla riga di comando come secondo argomento (o
specificando l'username nella forma \texttt{utente\%password}, altrimenti
verrà chiesta dal comando stesso sul terminale senza mostrarla. Se il servizio
a cui si accede non richiede una password se ne può eliminare la richiesta con
l'opzione \texttt{-N}, senza \texttt{-N} il comando chiede comunque una
password, anche quando questa non è richiesta.

Una forma alternativa del comando è quella in cui si usa soltanto l'opzione
\texttt{-L} per richiedere una lista dei servizi visibili presenti su un
server, il cui nome deve essere passato come parametro dell'opzione. Conviene
in genere abbinarla a \texttt{-N} (per l'operazione non è richiesta una
password), così da ottenere un risultato del tipo:
\begin{Console}
piccardi@hain:~$ \textbf{smbclient -N -L 192.168.1.129}
Domain=[TEST] OS=[Unix] Server=[Samba 3.5.6]

	Sharename       Type      Comment
	---------       ----      -------
	IPC$            IPC       IPC Service (squeeze server (Samba 3.5.6))
	PROVA           Disk      
	PRINT$          Disk      Printer Drivers
	lpcolor         Printer   Color Laserjet 2605dn
	lp              Printer   HP LaserJet 1320N
Domain=[TEST] OS=[Unix] Server=[Samba 3.5.6]

	Server               Comment
	---------            -------
	SQUEEZE              squeeze server (Samba 3.5.6)

	Workgroup            Master
	---------            -------
	TEST                 SQUEEZE
\end{Console}
%$

Se invece si usa \texttt{smbclient} per accedere ad un servizio una volta
completata l'autenticazione si verrà portati su una riga di comando che
supporta una sintassi simile a quella di FTP, con gli stessi comandi di
tab.~\ref{tab:net_FTP_commands}.  Per gli altri dettagli relativi all'uso del
comando e per l'elenco completo delle altre opzioni si può fare riferimento
alla rispettiva pagina di manuale, accessibile con \texttt{man smbclient}, che
riporta anche vari esempi di utilizzo.

Una seconda modalità per accedere ai dati di uno \textit{share} è quella di
montarne il contenuto all'interno del filesystem esattamente come si fa per
NFS.  Questo richiede il supporto nel kernel, di solito presente in tutte le
distribuzioni standard, e comunque attivabile nella sezione \texttt{Network
  filesystem} dei menu di configurazione. In realtà esistono due diversi
filesystem di rete che supportano il protocollo CIFS, il vecchio
\texttt{smbfs}, ormai deprecato e quasi universalmente sostituito dal nuovo
\texttt{cifs}.\footnote{si sono identificati le due diverse implementazioni
  utilizzando i nomi che devono essere indicati come parametro per l'opzione
  \texttt{-t} di \texttt{mount}.}

Tradizionalmente per montare uno \textit{share} era previsto l'uso esplicito
del comando \index{comando!\texttt{smbmount}} \texttt{smbmount} la cui
sintassi è:
\begin{Example}
smbmount service mount-point [ -o options ]
\end{Example}
dove \texttt{service} identifica lo \textit{share} da montare nella stessa
forma usata per \texttt{smbclient}. Il comando è sostanzialmente equivalente
all'uso di \texttt{mount} con l'opzione \texttt{-t smbfs}. Era anche previsto
un analogo comando \texttt{smbumount} per smontare un filesystem
\texttt{smbfs}.

Ormai questo comando è deprecato e nell'uso attuale viene utilizzato solo il
comando \index{comando!\texttt{mount.cifs}} \texttt{mount.cifs}, equivalente,
come visto in sez.~\ref{sec:file_disk_management}, all'uso di \texttt{mount -t
  cifs}.  Il comando segue la sintassi ordinaria di \texttt{mount} ma invece
che un file di dispositivo prevede che si passi come primo argomento
l'identificato dello \textit{share}, anche in questo caso con la stessa
sintassi usata per \texttt{smbclient}. 

Il comportamento del comando viene controllato dalle opzioni di montaggio, che
si passano al solito come parametri dell'opzione \texttt{-o} del comando come
lista di assegnazioni nella forma \texttt{opzione=valore} separate da
virgole. Le opzioni più importanti sono quelle che consentono di passare le
credenziali di autenticazione; queste possono essere specificate direttamente
sulla riga di comando con le opzioni \texttt{user} e \texttt{password}, anche
se l'opzione \texttt{user} consente l'indicazione contemporanea di entrambe
con la stessa sintassi dell'opzione \texttt{-U} di \texttt{smbclient}.

Dato che si ha a che fare con un accesso generico ad uno \textit{share}
Windows l'indicazione di un utente ed una password può non essere sufficiente
dato che in alcuni casi su una rete possono essere presenti più
\textsl{domini} per cui l'indicazione dell'utente deve anche indicare a quale
di questi domini si fa riferimento, nella forma \texttt{dominio/utente}.
Inoltre siccome la riga di comando può essere mostrata (con la password che vi
si è scritta) da \texttt{ps} è in genere preferibile inserire tutte queste
credenziali in un file (opportunamente protetto da letture indesiderate) ed
usare l'opzione \texttt{credentials} per indicarne il \textit{pathname}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Opzione} &\textbf{Significato}\\
    \hline
    \hline
    \texttt{credentials}& file da usare per leggere le credenziali di
                        autenticazione in modo che non compaiano sulla riga di
                        comando, prevede la presenza della assegnazione di
                        altrettanti valori alle opzioni \texttt{user},
                        \texttt{password} e \texttt{domain} (quest'ultima
                        opzionale) su altrettante righe distinte.\\ 
    \texttt{domain} & dominio a cui fare riferimento.\\ 
    \texttt{gid} & gruppo a cui assegnare la proprietà di file e directory.\\ 
    \texttt{guest} & richiede un accesso anonimo senza autenticazione.\\ 
    \texttt{password} & password da usare per l'autenticazione.\\
    \texttt{uid} & utente a cui assegnare la proprietà di file e directory.\\ 
    \texttt{user}     & utente da usare per l'autenticazione, supporta
                        l'indicazione anche della password e del dominio
                        usando la forma generica
                        \texttt{dominio/utente\%password}.\\ 
    \hline    
  \end{tabular}
  \caption{Le principali opzioni di montaggio per il filesystem \textit{cifs}.}
  \label{tab:mount_cifs_options}
\end{table}

Inoltre come per NFS si pone il problema di come gestire la proprietà dei file
e delle directory presenti nello \textit{share}. Se esiste un meccanismo che
consente di mappare gli utenti Windows sugli utenti locali della macchina,
questa viene gestita automaticamente, ma non è detto questo sia sempre
possibile, per cui in tal caso si possono usare le opzioni \texttt{uid} e
\texttt{gid} per forzare una assegnazione statica. Si sono riportate altre
principali opzioni di montaggio in tab.~\ref{tab:mount_cifs_options}, per
l'elenco completo ed i dettagli si consulti al solito la pagina di manuale,
accessibile con \texttt{man mount.cifs}.

Infine per il monitoraggio delle connessioni al server è disponibile il
comando \index{comando!\texttt{smbstatus}} \texttt{smbstatus} che inoltre
permette di controllare lo stato delle connessioni, degli utenti presenti e
dei file utilizzati sul proprio server.


\section{La gestione elementare della posta elettronica}
\label{sec:mail_base_management}

Tratteremo in questa ultima sezione le problematiche di base della gestione
della posta elettronica, e dopo una introduzione generica al funzionamento del
servizio tratteremo quanto riguarda le impostazioni da effettuare su una
macchina per la ricezione ed il reinoltro della posta locale ed i comandi di
base per la verifica del funzionamento e della spedizione della stessa.

\input{../mailservices/intromail}
\input{../mailservices/postfix}

% LocalWords:  nohide anonuid anongid mount point nfs TCP wrappers echo shosts
% LocalWords:  discard telnet ftp socket netstat sez DNS SSH client inetd debug
% LocalWords:  xinetd see for further informations configuration service name
% LocalWords:  sock type flags path args services stream tcp nowait root dgram
% LocalWords:  udp wait chargen daytime news and uucp nntp INFO Info ident raw
% LocalWords:  identd rdm seqpacket group pathname exec shell leafnode RFC tcpd
% LocalWords:  nobody ps localhost Trying Connected to Escape character is Recv
% LocalWords:  Active connections servers established Send Local Address LISTEN
% LocalWords:  Foreign Connection closed foreign host error portscan denial of
% LocalWords:  Simple defaults The number requests particular may handle at log
% LocalWords:  instances logging This logs that specified Another option SYSLOG
% LocalWords:  auth What when the connection succeeds PID pid processing ip as
% LocalWords:  request address USERID using EXIT exit DURATION duration session
% LocalWords:  success fails Same options above failure specific can have info
% LocalWords:  source includedir syslog facility priority tab ATTEMPT only from
% LocalWords:  dotted decimal CIDR access times nice disable yes protocol conf
% LocalWords:  port RPC UNLISTED bind redirect umask Wietse Wenema wrapper LDAP
% LocalWords:  hosts allow deny list not allowed system manual pages ALL sshd
% LocalWords:  portmap mountd statd lockd rquotad secure caching ssh wildcard
% LocalWords:  tcpdchk warning line apt proxy such process tcpdmatch oppish ARP
% LocalWords:  hostname official matched granted l'IP RARP BOOTP DHCP Reverse
% LocalWords:  Resolution ethernet MAC kernel Bootstrap nell' ramdisk TFTP home
% LocalWords:  Trivial Transfer bootpd standalone bootptab Dynamic broadcast we
% LocalWords:  pump dhclient route routing dhcpd Sample definitions common all
% LocalWords:  supported networks domain subnet mask lease netmask routers pag
% LocalWords:  fixed named cache keyword parameter value config ports protocols
% LocalWords:  listen version Lifetime size ephemeral key authentication should
% LocalWords:  used read files this work you will also need keys similar enable
% LocalWords:  empty passwords change tunneled clear text here PAM interactive
% LocalWords:  modules properly interface with forwarding scp username command
% LocalWords:  forward cp gapil public html RSA DSA crittato keygen bits new by
% LocalWords:  passphrase comment keyfile old fingerprint cat copy agent add Di
% LocalWords:  filesystem make locking control filesystems which exported crash
% LocalWords:  clients exports exportfs nogroup noauto SMB Message smbd GID UID
% LocalWords:  Block Windows NetBIOS nmbd global something sensible crashes dns
% LocalWords:  admin backtrace panic action printing load printers guest users
% LocalWords:  invalid security workgroup string encrypt true passdb backend tg
% LocalWords:  tdbsam unixsam homes Directories browseable printable writable
% LocalWords:  share smbpasswd wins support globals hash Neighborhood ldapsam
% LocalWords:  dall' smbclient servicename debuglevel netbios smbmount Piccardi
% LocalWords:  maxprotocol smbfs smbumount Permission distribute modify under
% LocalWords:  document terms GNU Free Documentation License any later Sections
% LocalWords:  published Foundation Invariant Front Cover Texts license section
% LocalWords:  included entitled l'uso all'ufficio Apache default ant compat bf
% LocalWords:  host's cps bootp Tag dn ds gw gateway hd hn rp sm td dhcp offer
% LocalWords:  discovery ack eth resolv Consortium insensitive Sarge Debian's
% LocalWords:  package sample conf's information about syntax comprehensive if
% LocalWords:  parameters understood Normally provides reasonable does leave ea
% LocalWords:  anything like example then few changes must send identifier com
% LocalWords:  supersede fugue prepend require retry reboot select initial ISC
% LocalWords:  interval reject l'hostname leases earthsea filename next SHell
% LocalWords:  rsh Sun rcp rlogin OpenSSH OpenBSD BSD etch openssh Window sftp
% LocalWords:  PermitRootLogin DisplayOffset Subsystem AllowGroups AllowUsers
% LocalWords:  DenyGroups DenyUsers ListenAddress IPs HostKeys HostKey LogLevel
% LocalWords:  KeyRegenerationInterval ServerKeyBits SyslogFacility StrictModes
% LocalWords:  LoginGraceTime RSAAuthentication PubkeyAuthentication rhosts ask
% LocalWords:  RhostsAuthentication Don't user's IgnoreRhosts RECOMMENDED des
% LocalWords:  RhostsRSAAuthentication HostbasedAuthentication keyboard Cipher
% LocalWords:  PermitEmptyPasswords PasswordAuthentication PrintMotd KeepAlive
% LocalWords:  PAMAuthenticationViaKbdInt ForwardAgent ForwardX BatchMode aes
% LocalWords:  CheckHostIP StrictHostKeyChecking IdentityFile Ciphers cbc pdf
% LocalWords:  blowfish arcfour EscapeChar l'username netadmin rsa dsa identity
% LocalWords:  authorized all'agent xhost keylogger NN FS NFSD menuconfig rpc
% LocalWords:  nfsd rw machine ro sync async av smb ini bsd printcap IPTOS tmp
% LocalWords:  LOWDELAY NODELAY SNDBUF RCVBUF NT foo HOWTO testparms smbstatus
% LocalWords:  passwd tdb authfile logfile bios destinationIP resolve order rc
% LocalWords:  known middle Compression CompressionLevel gzip Kbit WinSCP CUPS
% LocalWords:  challenge response append NIS dell'UID Kerberos soft sleep kill
% LocalWords:  uninterruptible intr major retrans rsize wsize nolock sec sys OS
% LocalWords:  krb CIFS PDC Primary Controller grep URL TRUELITE Sharename IPC
% LocalWords:  print Printer Drivers sarge NTP ntpdate ntpd SNTP l'UID ms ntp
% LocalWords:  Ferraris driftfile statsdir restrict sottodirettiva statistics
% LocalWords:  loopstats peerstats clockstats filegen kod notrap nomodify page
% LocalWords:  nopeer noquery Squeeze unsigned integer search static routes cap
% LocalWords:  LANG HashKnownHosts GSSAPIAuthentication AcceptEnv array never
% LocalWords:  GSSAPIDelegateCredentials AllowAgentForwarding firewall bad poll
% LocalWords:  stateless stateful SIGKILL Scientific uid ads cups valid SID
% LocalWords:  tinydb Switch cifs credentials gid SendEnv map netfilter ntpq
%  LocalWords:  iptables classless testparm Wheezy AllowTCPForwarding without
%  LocalWords:  DenyGroup these interfaces turned AuthorizedKeysFile beware
%  LocalWords:  issues threads tunnelled pass environment variables ecdsa reach
%  LocalWords:  ServerAliveCountMax keepalive ServerAliveInterval Filezilla
% LocalWords:  delay jitter


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "corso"
%%% End: 
