unito differenti repository
122
lpic/101/001_ispezione_hw.md
Normal file
@ -0,0 +1,122 @@
|
||||
## Comandi di ispezione delle periferiche
|
||||
|
||||
I comandi `lspic` e `lsusb` elencano tutti i dispositivi PCI e USB identificati dal SO. Ogni parte hardware richiede un componente software per controllare il dispositivo corrispondente, chiamato *kernel modules*. I moduli el kernel LInux relativi ai dispositivi hardware sono anche chiamati *drivers*.
|
||||
|
||||
### lscpi
|
||||
|
||||
```bash
|
||||
> lspci
|
||||
00:00.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 Root Complex
|
||||
00:00.2 IOMMU: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 IOMMU
|
||||
00:01.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge
|
||||
00:01.2 PCI bridge: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 PCIe GPP Bridge [6:0]
|
||||
00:01.3 PCI bridge: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 PCIe GPP Bridge [6:0]
|
||||
```
|
||||
I numeri esadecimali all'inizio di ogni riga sono gli indirizzi univoci del corrispondente dispositivo. Per ottenere maggiori dettagli su un dispositivo:
|
||||
|
||||
```bash
|
||||
lspci -s 04:00.0 -v
|
||||
|
||||
04:00.0 Network controller: Intel Corporation Wi-Fi 6 AX200 (rev 1a)
|
||||
Subsystem: Intel Corporation Wi-Fi 6 AX200NGW
|
||||
Flags: bus master, fast devsel, latency 0, IRQ 33, IOMMU group 0
|
||||
Memory at fcb00000 (64-bit, non-prefetchable) [size=16K]
|
||||
Capabilities: [c8] Power Management version 3
|
||||
Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
|
||||
Capabilities: [40] Express Endpoint, IntMsgNum 0
|
||||
Capabilities: [80] MSI-X: Enable+ Count=16 Masked-
|
||||
Capabilities: [100] Advanced Error Reporting
|
||||
Capabilities: [14c] Latency Tolerance Reporting
|
||||
Capabilities: [154] L1 PM Substates
|
||||
Kernel driver in use: iwlwifi
|
||||
```
|
||||
Il **modulo del kernel** puo' essere identificato nella riga `Kernel driver in use:`.
|
||||
|
||||
Un modo rapido per verificare quale modulo del kernel e' in uso per il dispositivo specificato:
|
||||
|
||||
```bash
|
||||
lspci -s 04:00.0 -k
|
||||
|
||||
04:00.0 Network controller: Intel Corporation Wi-Fi 6 AX200 (rev 1a)
|
||||
Subsystem: Intel Corporation Wi-Fi 6 AX200NGW
|
||||
Kernel driver in use: iwlwifi
|
||||
Kernel modules: iwlwifi
|
||||
```
|
||||
|
||||
### lsusb
|
||||
|
||||
```bash
|
||||
lsusb
|
||||
|
||||
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
|
||||
Bus 001 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver
|
||||
Bus 001 Device 003: ID 8087:0029 Intel Corp. AX200 Bluetooth
|
||||
Bus 001 Device 004: ID 3434:0381 Keychron Keychron V8
|
||||
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
|
||||
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
|
||||
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
|
||||
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
|
||||
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
|
||||
```
|
||||
|
||||
Per maggiori dettagli su un dispositivo specifico:
|
||||
|
||||
```bash
|
||||
lsusb -vd 3434:0381
|
||||
```
|
||||
|
||||
### lsmod
|
||||
|
||||
Mostra un elenco di tutti i moduli attualmente caricati:
|
||||
|
||||
```bash
|
||||
lsmod
|
||||
|
||||
Module Size Used by
|
||||
nft_chain_nat 12288 3
|
||||
xt_MASQUERADE 16384 1
|
||||
nf_nat 65536 2 nft_chain_nat,xt_MASQUERADE
|
||||
bridge 389120 0
|
||||
stp 12288 1 bridge
|
||||
llc 16384 2 bridge,stp
|
||||
```
|
||||
dove `Size` indica la RAM occupata da modulo, byte. Mentre `Used by` indica i moduli dipendenti dal modulo colonna `Module`.
|
||||
|
||||
### modprobe
|
||||
|
||||
Comando usato per *caricare* o *scaricare* i moduli del kernel.
|
||||
|
||||
```bash
|
||||
modprobe -r module
|
||||
|
||||
# se module non sia usato da un processo in esecuzione sul sistema
|
||||
```
|
||||
|
||||
### lscpu e lshw
|
||||
|
||||
Mostra informazioni riguardo alla cpu e all'hardware del sistema.
|
||||
|
||||
### modinfo
|
||||
|
||||
Mostra una descrizione del modulo specificato: `modinfo nvme_core`. Per la lista di tutti i parametri disponibili: `modinfo -p nvme_core`.
|
||||
|
||||
I parametri personalizzati possono essere resi persistenti includendoli nel file `/etc/modprobe.conf/` o in file con estensione .conf nella directory `/etc/modprobe.d/`.
|
||||
|
||||
Per impedire il caricamento di un modulo inserire la riga `blacklist module` nel file `/etc/modprobe.d/blacklist.conf`.
|
||||
|
||||
## File informativi e File dei dispositivi
|
||||
|
||||
I comandi precedenti sono dei front-end per leggere le informazioni hardware memorizzate dal SO. Tali informazioni sono presenti in file conservati nelle directory `/proc` e `/sys`.
|
||||
|
||||
La directory `/proc` contiene informazioni relative ai processi in esecuzione e alle risorse hardware. Alcuni dei file importanti:
|
||||
|
||||
- `/proc/cpuinfo`
|
||||
- `/proc/meminfo`
|
||||
|
||||
`/sys` contiene informazioni relative ai dispositivi hardware.
|
||||
|
||||
Ogni file all'interno della directory `/dev/`, invece, e' associato a un dispositivo di sistema, in particolare a un dispositivo di archiviazione. I dispositivi rimovibili sono gestiti da `udev`, che crea i dispositivi corrispondenti in `/dev/`. Quando vengono rilevati dei nuovi dispositivi, `udev` cerca una regola corrispondente nella cartella `/etc/udev/rules.d/`.
|
||||
|
||||
## Dispositivi di archiviazione
|
||||
|
||||
Generalmente chiamati *block device*, in quanto i dati vengono letti in blocchi di dati. Ogni dispositivo a blocchi e' identificato da un file in `/dev/`. Dalla versione 2.6 del kernel, tutti i dispositivi, indipendentemente dal tipo di hardware, sono identificati come dispositivi SCSI, tramite la sigla `sd`. Le partizioni sono elencate numericamente. L'eccezione sono le *schede SD* e i dispositivi *nvme*.
|
66
lpic/101/002_avviare_il_sistema.md
Normal file
@ -0,0 +1,66 @@
|
||||
## BIOS o UEFI
|
||||
|
||||
Il kernel viene caricato da un programma chiamato *bootloader*, a sua volta caricato da un firmware preinstallato come il BIOS o UEFI. Una volta caricato, il kernel continua il processo di avvio identificando e caricando l'hardware.
|
||||
|
||||
### BIOS
|
||||
|
||||
Il BIOS (*Basic Input/Output System*) e' un programma memorizzato in un chip di memoria non volatile collegato alla scheda madre.
|
||||
|
||||
I primi 440 byte nel primo dispositivo di archiviazione - seguendo l'ordine definito nel BIOS - sono il primo stadio del bootloader (*bootstrap*). I primi 512 byte di *ogni* dispositivo di archiviazione sono denominati *MBR* e contengono la tabella delle partizioni.
|
||||
|
||||
I passaggi per l'avvio di un sistema dotato di BIOS sono:
|
||||
|
||||
- Il processo POST (*power-on self-test*) identifica semplici guasti hardware
|
||||
- Il BIOS attiva i componenti di base per caricare il sitema
|
||||
- Il BIOS carica il primo stadio del bootloader dall'MBR (i primi 440 byte nel primo dispositivo di archiviazione)
|
||||
- Il primo stadio del bootloader richiama il secondo, responsabile del caricamento del kernel.
|
||||
|
||||
### UEFI
|
||||
|
||||
UEFI (*Unified Extensible Firmware Interface*), e' sempre un firmware, come il BIOS, ma e' in grado di identificare le partizioni e leggere diversi filesystem. Inoltre non si basa sull'MBR, prendendo in considerazioni solo le impostazioni memorizzate nella sua memoria non volatile (NVRAM). Nella partizione *ESP* (*EFI System Partition*), di un *qualsiasi filesystem compatibile* (es. FAT32), sono contenuti dei programmi, chiamati *EFI applications*, che vengono eseguiti automaticamente o richiamati da un menu d'avvio. Una di queste applicazioni e' il bootloader.
|
||||
|
||||
I passaggi per l'avvio di un sistema con UEFI sono:
|
||||
|
||||
- Il processo POST (*power-on self-test*) identifica semplici guasti hardware
|
||||
- UEFI attiva i componenti di base per caricare il sitema
|
||||
- UEFI esegue l'applicazione predefinita memorizzata nel filesystem della partizione ESP. Di solito, il bootloader
|
||||
- Il bootloader carica il kernel.
|
||||
|
||||
UEFI supporta una funzione chiamata **Secure Boot**, che consente l'esecuzione solo di applicazioni EFI firmate, ossia autorizzate dal produttore.
|
||||
|
||||
### Bootloader
|
||||
|
||||
Uno dei piu' utilizzati e' GRUB. Permette di passare dei parametri al kernel, seguendo il modello `option=value`.
|
||||
|
||||
Alcuni dei parametri:
|
||||
|
||||
- `init`: imposta un iniziatore di sistema alternativo, per esempio `init=/bin/bash`
|
||||
- `systemd.unit`: imposta il *target* da attivare, per esempio: `systemd.unit=graphical/target`
|
||||
- `mem`: imposta la qualità di RAM disponibile per il sistema
|
||||
- `quiet`: nasconde i messaggi di avvio
|
||||
- `root`: imposta la partizione di root
|
||||
- `rootflags`: opzioni di mount per il filesystem di root
|
||||
|
||||
I parametri del kernel devono essere aggiunti al file `/etc/default/grub` alla riga `GRUB_CMDLINE_LINUX` per renderli persistenti.
|
||||
|
||||
Una volta che il sistema e' in esecuzione, i parametri usati per la sessione corrente sono visibili nel file:
|
||||
|
||||
```bash
|
||||
cat /proc/cmdline
|
||||
|
||||
BOOT_IMAGE=/vmlinuz-6.11.2-amd64 root=/dev/mapper/pc--vg-root ro systemd.show_status=1 quiet splash
|
||||
```
|
||||
|
||||
## Inizializzazione del sistema
|
||||
|
||||
L'inizializzazione del SO inizia quando il bootloader carica il kernel nella RAM. Il kernel aprira' l'*initramfs* (*initial RAM filesystem*), un filesystem temporaneo usato durante il processo di avvio. Il suo scopo principale e' quello di fornire i moduli richiesti, in modo che il kernel possa accedere al filesystem root *reale* del SO.
|
||||
|
||||
Il kernel, non appena il filesystem root e' disponibile, montera' tutti i filesystem configurati in `/etc/fstab`, quindi eseguira' il primo programma, chiamato `init`, responsabile dell'esecuzione di tutti gli script e demoni di inizializzazione del sistema. Solo ora initramfs viene rimosso dalla RAM.
|
||||
|
||||
### Ispezionare l'inizializzazione
|
||||
|
||||
Tutti gli errori generano messaggi. Lo spazio di memoria in cui il kernel memorizza i suoi messaggi e' chiamato *kernel ring buffer*.
|
||||
|
||||
Un comando per visualizzare i messaggi del kernel e' `dmesg -T`. Nei sistemi che usano *systemd* e' possibile usare il comando `journalctl -k`. L'opzione `-D` puo' essere usata per leggere messaggi di registro al di fuori della cartella `/var/log/journal`.
|
||||
|
||||
I messaggi di log sono memorizzati in vari file all'interno della directory `/var/log/`.
|
113
lpic/101/003_init_runlevel_riavvio_e_spegnimento.md
Normal file
@ -0,0 +1,113 @@
|
||||
## Sistema di init
|
||||
|
||||
I servizi (o *demoni*) possono essere controllati da script di shell, come in `SysVinit`, o da un programma e dai suoi file di configurazione, come in `systemd`.
|
||||
|
||||
Il sistema di init e' il primo programma lanciato dal kernel, quindi il suo **PID** (*Process Identification Number*) sara' sempre 1.
|
||||
|
||||
### SysVinit
|
||||
|
||||
Fornisce un set predefinito di stati di sistema, chiamati *runlevel*, numerati da 0 a 6.
|
||||
|
||||
- **runlevel 0**: spegnimento del sistema
|
||||
- **runlevel 1**, s o single: modalita' utente singolo, senza rete (manutenzione)
|
||||
- **runlevel 2**,**3** o **4**: modalita' multiutente con accesso tramite console
|
||||
- **runlevel 5**: modalita' multiutente grafica
|
||||
- **runlevel 6**: riavvio del sistema
|
||||
|
||||
Il programma responsabile della gestione dei runlevel e dei demoni associati e' `/sbin/init`. Identifica il runlevel richiesto, definito nel file `/etc/inittab` o da un parametro del kernel, e carica gli script associati, definiti nella directory `/etc/init.d/`. Ogni runlevel ha una cartella `/etc/rcX.d/` con all'interno gli script che vengono eseguiti al runlevel corrispondente. Questi sono dei collegamenti simbolici agli script presenti in `/etc/init.d/`. La prima lettera del nome del collegamento indica se il servizio deve essere avviato (S, start), terminato (K, kill), ecc. per il runlevel corrispondente.
|
||||
|
||||
La sintassi del file `/etc/inittab` usa il seguente formato:
|
||||
|
||||
```bash
|
||||
id:runlevels:action:process
|
||||
```
|
||||
Le possibili azioni:
|
||||
|
||||
- **boot**: il processo sara' eseguito durante l'inizializzazione del sistema
|
||||
- **bootwait**: il processo sara' eseguito durante l'inizializzazione del sistema e init attendera' fino a termine prima di continuare
|
||||
- **sysinit**il processo sara' eseguito dopo l'inizializzazione del sistema
|
||||
- **wait**: il rpocesso verra' eseguito per il runlevel indicato e init attendera' fino al termine per continuare
|
||||
- **respawn**: il processo verra' riavviato, se viene terminato
|
||||
- **ctrlaltdel**: il processo sara' eseguito quando init riceve il segnale di SIGINT, attivato alla pressione di ctrl+alt+canc
|
||||
|
||||
Il runlevel predefinito e' definito nello stesso file: `id:x:initdefault`. `x` indica il numero del runlevel.
|
||||
|
||||
Ogni volta che il file `/etc/inittab` viene modificato, per ricaricare la configurazione, dare il comando: `telinit q`. IL comando puo' essere usato anche per spostarsi tra i runlevel, senza dover riavviare. Ad esempio, `telinit 1` cambia il sistema al runlevel 1.
|
||||
|
||||
Il comando `runlevel` mostra il runlevel corrente.
|
||||
|
||||
### systend
|
||||
|
||||
I servizi vengono definiti come *units*. Ogni unita' e' composta da un nome, un tipo e un file di configurazione.
|
||||
|
||||
Esistono sette tipi di unita':
|
||||
|
||||
- **service**
|
||||
- **socker**: puo' essere un socket di rete o un socket del filesystem (utilizzato per la comunicazione tra processi che si trovano sulla stessa macchina). Tutte le unita' socket hanno un unita' di servizio corrispondente, caricata quando il socket riceve una richiesta
|
||||
- **device**: associata a un dispositivo hardware identificato dal kernel
|
||||
- **mount**: una definizione del punto di mount nel filesystem, simile alle voci in `/etc/fstab`
|
||||
- **automount**: e' sempre una definizione del punto di mount nel filesystem, ma viene montata automaticamente. Ogni unita' di automount ha un'unita' di mount corrispondente che viene avviata quando si accede al punto di montaggio
|
||||
- **target**: un raggruppamento di altre unita'. Emula il concetto di runlevel
|
||||
- **snapshot**
|
||||
|
||||
Il comando principale per il controllo delle unita' systemd e' `systemctl`:
|
||||
|
||||
```bash
|
||||
systemctl start unit.service
|
||||
|
||||
systemctl stop unit.service
|
||||
|
||||
systemctl restart unit.service
|
||||
|
||||
systemctl status unit.service
|
||||
|
||||
systemctl is-active unit.service # mostra se unit.service e' in esecuzione
|
||||
|
||||
systemctl enable unit.service
|
||||
|
||||
systemctl disable unit.service
|
||||
|
||||
systemctl is-enable unit.service # verifica se unit.service si avvia col sistema
|
||||
|
||||
systemctl isolate multi-user.target # utile per passare tra un target e un altro
|
||||
|
||||
systemctl get-default # visualizza il target di avvio predefinito
|
||||
|
||||
systemctl set-default multi-user.target # imposta un nuovo target predefinito
|
||||
```
|
||||
|
||||
I file di configurazione di ogni unita' si trovano in `/etc/systemd/system/`L'eseguibile`/sbin/init` e' un collegamento simbolico a `/lib/systemd/systemd`.
|
||||
|
||||
```bash
|
||||
systemctl list-unit-files # elenca tutte le unita' disponibili e mostra se sono abilitate all'avvio
|
||||
|
||||
systemctl list-unit-files --type=service
|
||||
|
||||
systemctl list-unit-files --type=target
|
||||
|
||||
systemctl list-units # mostra le unita' attive
|
||||
```
|
||||
## Spegnimento e riavvio
|
||||
|
||||
Il comando principale per arrestare o riavviare il sistema e' `shutdown`, che avvisa anche tutti gli utenti che hanno effettuato un accesso con un messaggio di avviso nelle loro sessioni di shell.
|
||||
|
||||
```bash
|
||||
shutdown [option] time [message]
|
||||
```
|
||||
E' richiesto solo il parametro *time*, che accetta i seguenti formati:
|
||||
|
||||
- **hh:mm**
|
||||
- **+m**: quanti minuti attendere prima dell'esecuzione
|
||||
- **now**
|
||||
|
||||
Il comando systemctl puo' anche essere utilizzato per spegnere o riavviare la macchina:
|
||||
|
||||
```bash
|
||||
systemctl reboot
|
||||
|
||||
systemctl poweroff
|
||||
|
||||
systemctl suspend # manda il sistema nella modalita' di sospensione a basso consumo, mantenendo i dati in memoria
|
||||
|
||||
systemctl hibernate # copia tutti i dati su disco e iberna il sistema
|
||||
```
|
41
lpic/101/004_partizioni_lvm.md
Normal file
@ -0,0 +1,41 @@
|
||||
## Concetti
|
||||
|
||||
Un disco, prima di essere utilizzato deve essere partizionato. Una *partizione* e' un sottoinsieme logico del disco fisico. Le informazioni sulle partizioni sono archiviate nella *tabella delle partizioni*. Include informazioni sul primo e ultimo settore della partizione e sul suo tipo. All'interno di ogni partizione c'e' un *filesystem*, che descrive il modo in cui le informazioni sono memorizzate sul disco.
|
||||
|
||||
## Punto di mount
|
||||
|
||||
Prima di accedere a un filesystem, questo deve essere *montato*. Il punto di montaggio deve esistere prima di montare il filesystem. Se esiste e contiene file, questi non saranno disponibili fino a che il filesystem non sara' smontato. `/media/` e' il punto di montaggio predefinito per qualsiasi supporto rimovibile. Ogni volta che si monta *manualmente* un filesystem, e' buona norma montarlo in `/mnt/`.
|
||||
|
||||
## Partizioni
|
||||
|
||||
### /boot
|
||||
|
||||
La partizione di avvio, contiene i file usati dal bootloader per caricare il SO. I file di configurazione di GRUB2 si trovano in `/boot/grub/`. E' in genere la prima partizione sul disco. La partizione di avvio si trova all'inizio del disco e termina prima del cilindro 1024 (528 MB).
|
||||
|
||||
### ESP
|
||||
|
||||
Utilizzata dalle macchine basate su EUFI per memorizzare il bootloader, solitamente formattata in FAT32. Viene montata in `/boot/efi`.
|
||||
|
||||
### /var
|
||||
|
||||
Contiene *dati variabili* o file e directory su cui il sistema deve poter scrivere durante il funzionamento. Cio' include i log di sistema (`/var/log`), i file temporanei (`/var/tmp`) e file di cache (`/var/cache`).
|
||||
|
||||
### swap
|
||||
|
||||
Utilizzata per scambiare pagine di memoria dalla RAM al disco secondo necessita'. Non puo' essere montata come le altre, il che significa che non e' possibile accedervi come con una normale directory e osservarne il contenuto. Linux supporta anche file di swap, utili per aumentare rapidamente lo spazio di swap.
|
||||
|
||||
## LVM
|
||||
|
||||
*Logical Volume Management* e' una forma di virtualizzazione dello storage che offre una maggior flessibilita' nella gestione dello spazio disco.
|
||||
|
||||
L'unita' base e' il *Physical Volume* (PV). I PV sono raggruppati in *Volume Group* (VG) che astraggono i dispositivi sottostanti e sono visti dal SO come un unico dispositivo logico.
|
||||
|
||||
Ogni volume in un VG e' suddiviso in parti di dimensioni fisse chiamate *extents*. Tali parti su un PV sono denominate *Physical Extents* (PE), mentre su un LV sono denominate LE.
|
||||
|
||||
I VG possono essere suddivisi in *Logical Volumes* (LV), che sono simili alle partizioni, ma hanno maggior flessibilita'.
|
||||
|
||||
```txt
|
||||
dim LV = numero extents sul volume X dimensione singola extents (4MB)
|
||||
```
|
||||
|
||||
Nel SO viene visualizzato come un normale dispositivo a blocchi, nella forma: `/dev/VGNAME/LVNAME`.
|
212
lpic/101/005_grub.md
Normal file
@ -0,0 +1,212 @@
|
||||
# Bootloader
|
||||
|
||||
Il primo software ad essere eseguito, ha lo scopo di caricare un kernel e consegnargli il controllo. Il kernel carichera' i driver necessari, inizializzera' l'hardware e carichera' il SO.
|
||||
|
||||
*GRUB* e' il bootloader piu' utilizzato. Dalla versione 2 supporta anche LiveCD ISO.
|
||||
|
||||
Il primo settore del disco (512 byte) e' chiamato *Mater Boot Record* (MBR) e contiene la tabella delle partizioni e anche il *codice bootstrap* (installato tra l'MBR e la prima partizione). All'accensione del computer, questo codice minimale viene caricato, eseguito e passa il controllo a un bootloader (GRUB) secondario su disco, che carichera' il SO.
|
||||
|
||||
### Limitazioni MBR
|
||||
|
||||
- massimo 4 partizioni primarie
|
||||
- dimensioni massime del disco di 2TB
|
||||
|
||||
A causa di tali limitazioni e' stato creato un nuovo schema di partizionamento, *GPT* (*GUID Partition Table*), parte dello standard UEFI.
|
||||
|
||||
## /boot
|
||||
|
||||
I file necessari per il processo di avvio sono memorizzati in una partizione avviabile, montata in `/boot/`. La partizione di avvio, in genere, e' la prima partizione del disco e termina prima del cilindro 1024 (528 MB), per ragioni di compatibilita' storica. Le dimensioni consigliate per tale partizione sono di circa 300 MB.
|
||||
|
||||
### Contenuto
|
||||
|
||||
Il nome di molti file termina col suffisso *-VERSION*, che sta a indicare la versione del kernel Linux.
|
||||
|
||||
```bash
|
||||
ll /boot/
|
||||
|
||||
Permissions Size User Group Date Modified Name
|
||||
.rw-r--r-- 279k root root 6 ott 01:00 config-6.11.2-amd64
|
||||
drwxr-xr-x - root root 8 ott 22:02 grub
|
||||
.rw-r--r-- 40M root root 20 ott 09:41 initrd.img-6.11.2-amd64
|
||||
.rw-r--r-- 9,9M root root 6 ott 01:00 vmlinuz-6.11.2-amd64
|
||||
```
|
||||
|
||||
#### Config file
|
||||
|
||||
Questo file, chiamato di solito `config-VERSION` memorizza i parametri di configurazione per il kernel Linux. Generato automaticamente, non deve essere modificato dall'utente.
|
||||
|
||||
#### System map
|
||||
|
||||
Il file `System.map-VERSION` e' una tabella che abbina variabili o funzioni (*symbol names*) alla posizione corrispondente nella memoria.
|
||||
|
||||
#### Linux kernel
|
||||
|
||||
Il kernel del SO. Il nome di solito e' `vmlinux-VERSION`. Si puo' anche trovare col nome `vmlinuz`, che indica che si tratta di un file compresso.
|
||||
|
||||
#### Initial RAM disk
|
||||
|
||||
Contiene un filesystem root minimale caricato in RAM, contenente utility e moduli del kernel affinche' sia possibile montare il vero filesystem root.
|
||||
|
||||
#### Bootloader related files
|
||||
|
||||
Si trovano di solito in `/boot/grub/` e includono file di configurazione di GRUB (`grub.cfg`) e moduli (in `/boot/grub/i386-pc/`)
|
||||
|
||||
```bash
|
||||
ll /boot/grub/
|
||||
|
||||
Permissions Size User Group Date Modified Name
|
||||
drwxr-xr-x - root root 3 set 2023 fonts
|
||||
.rw------- 6,6k root root 8 ott 22:02 grub.cfg
|
||||
.rw-r--r-- 1,0k root root 20 ott 09:34 grubenv
|
||||
drwxr-xr-x - root root 16 lug 21:34 i386-pc
|
||||
drwxr-xr-x - root root 16 lug 21:34 locale
|
||||
.rw-r--r-- 2,4M root root 16 lug 21:34 unicode.pf2
|
||||
```
|
||||
|
||||
## GRUB2
|
||||
|
||||
### Installare GRUB2
|
||||
|
||||
```bash
|
||||
grub-install --boot-directory=/boot /dev/sda
|
||||
```
|
||||
|
||||
### Configurare GRUB2
|
||||
|
||||
Il file di configurazione predefinito e': `/boot/grub/grub.cfg`. Questo file viene generato automaticamente e la modifica e' sconsigliata. Per apportare delle modifiche alla configurazione di GRUB e' necessario modificare il file `/etc/default/grub` e quindi eseguire il comando `update-grub`.
|
||||
|
||||
Una lista delle principali opzioni:
|
||||
|
||||
- `GRUB_DEFAULT=` : indica la voce di menu' predefinita per l'avvio. Puo' avere valore numerico (come 0, 1, ecc.)
|
||||
- `GRUB_SAVEDEFAULT=`: se questa voce e' impostata su `true` e `GRUB_DEFAULT=save`, l'opzione di avvio predefinita sara' sempre l'ultima selezionata
|
||||
- `GRUB_TIMEOUT=`: il timeout, in secondi, prima che sia avviata la voce di menu predefinita. Se impostato su `0`, il sistema avviera' la voce predefinita senza mostrare un menu. Se impostato su `-1`, il sistema attendera' fino a quando l'utente selezionera' un'opzione
|
||||
- `GRUB_CMDLINE_LINUX=`: opzioni che verranno aggiunte come parametri all'avvio al kernel
|
||||
- `GRUB_CMDLINE_LINUX_DEFAULT=`: parametri aggiuntivi solo per la voce predefinita
|
||||
- `GRUB_PASSWORD=`changeme
|
||||
- `GRUB_GFXMODE=`1920x1080
|
||||
- `GRUB_ENABLE_CRYPTODISK=y`: GRUB cerchera' dischi crittografati
|
||||
|
||||
#### Voci del menu
|
||||
|
||||
Le voci di menu personalizzate vengono di solito aggiunte al file `/etc/grub.d/40_custom`.
|
||||
|
||||
```bash
|
||||
menuentry "Default OS" {
|
||||
set root=(hd0,1) # primo disco e prima partizione
|
||||
linux /vmlinuz root=/dev/sda1 ro quiet splash
|
||||
initrd /initrd.img
|
||||
}
|
||||
```
|
||||
|
||||
Il testo tra "" verra' visualizzato come etichetta della voce nel menu di avvio. il parametro `set root` definisce il disco e la partizione in cui si trova il filesystem root (i dischi sono numerati da zero, quindi hd0 indica il primo disco. Le partizioni sono numerate a partire dal numero uno).
|
||||
|
||||
Invece di specificare direttamente il dispositivo e la partizione, e' possibile anche indicare lo UUID (*Universal Unique Identifier*):
|
||||
|
||||
```bash
|
||||
search --no-floppy --fs-uuid --set=root 8c6d327e-e96e-44f3-8423-979ed6eb7cc8
|
||||
```
|
||||
|
||||
La riga `linux` indica dove si trova il kernel per il SO. Successivamente, sulla stessa riga, e' possibile passare dei parametri al kernel. Nell'esempio sopra, la partizione di root deve essere montata in sola lettura (`ro`), sono disabilitati la maggior parte dei messaggi di log (`quiet`) e viene visualizzata una schermata di avvio (`splash`).
|
||||
|
||||
```bash
|
||||
ll /
|
||||
|
||||
Permissions Size User Group Date Modified Name
|
||||
lrwxrwxrwx - root root 3 set 2023 bin -> usr/bin
|
||||
drwxr-xr-x - root root 20 ott 09:41 boot
|
||||
drwxr-xr-x - root root 20 ott 15:08 dev
|
||||
drwxr-xr-x - root root 20 ott 09:41 etc
|
||||
drwxr-xr-x - root root 3 ago 19:02 home
|
||||
lrwxrwxrwx - root root 8 ott 22:02 initrd.img -> boot/initrd.img-6.11.2-amd64
|
||||
lrwxrwxrwx - root root 8 ott 22:02 initrd.img.old -> boot/initrd.img-6.10.12-amd64
|
||||
lrwxrwxrwx - root root 3 set 2023 lib -> usr/lib
|
||||
lrwxrwxrwx - root root 3 set 2023 lib64 -> usr/lib64
|
||||
drwxr-xr-x - root root 3 set 2023 media
|
||||
drwxr-xr-x - root root 3 set 2023 mnt
|
||||
drwxr-xr-x - root root 5 ott 15:31 opt
|
||||
dr-xr-xr-x - root root 20 ott 09:34 proc
|
||||
drwx------ - root dado 19 ott 20:34 root
|
||||
drwxr-xr-x - root root 20 ott 10:19 run
|
||||
lrwxrwxrwx - root root 3 set 2023 sbin -> usr/sbin
|
||||
drwxr-xr-x - root root 3 set 2023 srv
|
||||
dr-xr-xr-x - root root 20 ott 17:26 sys
|
||||
drwxrwxrwt - root root 20 ott 16:44 tmp
|
||||
drwxr-xr-x - root root 3 set 2023 usr
|
||||
drwxr-xr-x - root root 22 set 2023 var
|
||||
lrwxrwxrwx - root root 8 ott 22:02 vmlinuz -> boot/vmlinuz-6.11.2-amd64
|
||||
lrwxrwxrwx - root root 8 ott 22:02 vmlinuz.old -> boot/vmlinuz-6.10.12-amd64
|
||||
```
|
||||
|
||||
### shell di GRUB2
|
||||
|
||||
Per entrare nella shell, premere `c` nella schermata dei menu.
|
||||
|
||||
1) Il comando `ls` mostra un elenco dei dischi e delle partizioni trovati da GRUB2:
|
||||
|
||||
```bash
|
||||
grub> ls
|
||||
(proc) (hd0) (hd0,msdos1)
|
||||
```
|
||||
|
||||
Nell'esempio, un solo disco `hd0` con una sola partizione `hd0,msdos1`.
|
||||
|
||||
2) Per trovare il kernel e initrd, affinche' sia possibile avviare il sistema:
|
||||
|
||||
```bash
|
||||
grub> ls (hd0,msdos1)/
|
||||
lost+found/ bin/ boot/ cdrom/ dev/ etc/ home/ lib/
|
||||
lib64/ media/ mnt/ opt/ proc/ root/ run/ sbin/
|
||||
srv/ sys/ tmp/ usr/ var/ vmlinuz vmlinuz.old
|
||||
initrd.img initrd.img.old
|
||||
```
|
||||
|
||||
3) Impostare la partizione di avvio
|
||||
|
||||
```bash
|
||||
grub> set root=(hd0,msdos1)
|
||||
```
|
||||
|
||||
4) Caricare il kernel Linux e indicare al kernel dove si trova il filesystem di root con l'opzione `root=`
|
||||
|
||||
```bash
|
||||
grub> linux /vmlinuz-6.10.12-amd64 root=/dev/sda1
|
||||
```
|
||||
|
||||
5) Caricare initdr e quindi avviare il sistema
|
||||
|
||||
```bash
|
||||
grub> initrd /initrd.img
|
||||
grub> boot
|
||||
```
|
||||
|
||||
## GRUB Legacy
|
||||
|
||||
### Installare GRUB Legacy
|
||||
|
||||
```bash
|
||||
grub-install --boot-directory=/boot DEVICE
|
||||
|
||||
grub-install --boot-directory=/boot /dev/sda
|
||||
```
|
||||
|
||||
### Installare GRUB Legacy dalla shell di GRUB
|
||||
|
||||
```bash
|
||||
```bash
|
||||
grub> root (hd0,0) # Impostare il dispositivo di avvio. Nell'esempio, la prima partizione del primo disco
|
||||
grub> setup (hd0) # Installare GRUB Legacy
|
||||
```
|
||||
|
||||
|
||||
#### Voci del menu
|
||||
|
||||
Le voci e le impostazioni del menu legacy di GRUB sono memorizzate in `/boot/grub/menu.lst`. A differenza di GRUB2, sia i dischi che le partizioni sono numerate a partire da zero.
|
||||
|
||||
```bash
|
||||
title My Linux Distro
|
||||
root (hd0,0)
|
||||
kernel /vmlinuz root=/dev/sda1 ro
|
||||
initrd /initrd.img
|
||||
module /boot/grub/i386-pc/json.mod
|
||||
```
|
||||
I moduli (presenti in `/boot/grub/i386-pc/`), che aggiungono funzionalita' extra, vengono caricati usando il comando `module`, seguito dal percorso completo del modulo (`.mod`).
|
58
lpic/101/006_librerie_condivise.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Librerie condivise
|
||||
|
||||
Raccolte di codice che possono essere riutilizzate da altri programmi. In base a come il *linker* collega le librerie ai vari file oggetto (codice macchina generato dal compilatore), si hanno due tipi di librerie.
|
||||
|
||||
## Librerie statiche
|
||||
|
||||
Una libreria statica viene unita al programma. Una copia del codice della libreria e' inglobata nel programma e ne diventa parte. Non ha quindi dipendenze esterne.
|
||||
|
||||
## Librerie dinamiche (o condivise)
|
||||
|
||||
Il *linker* si occupa solamente che il programma faccia riferimento alle librerie. In fase di esecuzione, la libreria deve essere disponibile per soddisfare le dipendenze del programma.
|
||||
|
||||
## Denominazione
|
||||
|
||||
Il nome di una libreria dinamica/condivisa, o *soname*, segue la seguente nomenclatura:
|
||||
|
||||
- nome della libreria, preceduto da *lib*
|
||||
- so (*share object*)
|
||||
- numero di versione. I nomi delle librerie statiche terminano con *.a*
|
||||
|
||||
Ad esempio: libthread.so.0 oppure libthread.so.a
|
||||
|
||||
## Posizione nel filesystem
|
||||
|
||||
- `/lib`
|
||||
- `/lib32`
|
||||
- `/lib64`
|
||||
- `/usr/lib`
|
||||
- `/usr/local/lib`
|
||||
|
||||
### Configurazione dei percorsi delle librerie condivise
|
||||
|
||||
Quando un programma viene eseguito, il linker dinamico ricerca le librerie in una serie di directory, in particolare `/etc/ld.so.conf.d/` e nel file `/etc/ld.so.conf`, che semplicemente include tutti i file .conf presenti nella cartella sopra indicata:
|
||||
|
||||
```bash
|
||||
cat /etc/ld.so.conf
|
||||
|
||||
include /etc/ld.so.conf.d/*.conf
|
||||
```
|
||||
La directory `/etc/ld.so.conf.d/` contiene una serie di file .conf che indicano i percorsi assoluti delle directory che contengono le librerie condivise.
|
||||
|
||||
Il comando `ldconfig` si occupa della lettura di questi file di configurazione e della creazione dei vari link simbolici. Deve quindi essere eseguito ogni volta che vengono aggiunti o aggiornati dei file di configurazione.
|
||||
|
||||
La variabile `LD_LIBRARY_PATH` puo' essere usata per aggiungere temporaneamente dei percorsi alle librerie condivise.
|
||||
|
||||
```bash
|
||||
LD_LIBRARY_PATH=/usr/local/mylib
|
||||
|
||||
export LD_LIBRARY_PATH # Aggiunge /usr/local/mylib al percorso delle librerie condivise per la shell corrente e lo esporta a tutti i processi figli L'aggiunta al file ~/.bashrc o /etc/bash rende la libreria persistente
|
||||
|
||||
unset LD_LIBRARY_PATH # Rimuove la variabile d'ambiente
|
||||
```
|
||||
|
||||
> Il comando `export` esporta il valore di una variabile d'ambiente anche alle shell figlie.
|
||||
|
||||
### Ricerca delle dipendenze
|
||||
|
||||
Per la ricerca delle dipendenze, usare il comando `ldd` seguito dal percorso assoluto del programma. Ad esempio: `ldd /usr/bin/git`.
|
162
lpic/101/007_apt.md
Normal file
@ -0,0 +1,162 @@
|
||||
# Gestione dei pacchetti
|
||||
|
||||
## dpkg
|
||||
|
||||
*Debian Package* (dpkg) e' il comando per installare e rimuovere pacchetti su sistemi basati su Debian.
|
||||
|
||||
### Installazione
|
||||
|
||||
```bash
|
||||
dpkg -i PACKAGENAME.deb
|
||||
```
|
||||
dpkg, se le dipendenze del pacchetto non sono soddisfatte, non installera' il pacchetto. Elenchera' quali dipendenze mancano, ma sara' compito dell'utente installarle.
|
||||
|
||||
Per forzare l'installazione usare il parametro `-f` o `--force`.
|
||||
|
||||
### Disinstallazione
|
||||
|
||||
```bash
|
||||
dpkg -r PACKAGENAME
|
||||
```
|
||||
|
||||
Un pacchetto non puo' essere rimosso, se non sia stato rimosso anche ogni altro pacchetto che dipende da esso.
|
||||
|
||||
```bash
|
||||
dpkg -P PACKAGENAME
|
||||
```
|
||||
|
||||
In questo modo vengono rimossi anche i file di configurazione, che altrimenti restano nel sistema.
|
||||
|
||||
### Ottenere informazioni sui pacchetti
|
||||
|
||||
```bash
|
||||
dpkg -I PACKAGENAME
|
||||
```
|
||||
|
||||
### Elencare i pacchetti
|
||||
|
||||
Per avere una lista di tutti i pacchetti installati sul sistema:
|
||||
|
||||
```bash
|
||||
dpkg --get-selections
|
||||
```
|
||||
Per avere un elenco di tutti i file installati da un pacchetto:
|
||||
|
||||
```bash
|
||||
dpkg -L PACKAGENAME
|
||||
```
|
||||
|
||||
### Riconfigurare i pacchetti
|
||||
|
||||
Per ripristinare le impostazioni di un pacchetto allo stato iniziale:
|
||||
|
||||
```bash
|
||||
dpkg-reconfigure PACKAGENAME
|
||||
```
|
||||
|
||||
## APT
|
||||
|
||||
*Advanced Package Tool* e' un sistema di gestione dei pacchetti che *risolve in automatico le dipende*. E' come un *front-end* di dpkg, che ne semplifica l'utilizzo e ne colma diverse lacune.
|
||||
|
||||
Esistono diverse utility:
|
||||
|
||||
- **apt-get**
|
||||
- **apt-cache**
|
||||
- **apt-file**
|
||||
- **apt**: combina le funzionalita' di apt-get e apt-cache
|
||||
|
||||
### Aggiornare l'indice dei pacchetti
|
||||
|
||||
```bash
|
||||
apt-get update
|
||||
```
|
||||
|
||||
### Installare e rimuovere pacchetti
|
||||
|
||||
Prima di installare un pacchetto, buona prassi e' quella di aggiornare gli indici
|
||||
|
||||
```bash
|
||||
apt-get install PACKAGENAME
|
||||
|
||||
apt-get remove PACKAGENAME
|
||||
```
|
||||
APT risolve automaticamente le dipendenze. Verranno quindi installati anche degli eventuali pacchetti aggiuntivi richiesti dal pacchetto che si sta installando. Verranno anche rimossi i pacchetti che dipendono dal pacchetto che si sta rimuovendo.
|
||||
|
||||
I file di configurazione rimangono sul sistema. Per eliminare qualsiasi cosa associata la pacchetto:
|
||||
|
||||
```bash
|
||||
apt-get purge PACKAGENAME
|
||||
```
|
||||
|
||||
### Riparare dipende
|
||||
|
||||
Per risolvere dipendenze errate o mancanti:
|
||||
|
||||
```bash
|
||||
apt-get install -f
|
||||
```
|
||||
|
||||
### Aggiornare i pacchetti
|
||||
|
||||
Per aggiornare tutti i pacchetti:
|
||||
|
||||
```bash
|
||||
apt-get upgrade
|
||||
```
|
||||
|
||||
Per aggiornare un singolo pacchetto:
|
||||
|
||||
```bash
|
||||
apt-get upgrade PACKAGENAME
|
||||
```
|
||||
|
||||
### Cache locale
|
||||
|
||||
Quando si installa o aggiorna un pacchetto, il corrispondente file *.deb *viene scaricato in una cartella locale di cache, che di default e': `/var/cache/apt/archives/`. I file parzialmente scaricati si trovano invece in `/var/cache/apt/archives/partial`. Per svuotare la directory di cache usare il comando `apt-cache clean`.
|
||||
|
||||
### Ricercare pacchetti
|
||||
|
||||
```bash
|
||||
apt-cache search
|
||||
```
|
||||
|
||||
Il comando seguente mostra i dettagli su un determinato pacchetto:
|
||||
|
||||
```bash
|
||||
apt-cache show PACKAGENAME
|
||||
```
|
||||
|
||||
### Elencare il contenuto di un pacchetto
|
||||
|
||||
```bash
|
||||
apt-file list PACKAGENAME
|
||||
```
|
||||
|
||||
### Repository
|
||||
|
||||
APT utilizza una lista di fonti (*repository*) per sapere da dove ottenere i pacchetti. Questo fonti sono memorizzate nel file `/etc/apt/sources.list` e nei file contenuti nella directory `/etc/apt/sources.list.d/`.
|
||||
|
||||
la sintassi:
|
||||
|
||||
```bash
|
||||
cat /etc/apt/sources.list
|
||||
|
||||
# Debian SID
|
||||
deb http://deb.debian.org/debian/ unstable main contrib non-free non-free-firmware
|
||||
|
||||
# Tipo archivio URL distribuzione componenti
|
||||
```
|
||||
#### Tipo
|
||||
|
||||
File binari (.deb) o sorgenti, *deb-src*
|
||||
|
||||
#### Componenti
|
||||
|
||||
Diversi tra le distribuzioni, su Debian i componenti principali sono:
|
||||
|
||||
- **main**: pacchetti conformi alle *Debian Free Software Guidelines* (DFSG)
|
||||
- **contrib**: pacchetti conformi alle DFSG, ma che dipendono da pacchetti che non sono in main
|
||||
- **non-free**: pacchetti non conformi alle DFSG
|
||||
- **security**: aggiornamenti di sicurezza
|
||||
- **backports**: versioni piu' recenti dei pacchetti che si trovano in main
|
||||
```
|
183
lpic/101/008_rpm_yum.md
Normal file
@ -0,0 +1,183 @@
|
||||
# Gestione dei pacchetti
|
||||
|
||||
## RPM
|
||||
|
||||
E' lo strumento per la gestione dei pacchetti su sistemi RedHat e derivati.
|
||||
|
||||
### Installare, aggiornare e rimuovere pacchetti
|
||||
|
||||
```bash
|
||||
rpm -i PACKAGENAME.rpm
|
||||
|
||||
rpm -u PACKAGENAME # Aggiornamento
|
||||
```
|
||||
L'opzione `-h` mostra una barra di avanzamento.
|
||||
|
||||
```bash
|
||||
rpm -u PACKAGENAME # Rimozione del pacchetto
|
||||
```
|
||||
|
||||
### Gestire le dipendenze
|
||||
|
||||
rpm non installa un pacchetto in mancanza delle dipendenze. Elenchera' solamente i pacchetti mancanti, ma non risolvera' in automatico le dipendenze.
|
||||
|
||||
### Elencare i pacchetti installati
|
||||
|
||||
```bash
|
||||
rpm -qa # query all: elenca tutti i pacchetti presenti nel sistema
|
||||
```
|
||||
|
||||
### Ottenere informazioni sui pacchetti
|
||||
|
||||
```bash
|
||||
rpm -qi PACKAGENAME # query info: informazioni su un pacchetto installato
|
||||
|
||||
rpm -qip PACKAGENAME # query info: informazioni su un pacchetto NON installato
|
||||
|
||||
rpm -ql PACKAGENAME # query list: informazioni su quali file si trovano all'interno di un pacchetto installato
|
||||
|
||||
rpm -ql PACKAGENAME # query list: informazioni su quali file si trovano all'interno di un pacchetto NON installato
|
||||
```
|
||||
|
||||
## YUM
|
||||
|
||||
Funziona similmente ad APT, essendo in grado di cercare, installare, aggiornare e rimuovere pacchetti, *gestendo in automatico le dipendenze*.
|
||||
|
||||
### Ricercare pacchetti
|
||||
|
||||
```bash
|
||||
yum search PATTERN
|
||||
```
|
||||
|
||||
### Installare, aggiornare e rimuovere pacchetti
|
||||
|
||||
```bash
|
||||
yum install PACKAGENAME
|
||||
|
||||
yum update PACKAGENAME
|
||||
|
||||
yum update # Aggiorna tutti i pacchetti del sistema
|
||||
|
||||
yum check-update PACKAGENAME
|
||||
|
||||
yum check-update # Controlla gli aggiornamenti per tutti i pacchetti del sistema
|
||||
|
||||
yum remove PACKAGENAME
|
||||
```
|
||||
|
||||
### Ottenere informazioni sui pacchetti
|
||||
|
||||
```bash
|
||||
yum info PATTERN
|
||||
```
|
||||
### Gestire i repository
|
||||
|
||||
I repository sono elencati nella directory `/etc/yum/repos.d/`. Ogni repository e' rappresentato da un file `.repo`. Il modo raccomandato per aggiungere repository e' attraverso l'utility `yum-config-manager`:
|
||||
|
||||
```bash
|
||||
yum-config-manager --add-repo URL.repo
|
||||
|
||||
yum repolist all # Elenco di tutti i repository
|
||||
|
||||
yum-config-manager --disable REPO_ID # Disabilita il repository REPO_ID
|
||||
|
||||
yum-config-manager --enable REPO_ID
|
||||
```
|
||||
|
||||
yum memorizza i pacchetti scaricati in `/etc/yum/cache`. Per recuperare lo spazio:
|
||||
|
||||
```bash
|
||||
yum clean packages
|
||||
|
||||
yum clean metadata
|
||||
```
|
||||
|
||||
## DNF
|
||||
|
||||
Fork di yum, e' il gestore predefinito di Fedora
|
||||
|
||||
```bash
|
||||
dnf search PATTERN
|
||||
|
||||
dnf info PACKAGENAME
|
||||
|
||||
dnf install PACKAGENAME
|
||||
|
||||
dnf remove PACKAGENAME
|
||||
|
||||
dnf upgrade PACKAGENAME
|
||||
|
||||
dnf upgrade # Aggiorna tutti i pacchetti
|
||||
|
||||
dnf list --installed
|
||||
|
||||
dnf repoquery -l PACKAGENAME # Elencare il contenuto di un pacchetto
|
||||
```
|
||||
|
||||
### Gestire i repository
|
||||
|
||||
```bash
|
||||
dnf repolist # Lista di tutti i repository
|
||||
|
||||
dnf --enabled repolist
|
||||
|
||||
dnf --disabled repolist
|
||||
|
||||
dnf-config-manager --add-repo URL.repo
|
||||
|
||||
dnf-config-manager --set-disabled REPO_ID # Disabilita il repository REPO_ID
|
||||
|
||||
dnf-config-manager --set-enabled REPO_ID
|
||||
```
|
||||
|
||||
I repository sono elencati nella directory `/etc/yum/repos.d/`. Ogni repository e' rappresentato da un file `.repo`.
|
||||
|
||||
## Zypper
|
||||
|
||||
Strumento di gestione dei pacchetti predefinito su SUSE Linux e OpenSUSE. Funziona similmente ad APT e YUM, essendo in grado di cercare, installare, aggiornare e rimuovere pacchetti, *gestendo in automatico le dipendenze*.
|
||||
|
||||
### Aggiornare l'indice dei pacchetti
|
||||
|
||||
```bash
|
||||
zypper refresh
|
||||
```
|
||||
|
||||
### Ricercare pacchetti
|
||||
|
||||
```bash
|
||||
zypper se PACKAGE # search
|
||||
|
||||
zypper se -i # Lista di tutti i pacchetti installati sul sistema
|
||||
```
|
||||
|
||||
### Installare, aggiornare e rimuovere pacchetti
|
||||
|
||||
```bash
|
||||
zypper in PACKAGE
|
||||
|
||||
zypper update # Aggiorna i pacchetti del sistema
|
||||
|
||||
zypper list-updates # Elenca, senza installarli, i pacchetti con aggiornamenti disponibili
|
||||
|
||||
zypper rm PACKAGE
|
||||
```
|
||||
|
||||
### Ottenere informazioni sui pacchetti
|
||||
|
||||
```bash
|
||||
zypper info PACKAGE
|
||||
```
|
||||
|
||||
### Gestire i repository
|
||||
|
||||
```bash
|
||||
zypper repos # Elenco di tutti i repository
|
||||
|
||||
zypper addrepo URL
|
||||
|
||||
zypper addrepo URL -f # Abilita gli aggiornamenti automatici
|
||||
|
||||
zypper remove REPO_NAME # Disabilita il repository REPO_ID
|
||||
|
||||
zypper setenabled REPO_ID
|
||||
```
|
65
lpic/101/009_virtualizzazione.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Concetti
|
||||
|
||||
La virtualizzazione consente ad un software, denominato *hypervisor*, di eseguire processi che contengono un sistema informatico completamente emulato.
|
||||
|
||||
Si tratta di un software che crea e gestisce macchine virtuali (VM), definite *guest* dell HV. Le macchine virtuali sono ambienti isolati che possono eseguire sistemi operativi e applicazioni come se fossero computer fisici separati.
|
||||
|
||||
Esistono due tipi principali di hypervisor:
|
||||
|
||||
- **Hypervisor di tipo 1** (*bare-metal*): vengono eseguiti direttamente sull'hardware fisico. Non richiedono un sistema operativo sottostante e gestiscono direttamente le risorse hardware. Esempi di hypervisor di tipo 1 includono VMware ESXi, Microsoft Hyper-V e Xen.
|
||||
|
||||
- **Hypervisor di tipo 2** (*hosted*): vengono eseguiti su un sistema operativo esistente. Esempi di hypervisor di tipo 2 includono VMware Workstation, VirtualBox e Parallels Desktop.
|
||||
|
||||
Gli hypervisor comunemente usati su Linux sono:
|
||||
|
||||
- **Xen**: un hypervisor di **tipo I** o *bare-metal*
|
||||
- **KVM**: *Kernel Virtual Machine* e' un modulo del Kernel per la virtualizzazione. E' un hypervisor sia di tipo I che di tipo II. Le VM erogate tramite KVM usano il demone *libvirt* per essere create e gestite. *qemu* e' il software su cui si basano le VM gestite da KVM. Fornisce all'HV il software per emulare i dispositivi HW che la VM utilizza.
|
||||
|
||||
## Macchine virtuali
|
||||
|
||||
Esistono tre tipi di VM:
|
||||
|
||||
- *completamente virtualizzate*: un guest completamente virtualizzato e' quello in cui il guest non e' consapevole di essere un'istanza virtuale in esecuzione. Nelle CPU x86 bisogna abilitare le estensioni VT-X per CPU Intel e AMD-V per CPU AMD.
|
||||
|
||||
- *paravirtualizzate*: un guest completamente paravirtualizzato e' quello in cui il guest e' consapevole di essere un'istanza virtuale in esecuzione. Questi tipi di guest fanno uso di driver speciali (*guest driver*) per utilizzare le risorse hardware e software dell'hypervisor.
|
||||
|
||||
- *ibride*: questo approccio combina elementi di virtualizzazione completamente virtualizzata e paravirtualizzata. In un ambiente ibrido, alcune parti del SO guest possono essere paravirtualizzate, mentre altre possono essere completamente virtualizzate
|
||||
|
||||
### Immagini disco
|
||||
|
||||
I tipi principali di immagini disco utilizzate dalle VM sono:
|
||||
|
||||
- *COW*: *copy-on-write*. E' un metodo che crea un file su disco con un limite di dimensione predefinito. La dimensione dell'immagine sul disco aumenta, ma non oltre il limite prestabilito, solo quando i dati vengono effettivamente scritti sul disco. Il formato usato e' `qcow2`.
|
||||
- *RAW*: si tratta di un file che ha tutto il suo spazio pre-allocato. Per esempio, un file di immagine disco raw da 10GB occupa esattamente 10GB sull'HV.
|
||||
|
||||
### D-BUS Machine ID
|
||||
|
||||
Si tratta di un numero che identifica univocamente un sistema Linux, che si genera la momento della sua creazione.
|
||||
|
||||
```bash
|
||||
dbus-uuidgen --ensure # Se non viene restituito un errore, esiste un ID per il sistema
|
||||
|
||||
dbus-uuidgen --get
|
||||
e3c4be9c5ad146d4800150b18f31d073
|
||||
```
|
||||
Il D-BUS Machine ID si trova in `/var/lib/dbus/machine-id`, che e' un collegamento simbolico a `/etc/machine-id`.
|
||||
|
||||
Per generare un nuovo ID:
|
||||
|
||||
```bash
|
||||
rm -rf /etc/machine-id
|
||||
|
||||
dbus-uuidgen --ensure=/etc/machine-id
|
||||
```
|
||||
|
||||
## Container
|
||||
|
||||
La principale differenza tra macchine virtuali e container è che questi ultimi condividono lo stesso kernel del sistema operativo host,
|
||||
Contengono solo le librerie e le dipendenze necessarie per l'applicazione, senza l'intero sistema operativo.
|
||||
I container vengono eseguiti direttamente sull'host, senza la necessità di un hypervisor.
|
||||
|
||||
Ogni VM esegue un sistema operativo completo, con il proprio kernel, librerie e applicazioni. Ogni VM ha il proprio sistema operativo guest installato, che può essere diverso dal sistema operativo host.
|
||||
Richiedono un hypervisor per gestire l'allocazione delle risorse hardware.
|
||||
|
||||

|
||||
|
79
lpic/101/010_unix_commands.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Comandi utili
|
||||
|
||||
- **apropos**: se non si ricorda il nome esatto di un comando, si puo' utilizzare *apropos* per ricercare tra i nomi e le descrizioni delle pagine man.
|
||||
- **pwd**: visualizza la directory di lavoro corrente
|
||||
- **uname**: visualizza informazioni sul sistema
|
||||
- **man**: permette di accedere alla documentazione sui comandi
|
||||
- **type**: visualizza la posizione nel filesystem *e il tipo* di uno o piu' comandi
|
||||
|
||||
```bash
|
||||
type gs
|
||||
gs ha "git status" come alias
|
||||
|
||||
type uname
|
||||
uname è /usr/bin/uname
|
||||
```
|
||||
- **which**: visualizza la posizione nel filesystem di un comando
|
||||
- **lsblk**: elenca i dispositivi a blocchi
|
||||
- **bzcat**: permette la lettura di file compressi tramite il metodo bzip2
|
||||
- **xzcat**: xz
|
||||
- **zcat**: gzip
|
||||
- **nl**: *number line*, visualizza il numero di linee di un file, anteponendo il numero ad ogni riga
|
||||
- **tr**: *translate*, permette di sostituire caratteri
|
||||
- **cut**: estrapola parti di testo come se fossero campi, identificandoli tramite un delimitatore
|
||||
- **paste**: unisce i file in colonne
|
||||
- **cat**: funziona anche con dati binari, come l'invio del contenuto di un dispositivo a blocchi a un file (o per unire diversi file video in un unico grande file)
|
||||
|
||||
### rm
|
||||
|
||||
Il comando `rm` (remove) è utilizzato per rimuovere file e directory
|
||||
|
||||
```bash
|
||||
rm [options] <File(s)>
|
||||
```
|
||||
|
||||
Le opzioni principali:
|
||||
|
||||
- `-r` o `-R`: per rimuovere ricorsivamente directory e i loro contenuti
|
||||
- `-f`: Rper rimuovi file forzatamente, senza chiedere conferma
|
||||
- `-i`: rimozione interattiva. Richiede conferma prima di rimuovere ogni file
|
||||
- `-v`: modalità verbosa
|
||||
- `--preserve-root`: evita la rimozione della directory radice ('/') e dei suoi contenuti
|
||||
- `--no-preserve-root`: Consente la rimozione della directory radice ('/') e dei suoi contenuti
|
||||
|
||||
### wget
|
||||
|
||||
```bash
|
||||
wget [options] <URL>
|
||||
```
|
||||
|
||||
#### Specificare il nome del file
|
||||
|
||||
```bash
|
||||
wget -O <Filename> <URL>
|
||||
```
|
||||
|
||||
#### Scaricare file in una directory specifica
|
||||
|
||||
```bash
|
||||
wget -P /path/to/download <URL>
|
||||
```
|
||||
|
||||
#### Scaricare in background
|
||||
|
||||
```bash
|
||||
wget -b <URL>
|
||||
```
|
||||
|
||||
#### Scaricamento multiplo
|
||||
|
||||
```bash
|
||||
nano wget.txt
|
||||
wget -i Filename
|
||||
```
|
||||
|
||||
### Riprendere i download
|
||||
|
||||
```bash
|
||||
wget -c <URL>
|
||||
```
|
60
lpic/101/011_variabili_ambiente.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Variabili d'ambiente
|
||||
|
||||
Le variabili d'ambiente (environment variables) sono coppie chiave-valore che vengono utilizzate per memorizzare informazioni di configurazione a livello di SO.
|
||||
|
||||
## Trovare le variabili d'ambiente
|
||||
|
||||
Per identificare i valori attuali per ciascuna delle variabili d'ambiente:
|
||||
|
||||
```bash
|
||||
env
|
||||
```
|
||||
|
||||
La variabile `PATH` contiene la lista delle directory nelle quali la shell cerca i programmi, senza doverli richiamare indicandone il percorso completo:
|
||||
|
||||
```bash
|
||||
PATH=/home/dado/.local/bin:/home/dado/bin:/usr/local/bin:/usr/bin:/bin:/home/dado/bin:/home/dado/scripts
|
||||
```
|
||||
Per stampare il valore di una variabile d'ambiente, utilizzare il comando `echo`:
|
||||
|
||||
```bash
|
||||
echo $EDITOR
|
||||
vim
|
||||
```
|
||||
|
||||
## Creare nuove variabili d'ambiente
|
||||
|
||||
```bash
|
||||
myvar=variable
|
||||
|
||||
echo $myvar
|
||||
variable
|
||||
```
|
||||
Una variabile d'ambiente creata nel modo precedente e' disponibile solo all'interno della stessa sessione di shell. Per passare il valore della variabile a tutte le shell figlie:
|
||||
|
||||
```bash
|
||||
myvar=variable
|
||||
|
||||
export myvar
|
||||
|
||||
bash
|
||||
|
||||
echo $myvar
|
||||
variable
|
||||
```
|
||||
|
||||
## Cancellare variabili d'ambiente
|
||||
|
||||
```bash
|
||||
unset myvar
|
||||
```
|
||||
|
||||
## Caratteri speciali
|
||||
|
||||
> NOTA: le virgolette singole '' conservano il valore letterale di tutti i caratteri, mentre le virgolette doppie "" conservano tutti i caratteri, ad **eccezione** di $, `, \
|
||||
|
||||
Anteporre il back slash (\) a un carattere speciale fara' si che bash lo interpreti letteralmente:
|
||||
|
||||
```bash
|
||||
touch my\ big\ file
|
||||
```
|
331
lpic/101/012_elaborare_flussi_di_testo.md
Normal file
@ -0,0 +1,331 @@
|
||||
# Reindirizzamenti e pipe
|
||||
|
||||
Tutti i programmi di manipolazione del testo partono da un input standard (`stdin`), lo inviano a un output standard (`stdout`) e inviano eventuali errori a un output degli errori standard (`stderr`). Solitamente, `stdin` e' quello digitato da tastiera.
|
||||
|
||||
Il carattere `>` dice a `cat` di indirizzare il suo output sul file `newfile`, non sullo `stdout`:
|
||||
|
||||
```bash
|
||||
cat > newfile
|
||||
Nuovo file di prova
|
||||
^C
|
||||
|
||||
cat newfile
|
||||
Nuovo file di prova
|
||||
```
|
||||
E' possibile usare la `|` per indirizzare l'output di un programma ad un altro programma.
|
||||
|
||||
### Ottenere una parte di un file di testo
|
||||
|
||||
Il comando `head` e' usato per leggere di default le prime 10 righe di un file, mentre il comando `tail` le ultime 10. Per indicare il numero di righe e' possibile reindirizzare l'output al comando `nl`:
|
||||
|
||||
```bash
|
||||
head /var/log/alternatives.log | nl
|
||||
1 update-alternatives 2024-10-02 20:46:38: run with --install /usr/bin/pager pager /bin/more 50 --slave /usr/share/man/man1/pager.1.gz pager.1.gz /usr/share/man/man1/more.1.gz
|
||||
2 update-alternatives 2024-10-02 20:47:08: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/brave-browser-nightly 1
|
||||
3 update-alternatives 2024-10-02 20:47:08: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/brave-browser-nightly 1
|
||||
4 update-alternatives 2024-10-02 20:47:08: run with --install /usr/bin/brave-browser brave-browser /usr/bin/brave-browser-nightly 1
|
||||
```
|
||||
|
||||
Oppure, per contare il numero di righe totali di un file:
|
||||
|
||||
```bash
|
||||
cat logs/borg_backup.log | wc -l
|
||||
10153
|
||||
```
|
||||
|
||||
## sed
|
||||
|
||||
Possiamo usare `sed` per cercare solo le righe che contengono un determinato pattern:
|
||||
|
||||
```bash
|
||||
sed -n /cat/p < ftu.txt
|
||||
|
||||
cat
|
||||
zcat
|
||||
bzcat
|
||||
xzcat
|
||||
```
|
||||
|
||||
il simbolo `<` indirizza il contenuto del file al comando `sed`. La stringa racchiusa dagli *slash*, ovvero `/cat/`, e' la stringa che stiamo ricercando. L'opzione `-n` indica a sed di non produrre output, se non quello generato dal comando `p`.
|
||||
|
||||
```bash
|
||||
sed /cat/d < ftu.txt
|
||||
cut
|
||||
head
|
||||
ls
|
||||
man
|
||||
md5sum
|
||||
nl
|
||||
paste
|
||||
sed
|
||||
sort
|
||||
split
|
||||
sort
|
||||
vim
|
||||
cd
|
||||
tail
|
||||
uniq
|
||||
wc
|
||||
mv
|
||||
cp
|
||||
sed
|
||||
passwd
|
||||
pwd
|
||||
```
|
||||
In questo modo `sed` visualizzera' tutto il contenuto del file, eccetto cio' che `d` indica a *sed* di cancellare dal suo output.
|
||||
|
||||
Un uso comune di *sed* e' quello di *trovare e sostituire del testo* all'interno di un file. Per sostituire tutte le occorrenze di *cat* con *dog*:
|
||||
|
||||
```bash
|
||||
sed s/cat/dog/ < ftu.txt
|
||||
|
||||
cut
|
||||
head
|
||||
ls
|
||||
man
|
||||
md5sum
|
||||
nl
|
||||
paste
|
||||
sed
|
||||
sort
|
||||
dog
|
||||
zdog
|
||||
split
|
||||
sort
|
||||
vim
|
||||
cd
|
||||
tail
|
||||
uniq
|
||||
wc
|
||||
mv
|
||||
cp
|
||||
sed
|
||||
passwd
|
||||
pwd
|
||||
bzdog
|
||||
xzdog
|
||||
```
|
||||
|
||||
E' possibile passare direttamente il file a `sed`:
|
||||
|
||||
```bash
|
||||
sed s/cat/dog/ ftu.txt
|
||||
cut
|
||||
head
|
||||
ls
|
||||
man
|
||||
md5sum
|
||||
nl
|
||||
paste
|
||||
sed
|
||||
sort
|
||||
dog
|
||||
zdog
|
||||
split
|
||||
sort
|
||||
vim
|
||||
cd
|
||||
tail
|
||||
uniq
|
||||
wc
|
||||
mv
|
||||
cp
|
||||
sed
|
||||
passwd
|
||||
pwd
|
||||
bzdog
|
||||
xzdog
|
||||
```
|
||||
|
||||
In realta', il file non e' stato mai modificato. Per procedere, creando una copia di backup:
|
||||
|
||||
```bash
|
||||
sed -i.backup s/cat/dog/ ftu.txt
|
||||
|
||||
ll ftu*
|
||||
Permissions Size User Group Date Modified Name
|
||||
.rw-rw-r-- 114 dado dado 29 ott 21:19 ftu.txt
|
||||
.rw-rw-r-- 114 dado dado 29 ott 21:09 ftu.txt.backup
|
||||
```
|
||||
|
||||
In questo modo, viene creato un file di backup e modificato direttamente il file originale.
|
||||
|
||||
## Integrita' dei dati
|
||||
|
||||
- md5sum
|
||||
- sha256sum
|
||||
- sha512sum
|
||||
|
||||
Per calcolare il valore SHA256 del file *ftu.txt* dare il seguente comando:
|
||||
|
||||
```bash
|
||||
sha256sum ftu.txt
|
||||
94cc7c49dfe55cd824d4e0c2f88881fba9daae41c11601f08b1bf818cd77a671 ftu.txt
|
||||
```
|
||||
|
||||
Se creiamo un file che contiene il valore di checksum, possiamo utilizzarlo per verificare l'integrita' del file:
|
||||
|
||||
```bash
|
||||
sha256sum ftu.txt > sha256sum.txt
|
||||
|
||||
sha256sum -c sha256sum.txt
|
||||
ftu.txt: OK
|
||||
```
|
||||
|
||||
Se il file originale fosse modificato, il controllo fallirebbe:
|
||||
|
||||
```bash
|
||||
echo "new line" >> ftu.txt
|
||||
|
||||
sha256sum -c sha256sum.txt
|
||||
ftu.txt: NON RIUSCITO
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
||||
|
||||
### Esercizi
|
||||
|
||||
```bash
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
||||
bin:x:2:2:bin:/bin:/usr/sbin/nologin
|
||||
sys:x:3:3:sys:/dev:/usr/sbin/nologin
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
nvidia-persistenced:x:121:128:NVIDIA Persistence Daemon,,,:/nonexistent:/sbin/nologin
|
||||
libvirt-qemu:x:64055:130:Libvirt Qemu,,,:/var/lib/libvirt:/usr/sbin/nologin
|
||||
libvirt-dnsmasq:x:122:133:Libvirt Dnsmasq,,,:/var/lib/libvirt/dnsmasq:/usr/sbin/nologin
|
||||
carol:x:1000:2000:Carol Smith,Finance,,,Main Office:/home/carol:/bin/bash
|
||||
dave:x:1001:1000:Dave Edwards,Finance,,,Main Office:/home/dave:/bin/ksh
|
||||
emma:x:1002:1000:Emma Jones,Finance,,,Main Office:/home/emma:/bin/bash
|
||||
frank:x:1003:1000:Frank Cassidy,Finance,,,Main Office:/home/frank:/bin/bash
|
||||
grace:x:1004:1000:Grace Kearns,Engineering,,,Main Office:/home/grace:/bin/ksh
|
||||
henry:x:1005:1000:Henry Adams,Sales,,,Main Office:/home/henry:/bin/bash
|
||||
john:x:1006:1000:John Chapel,Sales,,,Main Office:/home/john:/bin/bash
|
||||
```
|
||||
|
||||
- Elenca solo gli utenti del gruppo 1000
|
||||
|
||||
```bash
|
||||
[20:21 sab nov 02]dado@pc (957):~
|
||||
> grep 1000 passwd
|
||||
carol:x:1000:2000:Carol Smith,Finance,,,Main Office:/home/carol:/bin/bash
|
||||
dave:x:1001:1000:Dave Edwards,Finance,,,Main Office:/home/dave:/bin/ksh
|
||||
emma:x:1002:1000:Emma Jones,Finance,,,Main Office:/home/emma:/bin/bash
|
||||
frank:x:1003:1000:Frank Cassidy,Finance,,,Main Office:/home/frank:/bin/bash
|
||||
grace:x:1004:1000:Grace Kearns,Engineering,,,Main Office:/home/grace:/bin/ksh
|
||||
henry:x:1005:1000:Henry Adams,Sales,,,Main Office:/home/henry:/bin/bash
|
||||
john:x:1006:1000:John Chapel,Sales,,,Main Office:/home/john:/bin/bash
|
||||
|
||||
[20:21 sab nov 02]dado@pc (958):~
|
||||
> sed -n /1000/p < passwd
|
||||
carol:x:1000:2000:Carol Smith,Finance,,,Main Office:/home/carol:/bin/bash
|
||||
dave:x:1001:1000:Dave Edwards,Finance,,,Main Office:/home/dave:/bin/ksh
|
||||
emma:x:1002:1000:Emma Jones,Finance,,,Main Office:/home/emma:/bin/bash
|
||||
frank:x:1003:1000:Frank Cassidy,Finance,,,Main Office:/home/frank:/bin/bash
|
||||
grace:x:1004:1000:Grace Kearns,Engineering,,,Main Office:/home/grace:/bin/ksh
|
||||
henry:x:1005:1000:Henry Adams,Sales,,,Main Office:/home/henry:/bin/bash
|
||||
john:x:1006:1000:John Chapel,Sales,,,Main Office:/home/john:/bin/bash
|
||||
```
|
||||
|
||||
- Elenca solo i nomi completi di questi utenti
|
||||
|
||||
```bash
|
||||
[20:23 sab nov 02]dado@pc (962):~
|
||||
> sed -n /1000/p < passwd | cut -d : -f 5 | cut -d , -f 1
|
||||
Carol Smith
|
||||
Dave Edwards
|
||||
Emma Jones
|
||||
Frank Cassidy
|
||||
Grace Kearns
|
||||
Henry Adams
|
||||
John Chapel
|
||||
```
|
||||
|
||||
- Un comando che seleziona un utente a caso del Main Office
|
||||
|
||||
```bash
|
||||
[20:26 sab nov 02]dado@pc (971):~
|
||||
> sed -n /Main\ Office/p < passwd | cut -d : -f 5 | cut -d , -f 1 | sort -R | head -n 1
|
||||
```
|
||||
|
||||
- Quante persone lavorano in Finance, Engineering e Sales?
|
||||
|
||||
```bash
|
||||
[20:28 sab nov 02]dado@pc (978):~
|
||||
> grep -iE "finance|engineering|sales" passwd | wc -l
|
||||
7
|
||||
|
||||
[20:28 sab nov 02]dado@pc (979):~
|
||||
> grep -iE "finance" passwd | wc -l
|
||||
4
|
||||
|
||||
[20:30 sab nov 02]dado@pc (981):~
|
||||
> grep -iE "engineering" passwd | wc -l
|
||||
1
|
||||
|
||||
[20:30 sab nov 02]dado@pc (982):~
|
||||
> grep -iE "sales" passwd | wc -l
|
||||
2
|
||||
|
||||
[21:09 sab nov 02]dado@pc (1108):~
|
||||
> sed -n /Main\ Office/p < passwd | cut -d , -f 2 | sort | uniq -c
|
||||
1 Engineering
|
||||
4 Finance
|
||||
2 Sales
|
||||
```
|
||||
|
||||
- Creare un file .csv col formato seguente
|
||||
|
||||
```bash
|
||||
First Name, Last Name, Position
|
||||
|
||||
|
||||
[20:40 sab nov 02]dado@pc (1016):~
|
||||
> sed -n /Main\ Office/p < passwd | cut -d : -f 5 | cut -d , -f 1,2 | cut -d " " -f 1,2 --output-delimiter=, > names.csv
|
||||
Carol,Smith,Finance
|
||||
Dave,Edwards,Finance
|
||||
Emma,Jones,Finance
|
||||
Frank,Cassidy,Finance
|
||||
Grace,Kearns,Engineering
|
||||
Henry,Adams,Sales
|
||||
John,Chapel,Sales
|
||||
```
|
||||
|
||||
- Assicurasi l'integrita' del file precedente tramite `md5sum`:
|
||||
|
||||
```bash
|
||||
[20:44 sab nov 02]dado@pc (1024):~
|
||||
> md5sum names.csv > md5sum_names.txt
|
||||
|
||||
[20:45 sab nov 02]dado@pc (1026):~
|
||||
> md5sum -c md5sum_names.txt
|
||||
names.csv: OK
|
||||
|
||||
[20:45 sab nov 02]dado@pc (1027):~
|
||||
> echo "new line" >> md5sum_names.txt
|
||||
|
||||
[20:46 sab nov 02]dado@pc (1028):~
|
||||
> md5sum -c md5sum_names.txt
|
||||
names.csv: OK
|
||||
md5sum: WARNING: 1 line is improperly formatted
|
||||
```
|
||||
|
||||
- Dall'output di `ls -l /etc`, ottenere solo i nomi dei file
|
||||
|
||||
```bash
|
||||
[21:13 sab nov 02]dado@pc (1114):~
|
||||
> ls -l /etc/ | tr -s " " | cut -d " " -f 9
|
||||
```
|
||||
|
||||
- Nome e proprietario
|
||||
|
||||
```bash
|
||||
[21:13 sab nov 02]dado@pc (1114):~
|
||||
> ls -l /etc/ | tr -s " " | cut -d " " -f 9,3
|
||||
```
|
||||
|
||||
- SOLO i nomi delle cartelle e del proprietario
|
||||
|
||||
```bash
|
||||
[21:16 sab nov 02]dado@pc (1120):~
|
||||
> ls -l /etc/ | tr -s " " | grep ^d | cut -d " " -f 9,3
|
||||
```
|
84
lpic/101/013_inode_gestione_file.md
Normal file
@ -0,0 +1,84 @@
|
||||
# Gestione dei file
|
||||
|
||||
*Tutto in Linux e' un file.*
|
||||
|
||||
Un file consiste di contenuto e metadati (dimensione, proprietario, data di creazione, autorizzazioni, ecc). I file sono organizzati in directory, ossia un tipo particolare di file che memorizza altri file.
|
||||
|
||||
Esistono diversi tipi di file:
|
||||
|
||||
- **File regolari**: memorizzano dati e programmi
|
||||
- **Directory**: contengono altri file
|
||||
- **File speciali**: utilizzati per input e output
|
||||
|
||||
## Inode
|
||||
|
||||
Gli `inode` (o *index nodes*) sono una struttura dati utilizzata nei file system Unix e Unix-like per gestire le informazioni sui file e le directory. Ogni file o directory nel file system ha un inode associato, che contiene metadati importanti. Ecco alcune delle informazioni che un inode può contenere:
|
||||
|
||||
1. **Tipo di file**: Indica se l'oggetto è un file regolare, una directory, un link simbolico, ecc.
|
||||
2. **Dimensione del file**: La dimensione totale del file in byte.
|
||||
3. **Permessi di accesso**: Le autorizzazioni che determinano chi può leggere, scrivere o eseguire il file.
|
||||
4. **Proprietario e gruppo**: Informazioni su chi possiede il file e a quale gruppo appartiene.
|
||||
5. **Timestamp**: Diverse informazioni temporali, come la data di creazione, l'ultima modifica e l'ultimo accesso al file.
|
||||
|
||||
## Manipolazione dei file
|
||||
|
||||
### ls
|
||||
|
||||
Nella forma base, `ls` elenca solo i nomi di file e directory. Utilizzando il parametro `-l`, mostra i *permessi* di file e directory, *proprietario*, *dimensione*, *data di ultima modifica*, *ora* e *nome*:
|
||||
|
||||
```bash
|
||||
> ls -l
|
||||
totale 148
|
||||
drwxr-xr-x 4 dado dado 4096 1 nov 20.07 Applications
|
||||
drwxr-xr-x 2 dado dado 4096 13 dic 2023 bin
|
||||
drwxrwxr-x 3 dado dado 61440 3 nov 10.39 Camera
|
||||
-rw-r--r-- 1 dado dado 623 3 nov 15.05 crontab.bk
|
||||
drwxr-xr-x 2 dado dado 4096 21 gen 2024 Documents
|
||||
drwxr-xr-x 2 dado dado 4096 1 nov 22.50 Download
|
||||
drwxr-xr-x 8 dado dado 24576 3 nov 14.10 Downloads
|
||||
drwxr-xr-x 12 dado dado 4096 1 nov 15.40 git
|
||||
drwxr-xr-x 2 dado dado 4096 17 set 22.55 logs
|
||||
drwxr-xr-x 15 dado dado 4096 1 nov 21.23 Nextcloud
|
||||
drwxr-xr-x 2 dado dado 4096 1 nov 14.23 scripts
|
||||
```
|
||||
|
||||
Il primo carattere nell'output indica il tipo di file:
|
||||
|
||||
- `-`: indica un file regolare
|
||||
- `d`: una directory
|
||||
- `c`: un file speciale
|
||||
|
||||
#### Ricorsione
|
||||
|
||||
- `ls -R directory`: elenca il contenuto di una directory e delle sue sottodirectory
|
||||
|
||||
### Altri comandi
|
||||
|
||||
- *touch*: crea un nuovo file vuoto
|
||||
- *cp*: copia un file. Usare l'opzione `-i` per richiedere la conferma
|
||||
- *cp -r*: consente di copiare una directory insieme a tutte le sue sottodirectory e file
|
||||
- *mv*: sposta o rinomina un file. Usare l'opzione `-i` per richiedere la conferma
|
||||
- *rm*: rimuove un file. Usare l'opzione `-i` per richiedere la conferma
|
||||
- *rm -r*: elimina una directory insieme a tutto il suo contenuto (incluse le sue sottodirectory)
|
||||
- *mkdir*: crea una directory. Con l'opzione `-p` e' possibile creare una directory insieme alle varie sottodirectory
|
||||
- *rmdir*: eliminazione di una directory *non vuota*. Per rimuovere una directory e le sue sottodirectory usare l'opzione `-p`
|
||||
|
||||
### File globbing e Wildcards
|
||||
|
||||
Il `file globbing` e' una funzionalita' della shell che consente di rappresentare piu' nomi di file utilizzando caratteri speciali denominati *wildcards*.
|
||||
|
||||
Esistono tre caratteri jolly in Linux:
|
||||
|
||||
- `*`: rappresenta zero, una o piu' occorrenze di qualsiasi carattere
|
||||
- `?`: rappresenta una *sola* occorrenza di qualsiasi carattere
|
||||
- `[]` (caratteri tra parentesi quadre): rappresenta qualsiasi occorrenza di carattere/i racchiuso/i tra le parentesi quadre
|
||||
|
||||
Ad esempio:
|
||||
|
||||
```bash
|
||||
ls l[aef]st.txt
|
||||
|
||||
# le parentesi [] possono includere anche intervalli, come [A-Z], [0-9]
|
||||
```
|
||||
|
||||
Le wildcard (i caratteri jolly) possono essere combinate.
|
34
lpic/101/014_ricercare_file.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Ricercare file
|
||||
|
||||
Il comando principale si chiama `find`. Le opzioni per la ricerca di file in base al tipo sono:
|
||||
|
||||
- `-type f`: file
|
||||
- `-type d`: directory
|
||||
- `-type l`: link simbolici
|
||||
|
||||
Ad esempio: `find . -name "example" -type f`.
|
||||
|
||||
Altri criteri da utilizzare nella ricerca:
|
||||
|
||||
- `-iname`: ricerca in base al nome, non considerando lettere maiuscole o minuscole
|
||||
- `-not`: restituisce i risultati che non corrispondono
|
||||
- `-maxdepth N`: ricerca nelle sottodirectory fino a N livelli di profondiota'
|
||||
|
||||
### Dimensione
|
||||
|
||||
```bash
|
||||
find . -iname "example" -size 2G -type f
|
||||
```
|
||||
- `-size 100M`: file che corrispondono esattamente a 100Mb
|
||||
- `-size +100M`: file piu' grandi di 100Mb
|
||||
- `-size -20M`: file piu' piccoli di 20Mb
|
||||
- `-size +2G`: file piu' grandi di 2Gb
|
||||
|
||||
### Agire sui risultati
|
||||
|
||||
E' possibile eseguire delle azioni sui risultati usando l'opzione `-exec`:
|
||||
|
||||
```bash
|
||||
find . -name "*.conf" -exec chmod 644 '{}' \;
|
||||
```
|
||||
|
39
lpic/101/015_tar.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Archiviazione dei file
|
||||
|
||||
Il comando `tar` e' utilizzato per creare archivi di file.
|
||||
|
||||
```bash
|
||||
tar [OPERATION and OPTIONS] [ARCHIVE NAME] [FILES]
|
||||
```
|
||||
|
||||
Le operazioni principali sono:
|
||||
|
||||
- `-c`: crea un nuovo archivio
|
||||
- `-x`: estrae un archivio
|
||||
- `-t`: list, visualizza l'elenco dei file inclusi nell'archivio
|
||||
- `-f nome_archivio`: specifica il nome dell'archivio
|
||||
- `-v`: verbose
|
||||
|
||||
### Creazione di un archivio
|
||||
|
||||
`tar -cvf archive.tar file1 file2 directory1`
|
||||
|
||||
### Estrarre un archivio
|
||||
|
||||
`tar -xvf archive.tar`
|
||||
|
||||
Per estrarre il contenuto in una directory specifica usare l'opzione `-C`: `tar -xvf archive.tar -C /tmp`
|
||||
|
||||
### Comprimere un archivio
|
||||
|
||||
- `tar -czvf archive.tar.gz file1 file2`: gzip
|
||||
- `tar -cjvf archive.tar.bz file1 file2`: bzip2. Piu' lento, ma con maggior compressione
|
||||
|
||||
## dd
|
||||
|
||||
```bash
|
||||
dd if=oldfile of=newfile status=progress
|
||||
```
|
||||
|
||||
copia i dati da una posizione all'altra.
|
||||
|
52
lpic/101/016_reindirizzamenti.md
Normal file
@ -0,0 +1,52 @@
|
||||
# Reindirizzamenti
|
||||
|
||||
In Linux i processi hanno tre canali di comunicazione: `standard input` (`stdin`, il cui *descrittore di file* e'**0**), `standard output` (`stdout`, **1**) e `standard error` (`stderr`, **2**). I canali di comunicazione sono anche accessibili tramite i dispositivi speciali `/dev/stdin`, `/dev/stdout` e `/dev/stderr`.
|
||||
|
||||
## Descrittore di file
|
||||
|
||||
Il simbolo `>` ad esempio permette di reindirizzare lo `stdout` di un processo su un file,
|
||||
|
||||
```bash
|
||||
cat /proc/cpuinfo > cpu.txt
|
||||
```
|
||||
Per impostazione predefinita, viene reindirizzato solo il contenuto che arriva a *stdout*. Questo perche' il valore numerico del descrittore di file deve essere specificato prima del simbolo `>`. Se non specificato, Bash reindirizza lo *stdout*. Pertanto, usare `>` equivale a scrivere `1>`. Per catturare il contenuto di `stderr` bisognerebbe usare il simbolo `2>`. La destinazione di un descrittore di file e' rappresentata dal simbolo `>&`. Per esempio, `1>&2` reindirizza *stdout* a *stderr*.
|
||||
|
||||
Sia *stderr* che *stdout* vengono reindirizzati alla stessa destinazione con `&>`. Per scartare l'output di un comando o di un file, basta reindirizzarne il contenuto al file speciale `/dev/null`.
|
||||
|
||||
Il simbolo `<` viene utilizzato per reindirizzare il contenuto di un file allo *stdin* di un processo. I dati scorrono da destra a sinistra.
|
||||
|
||||
## Here document e Here String
|
||||
|
||||
Il reindirizzamento del *Here document* consente di digitare del testo su piu' righe che verra' utilizzato come contenuto:
|
||||
|
||||
```bash
|
||||
cat > file << EOF
|
||||
> riga 1
|
||||
> riga 2
|
||||
> riga 3
|
||||
> EOF
|
||||
|
||||
cat file
|
||||
riga 1
|
||||
riga 2
|
||||
riga 3
|
||||
|
||||
wc -c << EOF
|
||||
> Quanti caratteri ci sono in questo documento?
|
||||
> Non ne ho idea, ma scopriamolo!
|
||||
> EOF
|
||||
78
|
||||
|
||||
cat << EOF > file
|
||||
> riga 1
|
||||
> EOF
|
||||
```
|
||||
|
||||
La modalita' di inserimento terminera' non appena sara' inserito il termine di *fine file* (nell'esempio il carattere `EOF`).
|
||||
|
||||
Il metodo *Here string* e' molto simile, ma viene utilizzato il simbolo `>>>` e interessa solo una singola riga : `wc -c <<< "Quanti caratteri in questa stringa?"`. Le stringhe con spazi devono essere racchiuse tra `""`
|
||||
|
||||
```bash
|
||||
sha1sum <<< $USER
|
||||
06ad4c901e9f7dfdbf1bc5b01fe5d690686b54a4 -
|
||||
```
|
46
lpic/101/017_pipe_command_substitution.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Pipe
|
||||
|
||||
Diversi comandi possono essere concatenati insieme per produrre un output combinato. Il carattere della *pipe* `|` puo' essere utilizzato per creare una pipeline che collega lo *stout* di un programma con lo *stdin* di un altro programma, da sinistra verso destra.
|
||||
|
||||
```bash
|
||||
grep "model name" /proc/cpuinfo | uniq
|
||||
model name : AMD Ryzen 3 3200G with Radeon Vega Graphics
|
||||
```
|
||||
|
||||
## command substitution
|
||||
|
||||
Inserendo un comando all'interno degli ``, bash lo sostituisce col suo *stdout*. Ad esempio:
|
||||
|
||||
```bash
|
||||
mkdir `date +%Y-%m-%d`
|
||||
|
||||
ls -lh
|
||||
totale 148K
|
||||
drwxrwxr-x 2 dado dado 4,0K 9 nov 21.00 2024-11-09
|
||||
```
|
||||
|
||||
Un risultato identico si ottiene usando `$()`:
|
||||
|
||||
```bash
|
||||
mkdir $(date +%Y-%m-%d)
|
||||
|
||||
ls -lh
|
||||
totale 148K
|
||||
drwxrwxr-x 2 dado dado 4,0K 9 nov 21.02 2024-11-09
|
||||
```
|
||||
|
||||
Per memorizzare lo *stdout* di un comando come *variabile*:
|
||||
|
||||
```bash
|
||||
# Creazione di una variabile
|
||||
OS="uname -a"
|
||||
echo $OS
|
||||
uname -a
|
||||
|
||||
# Assegnazione dello stdout a una variabile
|
||||
OS=`uname -a`
|
||||
echo $OS
|
||||
Linux pc 6.11.6-amd64 Debian 6.11.6-1 (2024-11-04) x86_64 GNU/Linux
|
||||
```
|
||||
|
||||
Un altro metodo per usare lo *stdout* di un programma come argomento di un altro programma e' quello di utilizzare `xargs`.
|
304
lpic/101/018_jobs_ps_top.md
Normal file
@ -0,0 +1,304 @@
|
||||
# Processi
|
||||
|
||||
Ogni volta che eseguiamo un comando, vengono avviati uno o piu' processi.
|
||||
|
||||
## Controllare i job
|
||||
|
||||
I *job* sono processi che sono stati avviati in modo interattivo tramite una shell, inviati in background e non hanno terminato l'esecuzione. Per scoprire i job attivi, digitare sul terminale il comando:
|
||||
|
||||
```bash
|
||||
> jobs
|
||||
[1]+ Stopped sleep 60
|
||||
```
|
||||
- Il simbolo `[1]` rappresenta l'ID del job e puo' essere usato, preceduto dal simbolo `%`, per cambiare lo stato del job, attraverso le utility `fg`, `bg`, e `kill`.
|
||||
- `+`: indica il job corrente, ovvero l'ultimo messo in background. Il job precedente e' contrassegnato da un segno `-`. Eventuali altri job precedenti non sono contrassegnati
|
||||
- `Stopped`: indica lo stato del job
|
||||
- `sleep 60`: il comando
|
||||
|
||||
Con l'opzione `-l` viene mostrato anche il `PID` del processo:
|
||||
|
||||
```bash
|
||||
> jobs -l
|
||||
[1]+ 13637 Fermato sleep 60
|
||||
```
|
||||
|
||||
> Un job ha sia un job ID che un process ID (PID)
|
||||
|
||||
### Stato dei job
|
||||
|
||||
Una volta che un job e' in background o sospeso:
|
||||
|
||||
- Portarlo in primo piano con `fg`
|
||||
|
||||
```bash
|
||||
> fg %1
|
||||
sleep 60
|
||||
```
|
||||
|
||||
- Portarlo in background con `bg`
|
||||
|
||||
```bash
|
||||
> bg %1
|
||||
[1]+ sleep 60 &
|
||||
```
|
||||
|
||||
- Terminarlo col comando `kill`
|
||||
|
||||
```bash
|
||||
> kill %1
|
||||
[1]+ Terminato sleep 60
|
||||
```
|
||||
|
||||
### Detach dei job: nohup
|
||||
|
||||
Negli esempi precedenti, i job erano legati alla sessione dell'utente. Se termina, terminano anche i job. E' possibile scollegare un job dalla sessione, in modo che, se termina la sessione, non viene terminato anche il job.
|
||||
|
||||
```bash
|
||||
nohup COMMAND &
|
||||
```
|
||||
|
||||
Nel file `nohup.out` verranno salvati *stdin* e *stderr* in modo predefinito.
|
||||
|
||||
```bash
|
||||
> nohup ping localhost &
|
||||
[1] 14081
|
||||
nohup: input ignorato e output accodato a 'nohup.out'
|
||||
```
|
||||
|
||||
Nel caso volessimo indicare un file personalizzato: `nohup ping localhost > /path/to/file &`
|
||||
|
||||
Per terminare il processo: `kill %1` oppure `kill 14081`
|
||||
|
||||
## Controllare i processi
|
||||
|
||||
Un processo e' un'istanza di un programma in esecuzione.
|
||||
|
||||
### Inviare segnali ai processi
|
||||
|
||||
Ogni processo ha un identificatore univoco o `PID`. Un modo per scoprirlo e' tramite il comando `pgrep PROCESS_NAME`
|
||||
|
||||
```bash
|
||||
> pgrep sleep
|
||||
14384
|
||||
14515
|
||||
```
|
||||
|
||||
Oppure anche tramite:
|
||||
|
||||
```bash
|
||||
> pidof sleep
|
||||
14515 14384
|
||||
```
|
||||
|
||||
Il comando `pkill` termina il processo. Per terminare tutte le istanze dello stesso processo, e' possibile utilizzare il comando `killall`. I comandi `kill`, `pkill` e `killall` inviano un segnale di terminazione al processo. Se non specificato, viene inviato il valore predefinito di SIGTERM. I segnali di terminazione possono essere specificati anche mediante numero. Usare `kill -9` per terminare un processo quando qualsiasi altro segnale fallisce.
|
||||
|
||||
### Segnali di terminazione
|
||||
|
||||
Il segnale SIGTERM (*Signal Terminate*) è uno dei segnali utilizzati nel sistema operativo Unix e nei suoi derivati per gestire la terminazione dei processi. Quando un processo riceve un segnale SIGTERM, viene avvisato di terminare in modo controllato. Questo significa che il processo ha la possibilità di eseguire operazioni di pulizia, come il salvataggio dei dati o la chiusura delle risorse aperte, prima di terminare.
|
||||
|
||||
Oltre a SIGTERM, ci sono altri segnali di terminazione:
|
||||
|
||||
- SIGKILL (Uccisione): Questo segnale forza la terminazione immediata del processo. Non può essere gestito o ignorato dal processo, e non consente alcuna operazione di pulizia. È utilizzato quando un processo non risponde a SIGTERM.
|
||||
|
||||
- SIGINT (Interruzione): Questo segnale viene inviato quando un utente preme Ctrl+C in un terminale. È simile a SIGTERM, in quanto consente al processo di gestire la terminazione in modo controllato.
|
||||
|
||||
Alcuni segnali possono essere ignorati, ma non SIGKILL e SIGSTOP.
|
||||
|
||||
```txt
|
||||
SIGINT (2): Interrupt - Inviato quando l'utente preme Ctrl+C
|
||||
SIGKILL (9): Kill - Termina un processo in modo forzato; non può essere catturato o ignorato
|
||||
SIGSEGV (11): Segmentation Fault - Indica che un processo ha tentato di accedere a una memoria non valida
|
||||
SIGTERM (15): Terminate - Richiesta di terminare un processo; può essere catturato e gestito dal processo
|
||||
```
|
||||
|
||||
## top e ps
|
||||
|
||||
Mentre il primo produce un output dinamicamente, il secondo lo fa staticamente.
|
||||
|
||||
```bash
|
||||
> top
|
||||
top - 20:24:27 up 9:18, 2 users, load average: 0,52, 0,68, 0,60
|
||||
Tasks: 363 total, 1 running, 359 sleeping, 0 stopped, 3 zombie
|
||||
%Cpu(s): 2,2 us, 2,2 sy, 0,0 ni, 95,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
|
||||
MiB Mem : 30036,5 total, 13939,2 free, 6648,3 used, 10742,6 buff/cache
|
||||
MiB Swap: 980,0 total, 980,0 free, 0,0 used. 23388,2 avail Mem
|
||||
|
||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||
46892 dado 20 0 10428 5484 3308 R 8,3 0,0 0:00.02 top
|
||||
1 root 20 0 24688 15564 10476 S 0,0 0,1 0:04.42 systemd
|
||||
2 root 20 0 0 0 0 S 0,0 0,0 0:00.02 kthreadd
|
||||
```
|
||||
|
||||
`top` consente alcune interazioni:
|
||||
|
||||
- `M`: ordina per utilizzo della memoria
|
||||
- `N`: ordina per *numero* ID del processo
|
||||
- `T`: *tempo* di esecuzione
|
||||
- `P`: percentuale di uso della CPU
|
||||
- `R`: ordine ascendente/discendente
|
||||
- `k`: termina un processo
|
||||
- `r`: *renice*, ossia cambia la priorita' di un processo. `top` chiedera' il valore di `nice`, compreso tra -20 e 19 (solo root puo' impostare il valore a un numero negativo o inferiore a quello attuale). Maggiore il valore, minore la priorita'.
|
||||
- `u`: elenca i processi di un particolare utente
|
||||
- `c`: mostra i percorsi assoluti dei programmi e distingue tra processi in *userspace* e in *kernel space* (tra parentesi `[]`)
|
||||
- `V`: vista a foresta
|
||||
- `W`: salva le impostazioni di configurazione in `~/.toprc`
|
||||
|
||||
### Output di top
|
||||
|
||||
Suddiviso in:
|
||||
|
||||
- *summary area*
|
||||
- *task area*
|
||||
|
||||
#### Summary area
|
||||
|
||||
Composta dalle cinque righe superiori:
|
||||
|
||||
```bash
|
||||
top - 20:32:32 up 9:27, 2 users, load average: 0,90, 0,88, 0,73
|
||||
```
|
||||
- *current time* (nel formato 24 ore): `20:32:32`
|
||||
- *uptime*: `up 9:27`
|
||||
- *numero di utenti attivi* e *carico medio della CPU* per gli ultimi 1, 5, 15 minuti: `2 users, load average: 0,90, 0,88, 0,73`
|
||||
|
||||
```bash
|
||||
Tasks: 370 total, 1 running, 366 sleeping, 0 stopped, 3 zombie
|
||||
```
|
||||
- *numero di processi*: `Tasks: 370 total`
|
||||
- *processi running*: `1 running`
|
||||
- *sleeping* (processi in attesa di riprendere l'esecuzione): `366 sleeping`
|
||||
- *zombie*: quelli che hanno terminato l'esecuzione, ma stanno aspettando che il loro processo padre li rimuova dalla tabella dei processi
|
||||
|
||||
```bash
|
||||
%Cpu(s): 2,2 us, 4,3 sy, 0,0 ni, 93,5 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
|
||||
```
|
||||
|
||||
- *processi utente*: `2,2 us`
|
||||
- *processi system/kernel*: `4,3 sy`
|
||||
- *processi impostati tramite un valore di nice*: `0,0 ni`
|
||||
- *tempo di inattivita' della CPU*: `93,5 id`
|
||||
- *processi in attesa di operazioni di I/O*: `0,0 wa`
|
||||
- *processi che servono interrupt hardware* (periferiche che inviano segnali al processore e che richiedono attenzione): `0,0 hi`
|
||||
- *processi che servono interrupt software*: `0,0 si`
|
||||
- *processi che servono le attivita' di VM*: `0,0 st`
|
||||
|
||||
```bash
|
||||
MiB Mem : 30036,5 total, 11781,4 free, 7221,2 used, 12340,0 buff/cache
|
||||
```
|
||||
|
||||
- memoria totale: `Mem : 30036,5 total`
|
||||
- memoria inutilizzata: ` 11781,4 free`
|
||||
- memoria in uso: `7221,2 used`
|
||||
- memoria bufferizzata e memorizzata nella cache, per evitare un accesso eccessivo al disco: `12340,0 buff/cache`
|
||||
|
||||
```bash
|
||||
MiB Swap: 980,0 total, 980,0 free, 0,0 used. 22815,3 avail Mem
|
||||
```
|
||||
|
||||
- swap totale: `Swap: 980,0 total`
|
||||
- spazio di swap inutilizzato: `980,0 free`
|
||||
- spazio di swap in uso
|
||||
|
||||
#### Task area: campi e colonne
|
||||
|
||||
```bash
|
||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||
49342 dado 20 0 10428 5492 3316 R 9,1 0,0 0:00.02 top
|
||||
1 root 20 0 24688 15564 10476 S 0,0 0,1 0:04.48 systemd
|
||||
```
|
||||
|
||||
Include una serie di campi e colonne che riportano informazioni sui processi in esecuzione:
|
||||
|
||||
- `PID`
|
||||
- `USER`: utente che ha eseguito il comando che ha generato il processo
|
||||
- `PR`: priorita' del processo al kernel
|
||||
- `NI`: valore di *nice*
|
||||
- `VIRT`: memoria totale usata dal processo, incluso lo swap
|
||||
- `RES`: memoria RAM utilizzata dal processo
|
||||
- `SHR`: memoria condivisa con altri processi
|
||||
- `S`: stato del processo. I valori includono S (sleep), R (running) e Z (zombie)
|
||||
- `%CPU`: percentuale di CPU utilizzata dal processo
|
||||
- `%MEM`: percentuale di memoria RAM utilizzata (RES in %)
|
||||
- `TIME+`: tempo totale di attivita' del processo
|
||||
- `COMMAND`: comando che ha generato il processo
|
||||
|
||||
## ps
|
||||
|
||||
Mostra un'istantanea dei processi. Per vedere tutti i processi:
|
||||
|
||||
```bash
|
||||
> ps a
|
||||
PID TTY STAT TIME COMMAND
|
||||
2230 tty1 Ssl+ 4:29 sway
|
||||
3431 tty1 Sl+ 2:26 Xwayland :0 -rootless -core -terminate 10 -listenfd 26 -listenfd 32 -displayfd 106 -wm
|
||||
29065 tty1 S+ 0:00 swaybg
|
||||
29067 tty1 Sl+ 0:17 waybar -b bar-0
|
||||
49590 pts/1 Ss 0:00 /bin/bash
|
||||
49596 pts/1 R+ 0:00 ps a
|
||||
```
|
||||
|
||||
`ps` accetta tre diversi stili di opzioni: BSD (ps a), UNIX (ps -a) e GNU (ps --pid).
|
||||
|
||||
Per vedere i processi di un particolare utente:
|
||||
|
||||
- `ps U user` (BSD)
|
||||
- `ps -u user` (UNIX)
|
||||
- `ps --user user` (GNU)
|
||||
|
||||
Un comando utile, che produce un output simile a quello di top, che mostra i processi di tutte le shell, e' `ps aux`, dove:
|
||||
|
||||
- `a`: mostra tutti i processi collegati a un terminale
|
||||
- `u`: formato orientato all'utente
|
||||
- `x`: mostra i processi che non sono collegati a un terminale
|
||||
|
||||
```bash
|
||||
> ps aux
|
||||
'USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
root 1 0.0 0.0 24688 15564 ? Ss 11:05 0:04 /sbin/init
|
||||
root 2 0.0 0.0 0 0 ? S 11:05 0:00 [kthreadd]
|
||||
root 3 0.0 0.0 0 0 ? S 11:05 0:00 [pool_workqueue_release]
|
||||
```
|
||||
|
||||
- `USER`
|
||||
- `PID`
|
||||
- `%CPU`: percentuale di CPU utilizzata
|
||||
- `%MEM`: percentuale di memoria fisica utilizzata
|
||||
- `TT`: terminale (*tty*) che controlla il processo
|
||||
- `STAT`: codice che rappresenta lo stato del processo. I valori includono S (sleep), R (running), Z (zombie), T (stopped)
|
||||
- `STARTED`: ora in cui e' iniziato il processo
|
||||
|
||||
## killall
|
||||
|
||||
```bash
|
||||
killall [OPTIONS] process-name
|
||||
```
|
||||
Opzioni principali:
|
||||
|
||||
- `-e`: richiede una corrispondenza esatta per il nome del processo
|
||||
- `-I`: esegue la ricerca dei nomi dei processi in modo insensibile alle maiuscole e minuscole
|
||||
- `-i`: richiede conferma interattiva prima di uccidere i processi
|
||||
|
||||
```bash
|
||||
killall -i htop
|
||||
```
|
||||
|
||||
- `-r`: permette l'utilizzo di un'espressione regolare
|
||||
|
||||
```bash
|
||||
kill -r REGEX
|
||||
killall -r 'http.*'
|
||||
```
|
||||
|
||||
- `-s SIGNAL`: Specifica il segnale da inviare per terminare i processi (predefinito è SIGTERM)
|
||||
|
||||
```bash
|
||||
killall -s <Termination_Signal> process
|
||||
killall -s SIGKILL apache2
|
||||
```
|
||||
|
||||
- `-u USER`: uccide i processi di proprietà dell'utente specificato
|
||||
|
||||
```bash
|
||||
sudo killall -u <username> process
|
||||
sudo killall -u team htop
|
||||
```
|
102
lpic/101/019_screen_tmux.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Multiplexer
|
||||
|
||||
Un multiplexer, o *mux*, e' un dispositivo che consente ci collegare piu' ingressi a una singola uscita. Un multiplexer da terminale permette di passare tra diversi ingressi o sessioni. Due esempi sono `screen` e `tmux`.
|
||||
|
||||
Le sessioni possono essere scollegate dal terminale corrente, coi programmi che continuano ad essere eseguiti in background.
|
||||
|
||||
## screen
|
||||
|
||||
Invocato semplicemente digitando `screen` sul terminale. Il file di configurazione e' `~/.screenrc`
|
||||
|
||||
Ogni comando e' preceduto dalla combinazione `CTRL + a`.
|
||||
|
||||
Un elenco dei comandi principali:
|
||||
|
||||
- `CTRL + a + w`: mostra i nomi delle finestre. Il conteggio parte da 0
|
||||
- `CTRL + a + c`: crea una nuova finestra (il simbolo `*` indica la finestra corrente)
|
||||
- `CTRL + a + "`: mostra una lista a elenco: delle finestre
|
||||
|
||||
```bash
|
||||
0-$ bash 1*$ bash
|
||||
```
|
||||
|
||||
- `CTRL + a + A`: rinominare la finestra corrente
|
||||
- `screen -t anotherwindow`: crea una finestra con un nome stabilito
|
||||
- `CTRL + a + n`: spostarsi alla finestra successiva
|
||||
- `CTRL + a + p`: precedente
|
||||
- `CTRL + a + number`: alla finestra *number*
|
||||
- `CTRL + a + k`: chiude la finestra attualmente in uso
|
||||
- `CTRL + a + S`: divide il terminale in due regioni orizzontali
|
||||
- `CTRL + a + |`: verticalmente
|
||||
- `CTRL + a + Tab`: muoversi tra le regioni
|
||||
- `CTRL + a + Q`: termina tutte le regioni
|
||||
- `CTRL + a + X`: termina la regione corrente
|
||||
- `CTRL + a + D`: distacco dalla sessione
|
||||
- `CTRL + a + :`: per entrare nella modalita' di comando
|
||||
- `quit`
|
||||
|
||||
Alcune opzioni di screen:
|
||||
|
||||
- `screen -ls`: mostra un elenco di tutte le sessioni
|
||||
- `screen -S new-session`: creare una nuova sessione con nome *new-session*
|
||||
- `screen -R SESSION-PID` o `screen -R SESSION-NAME`: collegarsi alla medesima sessione
|
||||
- `screen -t SESSION-NAME COMMAND`: crea una sessione SESSION-NAME, nella quale sara' eseguito il comando COMMAND. Ad esempio: `screen -t top top`
|
||||
- `screen -X -S SESSION_NAME quit`: chiude la sessione
|
||||
|
||||
### Copia e incolla: scrollback-mode
|
||||
|
||||
- `CTRL + a + [`: accedere alla scrollback-mode
|
||||
- Spostarsi all'inizio del testo da copiare coi tasti freccia
|
||||
- Premere `Space`, per segnale l'inizio della selezione del testo
|
||||
- Spostarsi coi tasti freccia fino al termine del testo da copiare
|
||||
- Premere `Space`, per segnale il termine della selezione del testo
|
||||
- `CTRL + a + ]`: permette di incollare il testo
|
||||
|
||||
## tmux
|
||||
|
||||
- Implementa un modello client-server: il server fornisce una serie di sessioni, ciascuna delle quali puo' avere un numero di finestre ad esse collegate, che possono a loro volta essere condivise tra diversi client
|
||||
- Progetto piu' recente
|
||||
- Consente di gestire più sessioni contemporaneamente
|
||||
- tmux ha un sistema di plugin più avanzato, con possibilità di estendere le funzionalità del programma
|
||||
|
||||
Puo' essere invocato digitando `tmux`:
|
||||
|
||||
```bash
|
||||
[0] 0:bash* "pc" 21:36 10-dic-24
|
||||
```
|
||||
|
||||
La barra di stato fornisce le seguenti informazioni:
|
||||
|
||||
- data e ora
|
||||
- Nome della sessione: `[0]`
|
||||
- Numero della finestra: `0`
|
||||
- Window name: `bash*`. Nome di default del programma, che tmux aggiorna in modo da riflettere il programma in esecuzione. L'asterisco indica la finestra corrente
|
||||
|
||||
Un elenco dei comandi principali:
|
||||
|
||||
- `tmux new -s "NAME_SESSION" -n "WINDOW_NAME"`: assegnare un nome alla sessione e alla finestra
|
||||
- `CTRL + b`: prefisso dei comandi
|
||||
- `CTRL + b + c`: per creare una nuova finestra
|
||||
- `CTRL + b + w`: per visualizzare tutte le finestre
|
||||
- `CTRL + b + &`: per chiudere una finestra
|
||||
- `CTRL + b + $`: rinominare una sessione
|
||||
- `CTRL + b + ,`: rinominare una finestra
|
||||
- `CTRL + b + n`: per passare alla finestra successiva
|
||||
- `CTRL + b + p`: precedente
|
||||
- `CTRL + b + s` o `tmux ls`: elencare le varie sessioni
|
||||
- `tmux kill-session -t SESSION_NAME`: terminare la sessione SESSION_NAME
|
||||
- `tmux attach -t SESSION_NAME`: collegarsi alla sessione SESSION_NAME
|
||||
- `CTRL + b + d`: detach dalla sessione
|
||||
- `CTRL + b + :`: per entrare nella modalita' di comando
|
||||
- `split-window`
|
||||
- `kill-window`
|
||||
|
||||
### Riquadri
|
||||
|
||||
tmux permette di suddividere la finestra in *riquadri*. Si tratta di pseudo-terminali: terminare un riquadro terminera' anche il suo pseudo terminale e tutti i programmi ad esso associati.
|
||||
|
||||
- `CTRL + b + "`: per dividere la finestra orizzontalmente
|
||||
- `CTRL + b + %`: per dividere la finestra verticalmente
|
||||
- `CTRL + b + x`: per eliminare il riquadro corrente
|
||||
|
||||
I suoi file di conf si trovano in `/etc/tmux.conf` o `~/.tmux.conf`****
|
58
lpic/101/020_nice_renice.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Introduzione: sistemi multi-tasking
|
||||
|
||||
Gli OS in grado di eseguire piu' di un processo in contemporanea sono chiamati sistemi *multi-tasking*. La vera simultaneita' si verifica solamente quando sono disponibili piu' CPU, ma anche i sistemi a processore singolo possono simularla, passando da un processo ad un altro molto rapidamente. Infatti, solo un processo alla volta puo' utilizzare la CPU.
|
||||
|
||||
## Il Linux scheduler
|
||||
|
||||
Lo scheduler *organizza la coda dei processi*. Esistono due tipi principali di criteri di pianificazione (*scheduling*):
|
||||
|
||||
- *politiche in tempo reale*: *i processi vengono eseguiti in base ai loro valori di priorita'*. Se un processo con priorita' maggiore diventa pronto per essere eseguito, un processo meno importante viene interrotto e il processo con priorita' piu' alta assume il controllo della CPU. Un processo con priorita' inferiore otterra' il controllo della CPU solo quando i processi con priorita' maggiore saranno inattivi o in attesa di risposte hardware. Qualsiasi processo in tempo reale ha una priorita' maggiore di un processo normale
|
||||
- *politiche normali*: i processi normali hanno tutti lo stesso valore di priorita', ma le politiche normali possono definire delle regole di priorita' d'esecuzione utilizzando il *nice value*
|
||||
|
||||
## Priorita'
|
||||
|
||||
In Linux:
|
||||
|
||||
- *Processi in tempo reale*: priorita' statiche da 0 a 99
|
||||
- *Processi normali*: priorita' statiche da 100 a 139. Priorita' standard 120
|
||||
|
||||
Valori inferiori significano priorita' maggiore.
|
||||
|
||||
La priorita' puo' essere verificata col comando `ps -el`:
|
||||
|
||||
```bash
|
||||
> ps -el
|
||||
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
|
||||
4 S 0 1 0 0 80 0 - 6093 - ? 00:00:05 systemd
|
||||
1 S 0 2 0 0 80 0 - 0 - ? 00:00:00 kthreadd
|
||||
1 S 0 3 2 0 80 0 - 0 - ? 00:00:00 pool_workqueue_release
|
||||
1 I 0 4 2 0 60 -20 - 0 - ? 00:00:00 kworker/R-rcu_gp
|
||||
1 I 0 5 2 0 60 -20 - 0 - ? 00:00:00 kworker/R-sync_wq
|
||||
1 I 0 6 2 0 60 -20 - 0 - ? 00:00:00 kworker/R-slub_flushwq
|
||||
```
|
||||
|
||||
- La colonna `PRI` indica la priorita' statica assegnata dal Kernel. Per ragioni storiche, le priorita' visualizzate da `ps` vanno da -40 a 99, quindi la priorita' effettiva si ottiene aggiungendo 40 al numero visualizzato (80+40=120).
|
||||
|
||||
Anche tramite `top` e' possibile monitorare la priorita' dei processi. `top` sottrae il valore di priorita' di 100, per rendere tutte le priorita' in tempo reale *negative*. Le priorita' normali, pertanto, vanno da 0 a 39.
|
||||
|
||||
Riepilogando:
|
||||
|
||||
- linux: 0 a 139
|
||||
- `ps`: -40 a 99 (-40)
|
||||
- `top`: -100 a 39 (-100)
|
||||
|
||||
## Niceness
|
||||
|
||||
I numeri di *niceness* vanno da -20 (priorita' alta) a 19 (maggior gentilezza, priorita' bassa). Ogni processo normale inizia con un valore di *niceness* di 0 (priorita' 120).
|
||||
|
||||
- La colonna `NI`, nell'output di `ps` indica il valore di *niceness*. Solo l'utente root puo' diminuire la *niceness* di un processo al di sotto dello zero.
|
||||
|
||||
E' possibile avviare un processo con una priorita' non standard col comando `nice`:
|
||||
|
||||
```bash
|
||||
nice -n 5 tar czf backup.tar.gz /home
|
||||
```
|
||||
|
||||
Il comando `renice` puo' essere usato per modificare la priorita' di un processo in esecuzione: `renice -10 -p PID`. Le opzioni `-g` e `-u` sono usate per modificare rispettivamente tutti i processi di un gruppo o di un utente specifico. Ad esempio con `renice -5 -g users` la *niceness* dei processi degli utenti appartenenti al gruppo *users* sara' aumentata di 5.
|
||||
|
||||
La *niceness* puo' essere modificata anche con `top`, premendo il tasto `R`, quindi il PID del processo.
|
36
lpic/101/021_regularex.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Espressioni regolari
|
||||
|
||||
Le *espressioni regolari* o `regex` sono costituite da sequenze di caratteri che costituiscono un modello generico utilizzato per individuare una sequenza corrispondente in una stringa di dimensioni maggiori.
|
||||
|
||||
Esistono due forme di espressioni regolari: *basic* e *extended*.
|
||||
|
||||
Un *atomo*, l'elemento base di una regex, e' un carattere, che puo' avere o meno un significato speciale. Alcuni caratteri con un significato speciale:
|
||||
|
||||
- `.`: il carattere corrisponde a qualsiasi carattere
|
||||
- `^`: inizio linea. E' un carattere letterale e non ambiguo, tranne quando e' posizionato all'inizio della riga
|
||||
- `$`: fine linea. E' un carattere letterale e non ambiguo, tranne quando e' posizionato alla fine della riga
|
||||
|
||||
## Parentesi quadre
|
||||
|
||||
Un altro atomo sono le `[]`, denominato *bracket expression* (espressione tra []). Un'espressione tra parentesi quadre e' solo un elenco di caratteri letterali racchiusi da [], facendo corrispondere l'atomo a ogni singolo carattere dell'elenco.
|
||||
|
||||
Per specificare i caratteri a cui l'atomo non deve corrispondere, l'elenco deve iniziare con `^`, come in [^1b].
|
||||
|
||||
E' possibile anche specificare degli intervalli. Per esempio, `[0-9]` corrisponde alle cifre da 0 a 9 e `[a-z]` a qualsiasi lettera minuscola.
|
||||
|
||||
## Quantificatori
|
||||
|
||||
I quantificatori `*` hanno la stessa funzione sia nelle RE di base che in quelle estese: rappresentano un carattere letterale se appaiono all'inizio delle RE o se preceduto da `\`. Nelle RE di base, `+` e `?` sono, per la maggioranza dei casi, caratteri letterali.
|
||||
|
||||
- `*`: l'atomo (o il gruppo di caratteri) può comparire zero o più volte. Ad esempio, l'espressione `a*` corrisponde a "", "a", "aa", "aaa", e così via.
|
||||
- `+`: l'atomo deve comparire una o più volte. Ad esempio, l'espressione `a+` corrisponde a "a", "aa", "aaa", ma non corrisponde a "" (stringa vuota).
|
||||
- `?`: l'atomo può comparire zero o una volta
|
||||
|
||||
## Limiti
|
||||
|
||||
Un *buond* o limite permette all'utente di specificare il numero di volte che un atomo può apparire.
|
||||
|
||||
- `{n}`: l'atomo deve comparire esattamente n volte. Ad esempio, a{3} corrisponde a "aaa"
|
||||
- `{n,}`: L'atomo deve comparire almeno n volte. Ad esempio, a{2,} corrisponde a "aa", "aaa", "aaaa", e così via
|
||||
- `{n,m}`: L'atomo può comparire da n a m volte. Ad esempio, xyz{2,4} corrisponde a "xyzz", "xyzzz" e "xyzzzz"
|
||||
|
102
lpic/101/022_grep_sed.md
Normal file
@ -0,0 +1,102 @@
|
||||
# grep e sed
|
||||
|
||||
Due comandi sono particolarmente adatti per manipolare file e dati di testo usando le RE: `grep` e `sed`.
|
||||
|
||||
## grep
|
||||
|
||||
Il comando `grep` permette di ricercare pattern nei file di testo, utilizzando le RE. Il carattere pipe `|` e' usato per reindirizzare l'output di un comando direttamente allo stin di grep.
|
||||
|
||||
Alcune importanti opzioni:
|
||||
|
||||
- `-c` o `--count`: invece di visualizzare i risultati di ricerca, visualizza solo il conteggio del numero di volte in cui si verifica una determinata corrispondenza
|
||||
- `-i`: nessuna distinzione tra maiuscole o minuscole
|
||||
- `-n`: mostra il numero di riga
|
||||
- `-v` o `--invert-match`: seleziona solo le righe che non corrispondono alla ricerca
|
||||
- `-H`: stampa anche il nome del file
|
||||
- `-1`: viene inclusa una riga prima e una riga dopo la corrispondenza trovata. Queste righe aggiuntive sono chiamate *righe di contesto*.
|
||||
- `-E` o `--extended-regexp`: equivalente al comando `egprep`, permette di utilizzare le funzionalita' delle RE estese.
|
||||
|
||||
## sed
|
||||
|
||||
Permette di modificare i dati basati su testo in modo non interattivo. La sua sintassi di base:
|
||||
|
||||
- `sed -f SCRIPT`, quando le istruzioni sono memorizzate in un file SCRIPT
|
||||
- `sed -e COMMANDS`
|
||||
|
||||
### Esempi pratici
|
||||
|
||||
Partendo dal comando:
|
||||
|
||||
```bash
|
||||
> factor `seq 12`
|
||||
1:
|
||||
2: 2
|
||||
3: 3
|
||||
4: 2 2
|
||||
5: 5
|
||||
6: 2 3
|
||||
7: 7
|
||||
8: 2 2 2
|
||||
9: 3 3
|
||||
10: 2 5
|
||||
11: 11
|
||||
12: 2 2 3
|
||||
```
|
||||
|
||||
- Per **eliminare** la prima riga:
|
||||
|
||||
```bash
|
||||
> factor `seq 12` | sed 1d
|
||||
2: 2
|
||||
3: 3
|
||||
4: 2 2
|
||||
5: 5
|
||||
6: 2 3
|
||||
7: 7
|
||||
8: 2 2 2
|
||||
9: 3 3
|
||||
10: 2 5
|
||||
11: 11
|
||||
12: 2 2 3
|
||||
```
|
||||
|
||||
- Per **eliminare** un *intervallo* di righe
|
||||
|
||||
```bash
|
||||
> factor `seq 12` | sed 1,7d
|
||||
8: 2 2 2
|
||||
9: 3 3
|
||||
10: 2 5
|
||||
11: 11
|
||||
12: 2 2 3
|
||||
```
|
||||
|
||||
- E' possibile utilizzare piu' di un istruzione nella stessa esecuzione, separata da un `;`:
|
||||
|
||||
```bash
|
||||
> factor `seq 12` | sed '1,7d;12d'
|
||||
8: 2 2 2
|
||||
9: 3 3
|
||||
10: 2 5
|
||||
11: 11
|
||||
```
|
||||
|
||||
- Qualsiasi cosa inserita tra front-slash (`/`) e' considerata una RE. Invece di eliminare una riga, sed puo' sostituirla con un testo dato:
|
||||
|
||||
```bash
|
||||
> factor `seq 12` | sed '/:.*2/c REMOVED'
|
||||
1:
|
||||
REMOVED
|
||||
3: 3
|
||||
REMOVED
|
||||
5: 5
|
||||
REMOVED
|
||||
7: 7
|
||||
REMOVED
|
||||
9: 3 3
|
||||
REMOVED
|
||||
11: 11
|
||||
REMOVED
|
||||
```
|
||||
|
||||
- L'istruzione piu' usata: `s/FIND/REPLACE`. Solo la prima occorrenza verra' sostituita, a meno che non il flag `g` non sia posto al termina dell'istruzione: `s/FIND/REPLACE/g`
|
292
lpic/101/023_tabella _partizioni.md
Normal file
@ -0,0 +1,292 @@
|
||||
## Introduzione
|
||||
|
||||
Su qualsiasi OS, un disco deve essere partizionato, prima di poter essere utilizzato. Una *partizione* e' un sottoinsieme logico di un disco fisico; le informazioni sulle partizioni sono archiviate in una *tabella delle partizioni*.
|
||||
|
||||
Su Linux, ogni partizione e' assegnata a una directory sotto `/dev`, come `/dev/sda1`.
|
||||
|
||||
## MBR e GPT
|
||||
|
||||
Esistono due modi principali per memorizzare le informazioni sulle partizioni:
|
||||
|
||||
- MBR (*Master Boot Record*)
|
||||
- GPT (*Guid Partition Table*)
|
||||
|
||||
### MBR
|
||||
|
||||
La tabella delle partizioni é memorizzata nel primo settore di un disco, chiamato *Boot Sector*, insieme a un bootloader, solitamente GRUB. Ha diverse limitazioni:
|
||||
|
||||
- incapacità di indirizzare dischi di dimensione superiore ai 2TB
|
||||
- un massimo di 4 partizioni primarie per disco
|
||||
- per rendere il disco avviabile, la prima partizione deve essere primaria
|
||||
|
||||
Un disco MBR puo' avere due tipi differenti di partizioni: *primaria* ed *estesa*. In Linux sono trattate ugualmente, per cui non ci sono vantaggi nell'uso dell'una piuttosto che dell'altra.
|
||||
|
||||
### GPT
|
||||
|
||||
Risolve molti dei limiti di MBR. Non esiste un limite alla dimensione del disco e il numero massimo di partizioni dipende dal OS.
|
||||
|
||||
#### fdisk
|
||||
|
||||
L'utilità standard per la gestione delle partizioni. Esiste anche `cfdisk`.
|
||||
|
||||
```bash
|
||||
fdisk -l /dev/sda
|
||||
|
||||
Disk /dev/sda: 465.76 GiB, 500107862016 bytes, 976773168 sectors
|
||||
Disk model: CT500BX500SSD1
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: gpt
|
||||
Disk identifier: E224383F-FD8C-4067-8F01-09A7965B7EFA
|
||||
|
||||
Device Start End Sectors Size Type
|
||||
/dev/sda1 2048 976773119 976771072 465.8G Linux filesystem
|
||||
```
|
||||
|
||||
dove:
|
||||
|
||||
- `Device`: il dispositivo assegnato alla partizione
|
||||
- `Start`: il settore in cui inizia la partizione
|
||||
- `End`: il settore in cui termina la partizione
|
||||
- `Sectors`: il numero totale di settori della partizione
|
||||
- `Size`: la dimensione della partizione
|
||||
|
||||
#### gdisk
|
||||
|
||||
Utilità equivalente a *fdisk* e con comandi molto simili.
|
||||
|
||||
```bash
|
||||
sudo gdisk -l /dev/sda
|
||||
GPT fdisk (gdisk) version 1.0.10
|
||||
|
||||
Partition table scan:
|
||||
MBR: protective
|
||||
BSD: not present
|
||||
APM: not present
|
||||
GPT: present
|
||||
|
||||
Found valid GPT with protective MBR; using GPT.
|
||||
Disk /dev/sda: 937703088 sectors, 447.1 GiB
|
||||
Model: KINGSTON SA400S3
|
||||
Sector size (logical/physical): 512/512 bytes
|
||||
Disk identifier (GUID): 2393AA2C-252F-46A4-AAB9-35EE402D3D71
|
||||
Partition table holds up to 128 entries
|
||||
Main partition table begins at sector 2 and ends at sector 33
|
||||
First usable sector is 2048, last usable sector is 937703054
|
||||
Partitions will be aligned on 2048-sector boundaries
|
||||
Total free space is 1679 sectors (839.5 KiB)
|
||||
|
||||
Number Start (sector) End (sector) Size Code Name
|
||||
1 2048 937701375 447.1 GiB 8300
|
||||
```
|
||||
|
||||
- Ogni disco ha un identificatore (**GUI**) univoco: si tratta di un numero esadecimale a 128 bit, assegnato casualmente quando viene creata la tabella delle partizioni
|
||||
- Un disco GPT puo' avere fino a 128 partizioni
|
||||
- Le partizioni GPT possono essere facilmente riordinare o riorganizzate, utilizzando il comando `s`
|
||||
- Rispetto a fdisk, durante la creazione delle partizione, é possibile specificare il tipo di partizione (Linux, Windows, ecc.)
|
||||
- Fornisce utilità per aiutare nel ripristino, accessibili col comando `r`
|
||||
- Con GPT, la dimensione di una partizione non é limitata dalla quantità massima di spazio contiguo non allocato.
|
||||
|
||||
## Creare un file-system
|
||||
|
||||
Prima di utilizzare una partizione, occorre creare un file-system. *Controlla il modo in cui i dati vengono archiviati e acceduti*. Lo strumento standard utilizzato é `mkfs`.
|
||||
|
||||
### ext2/ext3/ext4
|
||||
|
||||
L'`extended file-system` (ext) é stato il primo file-system per Linux e nel corso degli anni é stato sostituito da nuove versioni, chiamate ext2, ext3 e ext4.
|
||||
|
||||
Le utilità `mkfs.ext2`, `mkfs.ext3` e `mkfs.ext4` sono utilizzate per creare file-system ext2, ext3 e ext4. Queste utilità sono collegamenti simbolici a `mke2fs`.
|
||||
|
||||
#### Sintassi
|
||||
|
||||
```bash
|
||||
mkfs.ext4 TARGET
|
||||
|
||||
mke2fs -t ext4 TARGET
|
||||
```
|
||||
|
||||
dove TARGET é il nome della partizione. Alcuni dei parametri principali:
|
||||
|
||||
- `-L` o Volume_Label: imposta un'etichetta
|
||||
- `-n`: simula la creazione del file-system
|
||||
- `-q`: modalità silenziosa
|
||||
- `-c`: controllo dei blocchi danneggiati prima di creare un file-system
|
||||
- `-d` (DIRECTORY): copia il contenuto della directory specificata nel nuovo file-system
|
||||
|
||||
### FAT o VFAT
|
||||
|
||||
Il file-system FAT ha avuto origine con MS-DOS e negli anni ha ricevuto diverse versioni, culminate in FAT32, rilasciato nel 1996. VFAT é a estensione di FAT16 con supporto a nomi di file lunghi (fino a 255 caratteri). Entrambi sono gestiti da `mkfs.fat`.
|
||||
|
||||
FAT16 supporta volumi di massimo 4GB e file con una dimensione massima di 2GB. FAT32 aumenta la dimensione massima dei file a 4GB e dei dischi a 2 PB.
|
||||
|
||||
```bash
|
||||
mkfs.fat TARGET
|
||||
```
|
||||
|
||||
### exFAT
|
||||
|
||||
É stato creato da Microsoft nel 2006, al fine di superare i limiti di FAT32: supporta file di dimensione massima di 16 exabyte e dischi di 128 petabyte. Ottima scelta per garantire l'interoperabilitá Linux-Windows. L'utilità predefinita é `mkfs.exfat`:
|
||||
|
||||
```bash
|
||||
mkfs.exfat TARGET
|
||||
```
|
||||
|
||||
### Btrfs
|
||||
|
||||
btrfs (*better FS*) é un file system specifico per Linux. Ha diverse caratteristiche interessanti, come: supporto ai volumi, quote, snapshot, backup incrementali, ecc. É un file-system *copy-on-write*: i dati vengono scritti nello spazio libero su disco e i metadati originali aggiornati per fare riferimento ai nuovi dati e solo allora i vecchi dati vengono eliminati. Questo riduce la possibilitá di perdita di dati in caso di arresto anomalo.
|
||||
|
||||
```bash
|
||||
mkfs.btrfs TARGET -L LABEL
|
||||
```
|
||||
|
||||
É possibile passare dispositivi multipli al comando. Per specificare come verranno distribuiti i metadati nell'array di dischi, utilizzare il parametro `-m`. I parametri validi sono: `raid0`, `raid1`, `raid5`, `raid6`, `raid10`, `single` e `dup`.
|
||||
|
||||
#### subvolume
|
||||
|
||||
Sono come filesystem dentro altri filesystem. Una specie di directory che puo' essere montata e trattata come un filesystem separato.
|
||||
|
||||
```bash
|
||||
btrfs subvolume create /mnt/disk/BKP
|
||||
|
||||
btrfs subvolume list /
|
||||
```
|
||||
|
||||
Per verificare che il volume sia attivo:
|
||||
|
||||
```bash
|
||||
btrfs subvolume show /mnt/disk/BKP
|
||||
```
|
||||
|
||||
Per *montare* il subvolume:
|
||||
|
||||
```bash
|
||||
mount -t btrfs -o subvol=BK /dev/sda1 /mnt/bk
|
||||
```
|
||||
|
||||
#### snapshot
|
||||
|
||||
Uno snapshot duplica l'albero del filesystem, mentre punta ai dati originali.
|
||||
|
||||
```bash
|
||||
btrfs subvolume snapshot /mnt/disk /mnt/disk/snap
|
||||
```
|
||||
|
||||
Per creare istantanee di sola lettura, basta aggiungere il parametro `-r`.
|
||||
|
||||
## GNU Parted
|
||||
|
||||
`GNU Parted` é un potente editor delle partizioni. Esistono dei front-end grafici, come *GParted*.
|
||||
|
||||
> WARNING: Parted apporta modifiche al disco immediatamente dopo che il comando é stato dato, senza attese, diversamente da fdisk e gdisk
|
||||
|
||||
```bash
|
||||
parted DEVICE
|
||||
|
||||
parted /dev/sda
|
||||
```
|
||||
|
||||
### Selezionare i dischi
|
||||
|
||||
Per passare da un disco diverso da quello selezionato, basta usare il comando `select`:
|
||||
|
||||
```bash
|
||||
parted /dev/sda
|
||||
Using /dev/sda
|
||||
(parted) select /dev/sdb
|
||||
Using /dev/sdb
|
||||
```
|
||||
|
||||
### Ottenere informazioni
|
||||
|
||||
Per ottenere informazioni sul disco, utilizzare il comando `print`:
|
||||
|
||||
```bash
|
||||
(parted) print
|
||||
Model: ATA CT500BX500SSD1 (scsi)
|
||||
Disk /dev/sdb: 500GB
|
||||
Sector size (logical/physical): 512B/512B
|
||||
Partition Table: gpt
|
||||
Disk Flags:
|
||||
|
||||
Number Start End Size File system Name Flags
|
||||
1 1049kB 500GB 500GB
|
||||
```
|
||||
|
||||
Per ottenere un elenco di tutti i dispositivi a blocchi, utilizzare `print devices`. Tramite il comando `print all` si ottengono informazioni su tutti i dispositivi a blocchi collegati. Tramite il comando `print free` é possibile visualizzare lo spazio libero a disposizione su un singolo device
|
||||
|
||||
### Creare una tabella delle partizioni
|
||||
|
||||
Per creare una tabella delle partizioni su un disco vuoto, usare il comando `mklabel`, seguito dal tipo di tabella che si desidera creare:
|
||||
|
||||
```bash
|
||||
(parted) mklabel msdos
|
||||
(parted) mklabel gpt
|
||||
```
|
||||
|
||||
### Creare una partizione
|
||||
|
||||
Per creare una partizione, si utilizza il comando `mkpart`:
|
||||
|
||||
```bash
|
||||
(parted) mkpart PARTTYPE FSTYPE START END
|
||||
```
|
||||
|
||||
dove:
|
||||
|
||||
- `PARTTYPE`: il tipo di partizione, che puo' essere *primary*, *logical* o *extended*
|
||||
- `FSTYPE`: il tipo di filesystem. Parted non crea il filesystem, ma imposta solo un flag sulla partizione che dice al OS che tipo di dati aspettarsi
|
||||
- `START`: specifica il punto esatto in cui inizia la partizione
|
||||
- `END`: specifica il punto in cui la partizione finisce (NON la dimensione)
|
||||
|
||||
```bash
|
||||
(parted) mkpart primary ext4 1m 100m
|
||||
```
|
||||
|
||||
### Eliminare una partizione
|
||||
|
||||
Utilizzare il comando `rm` seguito dal numero della partizione da eliminare, visualizzabile col comando `print`.
|
||||
|
||||
### Recuperare una partizione
|
||||
|
||||
Parted permette di recuperare una partizione cancellata. Utilizzare il comando `rescue`, con la sintassi: `rescue START END`, dove START indica la posizione approssimativa in cui la partizione iniziava e END quella in cui finiva. Parted eseguirà una scansione del disco alla ricerca di partizione e si offrirà di ripristinare quelle trovate. Puo' recuperare solo le partizioni in cui é presente un filesystem; quelle vuote non vengono rilevate.
|
||||
|
||||
### Ridimensionare una partizione ext2/3/4
|
||||
|
||||
Puo' essere anche usato per ridimensionare le partizioni, al fine di renderle piú grandi i piú piccole, con alcune accortezze:
|
||||
|
||||
- durante il ridimensionamento, la partizione deve essere inutilizzata e smontata
|
||||
|
||||
Il comando é `resizepart`, seguito da numero di partizione e di dove dovrebbe finire: `resizepart 2 300g`.
|
||||
|
||||
Una volta ridimensionata la partizione, bisogna ridimensionare il filesystem. Per i filesystem ext2/3/4, questo viene fatto da `resize2fs PARTITION SIZE`. Se si omette il parametro SIZE, verrá utilizzato tutto lo spazio disponibile: `resize2fs /dev/sdb3`.
|
||||
|
||||
Per *restringere* una partizione, il processo deve essere inverso:
|
||||
|
||||
- prima si restringe il filesystem, tramite `resize2fs`
|
||||
- poi si ridimensiona la partizione stessa utilizzando `parted`
|
||||
|
||||
```bash
|
||||
resize2fs /dev/sdb3 200g
|
||||
|
||||
parted /dev/sdb3
|
||||
(parted) resizepart 3 200g
|
||||
```
|
||||
|
||||
## swap
|
||||
|
||||
Su Linux, il SO puo' scambiare pagine di memoria dalla RAM al disco, secondo necessitá, memorizzandole in uno spazio separato, implementato come partizione separata (o file), chiamato *partizione di swap*.
|
||||
|
||||
Tramite fdisk, basta creare una partizione normale e poi cambiare il tipo di partizione in Linux Swap, tramite il comando `t`, con codice 82. Per gdisk, cambia solamente il codice, 8200.
|
||||
|
||||
Una volta che la partizione é stata correttamente creata, usare il comando `mkswap PARTITION`. Infine, per abilitare la partizione: `swapon PARTITION`. Allo stesso modo, `swapoff PARTITION` disabiliterá la swap per quel dispositivo.
|
||||
|
||||
Linux supporta anche l'uso di *file di swap*: basta creare un file vuoto, tramite *dd* e quindi utilizzare `mkswap` e `swapon`
|
||||
|
||||
```bash
|
||||
dd if=/dev/zero of+myswap bs=1M count=1024
|
||||
mkswap myswap
|
||||
swapon myswap
|
||||
```
|
||||
Per rendere il file di swap persistente, **aggiungerlo** a `/etc/fstab`. I permessi consigliati per il file di swap sono 0600 e il gruppo e il proprietario dovrebbero essere root.
|
||||
|
104
lpic/101/024_du_df.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Introduzione: journal
|
||||
|
||||
I moderni filesystem Linux hanno un *diario di bordo*. Questo significa che ogni operazione viene registrata in un log interno, il *journal*, prima di essere eseguita. Se un'operazione viene interrotta a causa di un errore di sistema, questa puo' essere ricostruita controllando il journal, evitando il danneggiamento del filesystem e la perdita di dati.
|
||||
|
||||
## Controllare l'utilizzo dei dischi
|
||||
|
||||
Un comando usato per controllare quanto spazio viene usato e quanto ne resta su un determinato filesystem é `du` o *disk usage*.
|
||||
|
||||
```bash
|
||||
1.1G ./Film/S09
|
||||
8.8G ./Film/S10
|
||||
32G ./Film
|
||||
55G ./Criterion
|
||||
86G .
|
||||
```
|
||||
Il comportamento predefinito é quello di mostrare l'utilizzo di ogni sottodirectory, quindi l'utilizzo totale della directory corrente, incluse le sottodirectory (86G nell'esempio). Per controllare quanto *profondo* l'output di `du` dovrebbe essere, si utilizza il parametro `-d N`, dove `N` indica il livello.
|
||||
|
||||
Per impostazione predefinita, `du` mostra solo il conteggio dell'utilizzo delle directory. Per mostrare un conteggio individuale per tutti i file, aggiungere il parametro `-a`.
|
||||
|
||||
Per escludere alcuni tipi di file dal conteggio si utilizza `--exclude="PATTERN"`:
|
||||
|
||||
```bash
|
||||
> du -h --exclude="*.mkv"
|
||||
0 ./Film/S09
|
||||
0 ./Film/S10
|
||||
0 ./Film
|
||||
0 ./Criterion
|
||||
356K .
|
||||
```
|
||||
|
||||
## Controllare lo spazio libero
|
||||
|
||||
`du` funziona a livello di file e directory. `df` mostra invece quanto spazio é disponibile a livello di filesystem. Mostra un elenco di tutti i filesystem montati nel sistema, inclusa la loro dimensione totale, lo spazio utilizzato, quello ancora disponibile, la percentuale e il mount-point.
|
||||
|
||||
```bash
|
||||
[21:03 Sun Jan 26]dado@dadopc (1425):~
|
||||
> df -h
|
||||
Filesystem Type Size Used Avail Use% Mounted on
|
||||
udev devtmpfs 15G 0 15G 0% /dev
|
||||
tmpfs tmpfs 3.0G 1.9M 3.0G 1% /run
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /
|
||||
```
|
||||
|
||||
Per mostrare gli inode usati/disponibili invece dei blocchi, si usa il parametro `-i`:
|
||||
|
||||
```bash
|
||||
[21:03 Sun Jan 26]dado@dadopc (1427):~
|
||||
> df -i
|
||||
Filesystem Type Inodes IUsed IFree IUse% Mounted on
|
||||
udev devtmpfs 3.7M 596 3.7M 1% /dev
|
||||
tmpfs tmpfs 3.7M 1.2K 3.7M 1% /run
|
||||
/dev/mapper/VG0-LV0 btrfs 0 0 0 - /
|
||||
```
|
||||
|
||||
Il parametro `-T` stampa il tipo di filesystem. É possibile anche filtrare l'output per mostrare solo un tipo di filesystem con `-t TYPE` o escludere un dato filesystem con `-x TYPE`:
|
||||
|
||||
```bash
|
||||
[21:06 Sun Jan 26]dado@dadopc (1428):~
|
||||
> df -hTt btrfs
|
||||
Filesystem Type Size Used Avail Use% Mounted on
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/cache
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /home
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /.snapshots
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/crash
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/lib/AccountsService
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/lib/gdm3
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/log
|
||||
/dev/mapper/VG0-LV0 btrfs 465G 117G 346G 26% /var/tmp
|
||||
```
|
||||
|
||||
## Manutenzione dei filesystem ext2, ext3 e ext4
|
||||
|
||||
Esiste l'utility `fsck` (*filesystem check*). Sintassi:
|
||||
|
||||
```bash
|
||||
fsck /dev/sda1
|
||||
```
|
||||
|
||||
> NOTA: MAI, MAI eseguire fsck su un filesystem montato
|
||||
|
||||
Alcune opzioni:
|
||||
|
||||
- `-A`: controlla tutti i filesystem elencati in `/etc/fstab`
|
||||
- `-C`: visualizza una barra di avanzamento durante il controllo (solo ext2/3/4)
|
||||
- `-N`: *dry-run*
|
||||
- `-R`: se usato insieme a `-A`, salta il controllo del filesystem root
|
||||
- `-V`: verbose
|
||||
|
||||
`fsck` non controlla il filesystem, ma richiama l'utilitá appropriata per il tipo di filesystem; `e2fsck` nel caso di ext2/3/4. Per impostazione predefinita, viene eseguito in modalitá interattiva: quando viene rilevato un errore, viene chiesto all'utente come procedere. Ci sono alcune opzioni per eseguire `e2fsck` in modalitá automatica:
|
||||
|
||||
- `-p`: tenta di correggere autonomamente gli errori. Se l'errore richiede l'intervento dell'amministratore, fornisce una descrizione e terminerá la propria esecuzione
|
||||
- `-y`: risponde `yes` a tutte le domande
|
||||
- `-n`: risponde `no` a tutte le domande
|
||||
|
||||
## Manutenzione di un filesystem xfs
|
||||
|
||||
Esiste l'utility `xfs_repair`, la cui sintassi di base:
|
||||
|
||||
```bash
|
||||
xfs_repair /dev/sda1
|
||||
```
|
||||
|
||||
- `-n`: *dry-run*. Nessuna modifica: il filesystem verrá controllato, ma non verrá effettuata alcuna riparazione.
|
107
lpic/101/025_mount.md
Normal file
@ -0,0 +1,107 @@
|
||||
## Montare e smontare un filesystem
|
||||
|
||||
Il comando per montare manualmente un filesystem si chiama `mount`:
|
||||
|
||||
```bash
|
||||
mount -t TYPE DEVICE MOUNTPOINT
|
||||
```
|
||||
|
||||
Il mountpoint non deve essere vuoto, ma deve esistere. Qualsiasi file sará inaccessibile fino a che il filesystem sará montato.
|
||||
|
||||
Per smontare il filesystem: `umount MOUNTPOINT` o `umount DEVICE`
|
||||
|
||||
### Elencari i filesystem
|
||||
|
||||
Se si digita `mount` si ottiene un elenco dei filesystem montati nel sistema. Il parametro `-t` permette di filtrare l'output per tipo di filesystem. É possibile specificare piú filesystem contemporaneamente separandoli con una virgola.
|
||||
|
||||
Alcuni parametri del comando `mount`:
|
||||
|
||||
- `-a`: monta tutti i filesystem elencati in `/etc/fstab`
|
||||
- `-o`: passa un elenco di *opzioni di montaggio* separate da virgole
|
||||
- `-ro`: monta il filesystem in sola lettura
|
||||
- `-rw`: monta il filesystem in modalitá scrivibile
|
||||
|
||||
Alcuni parametri del comando `umount`:
|
||||
|
||||
- `-a`: smonta tutti i filesystem elencati in `/etc/fstab`
|
||||
- `-f`: forza lo smontaggio
|
||||
- `-r`: rende il filesystem di sola lettura
|
||||
|
||||
### File aperti
|
||||
|
||||
Se, quando si smonta un filesystem, si incontra il messaggio di errore che indica che la destinazione é occupata (*target is busy*), si puo' usare il comando `lsof DEVICE`, per vedere un elenco di processi e a quali file accedono.
|
||||
|
||||
### Montare un filesystem all'avvio
|
||||
|
||||
Il file `/etc/fstab` contiene la lista dei filesystem che devono essere montati all'avvio del sistema. É costruito nel seguente modo:
|
||||
|
||||
```bash
|
||||
# <file system> <mount point> <type> <options> <dump> <pass>
|
||||
/dev/sda1 / btrfs defaults 0 0
|
||||
UUID=2858f3c1-995f-46ca-8164-76836b7860d2 /media/user/ btrfs defaults 0 2
|
||||
```
|
||||
dove:
|
||||
|
||||
- `FILESYSTEM`: il filesystem da montare. Al posto del dispositivo, é possibile specificare lo UUID (*Universally Unique Identifier*) o l'etichetta della partizione
|
||||
- `UUID=`
|
||||
- `LABEL=`
|
||||
- `OPTIONS`: le opzioni di montaggio, che saranno passate a mount
|
||||
- `DUMP`: indica se un filesystem debba essere considerato per il backup dal comando dump. Solitamente é zero
|
||||
- `PASS`: quando é diverso da zero, definisce l'ordine in cui i filesystem saranno controllati all'avvio
|
||||
|
||||
Le *opzioni* sono un elenco di parametri, separati da virgole:
|
||||
|
||||
- `atime` e `noatime`: per impostazione predefinita, ogni volta che un file viene letto, le informazioni sul tempo di accesso vengono aggiornate. Disabilitare questa opzione aumenta le performance
|
||||
- `auto` e `noauto`: se il filesystem puo' o non puo' essere montato automaticamente con `mount -a`
|
||||
- `defaults`: passa a mount le opzioni `rw,dev,suid,exec,auto,nouser,async`
|
||||
- `exec` e `noexec`: consente o nega l'esecuzione di file binari sul filesystem
|
||||
- `user` e `nouser`: consente o meno a un utente normale di montare il filesystem
|
||||
- `ro` e `rw`
|
||||
- `remount`: tenterá di rimontare un filesystem giá montato. Non viene usato in `/etc/fstab`, da come parametro del comando `mount -o`.
|
||||
- `sync` e `async`: indica se eseguire le operazioni di I/O sul filesystem in modo sincrono o asincrono
|
||||
|
||||
### Montare con Systemd
|
||||
|
||||
Bisogna creare un file di configurazione `.mount`, denominato *mount unit*, in `/etc/systemd/system`.
|
||||
|
||||
```bash
|
||||
[Unit]
|
||||
Description=Additional drive
|
||||
|
||||
[Mount]
|
||||
What=/dev/disk/by-uuid/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
Where=
|
||||
Type=
|
||||
Options=
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Nello specifico:
|
||||
|
||||
- `What`: cosa deve essere montato. Il volume deve essere specificato nella forma `/dev/disk/by-uuid/UUID`
|
||||
- `WantedBy`: usato per la gestione delle dipendenze
|
||||
|
||||
> Per funzionare correttamente, l'unitá di montaggio deve avere lo stesso nome del punto di mount. Se, per esempio, il punto di mount fosse `/mnt/external`, l'unitá si chiamerá `mnt-external.mount` e `mnt-external.automount`
|
||||
|
||||
#### Auto-mount
|
||||
|
||||
Le unitá di montaggio possono essere montate in automatico ogni volta che si accede al punto di mount. Basta creare, accanto al file `.mount`, un file `.automount`:
|
||||
|
||||
```bash
|
||||
Description=Automount Additional Drive
|
||||
|
||||
[Automount]
|
||||
Where=
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Ora ricaricare systemd e avviare l'unitá:
|
||||
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now mnt-external.automount
|
||||
```
|
123
lpic/101/026_proprieta_permessi_file.md
Normal file
@ -0,0 +1,123 @@
|
||||
# Introduzione ai permessi
|
||||
|
||||
Ogni file su disco é di proprietá di un utente e di un gruppo di utenti e dispone di tre tipi di autorizzazioni:
|
||||
|
||||
- per il proprietario
|
||||
- per il gruppo che possiede il file
|
||||
- per gli altri
|
||||
|
||||
```bash
|
||||
> ls -l
|
||||
total 0
|
||||
drwxrwxr-x 1 dado dado 0 Jan 5 15:49 Desktop
|
||||
drwxr-xr-x 1 dado dado 12 Jan 3 22:18 Videos
|
||||
```
|
||||
|
||||
- Il primo carattere, `d`, indica il tipo di file
|
||||
- I successivi tre, `rwx`, i permessi per il proprietario del file (*user*)
|
||||
- I successivi tre, `rwx`, i permessi per il gruppo che possiede il file (*group*)
|
||||
- Gli ultimi tre, `r-x`, indicano i permessi per gli altri (*others*)
|
||||
- La seconda colonna, `1`, indica il numero di *hard link* che puntano a quel file
|
||||
- La 5a colonna mostra la dimensione del file
|
||||
- La 6a la data e l'ora dell'ultima modifica del file
|
||||
|
||||
## Tipi di file
|
||||
|
||||
- `-`: normal file
|
||||
- `d`: directory
|
||||
- `l`: symbolic link
|
||||
- `b`: block device
|
||||
- `c`: le porte seriali sono esempi comuni di dispositivi a caratteri
|
||||
- `s`: i socket servono come tramite per il passaggio di informazioni tra due programmi
|
||||
|
||||
## Permessi sui file
|
||||
|
||||
- `r`: read, ha un valore ottale di 4. Indica il permesso di aprire un file e leggerne il contenuto
|
||||
- `w`: write, ha un valore ottale di 2. Indica il permesso di modificare un file
|
||||
- `x`: execute, con un valore ottale di 1. Permesso di esecuzione del file
|
||||
|
||||
## Permessi sulle directory
|
||||
|
||||
- `r`: read, ha un valore ottale di 4. Indica il permesso di leggere il contenuto della directory, ma non implica il permesso di leggere i file stessi
|
||||
- `w`: write, ha un valore ottale di 2. Indica il permesso di creare o eliminare file in una directory o modificarne i nomi, permessi e proprietari. Se un utente ha il permesso di scrittura su una directory, potrá modificare i permessi di *qualsiasi* file (contenuto) nella directory, anche se appartiene ad un altro utente
|
||||
- `x`: execute, con un valore ottale di 1. Indica il permesso di entrare in una directory, ma non di elencarne il contenuto (necessaria l'autorizzazione `r`).
|
||||
|
||||
### Modificare i permessi sui file
|
||||
|
||||
Si utilizza il comando `chmod`. Solo il proprietario di un file o l'utente root possono modificare i permessi di un file. É possibile cambiare i permessi con due modalitá:
|
||||
|
||||
- simbolica
|
||||
- ottale
|
||||
|
||||
Quando viene eseguito su una directory, vengono modificati solo i permessi di quella specifica directory. Per la modalitá ricorsiva, aggiungere `-R`.
|
||||
|
||||
#### Modalitá simbolica
|
||||
|
||||
```bash
|
||||
chmod u[,g,o]+x file
|
||||
chmod u-r file
|
||||
chmod u=rwx file
|
||||
chmod o=rw- file
|
||||
chmod u+x,g,o+r file
|
||||
|
||||
```
|
||||
|
||||
dove:
|
||||
|
||||
- `u`: user
|
||||
- `g`: group
|
||||
- `o`: others
|
||||
- `+`: concedere un permesso
|
||||
- `-`: revocare un permesso
|
||||
- `=`: impostare un set di permessi specifico
|
||||
- `r` o `w` o `x`: autorizzazione
|
||||
|
||||
#### Modalitá ottale
|
||||
|
||||
I permessi sono specificati come valore a tre cifre su notazione ottale. Sono specificati nel seguente ordine: r(4)w(2)x(1). Se non ci sono permessi, si usa il valore 0. Quindi il permesso rwx sarebbe 4+2+1=7. La prima lettera indica l'utente, la seconda il gruppo e la terza tutti gli altri.
|
||||
|
||||
### Modificare la proprietá di un file
|
||||
|
||||
Si usa il comando `chown`:
|
||||
|
||||
```bash
|
||||
chown USER:GROUP file
|
||||
```
|
||||
|
||||
## Gruppi
|
||||
|
||||
Per vedere quali gruppi esistono sul sistema: `getent group`. `groups user` per sapere a quali gruppi appartiene un utente. Per sapere quali utenti fanno parte di un gruppo si utilizza il comando: `groupmems -g group -l`.
|
||||
|
||||
## Permessi di default
|
||||
|
||||
Ogni file o directory che si crea sul filesystem avrá sempre le stesse autorizzazioni. Provengono dalla *user mask* o `umask`, che imposta i permessi predefiniti per ogni file (o directory) creato. Per controllare i valori correnti:
|
||||
|
||||
```bash
|
||||
umask -S
|
||||
u=rwx,g=rwx,o=rx
|
||||
```
|
||||
|
||||
## Permessi speciali
|
||||
|
||||
Ogni file puo' avere anche *tre permessi speciali*.
|
||||
|
||||
### Sticky Bit
|
||||
|
||||
Chiamato anche *indicatore di cancellazione ristretta*, ha il valore ottale di `1` e in modalitá simbolica viene indicato con una `t` all'interno dei permessi degli *others* (sostituisce la *x* sui permessi degli *altri*). Si applica *solo alle directory* e non ha effetto sui file normali. Impedisce agli utenti di rimuovere o rinominare un file all'interno di quella directory, a meno che non siano proprietari di quel file o directory.
|
||||
|
||||
In modalitá ottale i permessi vengono specificati con una notazione a 4 cifre, con la prima che rappresenta il permesso speciale: `chmod 1755 directory/`
|
||||
|
||||
### Set GID
|
||||
|
||||
Noto anche come *SGID*, ha il valore ottale di `2` in modalitá simbolica viene indicato con una `s` all'interno dei permessi di *group* (sostituisce la *x* sui permessi del gruppo). Si applica sia ai file eseguibili che alle directory. Sui file, eseguirá il processo coi privilegi del gruppo che possiede il file. Sulle directory, fa in modo che ogni file o subdirectory erediti il gruppo della directory principale.
|
||||
|
||||
```bash
|
||||
chmod 2755 file.sh
|
||||
chmod g+s file.sh
|
||||
```
|
||||
|
||||
### Set UID
|
||||
|
||||
*SUID* o *Set User ID*, ha il valore ottale di `4` in modalitá simbolica viene indicato con una `s` all'interno dei permessi *utente* (sostituisce la *x* sui permessi dell'utente). Si *applica solo ai file eseguibili* e non ha effetto sulle directory. Sui file, eseguirá il processo coi privilegi dell'utente che possiede il file.
|
||||
|
||||
É possibile combinare le autorizzazioni speciali in un unico parametro: `chmod 6755 file.sh`.
|
47
lpic/101/027_link_hard_soft.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Link
|
||||
|
||||
Esiste un tipo speciale di file, chiamato *link*. Ne esistono di due tipi:
|
||||
|
||||
- link *simbolici*: chiamati anche *soft link*, puntano al percorso di un altro file. Se si elimina il file a cui punta il collegamento (*target*), questo smetterá di funzionare
|
||||
- *hard link*: sono una voce aggiuntiva nel filesystem che punta alla stessa posizione (*inode*) sul disco (punta allo stesso dato). Se si elimina uno di questi nomi, gli altri continueranno a funzionare.
|
||||
|
||||
> Un inode é una struttura che memorizza gli attributi (o metadati) per un oggetto, come file o directory, su un filesystem. Tra questi attributi ci sono i permessi, le varie proprietá, ecc.
|
||||
|
||||
## Hard Link
|
||||
|
||||
```bash
|
||||
ln TARGET LINK_NAME
|
||||
```
|
||||
|
||||
Il target, ossia il file a cui punterá il collegamento, deve giá esistere.
|
||||
|
||||
```bash
|
||||
ln file hardlink
|
||||
|
||||
ls -li
|
||||
total 4
|
||||
880514 -rw-rw-r-- 2 dado dado 0 Feb 18 20:39 file
|
||||
880514 -rw-rw-r-- 2 dado dado 0 Feb 18 20:39 hardlink
|
||||
```
|
||||
Per verificare il numero di inode, si utilizza il comando `ls -i`. Il numero prima dei permessi é il numero di inode. I file `file` e `hardlink` hanno lo stesso numero di inode, poiché sono uno l'hardlink dell'altro.
|
||||
|
||||
In quanto un hardlink punta allo stesso inode, puo' essere spostato senza timore di rompere il collegamento.
|
||||
|
||||
Il numero `2` indica il numero di hard link che puntano al file (si parte da 1). I soft link non aumentano questo contatore.
|
||||
|
||||
## Soft Link
|
||||
|
||||
```bash
|
||||
ln -s TARGET LINK_NAME
|
||||
```
|
||||
|
||||
Ecco un esempio:
|
||||
|
||||
```bash
|
||||
ls -lh
|
||||
total 8.0K
|
||||
|
||||
lrwxrwxrwx 1 dado dado 4 Feb 18 20:44 softlink -> file
|
||||
```
|
||||
|
||||
Il primo carattere sui permessi é `l`, che indica un soft link. I permessi per i softlink sono sempre `rwxrwxrwx`, ma in realtá i permessi sono gli stessi della destinazione.
|
24
lpic/101/028_FSH.md
Normal file
@ -0,0 +1,24 @@
|
||||
# FHS: una introduzione
|
||||
|
||||
Il *Filesystem Hierarchy Standard* definisce un layout standard per il filesystem. É uno sforzo per standardizzare la struttura delle directory e il contenuto delle stesse nei sistemi Linux. Non é obbligatoria, ma viene seguita dalla maggior parte delle distribuzioni.
|
||||
|
||||
- `/`: é la directory principale, piú in alto nella gerarchia. Ogni altra directory si trova al suo interno
|
||||
- `/bin`: binari essenziali
|
||||
- `/boot`: file necessari al processo di avvio, come initrd e il kernel Linux stesso
|
||||
- `/dev`: file di dispositivo
|
||||
- `/etc`: file di configurazione
|
||||
- `/home`: ogni utente ha una propria directory home
|
||||
- `/lib`: librerie condivise
|
||||
- `/media`: punto di mount dei supporti rimovibili montati dall'utente
|
||||
- `/mnt`: punto di mount dei filesystem montati temporaneamente
|
||||
- `/opt`: pacchetti software applicativi
|
||||
- `/root`: directory home del superutente root
|
||||
- `/sbin`: binari di sistema
|
||||
- `/tmp`: file temporanei
|
||||
- `/usr`: dati utente di sola lettura
|
||||
- `/proc`: filesystem virtuale contenente dati relativi ai processi in esecuzione
|
||||
- `/var`: dati variabili, scritti durante il funzionamento del sistema
|
||||
- `/var/tmp`: un'altra posizione per i file temporanei. In file qui archiviati, solitamente persistono al riavvio del sistema
|
||||
- `/run`: contiene i dati delle variabili di runtime utilizzato dai processi in esecuzione, come i file di identificazione di processo (*.pid*). Deve essere ripulita durante l'avvio del sistema
|
||||
|
||||
|
26
lpic/101/029_find_locate.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Comandi per la ricerca
|
||||
|
||||
`find` é utilizzato per ricercare file su Linux. Per cercare solo nella directory corrente, si deve usare `maxdepth 1` (da considerare anche la directory corrente). Il parametro `-mount` puo' essere usato per evitare che *find* scenda all'interno dei filesystem montati. Per limitare la ricerca a specifici filesystem, si utilizza invece il parametro `-fstype`.
|
||||
|
||||
## find: attributi di ricerca
|
||||
|
||||
- `-user USERNAME`: corrisponde al file di proprietá dell'utente USERNAME
|
||||
- `-group GROUPNAME`: del gruppo GROUPNAME
|
||||
- `-readable/-writable/executable`: corrisponde ai file leggibili, scrivibili o eseguibili dall'utente corrente
|
||||
- `-perm NNN`: tutti i file che hanno esattamente l'autorizzazione NNN
|
||||
- `-empty`: file e directory vuote
|
||||
- `-size -N`: si utilizzano i prefissi `+` o `-`, che stanno per *piú grande di* o *piú piccolo di*. Per esempio `-size -10M` corrisponde a qualsiasi file di dimensioni inferiori ai 10MB.
|
||||
|
||||
## find: ricerche temporali
|
||||
|
||||
- `-amin N`, `-cmin N`, `-mmin N`: per trovare file a cui é stato effettuato l'*a*ccesso, , che hanno attributi modificati o che sono stati *m*odificati N minuti fa rispettivamente
|
||||
- `-atime N`, `-ctime N`, `-mtime N`: per trovare file a cui é stato effettuato l'*a*ccesso, , che hanno attributi modificati o che sono stati *m*odificati N*24 ore fa
|
||||
|
||||
## locate
|
||||
|
||||
A differenza di find, `locate` non cercherá il pattern nel filesystem, ma lo cerca in un database costruito eseguendo il comando `updatedb`. Cio' fornisce risultati molto rapidi, ma che potrebbero essere imprecisi, a seconda dell'ultimo aggiornamento del db.
|
||||
|
||||
## Trovare i binari
|
||||
|
||||
`which` é un comando utile che mostra il percorso completo di un eseguibile. `type` é un comando simile, che mostra informazioni su un binario, incluso il suo percorso e il su tipo.
|
||||
|
BIN
lpic/101/asset/image/container_vs_vm.png
Normal file
After Width: | Height: | Size: 145 KiB |
0
lpic/102/001_shell.md
Normal file
3
lpic/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# lpic
|
||||
|
||||
Materiale per certificazione lpic 101/102
|
122
networking/001-ISO⁄OSI-TCP⁄IP.md
Normal file
@ -0,0 +1,122 @@
|
||||
# Internet
|
||||
|
||||
Internet é una serie di dispositivi (host o nodi) interconnessi tra loro grazie ad altri dispositivi, come switch e router.
|
||||
|
||||
Per dimensioni, l'architettura di rete si puo' suddividere in:
|
||||
|
||||
- `LAN` (local area network)
|
||||
- `WAN` (wide area network)
|
||||
|
||||
## Stack protocollari
|
||||
|
||||
- Modello teorico `ISO/OSI`
|
||||
- Modello pratico `TCP/IP`
|
||||
|
||||

|
||||
|
||||
Per creare una comunicazione standard tra i vari host é stato creato il modello teorico ISO/OSI, implementato nel modello TCP/IP.
|
||||
|
||||
Si tratta di una struttura di dati che contiene un insieme di protocolli (regole), divisi, in base al loro scopo, tra i vari layer.
|
||||
|
||||
- `Physical layer` o `Layer 1`: livello piú basso, che si occupa dell'effettiva trasmissione fisica dei dati, mediante un mezzo trasmissivo (es. cavo in rame, fibra ottica, onde radio, ecc.). Le informazioni inviate sono codificate come `bit` (0 e 1).
|
||||
- `Data-Link` o `Layer 2`: una serie di standard che si occupano di comunicazioni tra dispositivi locali (LAN), con eventuali meccanismi di correzione degli errori. I pacchetti di informazioni sono chiamati `frame`, che contengono anche i vari mac-address sorgente e destinazione.
|
||||
- `Network Layer` o `Layer 3`: i `protocolli di routing` (instradamento dei pacchetti) permettono l'indirizzamento degli host a livello globale (WAN).
|
||||
- `Transport Layer` o `Layer 4`: crea un vero e proprio canale di comunicazione tra i singoli processi, associati ad una porta, di due o piú host (TPC/UDP).
|
||||
- `Session Layer` o `Layer 5`: gestione della sessione della comunicazione.
|
||||
- `Presentation Layer` o `Layer 6`: a questo livello l'informazione viene elaborata e trasformata in modo da presentarla all'`Application Layer` (e quindi per essere comprensibile a noi umani).
|
||||
- `Application Layer` o `Layer 7`: a stretto contatto coi software che utilizziamo.
|
||||
|
||||
In ogni layer, il pacchetto di informazioni ha varie nomenclature. Inoltre, ogni layer ha un suo determinato *meccanismo di indirizzamento* delle informazioni, che garantisce un flusso bidirezionale (come e da chi verso chi). Ad esempio, a livello data-link sarà il mac sorgente e destinatario.
|
||||
|
||||
- `Application`: payload o messaggio
|
||||
- `Transport`: segmento TCP (indirizzamento tramite porte)
|
||||
- `Network`: pacchetto IP (indirizzamento tramite indirizzo IP)
|
||||
- `Data-Link`: frame (indirizzamento tramite mac-address)
|
||||
- `Physical`: bit (mezzo trasmissivo che collega due o piú host)
|
||||
|
||||
### Interazione tra i layer
|
||||
|
||||
I layer sono modulari e indipendenti: qualche aggiunta o modifica ad un certo layer, non distrugge la struttura generale. Tuttavia, questi interagiscono tra di loro in diversi modi:
|
||||
|
||||
- Interazione adiacente (`adjacent layer interaction`): si verifica quando un layer richiede un servizio da quello immediatamente sottostante, oppure quando un layer offre un servizio a quello immediatamente soprastante. Offrire un servizio, in questo contesto, significa mettere a disposizione un protocollo specifico.
|
||||
Ad esempio, l'utilizzo del protocollo HTTPS implica la necessità di una trasmissione dati affidabile. Ciò comporta che il livello applicativo, che gestisce HTTPS, debba appoggiarsi al livello di trasporto per garantire la consegna affidabile dei dati. In altre parole, il livello applicativo "richiede" al livello di trasporto l'uso di un protocollo affidabile come il TCP, per assicurare che le informazioni vengano trasmesse correttamente.
|
||||
- `Same layer interaction`: indica l'interazione tra stessi livelli di due stack protocollari di host differenti (come se l'application layer dell'host A comunicasse direttamente con l'application layer dell'host B). Questo collegamento logico prevede un meccanismo chiamato incapsulamento/deincapsulamento.
|
||||
|
||||
1. **Incapsulamento**:
|
||||
- Al momento dell’invio, i dati generati dall’applicazione vengono passati attraverso i vari layer dello stack dell’host A
|
||||
- Ogni layer *aggiunge al payload informazioni* necessarie per la gestione della comunicazione, sotto forma di header e/o trailer
|
||||
|
||||
2. **Trasmissione**:
|
||||
- I dati, incapsulati in vari *strati*, viaggiano quindi attraverso la rete
|
||||
|
||||
3. **Deincapsulamento**:
|
||||
- All’arrivo dell’informazione sull’host B, i dati vengono elaborati seguendo l’ordine inverso rispetto a quello dell’incapsulamento
|
||||
- Ogni layer *rimuove (o "spacchetta") le informazioni* (header/trailer) che erano state aggiunte dal corrispondente layer dell’host A
|
||||
- In questo modo, l’host B riesce a recuperare i dati originali generati dall’applicazione
|
||||
|
||||
L’architettura a strati facilita l’interoperabilità tra differenti sistemi e protocolli, poiché ogni layer opera in modo indipendente.
|
||||
|
||||
Non tutti gli host implementano tutto lo stack protocollare. Ad esempio, un dispositivo embedded potrebbe avere solo le funzionalità base per comunicare via rete (come il livello di rete e di trasporto) senza implementare un layer applicativo complesso.
|
||||
|
||||
### Esempio pratico di incapsulamento e deincapsulamento
|
||||
|
||||
Vediamo un esempio pratico di incapsulamento e decapsulamento in una richiesta DNS per il caricamento di una pagina web.
|
||||
|
||||
Il pacchetto in uscita dal client é composto da vari strati:
|
||||
|
||||

|
||||
|
||||
A *livello applicativo*, il client genera una richiesta DNS (*DNS query*) per risolvere l'indirizzo IP del sito web.
|
||||
|
||||

|
||||
|
||||
Dopo aver generato la query DNS a livello applicativo, il *payload* viene incapsulato in un segmento UDP nel *livello di trasporto* (transport layer). Durante questo processo, viene aggiunto un header, che contiene informazioni fondamentali quali:
|
||||
|
||||
- la porta sorgente (determinata dal client)
|
||||
- la porta di destinazione (la *well-known port 53*, utilizzata dal protocollo DNS)
|
||||
|
||||

|
||||
|
||||
Il segmento UDP così formato diventa, nel *network layer*, il payload del *pacchetto IP*. In questo livello, viene aggiunto l'header IP che include:
|
||||
|
||||
- l'indirizzo IP sorgente, ovvero quello del client che ha inoltrato la richiesta
|
||||
- l'indirizzo IP di destinazione, corrispondente al server DNS
|
||||
- altre informazioni di gestione come la versione del protocollo (IPv4 o IPv6), la lunghezza totale del pacchetto, il TTL (Time To Live), ecc.
|
||||
|
||||

|
||||
|
||||
Al livello 2, il *data link layer*, avviene l'indirizzamento tramite MAC address:
|
||||
|
||||
- il pacchetto IP (contenente il segmento UDP con la query DNS) viene incapsulato in un *frame*. Qui interviene il *protocollo ARP* (Address Resolution Protocol), che permette di mappare l'indirizzo IP del server di destinazione all'indirizzo MAC fisico del dispositivo di destinazione
|
||||
- il frame, ora completo di header del livello 2 che include il MAC address sorgente e quello di destinazione, viene inviato allo switch
|
||||
|
||||

|
||||
|
||||
Lo switch riceve un frame in input
|
||||
|
||||

|
||||
|
||||
Lo switch, grazie alla sua MAC address table, sa quale porta utilizzare per inviare il frame al dispositivo corretto (in questo caso il DNS server). Le informazioni vengono quindi trasferite tramite il cavo
|
||||
|
||||

|
||||
|
||||
Lo switch, per poter svolgere il proprio compito, deve analizzare le informazioni fino al livello 2, in particolare il MAC address di destinazione, per poter effettuare l'instradamento corretto.
|
||||
|
||||
*Analisi del frame*:
|
||||
|
||||
- Lo switch riceve il frame e lo *deincapsula* parzialmente: ne esamina l'header per recuperare il MAC address di destinazione, in modo da capire su quale porta inoltrare il pacchetto
|
||||
|
||||
*Instradamento del frame*:
|
||||
|
||||
- Se il MAC address di destinazione è già presente nella MAC address table dello switch e associato a una porta, il frame viene *reincapsulato* e inviato attraverso il cavo (porta) corrispondente, garantendo così la consegna al dispositivo di destinazione
|
||||
|
||||
*Ricezione dal server DNS*:
|
||||
|
||||
- Il server DNS riceve il pacchetto e procede con il completo deincapsulamento: viene rimosso l'header del livello Data Link, lasciando il pacchetto IP. A sua volta, si rimuove l'header del livello di rete e quindi quello del livello trasporto (UDP), fino a ricostruire la query DNS originale
|
||||
- Dall'informazione contenuta nella query, il server DNS elabora la richiesta e incapsula la relativa risposta:
|
||||
- Nella risposta, il server DNS diventa il mittente e il client il destinatario
|
||||
- Lo stesso processo di incapsulamento viene applicato in senso inverso, in modo che il pacchetto risalga fino al client di origine
|
||||
|
||||

|
||||
|
||||
Adesso il processo di incapsulamento si ripete per la generazione di una richiesta HTTP verso il sito web, di cui ora si conosce l'indirizzo IP.
|
59
networking/002-ethernet.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Standard Ethernet
|
||||
|
||||
Ethernet è uno standard che definisce le regole per l'invio e la ricezione dei dati tra dispositivi all'interno di una rete LAN (Local Area Network). Esso opera a due livelli del modello OSI:
|
||||
|
||||
1. **Livello 1 – Fisico (Physical Layer)**
|
||||
- Specifica le caratteristiche fisiche dei componenti, come cavi, connettori, interfacce, moduli di trasmissione, ecc.
|
||||
- Nel contesto delle reti cablate (*wired*) la norma IEEE 802.3 definisce tutti gli aspetti relativi alla trasmissione dei segnali su cavi (reti cablate).
|
||||
- Nel contesto delle reti *wireless* la norma IEEE 802.11 si occupa delle caratteristiche della trasmissione senza fili, garantendo la compatibilità e le modalità comunicative delle reti wireless.
|
||||
|
||||
2. **Livello 2 – Data Link Layer**
|
||||
- Definisce la struttura dei pacchetti (*frame*) che viaggiano in rete.
|
||||
- Stabilisce i metodi di indirizzamento attraverso l’uso dei MAC-address
|
||||
|
||||
## Cavi fisici
|
||||
|
||||
Esistono vari tipi di cavi, caratterizzati da differenti lunghezze e capacità di trasmissione, che dipendono dalla tecnologia impiegata.
|
||||
|
||||
Possiamo classificarli in base alla velocità supportata:
|
||||
|
||||
- Ethernet: fino a 10 Mbps
|
||||
- Fast Ethernet: fino a 100 Mbps
|
||||
- Gigabit Ethernet: fino a 1000 Mbps (1 Gbps)
|
||||
- 10 Gigabit Ethernet: fino a 10 Gbps
|
||||
|
||||
Inoltre, i cavi si distinguono anche per la loro composizione: possono essere realizzati in rame oppure in fibra ottica.
|
||||
|
||||

|
||||
|
||||
Il cavo in figura è un cavo `UTP` (*Unshielded Twisted Pair*), ovvero non schermato, con coppie di cavi intrecciati. Questa particolare struttura serve a ridurre le interferenze elettromagnetiche e a prevenire il fenomeno del *crosstalk*, cioè l'interferenza tra i segnali che viaggiano su cavi adiacenti. Alle estremità, il cavo è dotato di connettori; il più comune è l'`RJ-45`.
|
||||
|
||||
Il cavo UTP è composto da 8 fili di rame, progettati per collegarsi ai pin della porta in cui viene inserito il connettore.
|
||||
|
||||

|
||||
|
||||
I pin di contatto dei dispositivi devono avere funzionalità opposte affinché la comunicazione possa avvenire correttamente. Ad esempio, i pin 1 e 2 di un dispositivo A devono inviare, mentre i pin 1 e 2 del dispositivo B devono ricevere, e viceversa per gli altri pin.
|
||||
|
||||
### Cable pinout Ethernet e Fast Ethernet
|
||||
|
||||
Vengono utilizzati solo 4 pin. Per quanto riguarda le connessioni Ethernet e Fast Ethernet, esistono due tipologie di pinout:
|
||||
|
||||
- `Straight Through Pinout` (cavo dritto): in questo tipo di cablaggio i cavi vengono collegati in modo diretto: il pin 1 di A va al pin 1 di B, il 2 di A al 2 di B, e così via. I dispositivi hanno funzionalità opposte sui rispettivi pin (trasmettitore e ricevitore), per cui la comunicazione avviene correttamente.
|
||||
|
||||

|
||||
|
||||
Un cavo con all'estremità un straight-through cable pinout é utile per mettere in comunicazione due dispositivi che, sugli stessi pin di contatto, hanno funzionalità opposte (sul pin 1 l'host A invia e sul pin 1 l'host B riceve).
|
||||
|
||||
- `Crossover Pinout`: in questo schema la disposizione dei pin alle estremità è *incrociata* (1A-3B, 2A-6B, 3A-1B, 6A-2B), permettendo così una comunicazione bidirezionale tra i dispositivi.
|
||||
|
||||
Il crossover pinout serve per collegare due dispositivi che, sugli stessi pin di contatto, assegnano la medesima funzionalità. Senza l'incrocio dei cavi non è quindi possibile instaurare una comunicazione bidirezionale.
|
||||
|
||||

|
||||
|
||||
Di solito, dispositivi identici (ad esempio, switch collegati tra loro) assegnano la medesima funzionalità agli stessi pin. Pertanto, per stabilire una comunicazione diretta tra di essi, viene utilizzato un cavo con pinout crossover. Nel caso di dispositivi differenti, come ad esempio un computer e uno switch, le funzionalità dei pin non coincidono: il computer trasmette su un set di pin mentre lo switch riceve su quelli corrispondenti. Pertanto, per collegare dispositivi differenti si utilizza tipicamente un cavo con pinout straight-through.
|
||||
|
||||

|
||||
|
||||
### Cable pinout Gigabit Ethernet
|
||||
|
||||
Vengono utilizzati tutti gli 8 pin, con le medesime tipologie di pinout. I pin lavorano sempre a coppie: ad esempio, i ping 1-2A inviano e i pin 1-2B ricevono, ecc. (nel caso del cablaggio straight-through)
|
10
networking/003-mac-address.md
Normal file
@ -0,0 +1,10 @@
|
||||
# MAC-Address
|
||||
|
||||
L'indirizzo MAC, noto anche come *Physical Address* o *indirizzo layer 2* o *data-link address*, è l'identificativo univoco utilizzato per il trasferimento di dati all'interno di una rete locale (LAN). Esso viene utilizzato per indirizzare i pacchetti all'interno della rete, assicurando che vengano trasmessi all'host corretto.
|
||||
|
||||
## Caratteristiche principali
|
||||
|
||||
- Il MAC address è composto da 48 bit (6 byte). Ogni byte è rappresentato in formato esadecimale e i byte possono essere separati da trattini (`-`), punti (`.`) oppure due punti (`:`), a seconda della notazione adottata
|
||||
- I primi 3 byte costituiscono l'**OUI** (Organizationally Unique Identifier), un codice standard che identifica il produttore della scheda di rete
|
||||
- Gli ultimi 3 byte sono assegnati dal produttore e garantiti univoci per ogni dispositivo
|
||||
- L'indirizzo MAC è fisso e direttamente integrato nella scheda di rete (NIC - network interface card)
|
30
networking/004-ethernet-frame.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Ethernet Frame
|
||||
|
||||
L'Ethernet Frame è definito dallo standard `IEEE 802.3` ed opera a livello data-link nelle reti cablate. Di seguito si descrive la struttura tipica di un frame Ethernet:
|
||||
|
||||

|
||||
|
||||
## Struttura del Frame
|
||||
|
||||
L'ethernet frame è composto da tre parti principali: header, payload e trailer. La dimensione totale di un frame Ethernet standard varia da un minimo di 64 byte a un massimo di 1518 byte.
|
||||
|
||||
### Header
|
||||
|
||||
- L'header include gli indirizzi MAC di origine e destinazione, che identificano rispettivamente il dispositivo mittente e quello ricevente all'interno della rete locale
|
||||
- **Type/Length**: questo campo può avere doppia funzione:
|
||||
- Puó indicare la lunghezza del payload
|
||||
- Tramite un valore esadecimale, identifica il tipo di protocollo utilizzato per generare il payload (ad esempio, 0x0800 equivale a IPv4).
|
||||
|
||||
### Payload
|
||||
|
||||
Il payload (*Data & Padding*) contiene i dati provenienti dal livello di rete (network layer).
|
||||
|
||||
- Il payload ha una dimensione massima di 1500 byte, nota come `MTU` (Maximum Transfer Unit)
|
||||
- Se il payload non raggiunge la dimensione minima di 46 byte, viene applicato un padding per garantire la corretta dimensione minima del frame
|
||||
- Nel caso in cui il payload del livello di rete superi l’MTU, esso viene frammentato in più pacchetti per poter essere correttamente incapsulato nei frame Ethernet.
|
||||
|
||||
### Trailer
|
||||
|
||||
- **FCS** (Frame Check Sequence): il trailer termina il frame con un campo di 4 byte, il cui scopo è la verifica dell’integrità dei dati trasmessi.
|
||||
|
||||

|
60
networking/005-wireless-frame.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Architettura wireless
|
||||
|
||||
L'architettura wireless è dominata dallo standard `IEEE 802.11`, che consente la comunicazione senza fili tra dispositivi. In un contesto di rete locale (LAN), è comune che una componente cablata venga estesa attraverso l'uso di `Access Point` (AP), permettendo così ai dispositivi di connettersi in modalità wireless. Le informazioni vengono trasmesse tramite onde radio, consentendo una maggiore flessibilità e mobilità.
|
||||
|
||||
Esistono due principali tipologie di infrastruttura wireless:
|
||||
|
||||
- `Ad Hoc (IBSS - Independent Basic Service Set)`: questa configurazione consiste in un insieme di dispositivi opportunamente configurati per comunicare direttamente tra loro tramite le loro schede wireless. Si tratta di una rete peer-to-peer, in cui ogni nodo funge sia da server che da client, permettendo una comunicazione diretta senza la necessità di un punto di accesso centrale.
|
||||
|
||||
- `Wireless LAN con Infrastruttura`: in questo modello, l'Access Point funge da punto di coordinamento centrale. L'AP consente la comunicazione tra più dispositivi wireless, noti anche come stazioni o terminali wireless.
|
||||
|
||||

|
||||
|
||||
## Concetti chiave
|
||||
|
||||
- Il `BSS` (Basic Service Set) rappresenta il gruppo di dispositivi che comunicano tra loro all'interno di una rete wireless. Ogni BSS è identificato da un `BSSID` (Basic Service Set Identifier), che è l'indirizzo MAC dell'Access Point nel caso di un BSS con infrastruttura, o l'indirizzo MAC di uno dei dispositivi nel caso di un BSS Ad Hoc.
|
||||
- `SSID` (Service Set Identifier): è un identificativo logico della rete, facile da ricordare, che consente agli utenti di riconoscere e connettersi alla rete wireless desiderata.
|
||||
- `ESSID` (Extended Service Set Identifier) è un'estensione del SSID, utilizzata per identificare reti wireless più ampie che possono includere più Access Point, garantendo una connessione continua e senza interruzioni per gli utenti in movimento.
|
||||
- `Roaming`: è una funzionalità fondamentale delle reti wireless che consente ai dispositivi di spostarsi automaticamente da un Access Point (AP) a un altro senza interruzioni nella connessione. Quando un dispositivo wireless si allontana dall'AP a cui è attualmente connesso e entra nella copertura di un altro AP, il processo di roaming avviene in modo fluido e automatico. Questo implica la deautenticazione dal primo AP e l'autenticazione sul secondo AP, garantendo così una continuità del servizio.
|
||||
- `DS` (Distributed System): consente la comunicazione tra dispositivi, sia wireless che cablati, al di fuori del singolo Basic Service Set (BSS). In un sistema distribuito, gli Access Point possono comunicare tra loro e con altri dispositivi (anche non wireless), consentendo una rete più ampia e complessa.
|
||||
|
||||
Gli *Access Point* svolgono un ruolo cruciale nella traduzione dei frame di rete. Sono in grado di convertire gli header degli ethernet frame in wireless frame e viceversa. Questo processo di traduzione è fondamentale per garantire che i dati possano essere trasmessi correttamente tra dispositivi cablati e wireless.
|
||||
|
||||
## Anatomia del Wireless Frame
|
||||
|
||||

|
||||
|
||||
É composto da diversi campi, ognuno con funzioni specifiche. Di seguito sono descritti i principali componenti di un wireless frame:
|
||||
|
||||
### Frame Control
|
||||
|
||||
Il campo `Frame Control` occupa due byte e contiene numerosi sottocampi, tra cui:
|
||||
|
||||
- **Version**: indica la versione dello standard IEEE 802.11 utilizzato per il frame
|
||||
- **Type e Subtype**: questi campi specificano il tipo e il sottotipo del frame. Esistono tre categorie principali di frame:
|
||||
- **Gestione** (Type 00): Utilizzato per le comunicazioni iniziali tra l'Access Point (AP) e i dispositivi wireless
|
||||
- **Controllo** (Type 01): Questo tipo si suddivide ulteriormente in:
|
||||
- **Frame RTS** (Request to Send): Sottotipo 1011
|
||||
- **Frame CTS** (Clear to Send): Sottotipo 1100
|
||||
- **Frame ACK** (Acknowledgment): Sottotipo 1101
|
||||
- **Dati** (Type 02): Questo tipo di frame trasporta i dati effettivi
|
||||
- **ToDS/FromDS**: i bit ToDS e FromDS indicano la direzione del frame rispetto al Distribution System (DS). Le varie combinazioni sono le seguenti:
|
||||
- **ToDS = 0** e **FromDS = 0**: il frame non è destinato a un DS e non proviene da esso. Ci troviamo dunque all'interno dello stesso BSS (Basic Service Set) e il frame viene scambiato direttamente tra stazioni wireless dello stesso BSS
|
||||
- **ToDS = 0** e **FromDS = 1**: il frame proviene da un DS. Questo scenario si verifica ad esempio quando un frame viene inoltrato dal DS fino a una stazione finale.
|
||||
- **ToDS = 1** e **FromDS = 0**: il frame è destinato al DS, il che significa che la stazione sorgente si trova all'interno del BSS e il frame deve essere trasmesso verso il DS per raggiungere una stazione esterna al BSS
|
||||
- **ToDS = 1** e **FromDS = 1**: ciò accade quando un frame viene trasmesso tra stazioni appartenenti a BSS differenti. La comunicazione, in questo caso, sfrutta il DS come ponte fra i due BSS
|
||||
|
||||
### Sequence Control
|
||||
|
||||
Contiene due sottocampi:
|
||||
|
||||
- `Fragment Number`: indica il numero di frammento del frame corrente. Quando un pacchetto di dati è troppo grande per essere trasmesso in un'unica volta, viene frammentato, e ogni frammento è identificato dal suo numero. Questo è essenziale per il destinatario, che utilizza il fragment number per ricostruire il pacchetto originale.
|
||||
- `Sequence Number`: indica il numero di sequenza del frame corrente. Questo campo è fondamentale per garantire che i frame vengano trasmessi e ricevuti nell'ordine corretto.
|
||||
|
||||
### Data
|
||||
|
||||
Il campo **Data** rappresenta il payload incapsulato dal livello di rete.
|
||||
|
||||
### Trailer
|
||||
|
||||
**FCS** (Frame Check Sequence): il trailer termina il frame con un campo di 4 byte, il cui scopo è la verifica dell’integrità dei dati trasmessi.
|
36
networking/006-csmaca.md
Normal file
@ -0,0 +1,36 @@
|
||||
# CSMA/CA
|
||||
|
||||
`CSMA/CA` (*Carrier Sense Multiple Access with Collision Avoidance* ovvero accesso multiplo tramite rilevamento della portante con prevenzione delle collisioni) è un meccanismo che, mediante il rilevamento della portante (o mezzo trasmissivo), previene le collisioni nelle trasmissioni wireless.
|
||||
|
||||
Nelle reti wireless, i dati vengono trasmessi tramite onde radio che viaggiano nell'aria. Poiché l'aria è un mezzo condiviso da più stazioni, le trasmissioni simultanee possono causare collisioni e perdita di informazioni. Il meccanismo di Collision Avoidance (prevenzione delle collisioni) cerca di ridurre tale rischio. Infatti, le stazioni wireless utilizzano la tecnica del Carrier Sense per ascoltare il canale trasmissivo - verificare quindi se ci sono attività sulla portante - prima di trasmettere i dati.
|
||||
|
||||
Uno dei problemi intrinseci nelle reti wireless è l'effetto dell'*hidden terminal*. Questo fenomeno si verifica quando un host può rilevare l'attività solo nel proprio raggio d'azione, ignorando le trasmissioni di altri host situati fuori dalla sua portata.
|
||||
|
||||
## Componenti e Tempi di Attesa
|
||||
|
||||
Nel meccanismo CSMA/CA intervengono alcuni intervalli temporali fondamentali:
|
||||
|
||||
- **DIFS** (Distributed Interframe Space): in questo intervallo di tempo la stazione attende per assicurarsi che il canale sia libero prima di trasmettere
|
||||
- **SIFS** (Short Interframe Space): é un intervallo di attesa più breve rispetto al DIFS
|
||||
|
||||
Durante questi intervalli, le stazioni effettuano il Carrier Sense per verificare l'assenza di trasmissioni attive prima di iniziare la propria trasmissione.
|
||||
|
||||
## Frame di Controllo
|
||||
|
||||
Oltre a trasmettere dati, le stazioni utilizzano specifici frame di controllo per coordinare le trasmissioni e ridurre le collisioni:
|
||||
|
||||
- **RTS** (Request to Send): il mittente invia questo frame per richiedere l'autorizzazione a trasmettere
|
||||
- **CTS** (Clear to Send): il destinatario risponde col frame CTS, confermando la ricezione dell'RTS e notificando alle altre stazioni di sospendere le trasmissioni per un periodo definito, evitando così interferenze
|
||||
- **ACK** (Acknowledge): una volta ricevuti correttamente i dati, il destinatario invia un frame ACK per confermare la ricezione
|
||||
|
||||
Questi frame contengono un campo chiamato "duration", che imposta il timer **NAV** (Network Allocation Vector). Il NAV è un ulteriore meccanismo di controllo che indica alle altre stazioni per quanto tempo il canale risulterà occupato.
|
||||
|
||||
## Sequenza di Trasmissione
|
||||
|
||||
1. La stazione A attende un intervallo DIFS durante il quale ascolta il canale (Carrier Sense) per verificare che non ci siano trasmissioni in corso
|
||||
2. Se il canale risulta libero, A invia un frame RTS per richiedere la trasmissione
|
||||
3. La stazione B, destinataria, attende un breve intervallo SIFS e risponde con un frame CTS, confermando la disponibilità a ricevere e notificando agli altri dispositivi di non interferire per un tempo prestabilito (impostato dal NAV)
|
||||
4. Dopo un ulteriore intervallo SIFS, la stazione A procede con l'invio dei dati
|
||||
5. Al termine della trasmissione, B attende ancora un tempo SIFS e invia un frame ACK a tutte le stazioni per segnalare la corretta ricezione dei dati e la fine della trasmissione
|
||||
|
||||
Questa procedura consente di ridurre al minimo le collisioni, garantendo una trasmissione più ordinata ed efficiente nel mezzo condiviso.
|
35
networking/007-hub-switch.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Hub e Switch
|
||||
|
||||
## Hub
|
||||
|
||||
L'hub è uno dei primi dispositivi utilizzati per consentire la comunicazione a livello di LAN tra gli host. É noto anche con il termine *ripetitore*, poiché opera in maniera non intelligente: non tiene traccia degli indirizzi MAC degli host connessi e quindi inoltra ogni frame in arrivo a tutte le porte, ad eccezione di quella da cui proviene il frame. In altre parole, il traffico viene trasmesso in broadcast, indipendentemente dal destinatario.
|
||||
|
||||

|
||||
|
||||
É molto inefficiente e tende a sovraccaricare inutilmente la rete, inondandola di pacchetti.
|
||||
|
||||
## Half-Duplex e Full-Duplex Logic
|
||||
|
||||
Nella modalità `half-duplex` un dispositivo può o trasmettere o ricevere informazioni in un determinato istante. Ciò significa che la comunicazione avviene in un'unica direzione alla volta, rendendo necessario alternare le modalità di invio e ricezione.
|
||||
|
||||
Con la modalità `full-duplex`, il dispositivo è in grado di inviare e ricevere informazioni contemporaneamente. Ció consente una comunicazione bidirezionale continua, aumentando l'efficienza e riducendo la possibilità di collisioni.
|
||||
|
||||
Gli hub supportano solo la modalità half-duplex, il che significa che in ogni istante possono trasmettere o ricevere dati, ma non entrambe le operazioni contemporaneamente.
|
||||
|
||||
## Switch
|
||||
|
||||
Lo switch è un dispositivo molto potente grazie alla sua MAC Address Table, che consente di associare ogni indirizzo MAC a una specifica porta fisica alla quale è collegato il cavo di rete.
|
||||
|
||||

|
||||
|
||||
Il funzionamento dello switch è basato su un meccanismo di learning: quando riceve un pacchetto, lo switch analizza il MAC address sorgente e aggiorna la sua tabella, associandolo alla porta di ingresso. In questo modo, lo switch *impara* quali dispositivi sono collegati a quale porta e può inoltrare i frame in modo mirato.
|
||||
|
||||
Nel caso in cui il MAC address di destinazione non sia presente nella tabella, lo switch invia il frame a tutte le porte in broadcast, comportandosi come un hub, fino a quando non avrà appreso la corretta associazione.
|
||||
|
||||
Lo switch supporta sia la modalità half-duplex che full-duplex, offrendo così una comunicazione più efficiente.
|
||||
|
||||
## Indirizzamento
|
||||
|
||||
- **Unicast**: comunicazione diretta e precisa tra due dispositivi. Ad esempio, il dispositivo A invia un messaggio specifico al dispositivo B
|
||||
- **Multicast**: comunicazione indirizzata a un gruppo selezionato di dispositivi. Il dispositivo A trasmette informazioni solo ai membri di un determinato gruppo di destinazione
|
||||
- **Broadcast**: comunicazione che raggiunge tutti i dispositivi all'interno della stessa LAN
|
15
networking/008-arp.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Il protocollo ARP
|
||||
|
||||
Il protocollo `Address Resolution Protocol` (`ARP`) opera a livello di rete (layer 3) e ha il compito di associare un indirizzo IP a un indirizzo MAC. Conoscendo il MAC di destinazione, un host può infatti costruire il frame appropriato (layer 2) per inoltrare i dati sulla rete.
|
||||
|
||||
Ogni computer mantiene una ARP cache table, ovvero una memoria temporanea che memorizza le associazioni già note. Quando un host deve comunicare con un altro dispositivo, verifica innanzitutto se l'associazione IP-MAC è presente nella propria ARP cache; in caso contrario, viene utilizzato il protocollo ARP per determinare l'indirizzo MAC corrispondente all'IP di destinazione. L'ARP request viene inoltrata in broadcast a tutti i dispositivi raggiungibili nella LAN. Gli host che non sono associati all'IP target ignorano la richiesta, mentre il computer in possesso dell'indirizzo IP richiesto risponde inviando un ARP response in modalità unicast, indirizzata direttamente all'host che ha originato la richiesta.
|
||||
|
||||
In Linux, il comando per vedere la ARP cache table é `ip neighbour` o `ip n`:
|
||||
|
||||
```bash
|
||||
ip neighbour
|
||||
192.168.0.1 dev wlp4s0 lladdr 10:3c:59:c3:ec:73 REACHABLE
|
||||
192.168.0.200 dev wlp4s0 lladdr 6a:f8:b0:92:ea:94 STALE
|
||||
192.168.0.42 dev wlp4s0 lladdr 84:2a:fd:f2:d7:12 STALE
|
||||
192.168.0.97 dev wlp4s0 lladdr 4e:a0:f9:eb:c5:63 STALE
|
||||
```
|
66
networking/009-network-address.md
Normal file
@ -0,0 +1,66 @@
|
||||
# Network Address
|
||||
|
||||
## Netmask (Wildcard)
|
||||
|
||||
La `netmask`, o maschera di rete, è un modo alternativo di rappresentare il CIDR (Classless Inter-Domain Routing) ed è comunemente utilizzata nella configurazione degli apparati di rete. Essa serve a indicare, dato un indirizzo IPv4, quanti bit sono destinati al prefisso (identificazione della rete) e quanti al suffisso (identificazione di un host all'interno della rete). La netmask è un indirizzo IPv4 a 32 bit in cui i primi n bit (dove n viene indicato nel CIDR, ad esempio /24) sono impostati a 1.
|
||||
|
||||
Esempio di netmask per /24:
|
||||
|
||||
```txt
|
||||
11111111.11111111.11111111.00000000
|
||||
255.255.255.0
|
||||
```
|
||||
|
||||
La `wildcard` è il complemento della netmask. Per una netmask di /24, la wildcard corrispondente è:
|
||||
|
||||
```txt
|
||||
/24
|
||||
255.255.255.0
|
||||
0.0.0.255
|
||||
```
|
||||
|
||||
L'indirizzo di rete (`Network Address`) è l'indirizzo che identifica una rete o una subnet, fungendo da identificatore rappresentativo. Il primo indirizzo IP di un range è il network address.
|
||||
|
||||
## Broadcast Address
|
||||
|
||||
L'ultimo indirizzo del range è il broadcast address, anch'esso non assegnabile a un host. Questo indirizzo speciale consente di inviare pacchetti a tutti gli host della rete contemporaneamente.
|
||||
|
||||
## Default Gateway
|
||||
|
||||
Il default gateway è l'indirizzo che consente agli host all'interno di una rete di comunicare con router e inviare pacchetti verso altre reti. Esso funge da punto di accesso per l'instradamento del traffico.
|
||||
|
||||
## Esempio di Indirizzo di Rete
|
||||
|
||||
Consideriamo l'indirizzo IP 192.168.13.122/27. In questo caso, i primi 27 bit sono fissi, mentre i rimanenti 5 bit sono variabili. Solo 30 indirizzi sono utilizzabili per gli host.
|
||||
|
||||
```txt
|
||||
# Rappresentazione binaria dell'indirizzo
|
||||
11000000.10101000.00001101.01111010
|
||||
```
|
||||
|
||||
- I primi 27 bit (11000000.10101000.00001101.011) sono fissi.
|
||||
- Gli ultimi 5 bit (11010) sono variabili.
|
||||
|
||||
Per ottenere il network address, impostiamo gli ultimi 5 bit a 0:
|
||||
|
||||
```txt
|
||||
11000000.10101000.00001101.01100000 (192.168.13.96)
|
||||
```
|
||||
|
||||
Per ottenere il broadcast address, impostiamo gli ultimi 5 bit a 1:
|
||||
|
||||
```txt
|
||||
11000000.10101000.00001101.01111111 (192.168.13.127)
|
||||
```
|
||||
|
||||
La netmask per /27 ha i primi 27 bit impostati a 1 e i restanti a 0:
|
||||
|
||||
```txt
|
||||
255.255.255.224
|
||||
```
|
||||
|
||||
Il complemento della netmask, ovvero la wildcard, è:
|
||||
|
||||
```txt
|
||||
0.0.0.31
|
||||
```
|
29
networking/010-nat.md
Normal file
@ -0,0 +1,29 @@
|
||||
# IPv4 e NAT/PAT
|
||||
|
||||
## Differenza tra IP Pubblici e Privati
|
||||
|
||||
Gli indirizzi IP pubblici e privati hanno ruoli distinti nella comunicazione di rete. Un IP pubblico consente a un dispositivo di uscire da una rete locale (LAN) e comunicare con altre reti globali. Al contrario, un IP privato non è univoco a livello globale e viene utilizzato all'interno di una LAN. Gli indirizzi IP privati sono riservati per l'uso interno e non possono essere instradati su Internet.
|
||||
|
||||
## Limitazioni di IPv4
|
||||
|
||||
Il protocollo IPv4 consente un massimo di 2^32 indirizzi, che corrisponde a circa 4 miliardi di possibili combinazioni. Questo numero, sebbene sembri elevato, è limitato a livello globale e ha portato a preoccupazioni riguardo l'esaurimento degli indirizzi IPv4. La soluzione definitiva a questo problema è la transizione a IPv6, che offre un numero praticamente illimitato di indirizzi (2^128). Tuttavia, la transizione a IPv6 è lenta e complessa.
|
||||
|
||||
Una soluzione temporanea, che non risolve definitivamente il problema ma ne attenua gli effetti, è la distinzione tra indirizzi IPv4 pubblici e privati. Gli indirizzi IP privati consentono la comunicazione all'interno di reti locali, mentre il Network Address Translation (NAT) è il meccanismo che consente di associare indirizzi IP privati a un indirizzo IP pubblico. Questo approccio consente di risparmiare sull'uso degli indirizzi IP, poiché diverse reti possono utilizzare gli stessi indirizzi IP privati, ma solo un singolo indirizzo IP pubblico per comunicare con l'esterno.
|
||||
|
||||
## Tipi di NAT
|
||||
|
||||
Il NAT classico è un processo gestito dai router e consiste nella traduzione degli indirizzi IP privati in pubblii (e viceversa). Esistono due principali varianti di NAT:
|
||||
|
||||
- **NAT Statico**: In questo caso, l'amministratore di rete configura manualmente il router per associare un determinato indirizzo IP privato a un indirizzo IP pubblico specifico
|
||||
|
||||
- **NAT Dinamico**: Questa variante offre un maggiore automatismo, utilizzando un pool di indirizzi IP pubblici. Quando un dispositivo interno richiede accesso a Internet, il router assegna dinamicamente un indirizzo IP pubblico disponibile dal pool
|
||||
|
||||
Con il NAT classico, un host deve attendere il proprio turno per comunicare. Quando un dispositivo all'interno della LAN invia un pacchetto verso Internet, il router traduce l'indirizzo IP privato del dispositivo in un indirizzo IP pubblico. Tuttavia, se più dispositivi tentano di comunicare contemporaneamente utilizzando lo stesso indirizzo IP pubblico, il router deve tenere traccia di quale pacchetto appartiene a quale dispositivo.
|
||||
|
||||
Nel NAT classico, non esiste un meccanismo per identificare univocamente i pacchetti provenienti da diversi dispositivi che utilizzano lo stesso indirizzo IP pubblico. Senza un sistema di identificazione univoca, il router potrebbe confondersi nel determinare quale pacchetto di risposta inviare a quale dispositivo.
|
||||
|
||||
## NAT/PAT
|
||||
|
||||
Per migliorare l'efficienza del NAT, si utilizza il Port Address Translation (PAT). L'associazione tra indirizzo IP e porta consente di identificare univocamente ciascun dispositivo, evitando la necessità di turni per l'uso dell'indirizzo IP pubblico.
|
||||
|
||||
Il PAT viene sempre implementato a livello del router, che mantiene una tabella di NAT contenente ogni associazione univoca. Quando un pacchetto di risposta ritorna, il router utilizza questa tabella per inviare il pacchetto al dispositivo corretto, effettuando la traduzione inversa dell'indirizzo.
|
30
networking/011-vlan.md
Normal file
@ -0,0 +1,30 @@
|
||||
# VLAN
|
||||
|
||||
Gli host all'interno della stessa rete locale possono comunicare tra loro grazie a dispositivi di rete di livello 2, come switch, hub e AP.
|
||||
|
||||
Le VLAN (Virtual Local Area Network) sono utilizzate per partizionare e segmentare una rete locale, creando diverse sottoreti logiche. Questo approccio offre numerosi vantaggi, principalmente in termini di sicurezza: separando le reti, si isolano le comunicazioni tra i vari dispositivi, creando ambienti distinti.
|
||||
|
||||
Inoltre, le VLAN permettono di implementare politiche di sicurezza più granulari e specifiche attraverso l'uso di firewall, che possono applicare regole di traffico diverse tra le varie VLAN.
|
||||
|
||||
Sebbene sia possibile ottenere una segmentazione simile senza l'uso delle VLAN, utilizzando più dispositivi fisici come switch, l'adozione delle VLAN consente di raggiungere gli stessi obiettivi a livello software, riducendo i costi e semplificando la gestione della rete.
|
||||
|
||||
Per assegnare i membri a una VLAN, si configurano le porte dello switch. Assegnando le porte a specifiche VLAN, si realizza la segmentazione desiderata.
|
||||
|
||||
## Configurazione VLAN Switch CISCO
|
||||
|
||||
Ad esempio, per configurare le interfacce 1 e 2 di uno switch nella VLAN 10
|
||||
|
||||
```txt
|
||||
switch> ena
|
||||
switch# conf t
|
||||
switch(config)# interface range fastEthernet0/1-2
|
||||
switch(if-range)# switchport mode access
|
||||
switch(if-range)# switchport access vlan 10
|
||||
switch(if-range)# end
|
||||
switch# show vlan brief # Visualizza un riepilogo della configurazione VLAN
|
||||
switch# write
|
||||
```
|
||||
|
||||
È importante notare che esiste sempre una VLAN nativa, la VLAN 1, che per impostazione predefinita include tutte le interfacce dello switch.
|
||||
|
||||
Dopo aver creato le VLAN, è necessario procedere con la segmentazione delle reti, ovvero il subnetting. Per consentire la comunicazione tra due o più reti distinte, è necessario utilizzare dispositivi di livello 3, come i router. Questi dispositivi sono responsabili dell'instradamento del traffico tra le VLAN, garantendo che i pacchetti possano viaggiare tra le diverse sottoreti.
|
16
networking/012-loop-layer2.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Loop Layer 2
|
||||
|
||||
Il protocollo Spanning Tree (STP) è fondamentale per prevenire i loop a livello rete. La necessità di STP nasce dall'esigenza di garantire la ridondanza all'interno delle reti. La ridondanza si riferisce alla presenza di più copie o istanze di un elemento, il che è cruciale per assicurare la disponibilità (availability) dei servizi. In altre parole, avere più percorsi per raggiungere lo stesso obiettivo significa che, se uno di questi percorsi si guasta, la rete può continuare a funzionare senza interruzioni.
|
||||
|
||||
Tuttavia, la ridondanza può anche introdurre problemi, come i *broadcast storm*. Questi problemi si verificano a causa del modo in cui gli switch gestiscono il traffico. Quando uno switch riceve un pacchetto destinato a un MAC address che non conosce, non avendo una corrispondenza nella MAC address table, lo inoltra in broadcast su tutte le sue interfaccie, tranne quella da cui è arrivato.
|
||||
|
||||
Se ci sono loop nella rete, il pacchetto di broadcast può circolare indefinitamente tra gli switch.
|
||||
|
||||
1. **Inoltro del pacchetto**: supponiamo che uno switch A riceva un pacchetto destinato a un MAC address sconosciuto. Inoltra il pacchetto a tutti gli switch collegati, inclusi switch B e C
|
||||
2. **Ritorno del pacchetto**: switch B riceve il pacchetto e, non conoscendo il MAC address di destinazione, lo inoltra a tutti gli switch, incluso switch A. Allo stesso modo, switch C riceve il pacchetto e lo inoltra a switch A e B
|
||||
3. **Circolazione continua**: questo processo continua, con il pacchetto che rimbalza tra gli switch senza mai raggiungere una destinazione finale. Ogni switch continua a inoltrare il pacchetto a tutte le porte, generando così copie multiple dello stesso pacchetto
|
||||
4. **Saturazione della rete**: man mano che il pacchetto circola, il numero di copie aumenta esponenzialmente. Ogni switch genera ulteriori copie del pacchetto, saturando la rete
|
||||
|
||||
Per prevenire questo tipo di situazione, il protocollo Spanning Tree (STP) viene utilizzato per identificare e disabilitare i percorsi ridondanti che possono causare loop. STP crea una topologia di rete logica priva di loop, mantenendo attivi solo i percorsi necessari per la comunicazione e garantendo così la stabilità e l'affidabilità della rete.
|
||||
|
||||
Negli switch moderni, STP è abilitato di default, offrendo una protezione automatica contro i loop e contribuendo a mantenere la stabilità e l'affidabilità della rete.
|
17
networking/013-stp.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Spanning Tree Protocol (STP)
|
||||
|
||||
Lo Spanning Tree Protocol (STP) è un protocollo di livello 2 progettato per creare una topologia virtuale priva di loop, mantenendo invariata la topologia fisica della rete.
|
||||
|
||||
In un grafo connesso, i nodi sono interconnessi tramite il massimo numero di archi, garantendo che tutti i nodi siano correttamente collegati tra loro. Con l'implementazione dello spanning tree, gli archi vengono ridotti al numero minimo necessario per mantenere la connettività tra i nodi, creando così una struttura loop-free.
|
||||
|
||||
## Standard IEEE 802.1D
|
||||
|
||||
Il protocollo STP è definito dallo standard IEEE 802.1D e opera secondo i seguenti passaggi:
|
||||
|
||||
1. **Elezione del Root Bridge**: tra gli switch interconnessi, viene eletto un *root bridge*, che funge da punto centrale di riferimento per la rete. Ogni switch ha un Bridge ID (BID) di 8 byte, composto da 2 byte per il campo di priorità (priority field) e 6 byte per l'indirizzo MAC. Il root bridge è scelto in base al valore più basso del campo di priorità; in caso di parità, viene selezionato lo switch con l'indirizzo MAC più basso
|
||||
2. Ogni switch non root bridge calcola il percorso a minor costo per raggiungere il root bridge, garantendo che i dati seguano il percorso più efficiente.
|
||||
3. **Blocco dei Link Inutilizzati**: STP identifica e disabilita i link non necessari, mantenendo attivi solo quelli essenziali per la comunicazione. I link bloccati rimangono in uno stato di standby e possono essere attivati automaticamente in caso di guasto di un link attivo, garantendo così la ridondanza e la resilienza della rete.
|
||||
|
||||
Grazie a questi meccanismi, STP previene la formazione di loop e assicura una comunicazione stabile e affidabile all'interno della rete.
|
||||
|
||||
Il comando `show spanning-tree` è utilizzato sugli switch Cisco per visualizzare informazioni dettagliate sulla configurazione e lo stato del protocollo Spanning Tree (STP) attivo. Questo comando fornisce una panoramica della topologia STP, inclusi dettagli sul root bridge, i costi dei percorsi, le porte e il loro stato (ad esempio, forwarding o blocking).
|
70
networking/014-router-rotte.md
Normal file
@ -0,0 +1,70 @@
|
||||
# Router
|
||||
|
||||
Il livello 2 del modello ISO/OSI, noto come livello di collegamento dati, consente la comunicazione all'interno di una rete locale (LAN). Tuttavia, per comunicare tra segmenti di rete diversi, è necessario utilizzare dispositivi di rete operanti al livello 3, come i router o i multi-layer switch. Questi dispositivi sono in grado di instradare i pacchetti di dati tra reti diverse, gestendo indirizzi IP e determinando il percorso migliore per il trasferimento delle informazioni.
|
||||
|
||||
## Routing dei pacchetti
|
||||
|
||||
Un pacchetto può seguire diversi percorsi per raggiungere una destinazione esterna. Questo implica un processo di selezione e instradamento dei pacchetti, noto come `routing`, che consiste nel determinare il percorso più appropriato, passo dopo passo, per arrivare a destinazione.
|
||||
|
||||
Le rotte sono necessarie quando ci sono più router coinvolti, poiché in tal caso esistono differenti percorsi che i pacchetti possono seguire per raggiungere la loro destinazione.
|
||||
|
||||
Esistono algoritmi di routing che gestiscono l'instradamento dinamico dei pacchetti, adattandosi alle variazioni della rete in tempo reale. In alternativa, è possibile configurare rotte statiche, che rimangono fisse e non si adattano automaticamente alle condizioni della rete.
|
||||
|
||||
### Rotte statiche
|
||||
|
||||
#### Linux
|
||||
|
||||
Per visualizzare le rotte attive:
|
||||
|
||||
```bash
|
||||
ip route
|
||||
```
|
||||
|
||||
Per aggiungere una rotta statica:
|
||||
|
||||
```bash
|
||||
ip route add destination_network/cidr via gateway
|
||||
|
||||
ip route add 10.10.1.0/24 via 192.168.0.195
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
Per visualizzare le rotte attive:
|
||||
|
||||
```cmd
|
||||
route print
|
||||
```
|
||||
|
||||
Per aggiungere una rotta statica:
|
||||
|
||||
```cmd
|
||||
route add destination_network MASK subnet_mask gateway
|
||||
|
||||
route add 192.168.35.0 MASK 255.255.255.0 192.168.0.2
|
||||
```
|
||||
|
||||
Per eliminare una rotta statica:
|
||||
|
||||
```cmd
|
||||
route delete destination_network
|
||||
```
|
||||
|
||||
#### Switch Layer 3
|
||||
|
||||
Per assegnare un indirizzo IP ad un'interfaccia:
|
||||
|
||||
```txt
|
||||
switch> ena
|
||||
switch# conf t
|
||||
switch(config)# interface g0/1
|
||||
switch(config-if)# ip address 192.168.2.1 255.255.255.0
|
||||
switch(config-if)# no shut
|
||||
```
|
||||
|
||||
Per aggiungere una rotta statica:
|
||||
|
||||
```txt
|
||||
ip route destination_network subnet_mask next_hop
|
||||
switch(config-if)# ip route 192.168.3.0 255.255.255.0 192.168.2.1
|
||||
```
|
18
networking/015-transport-layer.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Transport Layer
|
||||
|
||||
Al livello 4 del modello ISO/OSI, detto ``Transport Layer``, troviamo diversi protocolli, tra cui `UDP`, `TCP` e `QUIC`, che rappresenta un ibrido tra i primi due.
|
||||
|
||||
Nel livello 4, si crea un vero e proprio ponte tra due host che desiderano comunicare. Tuttavia, il canale di comunicazione non è direttamente tra l'host A e l'host B, ma piuttosto tra un processo specifico dell'host A e un processo remoto dell'host B.
|
||||
|
||||
Per identificare in modo univoco un processo, si utilizza l'associazione tra indirizzi IP e porte, che vanno da 0 a 65.535 (2^16-1). In questo contesto, si parla di `socket`, che permettono l'uso dello stack protocollare e l'inizio della comunicazione. Possono essere definiti come una coppia di indirizzo IP e numero di porta.
|
||||
|
||||
Esistono due tipi di socket:
|
||||
|
||||
- **locali**: utilizzati all'interno di un singolo host
|
||||
- **remoti**: utilizzati per comunicare con processi su host diversi
|
||||
|
||||
La IANA (Internet Assigned Numbers Authority) ha definito una suddivisione delle 65.535 porte:
|
||||
|
||||
- **Well-known ports** (0-1023): porte associate a servizi noti, ad esempio la porta 80 per HTTP
|
||||
- **Registered ports** (1024-49151): porte associate a servizi registrati, come la porta 3389 per RDP o la porta 1194 per OpenVPN
|
||||
- **Free ports** (49152-65535): porte rimanenti, non associate a servizi specifici, utilizzate per comunicazioni temporanee o dinamiche
|
33
networking/016-ipv4.md
Normal file
@ -0,0 +1,33 @@
|
||||
# IPv4
|
||||
|
||||
IPv4 è uno dei protocolli del network layer e definisce il formato degli indirizzi per la comunicazione tra host. In sostanza, l'IP serve come meccanismo di indirizzamento dei pacchetti, permettendo di identificare univocamente ogni host all'interno di una rete.
|
||||
|
||||
## Anatomia del pacchetto IPv4
|
||||
|
||||

|
||||
|
||||
Il datagramma o pacchetto IPv4 è composto da due parti principali:
|
||||
|
||||
- L'*header*, che contiene le informazioni di controllo e indirizzamento
|
||||
- Il payload, ossia i dati che vengono incapsulati all'interno del pacchetto
|
||||
|
||||
L'header ha una dimensione minima di 20 byte e può estendersi fino a 60 byte, includendo diversi campi importanti, quali:
|
||||
|
||||
- `Version`: specifica la versione del protocollo IP
|
||||
- `Source Address`: l'indirizzo IP del mittente, lungo 32 bit
|
||||
- `Destination Address`: l'indirizzo IP del destinatario, anch'esso lungo 32 bit
|
||||
- `Time to Live (TTL)`: campo di 8 bit che rappresenta il *tempo di vita* del pacchetto. Ad ogni passaggio (hop) tra router, il valore del TTL viene decrementato di uno. Quando il TTL raggiunge zero, il pacchetto viene scartato, evitando così che rimanga indefinitamente nella rete in caso di un errore di instradamento. Nel momento in cui un router scarta il pacchetto, ciò può generare un ICMP error message per informare il mittente
|
||||
- `Protocol`: un codice che indica il protocollo utilizzato per la parte dati incapsulata. Alcuni esempi:
|
||||
- ICMP: codice 1
|
||||
- TCP: codice 6
|
||||
- UDP: codice 17
|
||||
- EIGMP: codice 88
|
||||
- L2TP: codice 115
|
||||
|
||||
## IPv4 Fragmentation
|
||||
|
||||
Il livello di data link ha un limite dimensionale noto come `MTU` (`Maximum Transmission Unit`), che di norma è fissato a 1500 byte. Questo significa che il payload che deve essere incapsulato nel livello data link non può superare i 1500 byte. È importante notare che il valore della MTU può essere configurato a livello di switch o router.
|
||||
|
||||
Quando si devono inviare dati che superano il limite della MTU, entra in gioco il processo di *frammentazione*. Durante questo processo, i dati vengono suddivisi in pacchetti più piccoli, noti come frammenti, ciascuno dei quali include header IP originario, che contengono informazioni cruciali per l'instradamento e la ricostruzione dei pacchetti.
|
||||
|
||||
Ogni frammento è identificato da un campo `Identifier`, che consente di raggruppare i frammenti appartenenti allo stesso datagramma originale. Inoltre, il campo `Fragment Offset` indica la posizione di ciascun frammento all'interno del datagramma originale, permettendo al destinatario di ricostruire correttamente l'ordine dei dati.
|
2
networking/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# networking
|
||||
|
BIN
networking/asset/img/cavo-ethernet.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
networking/asset/img/crossover-pinout.png
Normal file
After Width: | Height: | Size: 526 KiB |
BIN
networking/asset/img/deincapsulamento-switch.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
networking/asset/img/device-connection.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
networking/asset/img/dns-query.png
Normal file
After Width: | Height: | Size: 217 KiB |
BIN
networking/asset/img/dns-request.png
Normal file
After Width: | Height: | Size: 196 KiB |
BIN
networking/asset/img/dns-response.png
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
networking/asset/img/frame-ethernet.png
Normal file
After Width: | Height: | Size: 209 KiB |
BIN
networking/asset/img/frame-structure-example.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
networking/asset/img/frame-structure.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
networking/asset/img/hub.png
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
networking/asset/img/ipv4.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
networking/asset/img/mac-address-table.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
networking/asset/img/model-tcp-ip-iso-osi.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
networking/asset/img/network-header.png
Normal file
After Width: | Height: | Size: 185 KiB |
BIN
networking/asset/img/packet-to-switch.png
Normal file
After Width: | Height: | Size: 139 KiB |
BIN
networking/asset/img/rj45.png
Normal file
After Width: | Height: | Size: 276 KiB |
BIN
networking/asset/img/straight-through-pinout.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
networking/asset/img/udp-header.png
Normal file
After Width: | Height: | Size: 232 KiB |
BIN
networking/asset/img/wireless architecture.png
Normal file
After Width: | Height: | Size: 340 KiB |
BIN
networking/asset/img/wireless-frame.png
Normal file
After Width: | Height: | Size: 157 KiB |