Testo |
File |
Strumenti
impiegati |
Data
di
svolgimento |
Contare
quanti file esistono con una certa estensione,
definita come la stringa posta dopo l'ultimo
carattere "punto" presente nel nome del file, per
tutte le estensioni trovate nei file presenti nel
direttorio corrente e nei sottodirettori. Limitare
l'output alle sole 5 estensioni più numerose. |
estensioni.sh |
find,
rev, grep, sort, uniq, head |
9/3
|
Creazionedi
utenti, gruppi, e directory condivise in cui
utenti di un gruppo possano collaborare (creando
file che siano automaticamente accessibili in
lettura e scrittura da tutti i membri del gruppo) |
traccia dei
comandi |
ripasso
su permessi, bit speciali, umask; adduser, chown,
chmod |
9/3
|
Esercizio
proposto: modificare estensioni.sh per
utilizzare ls al posto di find, ed evitare di
includere nel conteggio file senza estensione.
|
estensioni-ls.sh
(con commenti sulle regex e ulteriori domande)
|
grep
|
(9/3)
|
Modificare
l'esercizio precedente per contare quanti file
esistono con una certa estensione, limitatamente
all'elenco di estensioni passate come parametri
sulla riga di comando. |
estparam.sh |
ciclo
for, variabili speciali $n
|
16/3
|
Verificare se c'è un UID libero tra il
più alto presente nel file /etc/passwd e quello
immediatamente inferiore.
Migliorarlo stampando i nomi relataivi agli ID
(uid3) |
uid1.sh |
Variabili,
command substitution, pipelines, filtri (sort, head,
tail), aritmetica della shell, test, if-then-else |
16/3
|
uid2.sh |
read,
cicli while, apertura di subshell |
16/3
|
uid3.sh |
variabile
IFS, read di più variabili |
16/3 |
Esercizio
proposto: realizzare la stessa funziona
di modificare uid3.sh con gli strumenti utilizzati
per uid1.sh (usando quindi sort come ausilio per
individuare le due righe utili, invece del ciclo
con le variabili)
|
|
|
(16/3) |
Esercizio
proposto:
dato un file nel formato:
nomeutente1
indirizzo1
datanascita1 telefono1
nomeutente2 indirizzo2
datanascita2 telefono2
....
produrre in output
nomeutente1
telefono1
nomeutente2 telefono2
... |
duerighe.sh |
read,
variabile IFS
|
(16/3)
|
Stampare
gli username corrispondenti agli N più
elevati userid presenti nel file /etc/passwd,
essendo N un parametro passato sulla riga di
comando. |
5nomi-ciclo.sh
5nomi-awk.sh |
cut
avanzato, awk avanzato |
(studio
libero)
|
Mostra
gli N utenti con id immediatamente successivi
rispetto a quello dell'utente passato come primo
parametro (N sia il secondo parametro)
Variante proposta: usare il nome utente e non
l'id come primo parametro |
5nomi-awk-adv.sh
|
awk
avanzato
|
(studio
libero) |
Mostrare
tutti gli username, chiedendo all'utente conferma di
un'ipotetica azione da svolgere per ciascuno. |
readterminal.sh
|
read
alimentato esplicitamente da terminale |
16/3 |
Predisporre
uno script che aggiorni in tempo reale le
statistiche tratte da un file /tmp/attivita, che si
suppone sempre crescente (aperto in append dal
processo genlog.sh), ad
esempio permettendo di contare quante righe sono
comparse tra un'osservazione e la successiva, in
modo efficiente anche in caso di crescita del file
rapida e raggiungimento di grandi dimensioni.
Estensione:
- aggiungere un "lanciatore" che esegua logwatch
in background e lo segnali ogni 10 secondi; (soluzione)
Esercizio proposto
per il 30 marzo:
- ipotizzando che il file /tmp/attivita debba
sempre esistere, e nel caso non esista un
processo esterno si occuperà di ricrearlo,
aggiungere un controllo iniziale che eviti il
fallimento di "tail -f" attendendo la comparsa
del file prima di avviarne la lettura.
(soluzione)
|
logwatch.sh |
funzioni,
signal handling, tail -f, peculiarità delle subshell |
23/3
|
Progettare
uno script che lanci due comandi in parallelo (in
questo esempio i comandi siano "sleep 10" e "sleep
20") e verifichi ogni 5 secondi se sono ancora in
esecuzione o no, scrivendo sul file "log" lo stato
dei due processi e terminando l'esecuzione quando
entrambi terminano. |
parallelo.sh |
esecuzionein
background, variabile speciale $!, sleep, ps, break |
|
Modificare
l'esercizio precedente perchè accetti come parametri
un numero arbitrario di comandi da lanciare in
parallelo, poi proceda alla verifica periodica come
sopra.
Esercizio proposto:
(soluzione)
garantire che tutti i processi lanciati
vengano terminati se per qualsiasi motivo viene
terminato il processo parallenne
|
parallenne.sh
parallenne-alt.sh
(array con indici non consecutivi, controlli più
specifici sui processi in esecuzione)
|
array
della shell, shift e/o variabili speciali $* $@ |
23/3
|
Trovare
tutti i file con almeno un bit speciale settato,
metterli in un file elenco.nuovo,
(se il file esiste già, non sovrascriverlo ma
rinominarlo elenco.vecchio) ed al termine
confrontare i file elenco.nuovo
ed elenco.vecchio
mostrando le differenze
Esercizio proposto - mostrare le
differenze secondo questo formato:
Nuovi file trovati rispetto alla precedente
invocazione:
... elenco dei file che compaiono in elenco.nuovo ma
non in elenco.vecchio ...
File cancellati rispetto alla precedente
invocazione:
...
File a cui è stato rimosso il bit speciale
dalla precedente invocazione:
...
|
findspecial.sh |
find,
diff o sort o grep che utilizza pattern presi da un
file |
30/3
|
Copiare
tutti i file con le seguenti caratteristiche nella
cartella passata come primo parametro allo script,
riproducendo relativamente a questa il path
originale
(Es. se devo copiare /etc/passwd in /root, va a
finire in /root/etc/passwd)
Caratteristiche (individuarle singolarmente
componendo in tre passi l'elenco dei file per tar):
- file del sistema che non siano stati
modificati da un dato numero di giorni (passato
come secondo parametro allo script)
- file al di sotto di /home più grandi di 10k
- file con almeno un bit speciale settato
Esercizio proposto: verificare
cosa succede se un file rispetta più
caratteristiche e quindi viene inserito più volte
nell'elenco. Modificare la soluzione per prevenire
a priori questo caso (anche se non dovesse
costituire un problema)
|
archivetree.sh |
tar,
process substitution
|
30/3
|
Dato un file di
nome "testo" sulla macchina locale, lo si faccia
remotamente ordinare alla macchina che ha meno
processi in esecuzione tra quelle elencate nel file
"lista", memorizzando il risultato nel file
"testo.ord" in locale.
Esercizio proposto: sshload può
funzionare male se una macchina di "lista" è spenta.
Verificare perché e risolvere il problema. |
sshnum.sh
sshload.sh
sshsort.sh |
esecuzione
remota e spostamento dati con ssh |
30/3
|
Esercizio proposto (soluzione): descrivere
la configurazione di un account utente sshknock
sulla VM Server, in modo che sia possibile
raggiungerlo via ssh dall'utente root
della VM Client, ma non avviare una sessione
interattiva. L'unico effetto della connessione deve
essere la scrittura dell'indirizzo del client
che la origina nel file /home/sshknock/ip.new
|
|
file
authorized_keys |
(30/3)
|
Esercizio
proposto: Nella directory passata come
primo parametro allo script ed in tutte le
subdirectory, individuare i file che non siano stati
modificati da più di un dato numero di giorni
(passato come terzo parametro), e copiarli in una
directory passata come secondo parametro.
|
archiveflat.sh |
find |
(30/3)
|
Questo
script accetta tre parametri: il primo è una
directory locale, il secondo un nome di host, il
terzo una directory su tale host.
Lo script deve trasferire, mantenendo struttura e
permessi, ilcontenuto della dir. locale sull'host
remoto nella dir. indicata.
Ricordare di controllare la validità formale dei
parametri ed anche se possibilela validità
effettiva: in questo caso si può testare l'esistenza
delladir, la raggiungibilità dell'host, e se la dir
remota non esistecrearla.
|
sshcopy.sh |
ssh,tar,
ping/nc, esecuzione condizionata con "&&" |
(30/3)
|
Esercizio proposto:
realizzare una procedura di backup incrementale
rispetto al precedente esercizio "sshcopy.sh", cioè
un analogo sistema di copia remota che però
trasferisca solo i file cambiati o apparsi dopo
l'ultima esecuzione del backup. Risolvere il
problema in due modi:
1) con tar (si vedano le opzioni mtime, newer e
simili), facendo in modo che ogni backup
incrementale sia collocato in una subdirectory con
nomeINCR-YYYYMMDD
(si veda la manpage del comando date)
2) con rsync (si studi la man page corrispondente) |
incr-tar.sh
incr-rsync.sh |
tar,rsync,
ssh
confronto di timestamp |
(30/3)
|
Realizzareuno
script che accetti sulla riga di comando
- "-n" seguito da un numero che sarà memorizzato
nella variabile NCOPIES; il parametro è
opzionale e se assente NCOPIES deve assumere il
valore di default pari a 4.
- "-s" seguito da una stringa che sarà
memorizzata nella variabile LOGSIGNAL; il
parametro è opzionale e se assente LOGSIGNAL
deve assumere il valore di default pari a USR1.
- una stringa che sarà memorizzata nella
variabile LOGFILE
Lo script "ruota" il file LOGFILE per tenerne copie
storiche con estensione numerica (.1 corrisponde
sempre al file generato più recentemente, ogni
rotazione salva il file con estensione .n
nel file con estensione .n+1,
con un valore massimo pari a NCOPIES) e manda al
processo che sta scrivendo sul file il segnale
LOGSIGNAL (default=USR1) per avvertirlo al momento
giusto di chiudere e riaprire il file.
Esercizio proposto
(soluzione): verificare
nel modo più preciso possibile che i parametri
passati siano sintatticamente e semanticamente
corretti. Integrare lo script con cron in modo che
- se si rileva lanciato da terminale, configura cron
per auto-eseguirsi ogni giorno alle 22
- se si rileva lanciato da cron, esegue la rotazione
dei log
|
logrotate.sh
|
getopt,spostamentodi
file aperti, fuser, cicli for+seq
|
6/4
|
Seil
carico del sistema è inferiore ad una soglia
specificata come primo parametro dello script,
lancia il comando specificato come secondo
parametro. Altrimenti, con at,
rischedula il test dopo 2 minuti, e procede così
finchè non riesce a lanciare il comando.
Estensioni proposte
(soluzione):
- verificare i problemi di path e di output
dovuti all'esecuzione dello script da parte del
demone atd.
- estendere lo script perchè qualsiasi parametro
specificato dopo il secondo venga passato al
comando da eseguire.
- estendere lo script perchè accetti un nuovo
parametro, prima di tutti gli altri, che
rappresenta il numero massimo di tentativi
da eseguire. Superato tale numero il
processo non viene rischedulato, e il fallimento
viene loggato con priorità error; loggare con
priorità info
ogni tentativo.
|
niceexec.sh |
at |
6/4
|
Configurare
rsyslog perchè i messaggi etichettati local0.*
prodotti su Client siano loggati nel file
/var/log/attivita di Server |
Client_rsyslog.conf
Server_rsyslog.conf |
rsyslog |
6/4
|
Configurazione
di una rete client-router-server, analisi e
diagnostica del traffico |
Traccia della configurazione e
testing della rete
Come rendere
permanenenti le modifiche alla configurazione
|
ip,
ping, wireshark, netstat
|
20/4
|
Configurare
una VPN emulata sulla rete delle VM con OpenVPN.
Seconda parte (road warrior) proposta come
esercitazione autonoma
|
Procedimento (corretto
il 2/5) openvpn.tgz
bridge_utils
bridge
config
client config
|
openvpn,
tar, dpkg, apt
|
20/4
|
Configurareil
packet filter per una politica di "default deny",
che blocchi tutto ciò che non è esplicitamente
consentito.
Esercizio proposto:
predisporre una salvaguardia che eviti di "chiudersi
fuori" quando è necessario configurare il packet
filter su di una macchina remota
|
iptables.base.txt |
iptables
|
27/4
|
Configurareil
packet filter di Router perché consenta il traffico
tra Client e Server
- esponendo verso Server le connessioni come se
fossero originate da Router stesso
- accettando le connessioni da Client verso Router
stesso e ridirigendole verso Server
Esercizio proposto:
sperimentare con regole di conteggio per capire
quando viene effettuato il de-nat dei pacchetti
ricevuti in risposta a pacchetti nat-tati prodotti
da Router
|
iptables.nat.txt
|
iptables
|
27/4
|
Esercizio
proposto: Configurare iptables e
rsyslog su client e server in modo che tutti i
pacchetti ricevuti dal server sulla porta 22/TCP
vengano loggati sul client, nel file
/var/log/pacchetti
Sul client, esaminare continuamente il file
/var/log/pacchetti, e per il primo pacchetto di
una connessione mai vista prima, se la connessone
origina dal client stesso stampare su stdout il
nome dell'utente che ne è responsabile, se
proviene da altre macchine stamparne l'ip.
Sul client, pianificare la rotazione del log ogni
10 minuti: il log attivo deve essere archiviato
con nome /var/log/pacchetti.TIMESTAMP (essendo
TIMESTAMP una stringa che esprime un'appropriata
marcatura temporale) e tutti i processi che lo
stanno usando devono ricevere il segnale SIGHUP
(che
si suppone sia gestito correttamente, per chiudere
e riaprire il file) |
iptables-log-server.sh
iptables-log-client.sh
iptables-log-rotate.sh |
rsyslog,
cron, iptables, netstat |
(27/4)
|
Monitorare
il traffico ssh tra la VM Client e la VM Server
sulla VM Router:
- loggando attraverso syslog sul file
/var/log/newconn l'inizio e la fine di ogni
connessione diretta da Client a Server
- durante la "vita" di ogni connessione, al
superamento di una certa soglia
(espressa in numero di pacchetti per
minuto) connettersi alla sorgente del traffico
eccessivo ed individuare l'utente
responsabile e loggare lo username nel file
/var/log/excess;
- provvedere alla realizzazione di uno script di
controllo che avvii ed arresti il monitoraggio,
eseguendo tutte le operazioni di configurazione
in modo automatico.
Esercitazioni
proposte:
- completare gli script come da commenti
all'interno delle tracce
- curare tramite signal handling la pulizia
automatica di processi e catene in caso di
terminazione volontaria o involontaria del
procedimento di monitoraggio
|
Variante
con tcpdump:
netmon.sh
connection_monitor.sh
traffic_monitor.sh
log_user.sh
|
tcpdump
syslog
netstat
case
|
11/5
|
Variante
con iptables
netmon.sh
connection_monitor.sh
traffic_monitor.sh
log_user.sh
|
iptables
cron |
27/4
4/5
|
Esercizio
proposto: Predisporre il demone snmpd su
Server per poter realizzare via snmp i controlli
previsti dagli esercizi "sshnum" (rilevando il
carico del sistema anzichè il numero di processi
attivi) e "netmon" (elencando le connessioni attive
sulla macchina).
Verificare con wireshark il contenuto dei pacchetti. |
snmpd.conf.txt
pacchetti da installare per la risoluzione simbolica
degli OID (normalmente non installati per motivi di
licenza - già presenti sulle VM del corso):
smistrip, snmp-mibs-downloader
per attivarli commentare la riga "mibs" nel file
/etc/snmp/snmp.conf (nota: è il file dei default per
i client snmp, sulla macchina "manager", non il file
di configurazione dell'agent)
|
/etc/snmp/snmpd.conf
/etc/default/snmpd
snmpwalk, snmpget |
4/5
|
Esercitazione su
configurazione di server LDAP ed utilizzo dei
client tools a riga di comando (è
consigliabile aver letto la guida
a ldap)
filesystem.schema - Definire un attributo fn di tipo
adatto a rappresentare un nome di file, un attributo
fs adatto a
rappresentare una dimensione in byte, una classe
ausiliaria dir
che contenga obbligatoriamente fn e facoltativamente
fs, una classe ausiliaria file
che contenga obbligatoriamente sia fn che fs
ldap-fs-store.sh
- memorizzare nella directory un sottoalbero del
filesystem, passato come parametro allo script,
riproducendo con i DN la struttura gerarchica della
collocazione di file e directory
ESERCIZI
PROPOSTI:
ldap-fs-sumspace.sh
- esplorando la directory LDAP, calcolare per ogni
entry che rappresenta una directory lo
spazio occupato dai file presenti in tale
directory, ed aggiornare l'entry con la somma
es: in LDAP ho
fn=pippo,fn=lib,fn=usr.... con fs=10
fn=pluto,fn=lib,fn=usr.... con fs=20
--> aggiorno l'entry
fn=lib,fn=usr....
impostando fs=30
ldap-fs-purge.sh
- esplorare la directory LDAP, e verificare se i
file in essa rappresentati esistono ancora sul
filesystem. In caso contrario rimuoverli da LDAP. |
filesystem.schema
filesystem.ldif
ldap-fs-store.sh
ldap-fs-sumspace.sh
ldap-fs-purge.sh
|
/etc/ldap/*
ldapadd, ldapsearch, ldapmodify, ldapdelete |
18/5
|
Esercitazione completa
su routing, filtraggio, ssh, monitoraggio.
Dopo aver configurato come specificato sopra
una rete client/router/server realizzare il seguente
sistema di comunicazione.
Il primo script,
toctoc.sh, gira sulle macchine client
(della rete 10.1.1.0/24) ed accetta come
parametri due indirizzi IP (router
e server)
ed un numero di porta TCP (port).
Usando ssh, deve depositare nella directory /tmp/ di
router un
file che abbia come nome l'IP address di client,
che contenga in una singola riga i valori server
e port
separati da uno spazio, mantenendo poi la
connessione ssh per almeno un minuto.
Esempio, sulla macchina 10.1.1.1 lancio
toctoc.sh 10.1.1.254 10.9.9.1 80 ->
viene creato sulla macchina 10.1.1.254 un file di
nome /tmp/10.1.1.1 che contiene "10.9.9.1 80"
Il secondo script
routerconf.sh serve a configurare
inizialmente il router, che deve agire
da firewall, bloccando di default tutto il
traffico tranne quello indispensabile per il
funzionamento di toctoc.sh.
Il terzo script
serverconf.sh serve a configurare il
firewall dei server per accettare traffico entrante
solo dagli host della rete locale.
Il quarto script
avanti.sh è pensato per girare su router, e deve
verificare senza mai fermarsi, ogni 5 secondi, se
sono presenti connessioni ssh a router
a cui corrispondano in /tmp file inviati da
client "toctoc". Nel caso ne trovi deve:
1) inserire le regole nel packet filter che
consentano al client
di attraversare il router
solo per connettersi al server
sulla porta remotaspecificata
nel file. Porre attenzione alla direzione delle
connessioni. Vista la limitazione di traffico sui
server, mascherare i pacchetti che dai client
attraversano router.
2) cancellare il file creato dal
client e disconnettere forzatamente la connessione
ssh attivata da toctoc.sh agendo sul server sshd
Estensione
proposta: condizionare
l'esecuzione del punto 1 alla verifica, da
condurre via SNMP, che sul server sia in
esecuzione il processo rsyslogd -
Il quinto script
timeout.sh, in esecuzione sul router
anch'esso, deve osservare il transito dei
pacchetti relativo alle connessioni abilitate
da avanti.sh. Trascorsi 5 minuti circa (per comodità
nel calcolo si possono trascurare i secondi) di
assenza di traffico relativo ad una
connessione, deve rimuovere dal packet filter la
regola che la consente, inserita in precedenza
da avanti.sh.
Lo script
openclose.sh può essere usato per
concentrare le operazioni di apertura e chiusura del
firewall in modo da garantirne la coerenza tra
avanti.sh e timeout.sh.
Estensione
proposta: all'atto della chiusura
della connessione, aggiornare sulla directory LDAP
ospitata dal router il conteggio delle connessioni
osservate tra il client ed il server. A questo fine
predisporre uno schema che consenta di costruire un
sottoalbero del DIT formato da un primo livello di
entry che rappresentino i client, ed un secondo
livello di entry che rappresentino i server a cui il
client si è connesso (e quante volte)
|
NOTA:non
tutte le soluzioni sono complete, alcune come
specificato nei commenti sono solo tracce.
toctoc.sh
routerconf.sh
serverconf.sh
avanti.sh
timeout.sh
openclose.sh
snmpd.conf
count.schema.ldif
|
ssh
iptables
logging
inittab
kill
netstat
cron
at
ldap
snmp
|
25/5
1/6
|
Configurazione
di un NAS affidabile: partizionamento dei dischi,
definizione di un RAID software, formattazione,
configurazione per il restart automatico,
esportazione via NFS. |
traccia dei comandi
[PDF]
pacchetto
nfs-server per le VM
|
fdisk,mdadm,
lvm commands, mkfs.ext3,/etc/fstab, /etc/mdadm, nfs
server e client
|
|