Sezione 1 : Introduzione
1. Introduzione
virt-manager
Installazione di virt-manager:
sudo apt install virt -manager
sudo systemctl status libvirtd.service
sudo udermod -aG libvirt max
sudo systemctl restart libvirtd.service
sudo systemctl status libvirtd.service
virt-managerModifica della destinazione dei vari file iso e delle macchine virtuali:
- Edit -> Connectin details -> Storage;
- stoppare ed eliminare default /var/lib/libvirt/images;
- aggiungere una cartella in /home/ dove mettere anche gli iso files.
Autostart della connessione al boot:
- Edit -> Connection details -> Virtual Networks;
- flaggare Autostart oppure;
- sudo virsh net-autostart default
creazione virtual machine
Creazione debian-virt1 e debian-virt2:
- debian netinst iso;
- Other OS;
- 1024 RAM;
- 1 core;
- 20G HD;
- tasksel, standard system utilities.
Le macchine virtuali:
- si pingano regolarmente;
- pingano anche google.com.
Alle macchine così create ci si può anche collegare da remoto tramite Spice:
sudo apt install spice-vdagent # sulla macchina Guest
sudo apt install spice-client-gtk # sulla machcina Host
virsh -c qemu:///system start <VM> # su Host fa partire da CLI una VM
spicy -h localhost -p 5900 & # su Host si connette tramite 'spice-client' alla macchina avviataVedi questa Guida .
configurazione sudo
Configurazione sudo su entrambe le macchine:
apt install sudo
usermod -aG sudo maxQuindi logout e login.
set static ip
virsh net-dumpxml defaultDovrebbe essere simile al seguente codice:
<network>
<name>default</name>
... ... ...
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>virsh net-edit defaultVa modificato come il seguente codice (sono le 2 righe che impostano l’indirizzo ip statico per le 2 macchine virtuali):
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
<host mac='52:54:00:87:c5:d7' name='debian-virt1' ip='192.168.122.2'/>
<host mac='52:54:00:22:ba:50' name='debian-virt2' ip='192.168.122.3'/>
</dhcp>virsh net-destroy default # distrugge il Network
virsh net-start default # e lo riavvia con le modificheshared folder
Nella macchina Host creo la cartella che voglio condividere con le varie macchine Guest:
mkdir ~/virt-sharedNella configurazione della macchina virtuale imposto la condivisione come segue:
- Visualizza -> Dettagli -> Aggiungi hardware -> File system;
- Tipo: mount;
- Modalità: mapped;
- Percorso sorgente: /home/max/virt-shared;
- Percorso di destinazione: /nome-filesystem.
In questo modo tutti gli utenti delle varie macchine Guest scriveranno sulla cartella condivisa come utente libvirt-qemu e gruppo libvirt-qemu (visto da Host), pertanto la cartella condivisa dovrà appartenere a tale accoppiata utente:gruppo:
sudo chown libvirt-qemu:libvirt-qemu ~/virt-sharedInfine, per poter permettere anche agli utenti della macchina Host di accedere alla cartella condivisa, posso inserirli nel gruppo libvirt-qemu e dare i permessi anche ai proprietari del gruppo di scrivere nella cartella:
sudo usermod -aG libvirt-qemu <utente-host>
sudo chmod 775 ~/virt-sharedOccorre comunque sempre fare attenzione alle triplette dei permessi in quando gli utenti Guest agli occhi di Host scrivono come libvirt-qemu.
Alternativamente, se voglio operare prevalentemente attraverso un particolare utente della macchina Host, posso impostare che la scrittura da parte di qualsiasi utente di una macchina Guest sia effettuata con UID e GID pari a quelli del mio utente della macchina Host e quindi utilizzare una cartella normalissima.
Tale modifica viene effettuata tramite la modifica del file di configurazione /etc/libvirt/qemu.conf per le seguenti 2 voci (poi riavvio il servizio):
user = "+1000"
group = "+1000"
sudo systemctl restart libvirtd.serviceA questo punto posso accendere la macchina virtuale:
mkdir ~/shared-host # creo la cartella su cui monterò la cartella condivisa
sudo mount -t 9p -o trans=virtio /nome-filesystem ~/shared-host # montaggio cartella condivisaPer montare all’avvio la cartelle condivisa modifico il file /etc/fstab nella macchina virtuale aggiungendo la seguente riga:
/nome-filesystem /home/max/shared-host 9p trans=virtio,_netdev 0 0Vediamo le 2 opzioni di mount:
- 9p, protocollo di trasmissione client server;
- trans=virtio, transport method (virtio for using 9P over virtio);
- _netdev, monta il filesystem dopo aver avviato i servizi di rete.
Sezione 2 : 105 - Shell, scripting e gestione dati
2. 105.1 - Personalizzazione ed uso della shell
Nella cartelle /home/
- .bash_hystory;
- .bash_logout;
- .bashrc;
- .profile.
Questi file sono validi solamente per l’utente nella cui cartella home sono presenti. Sotto alla directory /etc troviamo invece gli analoghi file valevoli per tutti gli utenti, ossia che il singolo utente normale non può modificare. Il file .profile viene caricato ogni login (con inserimento della password) come ad esempio:
su -l <utente>
su - <utente>Sempre il file .profile viene letto solo se non esistono, nell’ordine:
- .bash_profile;
- .bash_login.
Il file .bashrc viene caricato ogni volta che lanciamo un terminale o lanciamo una shell bash figlia sempre da terminale. Gli alias sono scorciatoie a comandi che possono essere impostate all’interno dei file di personalizzazione della shell:
alias <alias>='<comando-parametri>' # configura un 'alias'
alias ls='ls -la' # esempio di impostazione di un 'alias'Quando stiamo usando la shell possiamo anche non utilizzare un alias tramite:
unalias <alias> # disattiva l'alias fino all'uscita dalla shell corrente
<alias> # esegue il comando senza aliasAll’interno di un file di personalizzazione posso anche impostare una funzione, ad esempio:
function status {
echo
who
uptime
ifconfig
uname -a
}Digitando status dalla shell vengono eseguiti i comandi inseriti nella funzione che abbiamo configurato. All’interno della cartella /etc/skel possiamo inserire tutti gli elementi che saranno presenti nella homedirectory di ogni nuovo utente creato (sia file che cartelle).
3. 105.2 - Personalizzazione e scrittura di script bash - 1
premesse
La prima riga di uno script è chiamata shebang e corrisponde a #! seguito dal percorso del comando che dovrà interpretare lo script, esempio:
#!/bin/bash
#!/bin/shQualsiasi altra riga all’interno di uno script che inizia con # è considerata un commento e non viene interpretata o eseguita. Uno script che non ha i permessi di esecuzione (x) può comunque essere eseguito come argomento al comando che deve interpretarlo / eseguirlo:
bash <script>
/bin/bash <script>Per poter eseguire lo script da solo va dato il relativo permesso di esecuzione (x) a seconda delle necessità:
chmod u+x <script> # solo all'utente proprietario
chmod ug+x <script> # all'utente proprietario ed agli utenti che appartengono al gruppo di appartenenza dello script
chmod +x <scrip> # a tutti gli utentiSe copio/sposto lo script in una cartella presente nella variabile $PATH posso lanciare lo script senza specificarne il percorso altrimenti:
./<script> # se lo script si trova nella cartelle corrente
<path/to/script>/<script> # con percorso relativo o assolutoIl seguente pezzo di codice presente nel file .profile aggiunge la cartella /bin a quelle in cui cercare comandi o script eseguibili:
if [ -d "$HOME/bin" ] ; then
PATH="$PATH:$HOME/bin"
fihello user
Il seguente script fa uso del comando read che prevede l’inserimento del valore di una variabile da parte dell’utente:
echo -e "inserisci il tuo nome...\c"
read nome
echo "hello $nome"L’opzione -e del comando echo permette di interpretare alcuni caratteri preceduti dal simbolo ** (escape) come per esempio \c che impedisce di andare a capo all’output.
creare ed eliminare utenti
Guardiamo ora al comando seq:
seq 5 # conta 1,2,3,4,5
seq 5 10 # conta 5,6,7,8,9,10
seq 5 2 10 # conta 5,7,9E scriviamo 3 pezzi di codice (script) che rispettivamente:
- creano 10 utenti con nome user1, user2, fino a user10;
- imposta una password iniziale pari a password;
- elimina i 10 utenti creati.
#crea 10 utenti
for num in $(seq 10); do
useradd user$num
done
#imposta la password iniziale
for num in $(seq 10); do
echo "user${num}:password"|chpasswd -c SHA512
done
#elimina i 10 utenti
for num in $(seq 10); do userdel user$num;Gli utenti creati possono essere facilmente visualizzati con:
tail -n 10 /etc/passwd | cut -d: -f1Negli script-bash la sequenza stringa$variabile viene correttamente interpretata mentre al contrario $variabilestringa viene interpretata come una variabile dal nome variabilestringa, per ovviare a questo la variabile può essere messa tra parentesi graffe come nell’esempio che precede.
4. 105.2 - Personalizzazione e scrittura di script bash - 2
cerca file, cartelle e collegamenti
Analizziamo il seguente codice:
if [[ $1 == "d" ]]
then
echo "cerco cartelle"
find / -maxdepth 1 -type d
elif [[ $1 == "l" ]]
then
echo "cerco link"
find / -maxdepth 1 -type l
elif [[ $1 == "f" ]]
then
echo "cerco file"
find / -maxdepth 1 -type f
else
echo "parametri errati"
fiA seconda del parametro inserito (d|l|f) restituisce una ricerca nella directory corrente rispettivamente della presenza di directory, collegamenti o files.
conto alla rovescia
Conto alla rovescia in secondi forniti dall’utente:
count=$1
while (( count > 0 ))
do
echo $count
sleep 1
(count --))
doneUtilizza il ciclo while per effettuare un conto alla rovescia tramite un parametro inserito al lancio dello script. Naturalmente mancano totalmente le verifiche riguardo al parametro inserito (che sia un numero intero).
controllo presenza file e invio mail
Il seguente script verifica la presenza di un file e ne invia il contenuto all’amministratore:
data=$HOME/data1.txt
if [ -e $data ]
then
mail -s "dati raccolti" root < $data
rm $data
else
echo "file non trovato!"
exit 2
fiL’invio di mail da riga di comando può anche essere eseguito tramite:
cat <file> | mail -s "dati raccolti" root # invia il contenuti di <file>
mail -s "dati raccolti" root <<< "testo" # invia quanto contenuto tra doppi apiciLa variabile $? contiene il codice di uscita dello script:
- 0, lo script è stato eseguito correttamente;
- per qualsiasi altro valore lo script non è stato eseguito correttamente.
Se vogliamo rendere eseguibili i nostri script per tutti gli utenti dobbiamo inserirli nella diretory /usr/local/bin.
5. 105.2 - Personalizzazione e scrittura di script bash - 3
Il comando source esegue comandi contenuti in altri file, analogo alla direttiva include del linguaggio C.
source <file>
echo $var
funzione1Il codice che precede stampa il contenuto della variabile $var ed esegue funzione1 che presumibilmente sono stati dichiarati in
6. 105.2 - Gli operatori &&, || e ; in Bash - Obiettivi 5.0
Operazioni concatenate su shell:
<comando1> && <comando2> # esegue 'comando2' solo se è andato a buon fine (exit '0' / variabile '$?') 'comando1'
<comando1> ; <comando2> # esegue 'comando2' indipendentemente dallo stato di uscita di 'comando1'
<comando1> || <comando2> # esegue 'comando2' solo se fallisce 'comando1'A questo punto posso creare una struttura tipo IF…THEN…ELSE:
<comando1> && <comando2> || <comando3>Facendo però attenzione che:
- comando2 viene eseguito se va a buon fine comando1;
- comando3 viene eseguito se fallisce comando2.
Quindi potrebbe succedere che comando1 viene eseguito correttamente e comando2 invece fallisce per qualche motivo e quindi viene eseguito ‘comando3’ anche se comando1 è andato a buon fine, quindi è meglio mettere come comando2 un comando che siamo sicuri non fallisca. La struttura precedente può essere utile per dirci se qualcosa non è stato eseguito correttamente da una serie di concatenazioni tipo &&, esempio:
<comando1> && <comando2> && <comando3> || echo "qualcosa KO"Vediamo un altro esempio che ci segnala se esiste connessione di rete:
while true
do
ping -pc 2 google.com &>/dev/null && echo "connection OK" || echo "connection KO"
sleep 1
done7. 105.3 - Gestione dati SQL - 1 - Non richiesto in LPI 5.0
installazione MariaDB
Per poter operare con dati SQL devo installare il relativo server sulla macchina. Posso scegliere se installare il server MySQL o MariaDB (quest’ultimo è un fork di MySQL 5.1). Per approfondire le caratteristiche e le differenze vedi al seguente link LINK . Procedura per installare MariaDB su Debian 11 (in sintesi):
sudo apt update # aggiorna i repository
sudo apt install mariadb-server # installa il server
sudo mysql_secure_installation # mette in sicurezza il server (rispondere alle domande che seguono)
Enter current password for root (enter for none): <ENTER>
Switch to unix_socket authentication [Y/n] n
Change the root password? [Y/n] n
Remove anonymous users? [Y/n] <ENTER>
Disallow root login remotely? [Y/n] <ENTER>
Remove test database and access to it? [Y/n] <ENTER>
Reload privilege tables now? [Y/n] <ENTER>Procedo poi a creare un utente amministratore per il server:
sudo mariadb
MariaDB [(none)]> GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'admin' WITH GRANT OPTION; # crea utente amministratore 'admin' con password 'admin'
MariaDB [(none)]> FLUSH PRIVILEGES; # ricarica le modifiche ai permessi
MariaDB [(none)]> exit
sudo systemctl status mariadb # verifica lo stato del server
sudo mysqladmin version # restituisce la versione e verifica che funzioni la connessionecreazione di database, tabelle e campi
mysql -uadmin -p
Enter password:
MariaDB [(none)]> help;Ogni comando va eseguito terminandolo con il simbolo ; mentre i comandi possono essere eseguito andando a capo (
MariaDB [(none)]> show databases; # mostra i databases
MariaDB [(none)]> create database db1; # crea 'db1'
MariaDB [(none)]> create table db1.clienti(id int AUTO_INCREMENT PRIMARY KEY, nome varchar(20) NOT NULL, cognome varchar(20) NOT NULL);Ed una tabella fornitori questa volta entrando nel db:
MariaDB [(none)]> use db1;
MariaDB [(db1)]> create table fornitori(id int AUTO_INCREMENT PRIMARY KEY, nome varchar(20) NOT NULL, cognome varchar(20) NOT NULL);
MariaDB [(db1)]> show tables;inserire i dati e visualizzarli
Per inserire dati devo conoscere la struttura:
MariaDB [(db1)]> describe clienti;
MariaDB [(db1)]> INSERT INTO clienti(nome,cognome) VALUES ("Mario","Rossi"); # il campo 'id' posso fare a meno di inserirlo in quanto si auto-incrementa
MariaDB [(db1)]> INSERT INTO clienti(nome,cognome) VALUES ("Carlo","Bianchi");
MariaDB [(db1)]> select * from clineti; # visualizza tutti i campi della tabella 'clienti'
MariaDB [(db1)]> select nome,cognome from clienti; # visualizza solo i campi 'nome' e 'cognome'
MariaDB [(db1)]> select * from clienti where id=1; # esegue una query
MariaDB [(db1)]> select * from clienti where nome="mario"; # non è case sensitivecreazione di un utente che gestisce db1 ed eliminazione di tabelle e del database stesso
Creiamo un utente che abbia accesso limitato ma pieni poteri su db1:
MariaDB [(db1)]> CREATE USER 'max'@'localhost' IDENTIFIED BY 'password';
MariaDB [(db1)]> SELECT user,host from mysql.user; # visualizza gli utenti
MariaDB [(db1)]> GRANT ALL PRIVILEGES ON db1.* TO 'max'@'localhost'; # attribuisce i permessi all'utente creato
MariaDB [(db1)]> FLUSH PRIVILEGES; # aggiorna i privilegi degli utenti
MariaDB [(db1)]> exitOra entriamo con l’utente appena creato:
mysql -umax -ppassword # la password si può digitare anche in chiaro
MariaDB [(none)]> show databases; # visualizzo solo il db che mi è stato assegnato
MariaDB [(none)]> use db1;
MariaDB [(db1)]> show tables;
MariaDB [(db1)]> drop table clienti; # elimino la tabella 'clienti'
MariaDB [(db1)]> show tables;
MariaDB [(db1)]> drop database db1; # elimino 'db1'
MariaDB [(none)]> show databases;
MariaDB [(none)]> exit;8. 105.3 - Gestione dati SQL - 2 - Non richiesto in LPI 5.0
Un database dump (ossia che è stato salvato in formato .sql) non è altro che un file di testo che contiene le varie istruzioni per creare all’interno di un database di destinazione le tabelle ed il loro contenuti (i dati) che sono stati precedentemente esportati da un altro database. Per fare il dump (esportare) di un database chiamato db2 e tutto il suo contenuto eseguo il seguente comando utilizzando un utente che abbia almeno i privilegi di lettura sul database che si vuole esportare:
mysqldump -uadmin -p db2 > db2.sql
Enter password:Ipotizziamo adesso di voler importare i dati contenuti nel db2.sql appena creato che contiene una tabella rubrica con i campi nome e cognome:
mysql -uadmin -p
Enter password:
MariaDB [(none)]> create database db2; # creo un database che possa contenere il dump
MariaDB [(none)]> exit
mysql -uadmin -p db2 < db2.sql; # importo il database contenuto in 'db2.sql'
Enter password:
mysql -uadmin -p db2 # entro direttamente nel 'db2' appena importato
Enter password:
MariaDB [(db2)]> show tables; # eseguo qualche 'query'
MariaDB [(db2)]> select * from rubrica;
MariaDB [(db2)]> describe rubrica; # osservo la struttura dei campi per poterli aggiornare
MariaDB [(db2)]> UPDATE rubrica set cognome="Rossi" where nome="Mario";
MariaDB [(db2)]> select * from rubrica; # verifico che l'aggiornamento sia andato a buon fine
MariaDB [(db2)]> select * from rubrica where nome="Mario" and cognome="Rossi"; # visualizza tutti i 'Mario Rossi' presenti nel 'db'
MariaDB [(db2)]> UPDATE rubrica set nome="Dario",cognome="Bianchi" where id=3; # aggiorna i campi indicati nel record con 'id=3'
MariaDB [(db2)]> DELETE from rubrica; # ATTENZIONE NON USARE in quanto cancella tutto il contenuto della tabella 'rubrica'
MariaDB [(db2)]> DELETE from rubrica where nome="Dario"; # elimina tutti i record il cui nome risulta essere 'Dario', se non vi sono record che soddisfano la caratteristica non cancella nienteQuando si è al prompt di MariaDB mi posso muovere sostanzialmente come quando sono nella shell:
C-r # esegue la ricerca inversa dei comandi già digitati (case sensitive, 'INVIO' per eseguire il comando trovato, 'ESC' per uscire dalla ricerca e modificare il comando trovato)
C-k # cancella tutto quanto fino a fine riga
C-a # sposta il cursore ad inizio riga di comando
C-e # sposta il cursore a fine riga9. 105.3 - Gestione dati SQL - 3 - Non richiesto in LPI 5.0
Ipotizziamo di avere a che fare con un db2 che contiene una tabella inventario costituita dai seguenti campi:
- id, numero intero che si auto-incrementa (la solita key);
- articolo, nome dell’articolo presente;
- magazzino, numero intero che identifica il magazzino in cui è stoccato l’articolo.
Eseguiamo quindi qualche operazione su db2:
mysql -uadmin -padmin db2 # entro direttamente in 'db2'
MariaDB [(db2)]> show tables;
MariaDB [(db2)]> select * from inventario; # visualizzo il contenuto della tabella
MariaDB [(db2)]> describe inventario; # osservo come sono strutturati i campi della tabella
MariaDB [(db2)]> select * from inventario where magazzino=1; # visualizzo gli articoli del magazzino '1'
MariaDB [(db2)]> select * from inventario where magazzino=1 ORDER BY articolo desc; # visualizzo gli articolo del magazzino '1' in ordine decrescente per 'articolo'
MariaDB [(db2)]> select * from inventario ORDER BY articolo asc; # visualizzo tutti il contenuto della tabella in ordine crescente per 'articolo'
MariaDB [(db2)]> select * from inventario GROUP BY magazzino; # vedo solamente il primo elemento presente in tabella per ogni valore diverso di 'magazzino' presente, ma non mi è molto utile
MariaDB [(db2)]> select count(*) from inventario GROUP BY magazzino; # visualizza un contatore che indica quanti elementi abbiamo per ogni valore diverso di 'magazzino', ma non è ancora molto utile
MariaDB [(db2)]> select magazzino,count(*) from inventario GROUP BY magazzino; # affianca il valore univoco di 'magazzino' al numero di elementi presenti per ogni valore univoco, ora l'informazione è un po' più utile10. 105.3 - Gestione dati SQL [4] - Non richiesto in LPI 5.0
Ipotizziamo il solito db2 con una tabella customers che contiene i seguenti campi:
- id;
- nome;
- cognome.
Poi una tabella orders strutturata come segue:
- id;
- date, data dell’ordine;
- customer_id, riferimento al cliente che ha fatto l’ordine tramite il suo id.
Posso estrarre dati dalle 2 tabelle confrontando id della tabella customer ed il campo customer_id della tabella orders. Questa operazione si chiama JOIN e posso lanciare 4 tipi di JOIN:
- INNER JOIN, estrae dati solo se i campi che vengono confrontati esistono in entrambe le tabelle (è l’impostazione di default, si può anche scrivere solamente JOIN);
- LEFT JOIN, estrae tutti i record della tabella indicata a sinistra del comando e solamente i record trovati nella tabella a destra del comando, se non vengono trovati dati indica NULL;
- RIGHT JOIN, estrae tutti i record della tabella indicata a destra del comando e solamente i record trovati nella tabella a sinistra del comando, se non vengono trovati dati indica NULL;
- FULL JOIN, estrae tutti i record di entrambe le tabelle, se non vengono trovati dati indica NULL.
Vediamo, come esempio, il comando LEFT JOIN:
mysql -uadmin -padmin db2 # entro direttamente in 'db2' digitando la pasword in chiaro
MariaDB [(db2)]> select * from customers; # visualizzo il contenuto della tabella 'customers'
MariaDB [(db2)]> select * from orders; # visualizzo il contenuto della tabella 'orders'
MariaDB [(db2)]> select * from orders LEFT JOIN customers ON orders.customer_id=customers.id; # mostra tutti i campi della tabella 'orders' (alla sinistra del comando) e solo i campi della tabella 'customers' (a destra del comando), dove non trovo corrispondenza inserisco 'NULL'
MariaDB [(db2)]> select date,nome,cognome from orders LEFT JOIN customers ON orders.customer_id=customers.id; # mostra solo alcuni campi
MariaDB [(db2)]> select date,nome,cognome from orders LEFT JOIN customers ON orders.customer_id=customers.id where nome="Mario"; # mostra tutti gli ordini di chi si chiama 'Mario'
MariaDB [(db2)]> select date,nome,cognome from orders LEFT JOIN customers ON orders.customer_id=customers.id where nome="Mario" and cognome="Rossi"; # mostra tutti gli ordini di 'Mario' (nome) e 'Rossi' (cognome)
MariaDB [(db2)]> select count(*),date,nome,cognome from orders LEFT JOIN customers ON orders.customer_id=customers.id where nome="Mario" and cognome="Rossi"; # raggruppa gli ordini di 'Mario Rossi' aggiungendo un campo in cui inserisce il totale dei record trovati con le caratteristiche indicate11. Test sul capitolo 105
Lezioni da n. 2 a n. 10.
Risposte giuste: 8 su 9.
Sezione 3 : 106 - Interfacce utente e Ambienti desktop
12. 106.1 - Installazione e configurazione di X11
Storicamente il file di configurazione di X11/Xorg è /etc/X11/xorg.conf. Oggi non abbiamo più questo file in quanto non più necessario. Per generare un tale file possiamo andare in ambiente console (non grafico, senza server grafico avviato) e digitare:
Xorg -configureOppure possiamo partire da un file di configurazione di esempio che possiamo trovare all’interno delle cartelle /etc. Strumenti di diagnostica:
xwininfo # mostra un mirino che una volta fatto clic su una finestra mostra varie utili informazioni
xdpyinfo | less # mostra tutte le informazioni riguardo Xserver, il display e gli schermi collegatiRappresentazione del server grafico X (X Server/Xorg):

X Server si frappone tra le periferiche I/O tastiera, mouse e schermo, collegati alla macchina e le applicazioni che vengono lanciate. Queste generalmente si trovano sulla stessa macchina, oppure possono anche trovarsi su una macchina collegata in remoto.
Ipotizziamo di avere:
- Server, un computer senza ambiente grafico (ip 192.168.122.2);
- Desktop, il nostro PC (ovviamente dotato di ambiente grafico X, ip 192.168.122.3 e variabile $DISPLAY:0)
Per poter lanciare una applicazione che si trova su Server e visualizzarla attraverso X-Server installato sulla macchine Desktop è indispensabile che le 2 macchine siano all’interno della stessa LAN, poi:
vi =/etc/X11/xinit/xserverrc # sulla macchina 'Desktop' e sostituisco il parametro di lancio del comando 'X' cambiandolo da '--nolisten tcp' con '--listen tcp' in modo che 'X-Server' rimanga in ascolto per poter eseguire applicazioni da macchine remote (va riavviato 'X')
xhost +192.168.122.2 # sulla macchina 'Desktop' per accettare connessioni dalla macchina 'Server' (funziona anche senza riavviare 'X')
export DISPLAY='192.168.122.3:0' # sulla macchina 'Server' in modo da indirizzargli le applicazioni che necessitano di 'X-Server'Ora ogni applicazione che lancio da Server che necessita di X-Server verrà lanciata su Desktop:
xterm &
xterm -display 192.168.122.3:0 &Abbiamo visto:
xhost # che serve a rendere accessibile 'X' da remoto
xhost + # disabilita 'xhost' e rende accessibile 'X' da chiunque
xhost - # riattiva 'xhost' con le impostazioni che aveva al momento in cui è stato disabilitato
xhost + <ip-address> # rende accessibile 'X' da 'ip-address'
xhost - <ip-address> # rende inaccessibile 'X' da 'ip-address'
echo $DISPLAY # numero dello schermo utilizzato da 'X'13. 106.1 - La struttura di Xorg
Rappresentazione del server grafico X (X Server / Xorg)

Xorg è un server grafico e si occupa di mediare le interazioni tra le applicazioni e l’utente attraverso le periferiche input (tastiera e mouse) e periferiche output (schermo). Le applicazioni comunicano con X-Server in entrambe le direzioni ed è anche possibile che l’applicazione-client si trovi anche su una macchina remota. Per poter interagire con le periferiche input/output Xorg le deve configurare ed esistono infatti i relativi file di configurazione (che vedremo nella prossima lezione).
In una ipotetica interazione tra utente e hardware il Display Server si inserisce appena dopo il kernel e gestisce l’interazione con tutte le applicazioni, compreso Window Manager e Desktop Environment.

14. 106.1 - File di configurazione di X11

Generalmente i file di configurazione si trovano:
- /etc/X11/xorg.conf, unico file;
- */etc/X11/xorg.conf.d/**, più di un file.
Servono a gestire e configurare le periferiche input/output e vengono letti tutti in ordine alfabetico (prima xorg.conf e poi i file all’interno della directory). Per fare un esempio inserisco il mio file di configurazione della tastiera che è servito ad impostare il layout italiano e impostare il tasto Blocca Maiuscole come fosse il tasto Ctrl:
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "it"
Option "XkbOptions" "ctrl:nocaps"
EndSectionPer ulteriori informazioni e aiuto:
man Xorg
man Xserver
man xkeyboard-configPossiamo trovare utili inforazioni anche al seguente LINK .
15. 106.1 - X11 Forwarding
Un metodo più sicuro per poter eseguire una applicazione che si trova su una macchina non dotata di Server-X su un’altra macchina (vedi lezione 13) è tramite ssh in quanto le informazioni trasmesse sono criptate (e non in chiaro come con xhost).
Sulla macchina remota modifichiamo /etc/ssh/sshd_config in modo che le applicazioni grafiche vengano reindirizzate (poi riavviamo il server ssh):
AllowAgentForwarding yes
AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
X11UseLocalhost noA questo punto ci colleghiamo dalla macchina locale tramite ssh alla macchina remota;
export DISPLAY # esporto la variabile per renderla disponibile anche nella shell figlia che verrà generata dal comando 'ssh'
ssh -Y <utente>@<ip-server> # il parametro '-Y' abilita 'X11 forwarding'E, una volta collegatomi alla macchina remota posso lanciare l’applicazione grafica che verrà visualizzata sulla macchina locale. E’ importante precisare che per utilizzare un Server-X è necessario, oltre che poter accedere alla macchina in cui è in esecuzione, essere autorizzati. Il comando xauth permette di gestire le tali autorizzazioni attraverso i c.d. MIT-MAGIC-COOKIE scritti all’interno del file .Xauthority presente nella home-directory. L’output del comando xauth è la rappresentazione leggibile/testuale del file binario .Xauthority:
xauth # lancia una shell interattiva
xauth> ? # fornisce i comandi disponibili
xauth> exit # noi non faremo uso della shell interattiva
xauth list # mostra tutti i 'cookies' che si possono utilizzare per collegarsi ai vari 'Server-X' avviati sulla macchina
xauth list $DISPLAY # mostra i 'cookies' per la sessione corrente
xauth extract <file> <cookie>:0 # esporta un 'cookie' di autorizzazione in 'file'
xauth merge <file> # importa un 'cookie' da 'file'La variabile $XAUTHORITY specifica dove si trova il file .Xauthority, se questa variabile non esiste il Server-X cerca il file all’interno della nostra home-directory. L’autorizzazione viene gestite automaticamente tramite:
- xhost, con scambio di dati in chiaro (vedi lezione 12);
- ssh, con scambio di dati criptato e quindi preferibile.
Possiamo volerla gestire manualmente tramite esportazione e importazione dei MAGIC-COOKIES (vedi sopra) quando vogliamo far utilizzare il Server-X in esecuzione da parte di un utente (max) ad applicazioni lanciate da altri utenti (user) che non lo stanno utilizzando e che non potrebbero accedere al Server-X per le restrizione di xhost:
<max>$ xauth extract <file> $DISPLAY # estrae l'autorizzazione per poter utilizzare il Server-X in esecuzione da parte dell'utente 'max'
<user>$ xauth merge <file> # importa l'autorizzazione ad utilizzare la sessione del Server-X in esecuzione da parte dell'utente 'max'
<user>$ export DISPLAY=:0 # ipotizzando che sia il numero utilizzato dal Server-X da 'max'
<user>$ xterm & # il comando viene gestito dal Server-X e visualizzato nella sessione grafica di 'max'Infine, per notizia, il file .xsession-errors, sempre nella nostra home-directory, registra gli errori prodotti a livello di server grafico X. Questo file non è sostitutivo dei vari log di sistema ed in particolare di journalctl che invece utilizzeremo più spesso per fare la diagnostica.
16. 106.2 - Setup di un display manager
Il display manager è un sofware che si occupa della gestione grafica del login degli utenti e permette di scegliere quale a Desktop Environment accedere:
- gdm, display manager di GNOME;
- kdm, display manager di KDE;
- xdm e lightdm, display manager indipendenti dal Desktop Environmet e generalmente più leggeri e versatili (per quanto anche gdm e kdm possono fare il login su qualsiasi Desktop Environment)
Ogni login manager ha la sua cartella di configurazione in /etc. Possiamo reperire istruzioni ed aiuto all’interno degli stessi file di configurazione o tramite le solite pagine del manuale man.
Funzioni utili/interessanti possono essere il login automatico di un utente utile per una macchina che si deve accendere e deve funzionare e basta. Per cambiare il display manager dopo averlo installato:
sudo apt install lightdm # installo il nuovo display manager
sudo systemctl disable gdm # disabilito quello attualmente in uso
sudo systemctl enable lightdm # abilito quello appena installato17. 106.2 - Protocolli di desktop remoto: XDMCP, VNC, Spice e RDP
I protocolli di Desktop Remoto permettono, come dice la parola stessa, di collegarsi ad una macchina da remoto e visualizzarne il Desktop. Ogni protocollo ha un’applicazione che gira lato Server (ossia sulla macchina a cui ci vogliamo collegare) ed una lato Client che installeremo sulla macchina da cui vogliamo effettuare il collegamento.
RDP (Remote Desktop Protocol)
Protocollo proprietario sviluppato da Microsoft anche se esistono client per tutti gli OS, è supportata la compressione del video ed abbiamo una criptazione a 128 bit.
VNC (Virtual Network Computing)
Stesso discorso di RDP ma con login che avviene a livello di VNC con credenziali e utenti VNC. Originariamente sviluppato da Olivetti ed Oracle oggi completamente opensource sotto licenza GPL e indipendente dalla piattaforma, supporta la criptazione.
XDMCP (X Display Manager Control Protocol)
E’ quasi sempre la scelta da non fare, è nativamente insicuro perchè non prevede la criptazione e non prevede neanche la compressione.
Spice
Funziona come VNC ma è pensato per essere eseguito su macchine virtuali. Abbiamo quindi uno Spice Server sulla macchina Host e degli Agent all’interno delle macchine virtuali. Molto spesso viene utilizzato sulla stessa macchina Host per collegarsi alle varie macchine virtuali installate. Utilizzato da QEMU per collegarsi al Desktop delle sue macchine virtuali.

18. 106.2 - Desktop Environment: XFCE, KDE, GNOME
Ubuntu
Utilizza GNOME in versione fortemente personalizzata. Premendo Attività o il tasto Super (Windows) viene presentato l’elenco delle applicazioni aperte ed il drawer dei vari Desktop Virtuali da cui posso riordinare complessivamente la Scrivania (i Desktop Virtuali vengono dinamicamente creati ogni volta che si utilizza quello libero). Ctrl+Alt+Up e Ctrl+Alt+Down per scorrere i Desktop Virtuali. Ubuntu Software è la versione grafica dei repository di Ubuntu. App Impostazioni per le varie personalizzazioni. Ubuntu LTS (Long Term Support) offre il supporto per 5 anni. Quando una operazione è di competenza dell’amministratore devo “sbloccare” l’impostazione inserendo la nostra password posto che l’utente appartenga al gruppo sudo.
GNOME
Rispetto ala versione di Ubuntu non c’è il Dock laterale ma questo viene visualizzato premendo Attività (o tasto Super/Windows) e mostra anche i Desktop Virtuali. Di default non è abilitato il tasto di riduzione a icona. La voci di menu delle applicazioni si trovano sulla barra in alto. Le impostazioni si trovano nella app impostazioni e personalizzazioni.
KDE
E’ il principale competitor di GNOME. Assomiglia un po’ a Windows in quanto ha la barra delle applicazioni in basso con il lancio delle applicazioni a sinistra e la system tray a destra. System settings con le varie impostazioni con la ricerca.
Cinnamon
Si propone di assomigliare a Windows, un po’ come KDE.
XFCE
E’ un Desktop Environment molto leggero e molto personalizzabile. Si possono aggiungere barre con pannelli e con contenuti di vario genere. Poco esoso di risorse e quindi adatto a macchine con lmitata capacità di CPU/Ram.
19. 106.3 - Accessibilità
Le opzioni di accessibilità sono pensate per persone con difficoltà varie di accesso o di utilizzo del computer (problemi di vista, di udito o di digitazione). Prendendo ad esempio il GNOME dobbiamo cercare nelle impostazioni la voce Accesso universale all’interno della quale troviamo le varie possibilità di configurazione (seguono alcuni esempi):
- per utenti ipovedenti: contrasto elevato, testo più grande e lettore a schermo;
- per utenti con problemi di udito: indicazione visiva (tipo lampeggiamento della finestra) invece del segnale acustico;
- per utenti con problemi di digitazione: abilitazione di una tastiera a schermo in luogo di quella fisica (per altre tastiere a schermo liberamente installabili nei vari Desktop Environment cerchiamo GOK);
- sempre per chi ha problemi di digitazione esiste la possibilità di controllare la ripetizione dei tasti in termini di tempo che intercorre tra la pressione di un tasto e la sua ripetizione se viene mantenuto premuto;
- ancora per problemi di digitazione avviamo l’assistente di digitazione che tratta una sequenza di tasti modificatori (Ctrl e Alt per esempio) come se fossero una combinazione unica dopo la pressione di INVIO.
20. Test sul capitolo 106
Lezioni da n. 12 a n. 19.
Risposte giuste: 3 su 5.
Sezione 4 : 107 - Task amministrativi
21. 107.1 - Gestione di utenti e gruppi e annessi file - 1
utenti
cat /etc/passwd- elenca tutti gli utenti del sistema;
- la password indicata con
xsia che sia impostata che non; - i campi sono separati da
:; - campo1, nome utente;
- campo2, password (
x); - campo3, UID (User Identifier);
- campo4, GID (Group Identifier);
- campo5, commento;
- campo6, home-directory;
- campo7, comando di shell (generalmente /bin/bash oppure /sbin/nologin per gli utenti di sistema che non hanno una shell valida);
- gli utenti di sistema hanno UID<1000 tranne root che ha
0; - gli utenti normali (non di sistema) hanno UID>=1000.
password
sudo cat /etc/shadow- può essere letto solo da root;
- i campi separati da
:; - campo1, username;
- campo2, password in formato hash (
!per un utente che non può accedere tipo anche per root quando si può solo usare sudo,*per gli utenti che non hanno impostato la password); - campo2, data ultimo cambio password;
- campo4, numero minimo di giorni che deve durare una password;
- campo5, numero massimo di giorni per cui poi bisogna cambiare password altrimenti l’account viene bloccato;
- campo6, scadenza password.
gruppi
cat /etc/group- campi sempre separati da
:; - campo1, nome gruppo;
- campo2, password per far parte del gruppo (indicato sempre
x); - campo3, GID (Group Identifier);
- campo4, utenti che fanno parte del gruppo;
- esiste sempre anche un gruppo con lo stesso nome dell’utente.
22. 107.1 - Gestione di utenti e gruppi e annessi file - 2
Gestione utenti:
Nella cartella /etc/skel, metto tutti i file e cartelle che voglio vengano replicati alla creazione di un nuovo utente nella sua home-directory.
adduser <utente> # è interattivo (debian)
useradd <utente> # non è interattivo (da usare per gli script) ed è utile conoscerne i parametri
passwd <user> # imposta la password di 'user' (o la cambia)
useradd <nome> -c <commento> -d <home-dir> -m -G <gruppi> # il parametro '-m' crea la directory se non esiste- /etc/passwd, contiene gli utenti;
- /etc/shadow, contiene le password (criptate);
- /etc/group, contiene i gruppi, wheel e sudo sono gruppi che permettono di eseguire il comando sudo.
id # fornisce i gruppi a cui appartengo
getent passwd | grep <utente> # il comando 'getent' fa il 'cat' di alcuni file (chiamati database) tipo 'passwd', 'group', 'shadow' e altri (funziona il completion)
userdel <utente> # elimina 'utente' ma non la cartella, lo spool delle email e lo spool di stampa
userdel <utente> -r # elimina tutto
usermod -d <cartella> # specifica una nuova home-directory (deve già esistere)
usermod -e <AAAA-MM-DD> # specifica la data di scadenza della password
usermod <utente> -g <gruppo> # cambia il gruppo primario
usermod <utente> -G <grupp1,gruppo2,...> # azzera i gruppi (tranne quello primario) ed aggiunge i gruppi indicati
usermod <utente> -aG <gruppo1,gruppo2,...> # aggiunge i gruppi indicati a quelli esistenti
usermod <utente> -l <nuovo-nome> # nuovo nome di login
usermod <utente> -L # blocca un account (aggiunge '!' prima della password nel file 'passwd')
usermod <utente> -U # sblocca l'account23. 107.1 - Gestione di utenti e gruppi e annessi file - 3
Il comando chage gestisce alcuni parametri legati alla scadenza della password degli utenti:
chage -l <utente> # mostra queste informazioni
chage <utente> -E <AAA-MM-DD> # imposta una data di scadenza alla password
chage <utente> -m <N> # giorni minimi che devono passare prima di un cambio password ('0' si può cambiare sempre)
chage <utente> -M <N> # giorni massimi di validità di una password ('-1' non scade mai)
chage <utente> -W <N> # giorni di preavviso prima del cambio password obbligatorio24. 107.1 - Gestione di utenti e gruppi e annessi file - 4
Gestire i gruppi.
groupadd <gruppo> # aggiunge 'gruppo' (GID>1000)
groupadd <gruppo> -p # aggiunge una password a 'gruppo'
getent group | grep <gruppo> # mostra la riga del file 'group' relativa a 'gruppo'
groupmod <gruppo> -n <nuovo-nome> # cambia il nome al gruppo
groupdel <gruppo> # elimina il gruppo25. 107.2 - Automatizzare e pianificare task amministrativi
at
Esegue un comando ad un determinato tempo indicato, se la macchina è spenta lo esegue appena la macchina viene riaccesa:
<comando> | at <time>
at <time> # entra in modalità interattiva chiede il comando da eseguire oppure una serie di comando ('Ctrl-D' per finire)
at <time> -f <file> # esegue i comandi all'interno di 'file'
<comando> | at now +1 minute
<comando> | at midnight
<comando> | at 16:00 Aug 12
atq # mostra lo stato dei comandi 'at'
at -l # come il comando precedente
atrm <N> # elimina il task 'N'- /etc/at.deny, file con gli utenti (uno per riga) che non possono utilizzare il comando at;
- /etc/at.allow, file con gli utenti (uno per riga) che possono utilizzare il comando at, se presente ignora at.deny.
cron
Permette di scadenzare, attraverso il servizio cron.service, l’esecuzione di script ad intervalli regolari. A differenza del comando at, se il computer è spento, lo script non verrà eseguito alla riaccensione della macchina ma alla successiva scadenza impostata. Utile per schedulazione di backup e schedulazione aggiornamenti:
sudo vi /etc/crontab # file da modificare per impostare 'cronjobs'All’inizio del file abbiamo l’inpostazine di alcune variabili che possono essere personalizzate:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=<utente>Osservando i 4 cronjobs presenti di default presenti nel file /etc/crontab si desume che posso inserire uno script nelle seguenti cartelle:
- /etc/cron.hourly, per eseguire lo script ogni ora;
- /etc/cron.daily, per eseguire lo script ogni giorno;
- /etc/cron.weekly, per eseguire lo script ogni settimana:
- /etc/cron.monthly, per eseguire lo script ogni mese.
Il comando crontab permette agli utenti normali di creare il proprio crontab-file salvato in /var/spool/cron/crontabs/
- /etc/cron.deny, file con gli utenti (uno per riga) che non possono utilizzare il comando crontab;
- /etc/cron.allow, file con gli utenti (uno per riga) che possono utilizzare il comando crontab, se presente ignora cron.deny;
crontab # crea il proprio 'crontab-file', inserire un 'cronjob' per riga con la medesima formattazione vista sopra ad esclusione del campo nome utente che va omesso in quanto è sottinteso essere chi ha lanciato 'crontab' ('Ctrl-D' per terminare l'inserimento)
crontab -e # modifica il 'crontab-file' utilizzando l'editor preferito ('select-editor' per cambiarlo)
crontab -l # stampa il 'crontab-file' dell'utente che lancia il comando
crontab -r # elimina il 'crontab-file' dell'utente che lancia il comandoanacron
Il comando anacron viene impostato modificando il relativo file (solo dall’utente root):
sudo vi /etc/anacrontabOgni volta che viene eseguito anacron (da root) viene verificato, per ogni cronjob elencato nel file di configurazione, se siano o meno trascorsi i giorni stabiliti per la sua riesecuzione, nel caso viene rieseguito. E’ quindi un comando che non può gestire cronjobs che abbiano intervalli inferiori al giorno ed è utile inserirlo in esecuzione in fase di startup della macchina.
Analogamente a cron, osservando i 3 cronjobs impostati di default, si desume che, all’esecuzione del comando anacron, verranno eseguiti gli script all’interno delle seguenti cartelle nel caso siano passati i giorni di intervallo stabiliti, precisamente:
- /etc/cron.daily, se è passato più di 1 giorno;
- /etc/cron.weekly, se sono passati più di 7 giorni;
- /etc/cron.monthly, se è passato più di un mese.
Non avendo in esecuzione un servizio permanente come nel caso di cron, il comando anacron viene richiamato regolarmente da anacron.timer gestito da systemd.
26. 107.2 - Systemd Timers e systemd-run
Systemd
Definizione
Si basa sulle c.d. units che possono essere gestire in maniera flessibile da systemd. La directory di default dove si trovano queste units è /lib/systemd/system. Se vogliamo sovrascrivere una unit, oppure aggiungerne altre, è meglio utilizzare la directory /etc/systemd/system che viene letta da systemd con precedenza. Esiste infine la directory /run/systemd/system che viene utilizzata prima delle precedenti 2, in questa directory si trovano tutte le unit “voloanti” o “temporanee”. Può essere utile per sovrascrivere temporaneamente un servizio, viene azzerata ad ogni riavvio.
Tipi di Unit
- .service, gestisce un servizio o un’applicazione sul sistema;
- .socket, definisce un socket e attiva la unit associata (.service) quando rileva attività sul socket;
- .device, definisce i devices;
- .mount, definisce un punto di mount;
- .automount, definisce un punto di mount che deve essere montato (ha sempre collegato una .mount unit);
- .swap, descrive lo spazio swap del sistema;
- .target, definisce dei punti di sincronizzazione per le varie unit di systemd;
- .path, definisce un percorso di attivazione delle unit;
- .timer, definisce intervalli in cui vengono eseguite le unit (come cron);
- .snapshot, salva degli snapshot dello stato di systemd;
- .slice, gestisce la gerarchia con Linux Control Group nodes;
- .scope, sono create da systemd e servono a gestire processi creati esternamente a systemd.
Unit - section
Si trova all’inizio del file di configurazione:
- Description, descrive la unit;
- Documentation, elenca documentazione a supporto;
- Requires, elenca altre units necessarie al corretto funzionamento che devono essere attivate, se una di queste non riesce, anche la presente unit fallisce;
- Wants, come Requires ma non implica il fallimento se una delle unit indicate non viene trovata o non viene caricata;
- BindsTo, come Requires inoltre termina la unit quando anche quella associata termina;
- Before, le units indicate vengono attivate dopo che è stata attivata la presente;
- After, le units indicate devono essere attivate prima della presente;
- Conflicts, elenca le unit che vengono stoppate quando viene avviata la presente in quanto confliggenti;
- Condition, condizioni da verificare prima di avviare la unit;
- Assert, come Condition ma, in caso non vi siano le condizioni per avviare la unit, la fa fallire.
Install - section
Si trova alla fine del file di configurazione: E’ una sezione opzionale e definisce il comportamento della unit in caso sia abilitata (enabled, ossia lanciata al boot). Crea un legame con le altre units per stabilire quando deve essere avviata:
- WantedBy, è la direttiva più comune e stabilisce una relazione simile a Wants nella Unit section. Se, ad esempio, abbiamo WantedBymulti-user.target*, verrà creata una directory chiamata multi-user.target.wants con un link simbolico a questa unit che stiamo configurando.
- RequiredBy, simile al precedente ma stabilisce una dipendenza che il fallimento della unit se non dovesse essere rispettata, questa crea una directory con finale .requires.
- Alias, la unit in questione può essere abilitata anche tramite altri alias.
- Also, abilita contestualmente anche altre unit che devono operare insieme a questa.
- DefaultInstance, template di una istance della unit.
Service - section
Configura la unit di tipo Service.
Socket - section
Configura la unit di tipo Socket.
Mount - section
Configura la unit di tipo Mount.
Automount - section
Configura la unit di tipo Automount.
Swap - section
Configura la unit di tipo Swap.
Path - section
Configura la unit di tipo Path.
Timer - section
Configura la unit di tipo Timer.
Slice - section
Configura la unit di tipo Slice.
LEZIONE
systemd unit
A titolo di esempio, modifico il file /etc/systemd/system/test.service come segue:
[Unit]
Description=Google Drive sync service
[Service]
User=max
WorkingDirectory=/home/max
Type=oneshot # per gli script/comandi
Type=simple # per i demoni
ExecStart=<comando> # percorso assolutosystemd timer
Allo stesso modo creo un timer modificando il file /etc/systemd/system/test.timer come segue:
[Unit]
Description=Timer di sincronizzazione per grive
[Timer]
OnBootSec=30s # dopo 30 secondi dall'avvio
OnUnitActiveSec=300s # e dopo ogni 5 minuti
Unit=grive-sync.service # non è necessario quando il timer ed il servizio hanno lo stesso nome
[Install]
WantedBy=timers.target # questo servizio viene avviato quando vengono avviati i timer di systemdutilizzo
sudo systemctl daemon-reload # ricarica le units
systemctl status test.service
sudo systemctl start test.service # esegue 'one-shot' la unit
sudo systemctl enable test.timer # abilita il timer per avviarsi al reboot
sudo systemctl start test.timer # avvia il timer
sudo systemctl list-timers # elenca i timers attivisystemd-run
systemd-run esegue dei timer creandoli al volo (tipo il comando at) da eseguire una volta soltanto creando (nella directory /run/systemd/system) una unit ed un timer non permanenti:
sudo systemd-run --on-active="30s" /usr/bin/touch /home/max/newfilesystemd-run ci può servire a fare la diagnostica per la configurazione di nuove unit, esempio:
sudo systemd-run env # ad esempio per stampare le variabili d'ambiente in systemd
sudo journalctl -u <unit-temporanea-creata> # osservo l'output generato dal comando precedente27. 107.3 - Localizzazione e internazionalizzazione
Il file /etc/timezone non è presente in RedHat, Fedora e CentOS, pertanto facciamo riferimento al link simbolico /etc/localtime che, a sua volta, fa riferimento al file binario della nostra localizzazione, che è un file c.d. timezone-data:
zdump /etc/localtime # interroga l'orario sulla timezone correntePer riconfigurare la timezone era disponibile il comando tzconfig (deprecato) oggi invece utilizziamo:
sudo dpkg-reconfigure tzdata
tzselect # cambia timezone per il singolo utente fornendo le istruzioni per modificare la riga in '.profile'Anche systemd prevede la possibilità di variare la timezone:
timedatectl # mostra l'attuale timezone
timedatectl list-timezones # elenca tutte le timezone
sudo timedatectl set-timezone <timezone> # con completionIl comando locale restituisce invece le variabili localizzate:
which locale
locale # restituisce le variabili di localizzazione
locale -a # mostra tutti i locale disponibili
locale -m # mostra tutte le codifiche dei caratteri disponibili
sudo dpkg-reconfigure locales # per riconfigurare i localeTra le variabili localizzate:
- LC_LANG, cambia anche tutte le altre tranne LANG;
- LANG, può essere variato anche da solo.
sudo dpkg-reconfigure locales # cambia tutte le variabili di localizzazioneIl comando date infine permette di stampare la data nella timezone locale con vari parametri e vari formati, utile negli script.
28. 107.3 - Localizzazione e internazionalizzazione [2]
Il codice ASCII è quello più vecchio, che rispondeva alle esigenze della lingua inglese, la quale non aveva lettere accentate ed era costituito da 128 caratteri di cui 96 stampabili:
- codifica ASCII;
- codifica ISO-8859, aggiungono altri 96 caratteri;
- codifica unicode, contiene più di 128k caratteri;
- codifica UTF-8, un’implementazione di unicode, utilizza 8 bit (o multipli) per rappresentare ogni carattere.
La differente codifica utilizzata (ad esempio) da Linux e Windows, fa si che nel salvataggio del file il carattere a-capo-riga venga rappresentato diversamente:
file <file-testo> # mostra la codifica utilizzata dal fileIl comando iconv permette di convertire un file di testo tra diverse codifiche:
iconv -l # elenca tutte le codifiche disponibili
iconv <file> -t ASCII # converte in formato ASCII
iconv <file> -t ASCII//IGNORE # in caso di presenza di caratteri non convertibili li omette
iconv <file> -t ASCII//TRANSLIT # in caso di presenza di caratteri non convertibili li sostituisce con un carattere simile
iconv <file> -f UNICODE -t ASCII/TRANSLIT -o <file-output> # il parametro '-f' indica la codifica di 'file'29. Test sul capitolo 107
Lezioni da n. 21 a n. 28.
Risposte giuste: 11 su 13.
Sezione 5 : 108 - Servizi essenziali di sistema
30. 108.1 - Mantenere l’orario del sistema
ntp, network time protocol, permette di mantenere sincronizzato l’orologio di sistema con server autorevoli:
sudo apt install ntpdate
sudo ntpdate pool.ntp.org # aggiorna l'orario locale manualmente
sudo apt install ntp # servizio che aggiorna automaticamente l'orario con un server autorevole tramite un demone gestito da systemd
sudo systemctl status ntp.service
sudo systemctl enable ntp.service
sudo systemctl start ntp.service
ntpq -p # mostra i server utilizzati
man ntpq/etc/ntp.conf è il file di configurazione (sostanzialmente indica i server utilizzati). Il comando hwclock gestisce l’orologio hardware del computer:
sudo hwclock --show # mostra orario e informazioni
sudo hwclock --hctosys # (h)ard(w)are clock (to) (sys)tem, allinea l'orologio di sistema con quello hardware
sudo hwclock --systosys # (sys)tem (to) (h)ard(w)are clock, allinea l'orologio hardware con quello di sistema, viene eseguito ogni volta che il servizio ntp viene stoppato (es. allo spegnimento della macchina)31. 108.1 - chrony / chronyc
chrony è un altro gestore dell’orologio di sistema:
sudo apt search chrony
sudo apt search chronyc
sudo apt install chrony
sudo vi /etc/chrony/chrony.conf
chronyc # comando (console)
chronyd # demone
sudo chronyc online # va online
sudo chronyc activity # mostra le attività in corso
sudo chronyc offline # torna offline
man chronyAndare periodicamente online/offline sono operazioni che si possono automatizzare tramite i relativi strumenti studiati nelle lezioni precedenti.
32. 108.1 - timedatectl
Il comando timedatectl fa parte di systemd e mostra le informazioni del timezone locale:
timedatectl --help # semplice, da vedere
timedatectl status # medesimo output come lanciato senza parametri
timedatectl list-timezones # elenca tutte le timezones disponibili
sudo timedatectl set-timezone <ZONE> # con la completion abilitata
sudo timedatectl set-time "AAAA-MM-GG HH:MM:SS" # cambia l'orario manualmente (se non è attiva la sincronizzazione con server remoto
sudo timedatectl set-ntp 0 # disabilita la sincronizzazione con server autorevole
sudo timedatectl set-ntp 1 # abilita la sincronizzazione33. 108.2 - I log di sistema - 1 - syslog
facility e priority
I vari log generati dal sistema e dai programmi possono essere suddivisi in diverse categorie (0-23) chiamate facility che a loro volta hanno diverse priority (0-7) a seconda della gravità del problema sottostante al messaggio di log, vediamole entrambe.
Facilities
| Code | Keyword | Description |
|---|---|---|
| 0 | kern | kernel messages |
| 1 | user | user-level messages |
| 3 | daemon | rsystem daemons |
| 4 | auth | security/authorisation messages |
| 5 | syslog | internal syslog messages |
| 6 | lpr | line printer subsystem |
| 7 | news | netrwork news subsystem |
| 8 | uucp | UUCP subsystem |
| 9 | cron | clock daemon |
| 10 | authpriv | security/authorisation messages |
| 11 | ftp | FTP daemon |
| 12 | ntp | NTP subsystem |
| 13 | security | log audit |
| 14 | console | log alert |
| 15 | solaris-cron | scheduling daemon |
| 16-23 | local0..local7 | locally used facilities |
Priorities
| Value | Severity | Keyword (deprecated) | Description |
|---|---|---|---|
| 0 | Emergency | emerg (panic) | System is unusable |
| 1 | Alert | alert | Action must be taken |
| 2 | Critical | crit | Critical conditions |
| 3 | Error | err (error) | Error conditions |
| 4 | Warning | warning (warn) | Warning conditions |
| 5 | Notice | notice | Normal but significant |
| 6 | Informational | info | Informational messages |
| 7 | Debug | debug | Debug-level messages |
rsyslog
Iniziamo a dire che il demone syslog è stato sostituito da rsyslog:
systemctl status syslog.service # è infatti un alias di 'rsyslog.service'Il file di configurazione /etc/rsyslog.conf ha una sezione RULES in cui devo inserire le regole per catturare ed archiviare i vari log, esempio:
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.=warn /var/log/kern.logLa parte a sinistra descrive i log da intercettare mentre la parte a destra descrive il file dove questi log vanno registrati:
-, davanti al file scrive su buffer poi su disco, se viene omesso scrive direttamente su disco;=, indica esattamente quella priorità (altrimenti intercetta i log da quella priorità in su, in ordine di gravità);;, divide 2 regole;none, significa nessuna priorità, sostanzialmente esclude le facility a cui è aggiunto;*, significa tutte le facility o priority a seconda se viene messo;,, divide le facility da intercettare.
Infine possiamo anche stabilire regole su facility locali (local0–local7):
local1.info <log-file> # inserisco la facility personalizzata
sudo systemctl restart rsyslog # riavvio per rendere effettiva la regola
logger -p local1.warn "prova warning" # scrivo manualmente il log34. 108.2 - I log di sistema - 2 - logrotate
E’ importante comprimere e archiviare i log ed eliminarli quando sono vecchi. A questa funzione adempie il comando logrotate che viene lanciato quotidianamente da cron (si trova infatti nella cartella /etc/cron.daily):
- /etc/logrotate.conf, file di configurazione;
- /etc/logrotate.d, cartella in cui vi sono le regole per i singoli comandi.
Le regole sono scritte nella seguente forma:
log-file {
<regole>
}Alcuni regole sono:
- monthly, rotazione mensile;
- rotate N, eliminare le rotazioni >N;
- compress, comprime le rotazioni;
- delaycompress, effettua la compressione alla successiva rotazione;
- missingok, il file di log potrebbe anche non esserci;
- notifempty, non eseguire la rotazione se il file è vuoto;
- create 644 root root, crea i file con i permessi, user e group indicati;
- maxsize
, al raggiungimento di SIZE effettua la rotazione, anche prima che sia passato il periodo previsto; - minsize
, prima di fare la rotazione il file deve raggiungere SIZE, anche se il periodo previsto è stato raggiunto.
35. 108.2 - I log di sistema - 3 - journalctl
journalctl si occupa dei log di sistema:
man journalctl
journalctl # visualizza tutti i log dal primo all'ultimo
journalctl -r # visualizza tutti i log partendo dai più recenti
journalctl --unit=<Unit> # visualizza i log di 'Unit'
journalctl -f # segue in tempo reale i logPer navigare i log posso usare le frecce Up/Down ma anche Left/Right per vedere le righe lunghe. I log di journalctl vengono registrati nella directory /var/log/journal ma non sono scritti in formato testuale ma binario e quindi non sono visualizzabili da comandi quali cat oppure less ma sono solamente gestibili (appunto) dal comando journalctl. /etc/systemd/journald.conf è il file configurazione in cui troviamo alcune impostazioni simili a logrotate:
man 5 journald.conf # per vedere le varie opzioniTODO 36. 108.2 - I log di sistema - 4 - approfondimento su journalctl e systemd-cat
journalctl -b # log dall'ultimo boot
journalctl -b -r # log dell'ultimo boot dal più recenteNel file di configurazione /etc/systemd/journald.conf la voce Storage=persistent significa che vengono mantenuti anche i log dei boot precedenti:
journalctl --list-boots # elenca i boot precedenti ('0' il presente '-1' il penultimo ecc...)Gli utenti che appartengono al gruppo adm, possono vedere tutti i messaggi di systemd-journal. Altri comandi:
dmesg # messaggi del kernel
journalctl -k # mostra gli stessi messaggi come prima
journalctl -k -b -5 # messaggi kernel di 5 boot precedenti
journalctl --disk-usage # spazio disco utilizzato dai messaggi log
sudo journalctl --vacuum-size=50M # elimina i messggi log eccedenti per rientrare nel limite di 50M
sudo journalctl --vacuum-time=1month # elimina i log più vecchi di 1 meseNel file /etc/systemd/journald.conf, il parametro SystemMaxUse=50M imposta il max di spazio.
ls | systemd-cat # redirige nei log
systemd-cat ls # come sopra man
systemd-cat -t identifier ls | systemd-cat -t # output di lssystemd-cat è come logger. /var/log/journal con cartelle e file binari.
journalctl --directory=<directory> # legge i log anche di un altra macchina
journalctl --file <file>TODO 37. 108.2 - I log di sistema - 5 - relazione tra syslog e journalctl
- syslogd, rsyslogd, /var/log/syslog - file
- journald, /var/log/journal - cartella
- /etc/rsyslog.conf - sezione MODULES module(load=“imuxsock”)
module(load=“imjournal”)- x Fedora raccoglie i log da journalctl- /etc/rsyslog.d/50-default.conf