Compare commits
97 Commits
0874306884
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
2a1d55672c | ||
|
842a218ec6 | ||
|
7f4ceea31e | ||
|
7780f1cca8 | ||
|
0ebbb57666 | ||
|
63ba202c94 | ||
|
22e4d715cc | ||
|
57d3ffaac5 | ||
|
f303484415 | ||
|
3726e00c94 | ||
|
50e54ffe15 | ||
|
73b721874b | ||
|
988a3ff711 | ||
|
117dac37a0 | ||
|
5a76f0b30b | ||
|
64934435cb | ||
|
c92d80279c | ||
|
507ef21cdd | ||
|
2e5d4e2223 | ||
|
8fa6badf22 | ||
|
8d4fc1dd6d | ||
|
3a8bc79727 | ||
|
5b1b0584fa | ||
|
e46648d470 | ||
|
5f6102d1bf | ||
|
e62e6095f5 | ||
|
30a50e7dbc | ||
|
587a6a415d | ||
|
006bc5c7ec | ||
|
b3694d492c | ||
|
cf9eeb18ca | ||
|
ed53ecd2d6 | ||
|
fef5f83f26 | ||
|
7374d91b88 | ||
|
c0074341f7 | ||
|
0a270d7d82 | ||
|
524cd1b2b6 | ||
|
d6e2a46b25 | ||
|
6638ea55e9 | ||
|
61c6907a6b | ||
|
9b39278de9 | ||
|
a3faf3590c | ||
|
4af9158b77 | ||
|
9b31e72864 | ||
|
8c21beae40 | ||
|
1576d6d9a2 | ||
|
10ce3d3366 | ||
|
7be124e390 | ||
|
63bb25952d | ||
|
075737e4cf | ||
|
a2ac9b25cf | ||
|
32df249455 | ||
|
d9b52e190b | ||
|
8b9c681d1e | ||
|
226c309d89 | ||
|
5c02027d4e | ||
|
e136ddc04e | ||
|
585f7e0806 | ||
|
b3b333f48d | ||
|
5224b51c66 | ||
|
09ab62d111 | ||
|
2ef85d1e31 | ||
|
f588bf6775 | ||
|
84552a12ce | ||
|
6214b4078c | ||
|
3cdb7cf22f | ||
|
f712b69c63 | ||
|
4f50f45c0e | ||
|
5df5335964 | ||
|
be0460288e | ||
|
fc82a5e52d | ||
|
32ade33c7f | ||
|
f6692a76d1 | ||
|
63aba42c68 | ||
|
cc5dd228d9 | ||
|
12482b0bc5 | ||
|
ffd57ea3d7 | ||
|
44c3afa5ad | ||
|
645634eb2f | ||
|
2022490658 | ||
|
426bcf1847 | ||
|
9adf1aea11 | ||
|
5e6793520a | ||
|
edf9cb228e | ||
|
8ac0c911af | ||
|
5c8e81ee80 | ||
|
8ac4e00a62 | ||
|
46848052e7 | ||
|
3a59c544b1 | ||
|
30f2d5d283 | ||
|
9a2a988e08 | ||
|
fbd38a2b79 | ||
|
09da7d6c0b | ||
|
745c9fb219 | ||
|
4ebff92bad | ||
|
77b2d1b48b | ||
|
f096f691a7 |
25
docker/001-intro.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Virtual Machine vs Container
|
||||
|
||||
## Virtual Machine
|
||||
|
||||
Una VM è un ambiente di esecuzione isolato che emula un sistema operativo completo Questo significa che ogni VM ha il proprio kernel, sistema operativo, librerie e applicazioni. Le VM sono utilizzate per isolare completamente i processi e le risorse, fornendo un ambiente di esecuzione indipendente e sicuro.
|
||||
|
||||
Nel paradigma delle Virtual Machine, un OS completo, dotato del proprio kernel, funge da `hypervisor` (HV). Questo consente di eseguire più VM, ognuna con il proprio sistema operativo e i propri servizi in esecuzione. Ogni VM opera come un'istanza isolata, garantendo un *elevato livello di separazione*.
|
||||
|
||||
Tuttavia, questa architettura presenta un'importante limitazione: ogni VM interagisce con l'hardware virtualizzato attraverso l'HV, che media la comunicazione con l'hardware fisico sottostante. Questo processo di mediazione introduce un *overhead* significativo, che rappresenta una delle principali cause di perdita di performance.
|
||||
|
||||
## Container
|
||||
|
||||
Il paradigma dei container si propone di affrontare le problematiche di overhead e performance associate alle VM. In questo modello, l'OS host non funge da hypervisor, ma esegue un `container engine`, che costituisce uno strato sottile di isolamento tra le applicazioni in esecuzione all'interno dei container e il sistema operativo sottostante.
|
||||
|
||||
A differenza delle VM, i container non eseguono un sistema operativo completo. Non possiedono un proprio kernel, poiché non gestiscono direttamente la comunicazione con l'hardware; piuttosto, *sfruttano il kernel del sistema host*. Le richieste di risorse hardware da parte dei container vengono, tramite il container engine, inoltrate direttamente al kernel dell'OS host, riducendo così l'overhead e migliorando le performance complessive.
|
||||
|
||||
## Vantaggi e limitazioni dei container
|
||||
|
||||
Rispetto alle VM, i container offrono prestazioni superiori e una maggiore flessibilità. È possibile modificare le risorse allocate a un container durante la sua esecuzione, senza necessità di spegnere il container stesso, evitando così downtime. Al contrario, le VM, simili a hardware reale, richiedono un riavvio per apportare modifiche alle risorse allocate.
|
||||
|
||||
Tuttavia, i container presentano anche delle *limitazioni, in particolare riguardo all'isolamento*. Sebbene offrano un certo livello di separazione, l'isolamento dei container è più debole rispetto a quello delle VM, poiché avviene solo a livello di processo e non di risorse. I container sono, infatti, *processi in esecuzione* sul sistema host e, a differenza delle applicazioni tradizionali, hanno accesso limitato alle risorse.
|
||||
|
||||
Un programma in esecuzione all'interno di un container è quindi *isolato* nel senso che può accedere esclusivamente alle risorse specificamente assegnate a quel container.
|
||||
|
||||

|
9
docker/002-immagini.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Immagini
|
||||
|
||||
L'immagine può essere vista come l'eseguibile che avvia un container. A partire da un'immagine, è possibile creare molteplici container, che rappresentano *istanze* di quell'immagine. In altri termini, l'immagine si comporta come una specie di *archivio*, contenente l'applicativo da eseguire, insieme a tutte le sue dipendenze, librerie e altri asset necessari.
|
||||
|
||||
Ogni immagine é composta da piú strati, o `layer`, che introducono nuove funzionalità o modifiche. La separazione delle aggiunte su layer distinti consente di condividere i layer comuni tra diverse immagini, evitando la duplicazione dei dati e ottimizzando l'uso dello spazio su disco.
|
||||
|
||||

|
||||
|
||||
La definizione dell'immagine avviene tramite i `Dockerfile`, che specificano le istruzioni necessarie per costruire l'immagine.
|
9
docker/003-registry.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Registry
|
||||
|
||||
Un registry può essere paragonato a un elenco telefonico, in quanto contiene gli indirizzi di tutti i repository disponibili. I repository, a loro volta, ospitano tutte le versioni di un determinato software.
|
||||
|
||||

|
||||
|
||||
Il registry più popolare e ampiamente utilizzato è [Docker Hub](https://hub.docker.com/).
|
||||
|
||||
È fondamentale sottolineare che tutte le immagini presenti nei repository dei vari registry seguono lo stesso standard, l'`OCI` (*Open Container Initiative*). Questo standard garantisce che qualsiasi immagine scaricata da questi registry sia completamente compatibile con Docker, Podman o qualsiasi altro container engine che rispetti questa specifica.
|
19
docker/004-docker-podman.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Docker vs Podman
|
||||
|
||||
`Docker` è stato il pioniere nel settore della containerizzazione, guadagnandosi una notevole popolarità e un ampio supporto. D'altra parte, `Podman`, sviluppato da Red Hat, è preinstallato su tutte le distribuzioni Red Hat based.
|
||||
|
||||
## Architettura
|
||||
|
||||
Entrambi gli strumenti sono multipiattaforma, ma presentano differenze significative nella loro architettura. Docker utilizza un *demone central*e per gestire tutti i container in esecuzione. Questo demone, noto come `Docker daemon`, è responsabile dell'avvio, della gestione e dell'arresto dei container. Tuttavia, questa architettura introduce un *single point of failure*: se il Docker daemon dovesse andare in crash, tutti i container avviati ne risentirebbero.
|
||||
|
||||
Al contrario, Podman adotta un'architettura `daemonless`: ogni container avviato è un processo indipendente.
|
||||
|
||||

|
||||
|
||||
## Sicurezza
|
||||
|
||||
In termini di sicurezza, Podman è nativamente `rootless`, il che significa che, per impostazione predefinita, i container vengono eseguiti con i privilegi dell'utente. Questo approccio riduce il rischio che un container compromesso possa accedere all'intero sistema, poiché non opera con privilegi elevati. Sebbene Docker richieda, per impostazione predefinita, l'esecuzione come utente root, è possibile configurarlo per funzionare in modalità rootless.
|
||||
|
||||
## Interoperabilità
|
||||
|
||||
Docker e Podman sono perfettamente *intercambiabili*. Entrambi supportano le stesse opzioni e possono utilizzare le stesse immagini.
|
23
docker/005-docker.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Docker
|
||||
|
||||
## Installazione Docker Engine
|
||||
|
||||
Seguire la documentazione [ufficiale](https://docs.docker.com/engine/install/)
|
||||
|
||||
### Rootless setup
|
||||
|
||||
Su Debian bisogna installare il pacchetto `dbus-user-session` per procedere.
|
||||
|
||||
Per eseguire docker come utente non privilegiato, seguendo la [documentazione](https://docs.docker.com/engine/security/rootless/), bisogna eseguire il seguente script:
|
||||
|
||||
```bash
|
||||
dockerd-rootless-setuptool.sh install
|
||||
```
|
||||
|
||||
Se il file `dockerd-rootless-setuptool.sh` non è presente, potrebbe essere necessario installare manualmente il pacchetto `docker-ce-rootless-extras`:
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y docker-ce-rootless-extras
|
||||
```
|
||||
|
||||
Per verificare lo stato del servizio `systemctl --user status docker`.
|
212
docker/007-commands.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# Comandi
|
||||
|
||||
## Immagini
|
||||
|
||||
### Ricerca sul registry
|
||||
|
||||
```bash
|
||||
docker search <image_name>
|
||||
|
||||
docker search ubuntu
|
||||
```
|
||||
|
||||
### Scaricare un'immagine
|
||||
|
||||
Per scaricare un'immagine, si utilizza il comando `docker pull`, specificando il nome dell'immagine e, se necessario, il `tag` per una versione specifica. Se il `tag` non è specificato, verrà scaricata l'ultima versione disponibile, indicata come `latest`. È possibile avere più versioni della stessa immagine sullo stesso sistema.
|
||||
|
||||
```bash
|
||||
docker pull <image_name>
|
||||
|
||||
docker pull ubuntu
|
||||
|
||||
docker pull nginx:stable
|
||||
```
|
||||
|
||||
Quando si scarica un'immagine, il terminale mostrerà un output simile al seguente:
|
||||
|
||||
```txt
|
||||
docker pull node:latest
|
||||
|
||||
latest: Pulling from library/node
|
||||
c19952135643: Pull complete
|
||||
7bbf972c6c2f: Pull complete
|
||||
900e2c02f17f: Pull complete
|
||||
abe9c1abe6f3: Pull complete
|
||||
09461c05d868: Pull complete
|
||||
16707a187717: Pull complete
|
||||
2b24aa75a958: Pull complete
|
||||
74d4dfcbaa69: Pull complete
|
||||
Digest: sha256:601f205b7565b569d3b909a873cc9aa9c6f79b5052a9fe09d73e885760237c4c
|
||||
Status: Downloaded newer image for node:latest
|
||||
```
|
||||
|
||||
Ogni hash rappresenta un layer che compone l'immagine, il quale introduce una modifica rispetto all'immaigne base.
|
||||
|
||||
### Lista e rimozione delle immagini
|
||||
|
||||
```bash
|
||||
docker image ls
|
||||
|
||||
docker image ls
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
node latest 2c85757b0aae 4 days ago 1.13GB
|
||||
```
|
||||
|
||||
Questo comando fornisce, per ogni immagine scaricata, e per ogni versione, un resoconto. L'attributo della colonna `CREATED` indica quando l'immagine é stata creata dal suo autore, non quando l'abbiamo scaricata.
|
||||
|
||||
Per rimuovere un'immagine specifica, esiste invece il comando `docker rmi <image_name>:tag` oppure `docker rmi <image_id>`.
|
||||
|
||||
Per rimuovere invece tutte le immagini, eccetto quelle utilizzate da container avviati o stoppati, si utilizza il comando `docker image prune`.
|
||||
|
||||
### History
|
||||
|
||||
Il comando `docker history <image_name>:tag` ripercorre le istruzioni del Dockerfile utilizzate per costruire l'immagine indicata. Ad esempio:
|
||||
|
||||
```bash
|
||||
docker history node:latest
|
||||
|
||||
IMAGE CREATED CREATED BY SIZE COMMENT
|
||||
2c85757b0aae 4 days ago CMD ["node"] 0B buildkit.dockerfile.v0
|
||||
<missing> 4 days ago ENTRYPOINT ["docker-entrypoint.sh"] 0B buildkit.dockerfile.v0
|
||||
<missing> 4 days ago COPY docker-entrypoint.sh /usr/local/bin/ # … 388B buildkit.dockerfile.v0
|
||||
<missing> 4 days ago RUN /bin/sh -c set -ex && export GNUPGHOME… 5.34MB buildkit.dockerfile.v0
|
||||
<missing> 4 days ago ENV YARN_VERSION=1.22.22 0B buildkit.dockerfile.v0
|
||||
<missing> 4 days ago RUN /bin/sh -c ARCH= && dpkgArch="$(dpkg --p… 192MB buildkit.dockerfile.v0
|
||||
<missing> 4 days ago ENV NODE_VERSION=24.4.1 0B buildkit.dockerfile.v0
|
||||
<missing> 4 days ago RUN /bin/sh -c groupadd --gid 1000 node &&… 8.94kB buildkit.dockerfile.v0
|
||||
<missing> 18 months ago RUN /bin/sh -c set -ex; apt-get update; ap… 588MB buildkit.dockerfile.v0
|
||||
<missing> 18 months ago RUN /bin/sh -c set -eux; apt-get update; a… 177MB buildkit.dockerfile.v0
|
||||
<missing> 2 years ago RUN /bin/sh -c set -eux; apt-get update; a… 48.4MB buildkit.dockerfile.v0
|
||||
<missing> 2 years ago # debian.sh --arch 'amd64' out/ 'bookworm' '… 117MB debuerreotype 0.15
|
||||
```
|
||||
|
||||
Un ulteriore comando per ispezionare un'immagine é `docker inspect <image_name>:tag`, il quale specifica le variabili d'ambiente, l'`entrypoint`, ossia il programma eseguito all'avvio del container, i vari layer, ecc.
|
||||
|
||||
## Container
|
||||
|
||||
### Esecuzione di un container Docker
|
||||
|
||||
Quando si esegue il comando `docker run ubuntu`, non si osserva alcun output apparente. Questo comportamento è dovuto al fatto che quella di ubuntu è un'immagine base, priva di un entrypoint che avvii un servizio in esecuzione, causando la terminazione immediata del container. Per eseguire una shell interattiva all'interno del container, è possibile utilizzare il comando:
|
||||
|
||||
```bash
|
||||
docker run ubuntu bash
|
||||
```
|
||||
|
||||
Tuttavia, anche in questo caso non verrà visualizzato alcun output, poiché Docker, per impostazione predefinita, non collega il terminale corrente al processo in esecuzione. Per collegare il terminale al processo `bash` all'interno del container, è necessario utilizzare il parametro `-it`, che sta per *interactive terminal*. Il comando diventa quindi:
|
||||
|
||||
```bash
|
||||
docker run -it ubuntu bash
|
||||
```
|
||||
|
||||
A questo punto, si otterrà un prompt simile al seguente:
|
||||
|
||||
```bash
|
||||
root@a9c42c663b02:/#
|
||||
```
|
||||
|
||||
dove `a9c42c663b02` rappresenta l'ID del container in esecuzione.
|
||||
|
||||
Ogni volta che si esegue il comando `docker run`, viene creato un nuovo container con un ID univoco. È possibile assegnare un nome specifico al container utilizzando l'opzione `--name`, come mostrato di seguito:
|
||||
|
||||
```bash
|
||||
docker run -it --name ubuntu ubuntu bash
|
||||
```
|
||||
|
||||
Per uscire dal container, si può digitare `exit` o premere la combinazione `CTRL+D`, il che comporterà la chiusura del container. In alternativa, utilizzando la combinazione `CTRL+P CTRL+Q`, si può uscire dal container mantenendolo attivo in background.
|
||||
|
||||
Per verificare lo stato dei container in esecuzione, si può utilizzare il comando:
|
||||
|
||||
```bash
|
||||
docker container ls
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
a9c42c663b02 ubuntu "bash" 3 minutes ago Up 3 minutes romantic_agnesi
|
||||
```
|
||||
|
||||
Per ricollegarsi a un container già in esecuzione, si utilizza il comando:
|
||||
|
||||
```bash
|
||||
docker attach <container_id>
|
||||
```
|
||||
|
||||
### Gestire i container
|
||||
|
||||
I container non sono realmente effimeri: quando un container viene arrestato, il suo contenuto non viene perso. È possibile riavviare un container fermato e recuperare qualsiasi dato generato al suo interno. Per eliminare un container e le relative informazioni, è necessario eseguire un'operazione esplicita.
|
||||
|
||||
#### Rimozione dei container
|
||||
|
||||
Per rimuovere un container non in esecuzione, utilizzare il comando:
|
||||
|
||||
```bash
|
||||
docker rm <container_id>
|
||||
|
||||
docker rm <container_name>
|
||||
```
|
||||
|
||||
Il flag `-f` forza la rimozione di un container, anche qualora fosse in esecuzione.
|
||||
|
||||
Per eliminare automaticamente un container al termine della sua esecuzione, esiste invece il comando:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --name ubuntu ubuntu bash
|
||||
```
|
||||
|
||||
Il comando `docker container prune` eliminerá tutti i container non in esecuzione.
|
||||
|
||||
#### Elencare i container
|
||||
|
||||
Il comando `docker ps` restituisce l'elenco dei container attualmente in esecuzione. Aggiungendo il flag `-a`, è possibile visualizzare anche tutti i container non in esecuzione.
|
||||
|
||||
#### Arrestare e avviare un container
|
||||
|
||||
Per fermare un container, utilizzare il comando
|
||||
|
||||
```bash
|
||||
docker stop <container_id>
|
||||
|
||||
docker stop <container_name>
|
||||
```
|
||||
|
||||
Per fermare forzatamente un container e liberare le risorse utilizzate, esiste l'opzione `kill`.
|
||||
|
||||
Per avviarlo nuovamente:
|
||||
|
||||
```bash
|
||||
docker start <container_id>
|
||||
|
||||
docker start <container_name>
|
||||
```
|
||||
|
||||
#### Modalità detached
|
||||
|
||||
Quando si esegue il comando `docker run ubuntu sleep 60`, la shell rimane occupata fino al termine dell'esecuzione del comando. Per lanciare container in modalità *detached*, che consente di liberare la shell, utilizzare il flag `-d`:
|
||||
|
||||
```bash
|
||||
docker run -d ubuntu sleep 60
|
||||
```
|
||||
|
||||
### Concatenazione di comandi
|
||||
|
||||
Per eseguire più comandi all'interno di un container Docker, è possibile utilizzare la seguente sintassi:
|
||||
|
||||
```bash
|
||||
docker run --rm -it ubuntu bash -c "sleep 5; ls -lh"
|
||||
```
|
||||
|
||||
### Lettura dei Log
|
||||
|
||||
Il comando seguente consente di visualizzare i log di un container in tempo reale:
|
||||
|
||||
```bash
|
||||
docker logs -f <container_id>
|
||||
|
||||
docker logs -f <container_name>
|
||||
```
|
||||
|
||||
### Utilizzo delle risorse
|
||||
|
||||
Per limitare l'uso delle risorse da parte di un container, è possibile specificare il numero massimo di core CPU e la quantità di memoria RAM utilizzabile. Utilizzando i parametri `--cpus` e `--memory`, si può evitare che il container saturi le risorse del sistema.
|
||||
|
||||
```bash
|
||||
docker run --rm -it --cpus 2 --memory 1024m --name ubuntu ubuntu
|
||||
```
|
82
docker/008-compose.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Compose
|
||||
|
||||
`Docker Compose` è uno strumento di orchestrazione per Docker che permette di definire e eseguire applicazioni multi-container utilizzando un singolo file YAML, chiamato `docker-compose.yml`. Questo file contiene tutte le informazioni necessarie per configurare e avviare tutti i servizi dello stack applicativo, incluse le reti e i volumi.
|
||||
|
||||
Facilita l'avvio, l'arresto e la gestione dei container.
|
||||
|
||||
Come si vede dall'esempio, vi é una corrispondenza 1:1 tra i parametri della linea di comando e il file di configurazione:
|
||||
|
||||
```yml
|
||||
services:
|
||||
php:
|
||||
image: 'php:8.1-fpm'
|
||||
container_name: php
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: nginx
|
||||
ports:
|
||||
- 8080:80
|
||||
- 8443:443
|
||||
volumes:
|
||||
- './app:/var/www/html:ro'
|
||||
- './config/nginx:/etc/nginx/conf.d'
|
||||
depends_on:
|
||||
- php
|
||||
```
|
||||
|
||||
È importante notare che tutti i servizi definiti nello stesso file `docker-compose.yml` sono automaticamente collocati nella stessa rete. Questo consente loro di comunicare tra loro senza la necessità di aprire porte specifiche.
|
||||
|
||||
Nell'esempio fornito, il container di nginx dipende da quello di php. Di conseguenza, nginx verrà avviato dopo php, garantendo che le dipendenze siano rispettate.
|
||||
|
||||
## Gestione dello Stack
|
||||
|
||||
Per avviare lo stack Docker, è sufficiente eseguire il comando `docker compose up -d` dalla stessa directory in cui si trova il file docker-compose.yml. Per arrestare i container, utilizzare invece `docker compose down`.
|
||||
|
||||
## Variabili d'ambiente
|
||||
|
||||
```yml
|
||||
services:
|
||||
php:
|
||||
image: 'php:8.1-fpm'
|
||||
container_name: ${APP_NAME:?err}-php
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '8081:80'
|
||||
- '8443:443'
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
- './config/nginx:/etc/nginx/conf.d'
|
||||
|
||||
mariadb:
|
||||
image: 'mariadb:latest'
|
||||
container_name: ${APP_NAME:?err}-mariadb
|
||||
restart: 'on-failure'
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?err}
|
||||
```
|
||||
|
||||
La sintassi `${}` viene utilizzata per indicare le variabili d'ambiente nel file `docker-compose.yml`. In particolare, nel caso in cui la variabile `APP_NAME` non venga valorizzata, Docker Compose mostrerà un errore. Questa variabile sarà valorizzata all'interno del file `.env`.
|
||||
|
||||
L'utilizzo del file `.env` permette di separare i dati, anche quelli sensibili, dalla configurazione vera e propria, risultando in un file compose pulito, generico e riutilizzabile.
|
||||
|
||||
Inoltre, il parametro `environment` serve a impostare delle variabili d'ambiente che saranno esportate all'interno del container, rendendole disponibili e utilizzabili dal servizio.
|
||||
|
||||
## Restart policy
|
||||
|
||||
La politica di riavvio definisce le condizioni in cui un container deve essere riavviato dopo un arresto o un riavvio del servizio Docker. Per impostazione predefinita, non è presente alcuna politica di restart; pertanto, se il demone Docker viene arrestato e successivamente riavviato, il container non riprenderà automaticamente l'esecuzione.
|
||||
|
||||
Le politiche di riavvio disponibili sono:
|
||||
|
||||
- `on-failure`: questa opzione indica che il container verrà riavviato automaticamente solo se termina con un errore
|
||||
- `always`: se questa politica è impostata, il container verrà riavviato indipendentemente dal motivo per cui è terminato, a meno che non venga arrestato manualmente. In questo caso, il container riprenderà l'esecuzione automaticamente al successivo riavvio del demone Docker, magari seguito del riavvio del sistema
|
||||
- `unless-stopped`: questa opzione mantiene l'ultimo stato del container. Se il container è stato arrestato manualmente, non verrà riavviato, anche dopo un riavvio del demone. Tuttavia, se il container era in esecuzione prima dell'arresto del demone, riprenderà automaticamente l'esecuzione
|
||||
|
||||
Le politiche di riavvio possono essere configurate sia tramite la riga di comando, utilizzando l'opzione `--restart`, ad esempio `docker run --restart always redis`, sia nel file `docker-compose.yml` attraverso l'apposita direttiva di configurazione `restart`.
|
182
docker/009-networking.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Networking
|
||||
|
||||
## Concetti base
|
||||
|
||||
I container, per impostazione predefinita, sono completamente isolati dal sistema host e tra di loro. Per consentire la comunicazione tra i container e il sistema host, è necessario aprire esplicitamente una determinata porta, rendere disponibile una specifica risorsa, ecc.
|
||||
|
||||
Per esporre una porta, si utilizza l'opzione `-p` con la seguente sintassi:
|
||||
|
||||
```bash
|
||||
docker run -d -p 8080:80 nginx
|
||||
```
|
||||
|
||||
In questo esempio, la porta 80 del container viene mappata sulla porta 8080 del sistema host. Ciò significa che le richieste inviate alla porta 8080 dell'host verranno inoltrate alla porta 80 del container, dove il servizio nginx è in ascolto.
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
f00ddc2a0b6a nginx "/docker-entrypoint.…" 13 seconds ago Up 13 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp interesting_meninsky
|
||||
```
|
||||
|
||||
Se si desidera servire contenuti web, è possibile utilizzare l'opzione `-v` (*volume*) per mappare un contenuto all'interno del container. La sintassi è simile alla precedente:
|
||||
|
||||
```bash
|
||||
docker run -d -p 8080:80 -v /path/to/my/webcontent:/usr/share/nginx/html nginx
|
||||
```
|
||||
|
||||
In questo caso, il contenuto presente nella directory `/path/to/my/webcontent` del sistema host sarà disponibile all'interno del container nella directory `/usr/share/nginx/html`.
|
||||
|
||||
## Tipologie
|
||||
|
||||
Esistono diverse tipologie di networking che possono essere utilizzate in Docker, denominate `driver`. I tre driver principali sono:
|
||||
|
||||
- `host`: in questa modalità, il container condivide l'interfaccia di rete con il sistema host. Non vi è alcun isolamento, pertanto qualsiasi processo eseguito all'interno del container ha accesso diretto alla rete dell'host. Questo tipo di accesso alla rete è analogo a quello di un browser web su un sistema operativo
|
||||
- `bridge`: questo driver fornisce isolamento tra l'host e i container, consentendo la creazione di reti virtuali. Tali reti operano in uno spazio di indirizzamento separato rispetto al sistema host e alla rete fisica, permettendo ai container di comunicare tra loro in modo privato o semi-privato. Questa modalità è la più comune e preferita per la maggior parte delle applicazioni Docker
|
||||
- `null`: in questa configurazione, il container è completamente isolato dalla rete, non avendo alcuna connettività di rete disponibile
|
||||
|
||||
Altri driver per configurazioni specifiche sono:
|
||||
|
||||
- `macvlan`: consente ai container di avere indirizzi MAC unici e di apparire come dispositivi fisici sulla rete. Richiede la creazione di una rete macvlan e l'assegnazione di un'interfaccia fisica
|
||||
- `overlay`: utilizzata per collegare container su più host, ideale per ambienti di orchestrazione come Docker Swarm o Kubernetes
|
||||
|
||||
## Port mapping
|
||||
|
||||
Mappare una porta significa associare una porta specifica del sistema host a una porta di un container. Questo processo consente di rendere accessibili i servizi in esecuzione all'interno del container dall'esterno.
|
||||
|
||||

|
||||
|
||||
Il seguente stack di esempio è composto da due servizi: *php* e *nginx*. In particolare, il servizio nginx espone due porte: la porta 80 del container sulla porta 8080 del sistema host e la porta 443 del container sulla porta 8443 dell'host.
|
||||
|
||||
```yml
|
||||
services:
|
||||
php:
|
||||
image: 'php:8.1-fpm'
|
||||
container_name: ${APP_NAME:?err}-php
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '8081:80'
|
||||
- '8443:443'
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
- './config/nginx:/etc/nginx/conf.d'
|
||||
```
|
||||
|
||||
Se si avvia lo stack con il comando `docker compose up -d`, il comando `docker ps` conferma che nginx è in esecuzione e in ascolto su tutte le interfacce di rete (`0.0.0.0`) alla porta 8080.
|
||||
|
||||
```bash
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
73a0991fb71b nginx:latest "/docker-entrypoint.…" 3 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp eager_northcutt
|
||||
```
|
||||
|
||||
Accedendo a `localhost:8080`, è possibile raggiungere il sito web servito dallo stack. Tuttavia, questo consente anche a chiunque si trovi sulla stessa rete o, se presente il NAT sul router, a chiunque conosca l'indirizzo IP del sistema host di accedere al servizio.
|
||||
|
||||
Per **limitare l'accesso** al servizio nginx in modo che sia raggiungibile solo dal sistema host, è necessario modificare la configurazione dello stack affinché ascolti solo su localhost e non su tutte le interfacce di rete:
|
||||
|
||||
```yml
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '127.0.0.1:8081:80'
|
||||
- '127.0.0.1:8443:443'
|
||||
```
|
||||
|
||||
Se non è importante che le porte associate sul sistema host siano sempre le stesse, è possibile **allocarle dinamicamente**, in modo da sceglierne sempre una disponibile, evitando conflitti:
|
||||
|
||||
```yml
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '80'
|
||||
- '443'
|
||||
```
|
||||
|
||||
Le porte sono ora allocate in modo casuale:
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
654f739ce935 nginx:latest "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:32770->80/tcp, [::]:32770->80/tcp crazy_jackson
|
||||
```
|
||||
|
||||
Se si desidera che Docker assegni automaticamente una porta disponibile in `localhost`, è possibile utilizzare la seguente sintassi:
|
||||
|
||||
```yml
|
||||
services:
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '127.0.0.1:0:80' # Assegna una porta casuale su localhost
|
||||
```
|
||||
|
||||
In questo caso, `127.0.0.1:0` indica a Docker di scegliere automaticamente una porta disponibile sul sistema host, associandola alla porta 80 del container:
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
6559daa92656 nginx:latest "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 127.0.0.1:32769->80/tcp nginx
|
||||
```
|
||||
|
||||
### Mapping Multiple Ports
|
||||
|
||||
Docker consente anche di mappare più porte contemporaneamente. Questo è utile quando il container deve esporre più servizi su porte diverse:
|
||||
|
||||
```bash
|
||||
docker run -p 8080:80 -p 443:443 nginx
|
||||
```
|
||||
|
||||
Oppure, per mappare un intervallo di porte: `docker run -p 5000-5100:5000-5100 nginx`.
|
||||
|
||||
## Reti virtuali
|
||||
|
||||
Per impostazione predefinita, i container Docker sono isolati l'uno dall'altro, il che impedisce la comunicazione diretta tra servizi che operano su stack diversi. Tuttavia, è possibile creare una rete virtuale condivisa tra container di due stack differenti, consentendo loro di comunicare.
|
||||
|
||||
La sintassi, per definire un nuovo network è la seguente:
|
||||
|
||||
```yml
|
||||
services:
|
||||
nginx:
|
||||
image: 'nginx:latest'
|
||||
container_name: ${APP_NAME:?err}-nginx
|
||||
ports:
|
||||
- '8081:80'
|
||||
- '8443:443'
|
||||
volumes:
|
||||
- './app:/var/www/html'
|
||||
- './config/nginx:/etc/nginx/conf.d'
|
||||
networks:
|
||||
- default # Le reti sotto network non vengono aggiunte alla configurazione di default, ma sostituite. Pertanto, la rete default deve essere specificata esplicitamente
|
||||
- nginx # Il container nginx farà parte dei seguenti network
|
||||
networks:
|
||||
nginx:
|
||||
name: mynetwork
|
||||
```
|
||||
|
||||
Nel secondo stack, è necessario definire la stessa rete per consentire la comunicazione tra i container:
|
||||
|
||||
```yml
|
||||
services:
|
||||
debug:
|
||||
image: ubuntu
|
||||
entrypoint: "bash -c 'while true; do sleep 1; done'"
|
||||
networks:
|
||||
- default
|
||||
- nginx
|
||||
|
||||
networks:
|
||||
nginx:
|
||||
name: mynetwork
|
||||
external: true # La rete è definita esternamente. Se non specificato, verrebbe generato un errore, poiché la rete esiste già e non può essere creata una rete con nome identico
|
||||
|
||||
```
|
||||
|
||||
In questo modo, è possibile mettere in comunicazione due container di due stack diversi, semplicemente creando una rete virtuale condivisa.
|
113
docker/010-volumi.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Volumi
|
||||
|
||||
Per impostazione predefinita, tutte le operazioni eseguite all'interno di un container Docker vengono scritte in un layer scrivibile del container stesso. Questo approccio presenta due principali limitazioni: innanzitutto, i dati scritti in questo layer vengono persi quando il container viene eliminato; inoltre, tali dati sono strettamente legati a uno specifico container, rendendone difficile lo spostamento o la condivisione dei dati con altri container.
|
||||
|
||||
Docker offre due soluzioni per garantire la persistenza dei dati:
|
||||
|
||||
- `bind mounts`: consentono uno scambio bidirezionale tra una cartella (o un file) definita sull'host e una cartella (o file) defina all'interno del container. Questa soluzione è particolarmente utile quando si desidera rendere disponibili all'interno del container risorse presenti sull'host, come file di configurazione. La sintassi, nel file `docker-compose.yml` é la seguente: `./config/nginx:/etc/nginx/conf.d`. Prima il percorso, relativo o assoluto, sull'host e poi il percorso assoluto nel container in cui questa directory deve essere montata. Opzionalmente, é possibile montare la cartella in sola lettura, utilizzando l'opzione `:ro`
|
||||
|
||||
- `volumi`: rappresentano il metodo migliore per garantire la **persistenza dei dati**. I volumi possono essere condivisi tra più container e offrono grande flessibilità, poiché non richiedono che il sistema host disponga di un path specifico da montare nel container. I volumi sono gestiti direttamente da Docker
|
||||
|
||||
I volumi, quando Docker è eseguito come utente root, sono mappati nella directory `/var/lib/docker/volumes`. Se Docker è eseguito in modalitá rootless, in `/home/user/.local/share/docker/volumes`, mentre con Podman sono localizzati in `/home/user/share/containers/storage/volumes`.
|
||||
|
||||
> Per migrare i dati su un altro host, basta semplicemente migrare il contenuto di queste directory e ricreare il volume associato.
|
||||
|
||||
La sintassi, come si vede dall'esempio, é leggermente diversa rispetto ai bind mounts:
|
||||
|
||||
```yml
|
||||
services:
|
||||
mealie:
|
||||
image: ghcr.io/mealie-recipes/mealie:v1.11.0
|
||||
container_name: mealie
|
||||
restart: always
|
||||
ports:
|
||||
- "9925:9000"
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 500M
|
||||
volumes:
|
||||
- mealie-data:/app/data/
|
||||
environment:
|
||||
# Set Backend ENV Variables Here
|
||||
ALLOW_SIGNUP: false
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
TZ: Europe/Rome
|
||||
MAX_WORKERS: 1
|
||||
WEB_CONCURRENCY: 1
|
||||
BASE_URL: https://localhost
|
||||
|
||||
volumes:
|
||||
mealie-data:
|
||||
```
|
||||
|
||||
## Comandi principali
|
||||
|
||||
Per creare un volume da associare successivamente a uno o più container, è disponibile il comando `docker volume create`. Questo comando genera un **volume anonimo**, identificato da un hash alfanumerico generato da Docker. Per creare un volume con un nome specifico, si utilizza il comando `docker volume create volume_name`.
|
||||
|
||||
I volumi sono entità indipendenti che possono esistere anche senza essere associati a un container.
|
||||
|
||||
A meno che non siano implementati limiti di quota, il volume crescerà in dimensione all'aumentare dei dati contenuti.
|
||||
|
||||
### Elencare i volumi
|
||||
|
||||
Per visualizzare l'elenco dei volumi esistenti, esiste il comando `docker volume ls`.
|
||||
|
||||
### Rimuovere i volumi
|
||||
|
||||
Per rimuovere **tutti i volumi anonimi non in uso da alcun container**, si utilizza il comando `docker volume prune`. Per eliminare tutti i volumi inutilizzati, si può utilizzare `docker volume prune -a`.
|
||||
|
||||
### Ispezionare i volumi
|
||||
|
||||
Per ispezionare un volume specifico, si utilizza il comando `docker volume inspect <volume_name>` oppure `docker volume inspect <hash>`.
|
||||
|
||||
L'associazione tra il volume e il container che lo utilizza non è registrata nel volume stesso, ma nel container. In altre parole, il volume non riporta i suoi utilizzatori; sono i container a registrare il volume che utilizzano. Pertanto, per trovare l'associazione, si può utilizzare il comando `docker inspect <container_name>`.
|
||||
|
||||
## Copiare i dati
|
||||
|
||||
Docker utilizza un `filesystem overlay2` per gestire i layer dei container. Questo filesystem permette di sovrapporre più layer, consentendo di mantenere un layer di base immutabile e di applicare modifiche in layer superiori. Quando un container viene avviato, Docker crea una directory chiamata `UpperDir`. Questa directory contiene tutte le modifiche apportate al filesystem del container rispetto al layer di base. In altre parole, qualsiasi file creato, modificato o eliminato all'interno del container sarà registrato in UpperDir. In particolare, all'interno di UpperDir, c'è una directory chiamata `diff` che contiene tutte le differenze rispetto al layer di base. Ad esempio, se si crea un nuovo file all'interno del container, questo file sarà presente nella directory diff di UpperDir. Pertanto, i file creati sono sempre disponibili in tale percorso.
|
||||
|
||||
- `LowerDir`: rappresenta i layer sottostanti, che contengono i dati originali dell'immagine. Questi layer non possono essere modificati direttamente; invece, le modifiche vengono registrate nel layer superiore `UpperDir`
|
||||
- `MergedDir`: è la vista combinata di tutti i layer, che consente di visualizzare i file come se fossero in un'unica directory. Questo è ciò che gli utenti vedono quando accedono al filesystem del container
|
||||
- `WorkDir`: è una directory temporanea utilizzata da OverlayFS per gestire le operazioni di unione dei file
|
||||
|
||||
```txt
|
||||
root@laptop:~# docker run --rm -it -d --name ubuntu ubuntu
|
||||
82b1eaab3995a3e5c7c482e41dbc4c80a291521fe6712e1b9ba6f8ed867e2afc
|
||||
root@laptop:~# docker exec -it ubuntu bash
|
||||
root@82b1eaab3995:/# touch LEGGIMI.txt
|
||||
root@82b1eaab3995:/# exit
|
||||
```
|
||||
|
||||
Successivamente, è possibile ispezionare il container per ottenere informazioni dettagliate sulla sua configurazione e sui suoi mountpoint:
|
||||
|
||||
```bash
|
||||
root@dadopc:~# docker container inspect ubuntu
|
||||
|
||||
[...]
|
||||
"GraphDriver": {
|
||||
"Data": {
|
||||
"ID": "82b1eaab3995a3e5c7c482e41dbc4c80a291521fe6712e1b9ba6f8ed867e2afc",
|
||||
"LowerDir": "/var/lib/docker/overlay2/c3da0b1ac3995e0ed4103ffa7137361dd07a4e40a1979f0e3e0f083a05da6416-init/diff:/var/lib/docker/overlay2/fcdf120da8d033d61a0c71068494bfe8ef0d70e989c7264aab6ea2ddf3fe4870/diff",
|
||||
"MergedDir": "/var/lib/docker/overlay2/c3da0b1ac3995e0ed4103ffa7137361dd07a4e40a1979f0e3e0f083a05da6416/merged",
|
||||
"UpperDir": "/var/lib/docker/overlay2/c3da0b1ac3995e0ed4103ffa7137361dd07a4e40a1979f0e3e0f083a05da6416/diff",
|
||||
"WorkDir": "/var/lib/docker/overlay2/c3da0b1ac3995e0ed4103ffa7137361dd07a4e40a1979f0e3e0f083a05da6416/work"
|
||||
},
|
||||
"Name": "overlay2"
|
||||
```
|
||||
|
||||
Il comando `ls` può essere utilizzato per visualizzare il contenuto della directory `diff`, dove sono memorizzati i file creati all'interno del container.
|
||||
|
||||
```bash
|
||||
root@laptop:~# ls -lh /var/lib/docker/overlay2/c3da0b1ac3995e0ed4103ffa7137361dd07a4e40a1979f0e3e0f083a05da6416/diff
|
||||
total 0
|
||||
-rw-r--r-- 1 root root 0 Jul 31 20:45 LEGGIMI.txt
|
||||
drwx------ 1 root root 26 Jul 31 20:45 root
|
||||
```
|
||||
|
||||
In alternativa, è possibile utilizzare il comando `docker cp` per copiare i dati da e verso un container. È necessario fornire due argomenti: il percorso sorgente all'interno del container e il percorso di destinazione nel filesystem locale (o viceversa).
|
||||
|
||||
```bash
|
||||
root@laptop:~# docker cp ubuntu:/LEGGIMI.txt .
|
||||
```
|
104
docker/011-dockerfile.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Docker file
|
||||
|
||||
## Introduzione
|
||||
|
||||
Il `Dockerfile` è un file di testo che contiene una serie di istruzioni per creare immagini Docker personalizzate. Nel caso di Podman, il file è denominato `Containerfile`, ma la sintassi rimane invariata.
|
||||
|
||||
```dockerfile
|
||||
FROM ubuntu
|
||||
|
||||
LABEL Description="ubuntu con curl preinstallato"
|
||||
RUN apt update && apt install -y curl
|
||||
|
||||
ENTRYPOINT ["/usr/bin/curl"]
|
||||
```
|
||||
|
||||
In questo esempio, l'istruzione `FROM` specifica l'immagine base, `LABEL` imposta una descrizione e `RUN` esegue i comandi `apt update` e `apt install -y curl`.
|
||||
|
||||
Ogni istruzione nel Dockerfile crea un nuovo layer. Se si utilizzano molte istruzioni, l'immagine risultante sarà più grande. Per ridurre le dimensioni dell'immagine, è consigliabile combinare più comandi in un'unica istruzione. Ad esempio, l'uso di apt-get update e apt-get install in un'unica riga evita la creazione di layer aggiuntivi.
|
||||
|
||||
Durante la creazione dell'immagine, il container viene spento e riacceso tra un'istruzione e l'altra. Questo significa che non c'è continuità tra le istruzioni: le variabili d'ambiente impostate in un'istruzione non saranno disponibili nelle istruzioni successive.
|
||||
|
||||
### Caching
|
||||
|
||||
Docker utilizza un meccanismo di caching per ottimizzare la creazione delle immagini. Se un'istruzione non viene modificata, Docker utilizzerà il risultato della cache invece di eseguire nuovamente l'istruzione. Tuttavia, se un'istruzione prevede il download di una risorsa, la versione memorizzata nella cache potrebbe non essere aggiornata se la risorsa online è cambiata. Per forzare Docker a non utilizzare la cache, è possibile utilizzare l'opzione `--no-cache` durante la costruzione dell'immagine.
|
||||
|
||||
### Direttive
|
||||
|
||||
Le direttive più comuni utilizzate in un Dockerfile includono:
|
||||
|
||||
- `ADD`: consente di aggiungere file o directory remoti o locali al container
|
||||
- `COPY`: copia file e directory locali all'interno del container
|
||||
- `ENV`: imposta variabili d'ambiente che saranno disponibili in fase di esecuzione del container
|
||||
- `EXPOSE`: indica al demone Docker che il container ascolta su una certa porta
|
||||
- `FROM`: definisce l'immagine di base da cui derivare la nuova immagine
|
||||
- `RUN`: esegue comandi all'interno del container durante la costruzione dell'immagine
|
||||
- `USER`: specifica l'utente con cui vengono eseguite le operazioni all'interno del container. Se non viene specificato alcun utente, le operazioni vengono eseguite con l'utente root. Questa direttiva imposta anche l'utente che eseguirà i processi all'interno del container una volta avviato
|
||||
- `WORKDIR`: imposta la directory di lavoro all'interno del container. Ha una duplice funzione: sposta il contesto nella directory specificata e, se questa non esiste, la crea automaticamente
|
||||
- `ENV`: consente di impostare variabili d'ambiente che saranno sempre disponibili all'interno del container
|
||||
- `VOLUME`: rende persistente il percorso specificato utilizzando un volume anonimo
|
||||
- `ENTRYPOINT`: definisce l'eseguibile predefinito all'avvio del container. Se non viene specificato, l'eseguibile predefinito è tipicamente `/bin/sh`
|
||||
- `CMD`: specifica i parametri di avvio per l'ENTRYPOINT
|
||||
|
||||
```dockerfile
|
||||
# Pull base image
|
||||
FROM debian:latest
|
||||
|
||||
# Dockerfile Maintainer
|
||||
MAINTAINER dado "dado@mail.me"
|
||||
|
||||
# Install nginx and adjust nginx config to stay in foreground
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y nginx; \
|
||||
echo "daemon off;" >> /etc/nginx/nginx.conf
|
||||
|
||||
# Expose HTTP
|
||||
EXPOSE 80
|
||||
|
||||
# Start nginx
|
||||
CMD ["/usr/sbin/nginx"]
|
||||
```
|
||||
|
||||
## Buid di una immagine Docker
|
||||
|
||||
Per costruire un'immagine Docker, è necessario utilizzare il seguente comando:
|
||||
|
||||
```bash
|
||||
docker build [--no-cache] -t <username>/image_name /path/to/dockerfile
|
||||
```
|
||||
|
||||
Ad esempio, se il Dockerfile si trova nella cartella corrente, il comando sarà:
|
||||
|
||||
```bash
|
||||
docker build -t <username>/myubuntu .
|
||||
```
|
||||
|
||||
L'immagine viene costruita seguendo le istruzioni specificate nel Dockerfile. Eseguendo il comando `docker image ls`, sarà possibile visualizzare l'immagine appena costruita, che potrà essere eseguita come qualsiasi altra immagine Docker.
|
||||
|
||||
## Pubblicazione dell'immagine su un registry
|
||||
|
||||
È possibile caricare l'immagine su un registry, come Docker Hub, dove sarà pubblica per impostazione predefinita. Prima di procedere, è necessario effettuare il login:
|
||||
|
||||
```bash
|
||||
docker login
|
||||
```
|
||||
|
||||
Dopo aver effettuato il login, è possibile taggare l'immagine e caricarla utilizzando i seguenti comandi:
|
||||
|
||||
```bash
|
||||
docker tag myubuntu <username>/myubuntu:<tag>
|
||||
docker push <username>/myubuntu:latest
|
||||
```
|
||||
|
||||
## Backup e ripristino dell'immagine
|
||||
|
||||
Per eseguire un backup dell'immagine localmente, senza caricarla su un registry, utilizzare il comando `docker save`:
|
||||
|
||||
```bash
|
||||
docker save -o myubuntu.tar.gz myubuntu
|
||||
```
|
||||
|
||||
Per importare l'immagine su un altro sistema, utilizzare il comando:
|
||||
|
||||
```bash
|
||||
docker image import myubuntu.tar.gz <username>/myubuntu:latest
|
||||
```
|
BIN
docker/asset/img/container-vm.png
Normal file
After Width: | Height: | Size: 278 KiB |
BIN
docker/asset/img/docker-podman.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
docker/asset/img/layer.png
Normal file
After Width: | Height: | Size: 150 KiB |
BIN
docker/asset/img/port-mapping.png
Normal file
After Width: | Height: | Size: 280 KiB |
BIN
docker/asset/img/registry.png
Normal file
After Width: | Height: | Size: 122 KiB |
118
networking/000-introduzione.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Networking
|
||||
|
||||
## Tipologie di reti
|
||||
|
||||
La classificazione di una rete si basa su diversi parametri:
|
||||
|
||||
- estensione geografica
|
||||
- topologia logica e fisica
|
||||
- logica di funzionamento (peert to peer o client/server)
|
||||
- mezzo trasmissivo utilizzato
|
||||
|
||||
### Estensione geografica
|
||||
|
||||
Per dimensioni, l'architettura di rete si puo' suddividere in:
|
||||
|
||||
- `LAN` (local area network)
|
||||
- `WAN` (wide area network)
|
||||
|
||||
### Topologia di rete
|
||||
|
||||
Il termine *topologia* identifica la modalitá in cui le stazioni sono interconnesse tra loro, ovvero la forma del canale di comunicazione. Le piú diffuse sono ad anello, lineare e a stella o ad albero.
|
||||
|
||||
#### Rete ad anello
|
||||
|
||||
In una topologia ad anello, la rete é costituita da un insieme di apparati collegati direttamente (*connessione punto-punto*) tra di loro, in modo da formare una struttura circolare chiusa, all'interno della quale i dati scorrono in un'unica direzione.
|
||||
|
||||
Le reti ad anello presentano una scarsa tolleranza ai guasti: un guasto ad un elemento della rete puó determinare l'interruzione delle stessa.
|
||||
|
||||
#### Rete lineare
|
||||
|
||||
In una topologia lineare, la rete é costituita dal mezzo di trasmissione al quale tutte le stazioni sono connesse direttamente.
|
||||
|
||||
#### Rete a stella o ad albero
|
||||
|
||||
Nella topologia a *stella* (o *star topology*) tutti i dispositivi sono collegati a un dispositivo centrale, come uno switch o un hub, per la trasmissione delle informazioni e ogni host è connesso a tale punto.
|
||||
|
||||
Il guasto di una linea trasmissiva che collega un host all'hub determinerà l'isolamento di tale host da tutti gli altri, ma il resto della rete continuerà a funzionare tranquillamente.
|
||||
|
||||
## Mezzi trasmissivi
|
||||
|
||||
Per formare il canale di trasmissione, si possono utilizzare diversi mezzi trasmissivi. Questi sono raggruppati in tre grandi categorie:
|
||||
|
||||
- mezzi di trasmissione *elettrici*: l'informazione da trasmettere, il flusso di bit, viene inviata sfruttando la conduzione elettrica
|
||||
- *ottici*: si utilizza la trasmissione di raggi luminosi attraverso un materiale dielettrico (un isolante elettrico che non conduce corrente, ma può immagazzinare energia elettrica quando è sottoposto a un campo elettrico)
|
||||
- *wireless*: senza l'utilizzo dei supporti fisici
|
||||
|
||||
Alcuni mezzi trasmissivi storicamente usati sono:
|
||||
|
||||
- cavo coassiale
|
||||
- il doppino di rame incrociato
|
||||
- fibra ottica
|
||||
|
||||
### Cavo coassiale
|
||||
|
||||

|
||||
|
||||
É stato il primo mezzo trasmissivo utilizzato, ormai abbandonato. É costituito da un conduttore centrale circondato da uno o piú schermi.
|
||||
|
||||
### Doppino di rame incrociato
|
||||
|
||||

|
||||
|
||||
Il doppino di rame incrociato (*twisted pair*) consiste da una coppia di fili di rame protetti da una guaina isolante e incrociati. Esistono diverse versioni del doppino incrociato:
|
||||
|
||||
- `UTP` (Unshielded Twisted Pair): versione non schermata, soggetto a interferenze
|
||||
- `FTP` (Foiled Twisted Pair): presenta una singola schermatura, costituita solitamente da un foglio di alluminio
|
||||
- `STP` (Shielded Twisted Pair): la versione piú protetta, in quanto presenta una schermatura per ogni singola coppia piú una generale
|
||||
|
||||
Sono state definite le seguenti categorie:
|
||||
|
||||
- Categoria 1: cavi adatti solo per telefonia analogica
|
||||
- Categoria 2: cavi adatti per telefonia analogia o digitale (ISDN)
|
||||
- Categoria 3: consigliati per realizzare reti fino a un massimo di 10 Mbps
|
||||
- Categoria 4: possono essere utilizzati anche per reti Ethernet fino a 10 Mbps
|
||||
- Categoria 5: supporta velocità di trasferimento fino a 100 Mbps
|
||||
- Categoria 5e (Enhanced): un miglioramento rispetto al Cat 5, il Cat 5e è in grado di supportare velocità fino a 1 Gbps. È ancora molto utilizzato in ambienti domestici e uffici
|
||||
- Categoria 6: questo cavo è progettato per velocità più elevate, fino a 10 Gbps su distanze ridotte (fino a 55 metri)
|
||||
- Categoria 7: progettato per supportare velocità fino a 10 Gbps. Ha una migliore schermatura rispetto ai cavi precedenti, riducendo le interferenze elettromagnetiche e garantendo connessioni più stabili
|
||||
- Categoria 8: il più recente tra i cavi Ethernet, il Cat 8 supporta velocità fino a 40 Gbps
|
||||
|
||||
### Fibra ottica
|
||||
|
||||
Il cablaggio in fibra ottica viene utilizzato per trasferire le informazioni tramite impulsi di luce, che passano lungo uno o più tubi di vetro. Quest'ultimo viene racchiuso in una struttura costituita da tre sezioni concentriche:
|
||||
|
||||
- il nucleo o *core*
|
||||
- il mantello o *cadding*
|
||||
- un rivestimento plastico di protezione
|
||||
|
||||
Le tipologie più comuni di connettori per cavi in fibra ottica sono:
|
||||
|
||||
- `Connettori SC`: sono la variante più utilizzata
|
||||
- `Connettori LC`: piccoli e compatti, ideali per applicazioni in cui lo spazio è limitato
|
||||
- `Connettori ST`: sebbene siano ancora in uso, oggi vengono utilizzati meno spesso rispetto ai connettori LC e SC
|
||||
|
||||

|
||||
|
||||
#### Tipi di cavi in fibra
|
||||
|
||||
Esistono diversi tipi di cavi in fibra ottica.
|
||||
|
||||
- `Monomodale`: sono progettati con un nucleo molto sottile. Questa configurazione riduce significativamente la riflessione interna, permettendo ai segnali di percorrere distanze maggiori senza perdere qualità. Di conseguenza, i cavi monomodali sono in grado di trasmettere dati a velocità molto elevate, rendendoli ideali per collegamenti a lunga distanza
|
||||
- `Multimodale`: presentano un nucleo più grande. Questa struttura aumenta la riflessione interna, il che porta a una maggiore attenuazione e dispersione del segnale. Di conseguenza, i cavi multimodali sono più adatti per brevi distanze
|
||||
|
||||

|
||||
|
||||
#### FTTC e FTTH
|
||||
|
||||
`FTTC` sta per *Fiber to the Cabinet*, ossia *fibra fino al cabinato*, mentre `FTTH` sta per *Fiber to the Home*, cioè *fibra fino a casa*.
|
||||
|
||||

|
||||
|
||||
In presenza di una connessione FTTC, il cavo che collega la centrale al cabinato (spesso presente a bordo strada) è in fibra ottica, mentre il tratto dal cabinato a casa è in rame. Questo vuol dire che la seconda parte del collegamento resta soggetta a dispersioni. La tecnologia FTTC si propone come un compromesso per portare quindi la fibra ottica solo fino al cabinato, e sfruttare da lì in poi la vecchia struttura in rame. Se da un lato assistiamo ad un contenimento dei costi, dall’altro però si otterrà una notevole limitazione del segnale, dovuta all’utilizzo della banda in rame nell’ultimo tratto.
|
||||
|
||||
Le velocità raggiunte sono comunque superiori rispetto a quelle della classica connessione ADSL. Orientativamente, una connessione FTTC può raggiungere i 100/200 Mbps.
|
||||
|
||||
L’acronimo FTTH Indica le connessioni a banda ultra larga in cui il collegamento dalla centrale di trasmissione fino al modem dell’utente finale è realizzato per intero in fibra ottica. Esiste anche una soluzione intermedia, nel caso in cui non sia possibile effettuare lavori in appartamento per l’installazione della fibra: `FTTB`, ossia *Fiber to the Building*. Questo tipo di cablatura prevede il collegamento in fibra ottica dalla centrale di trasmissione a una centralina condominiale, con collegamento in rame da quest’ultima ai singoli appartamenti.
|
||||
|
||||
Attualmente la tecnologia FTTH è quella che garantisce maggiore stabilità della connessione e prestazioni elevate. In termini di prestazioni, è possibile raggiungere 1 Gbps di velocità.
|
@@ -1,13 +1,4 @@
|
||||
# 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
|
||||
# Stack protocollari
|
||||
|
||||
- Modello teorico `ISO/OSI`
|
||||
- Modello pratico `TCP/IP`
|
||||
@@ -34,7 +25,11 @@ In ogni layer, il pacchetto di informazioni ha varie nomenclature. Inoltre, ogni
|
||||
- `Data-Link`: frame (indirizzamento tramite mac-address)
|
||||
- `Physical`: bit (mezzo trasmissivo che collega due o piú host)
|
||||
|
||||
### Interazione tra i layer
|
||||

|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||
@@ -64,18 +59,18 @@ Vediamo un esempio pratico di incapsulamento e decapsulamento in una richiesta D
|
||||
|
||||
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:
|
||||
|
||||
@@ -83,22 +78,22 @@ Il segmento UDP così formato diventa, nel *network layer*, il payload del *pacc
|
||||
- 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.
|
||||
|
||||
@@ -117,6 +112,8 @@ Lo switch, per poter svolgere il proprio compito, deve analizzare le informazion
|
||||
- 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.
|
||||
|
||||

|
@@ -24,13 +24,13 @@ Possiamo classificarli in base alla velocità supportata:
|
||||
|
||||
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.
|
||||
|
||||
@@ -40,7 +40,7 @@ Vengono utilizzati solo 4 pin. Per quanto riguarda le connessioni Ethernet e Fas
|
||||
|
||||
- `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).
|
||||
|
||||
@@ -48,11 +48,11 @@ Un cavo con all'estremità un straight-through cable pinout é utile per mettere
|
||||
|
||||
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
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -27,4 +27,4 @@ Il payload (*Data & Padding*) contiene i dati provenienti dal livello di rete (n
|
||||
|
||||
- **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.
|
||||
|
||||

|
||||

|
||||
|
@@ -8,7 +8,7 @@ Esistono due principali tipologie di infrastruttura wireless:
|
||||
|
||||
- `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
|
||||
|
||||
@@ -22,7 +22,7 @@ Gli *Access Point* svolgono un ruolo cruciale nella traduzione dei frame di rete
|
||||
|
||||
## Anatomia del Wireless Frame
|
||||
|
||||

|
||||

|
||||
|
||||
É composto da diversi campi, ognuno con funzioni specifiche. Di seguito sono descritti i principali componenti di un wireless frame:
|
||||
|
||||
|
@@ -26,7 +26,26 @@ Il funzionamento dello switch è basato su un meccanismo di learning: quando ric
|
||||
|
||||
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.
|
||||
Lo switch supporta sia la modalità half-duplex che full-duplex, offrendo così una comunicazione più efficiente.
|
||||
|
||||
### Modalitá di configurazione delle porte
|
||||
|
||||
In `access mode`, la porta di uno switch non può trasmettere traffico di più VLAN e accetta solo frame non taggati.
|
||||
|
||||
Gli switch di rete possono operare in altre modalità, tra cui:
|
||||
|
||||
- `Trunk mode`: consente a una porta di trasportare il traffico di più VLAN attraverso un singolo collegamento fisico. In questa modalità, i frame Ethernet vengono taggati con un `VLAN tag` (secondo lo standard IEEE 802.1Q) per identificare a quale VLAN appartengono
|
||||
|
||||
```txt
|
||||
enable
|
||||
configure terminal
|
||||
interface GigabitEthernet0/1
|
||||
switchport mode trunk
|
||||
switchport trunk allowed vlan 10,20,30
|
||||
switchport trunk encapsulation dot1q
|
||||
exit
|
||||
write
|
||||
```
|
||||
|
||||
## Indirizzamento
|
||||
|
||||
|
@@ -1,4 +1,10 @@
|
||||
# Il protocollo ARP
|
||||
# Network Layer
|
||||
|
||||
Questo livello riceve segmenti dal soprastante livello di trasporto e forma pacchetti che vengono passati al sottostante data link layer.
|
||||
|
||||
Il compito del livello di rete è la trasmissione logica di pacchetti tra due host, che in generale non sono direttamente connessi, attraverso il percorso di rete più appropriato.
|
||||
|
||||
## 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.
|
||||
|
@@ -2,14 +2,27 @@
|
||||
|
||||
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.
|
||||
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.
|
||||
I pacchetti inviati da una stazione appartenente a una specifica VLAN saranno ricevuti esclusivamente dalle macchine che fanno parte della stessa sottorete. Per comunicare con stazioni appartenenti a VLAN diverse, è necessario utilizzare un dispositivo di livello superiore, come un router o uno switch multilayer, che consenta l'instradamento dei dati tra le diverse VLAN.
|
||||
|
||||
Per assegnare i membri a una VLAN, si configurano le porte dello switch. Assegnando le porte a specifiche VLAN, si realizza la segmentazione desiderata.
|
||||
|
||||
## VLAN Tagging
|
||||
|
||||
Un link definito come `trunk` è un canale capace di trasportare i frame di tutte le VLAN. Attraverso una procedura nota come *tagging*, l'intestazione del frame viene modificata per includere un indicatore di VLAN, secondo lo standard `IEEE 802.1Q`. Questa operazione può essere eseguita solo da dispositivi `VLAN Aware`, che sono in grado di gestire correttamente le VLAN.
|
||||
|
||||
Un tag `.1Q` è composto da due parti principali:
|
||||
|
||||
- `VPId` (*VLAN Protocol Identifier*): questo campo serve a distinguere i frame marcati da quelli non marcati
|
||||
- `TCI` (*Tag Control Information*): questo campo contiene le informazioni relative alla VLAN di appartenenza e include:
|
||||
- *Priority*: un campo di 3 bit utilizzato per impostare la priorità del frame
|
||||
- *VLAN Identifier* (`VId`): un campo di 12 bit che contiene l'ID della VLAN, consentendo così fino a *4096 VLAN diverse*
|
||||
|
||||
### VLAN Native
|
||||
|
||||
In un ambiente 802.1Q, è possibile connettere anche dispositivi che non sono VLAN Aware. Questo supporto avviene tramite la VLAN Native. In pratica, il traffico generato da questa VLAN non viene taggato, permettendo così che possa essere interpretato correttamente anche da stazioni non compatibili con lo standard 802.1Q.
|
||||
|
||||
## Configurazione VLAN Switch CISCO
|
||||
|
||||
Ad esempio, per configurare le interfacce 1 e 2 di uno switch nella VLAN 10
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Loop Layer 2
|
||||
# Spanning Tree
|
||||
|
||||
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.
|
||||
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 interfacce, tranne quella da cui è arrivato.
|
||||
|
||||
Se ci sono loop nella rete, il pacchetto di broadcast può circolare indefinitamente tra gli switch.
|
||||
|
@@ -42,7 +42,7 @@ Gli header di una richiesta HTTP vengono utilizzati dal client per fornire al se
|
||||
|
||||
Una risposta HTTP è il messaggio che un server invia a un client (come un browser o un'applicazione) dopo aver ricevuto e processato una richiesta HTTP. La struttura di una risposta HTTP è composta da quattro elementi principali:
|
||||
|
||||
- `Riga di stat`o, la prima riga della risposta che include la *versione del protocollo HTTP*, il *codice di stato* e la frase di stato descrittiva (ad esempio, *OK*)
|
||||
- `Riga di stato`, la prima riga della risposta che include la *versione del protocollo HTTP*, il *codice di stato* e la frase di stato descrittiva (ad esempio, *OK*)
|
||||
- `Headers`: le righe successive contengono le intestazioni, organizzate come coppie chiave-valore. Queste intestazioni forniscono informazioni supplementari sulla risposta, quali il tipo di contenuto, la lunghezza del contenuto e altri metadati
|
||||
- `Riga vuota` che separa le intestazioni dal corpo della risposta.
|
||||
- `Body`: il corpo del messaggio, che contiene i dati effettivi della risposta
|
||||
@@ -61,6 +61,22 @@ I codici di stato HTTP sono numeri a tre cifre che il server invia al client per
|
||||
|
||||

|
||||
|
||||
### Intestazione della Risposta HTTP
|
||||
|
||||
Le intestazioni di risposta permettono al server di fornire al client (tipicamente un browser) informazioni aggiuntive sul messaggio restituito. Tra le più importanti:
|
||||
|
||||
- `Content-Type`: specifica il tipo di contenuto della risposta, ad esempio `text/html`, `application/json`, ecc.
|
||||
- `Content-Length`: indica la lunghezza del corpo della risposta, espressa in byte
|
||||
- `Date`: riporta la data e l’ora (*timestamp*) in cui il messaggio è stato generato dal server
|
||||
- `Server`: indica il software (e talvolta la versione) in uso sul server HTTP
|
||||
- `Set-Cookie`: invia uno o più cookie al client, che potrà conservarli e ritrasmetterli nelle richieste successive per gestire sessioni, preferenze o tracciamento dell’utente.
|
||||
- `Cache-Control`: fornisce direttive su come il client (o eventuali proxy intermedi) deve memorizzare nella cache la risposta
|
||||
- `Expires`: definisce una data/ora oltre la quale la risposta è considerata scaduta e non più valida in cache
|
||||
- `Last-Modified`: specifica il timestamp dell’ultima modifica della risorsa richiesta
|
||||
- `ETag`: un identificatore univoco (e solitamente in forma di hash) della versione corrente della risorsa. Consente al client di effettuare richieste condizionali (`If-None-Match`) per verificare se la risorsa è cambiata
|
||||
- `Location`: utilizzata nei codici di stato *3xx* per indicare al client l’URL di destinazione a cui effettuare il reindirizzamento
|
||||
- `Allow`: elenca i metodi HTTP che il server supporta per la risorsa richiesta
|
||||
|
||||
## Metodi HTTP
|
||||
|
||||
I metodi HTTP indicano al server l'azione da eseguire su una risorsa. I principali metodi:
|
||||
@@ -73,6 +89,26 @@ I metodi HTTP indicano al server l'azione da eseguire su una risorsa. I principa
|
||||
- `DELETE`: consente di eliminare una risorsa sul server. Anche questo metodo, per ragioni di sicurezza, è spesso disabilitato di default
|
||||
- `OPTIONS`: utilizzato per verificare quali metodi HTTP sono supportati dal server, consentendo così al client di conoscere le possibili azioni disponibili
|
||||
|
||||
## Cookie e sessioni
|
||||
|
||||
Il protocollo HTTP è progettato per il trasferimento di pagine web attraverso richieste e risposte. Tuttavia, il protocollo HTTP è intrinsecamente `stateless`, ovvero privo di memoria. Ciò significa che non può memorizzare le preferenze o lo stato di un utente tra una richiesta e l'altra.
|
||||
|
||||
Per ovviare a questa limitazione, sono stati introdotti i cookie e le sessioni, che rendono HTTP `stateful`, un meccanismo con memoria che può tenere traccia dell'utente.
|
||||
|
||||
I `cookie` sono piccoli file di testo che il server invia al browser dell'utente, che li memorizza. Quando l'utente effettua una nuova richiesta, il browser invia nuovamente i cookie al server, permettendogli di riconoscere l'utente e mantenere le sue preferenze.
|
||||
|
||||
Le caratteristiche principali dei cookie sono:
|
||||
|
||||
- *Persistenza*: possono essere di sessione (temporanei, eliminati alla chiusura del browser) o persistenti (con una data di scadenza e memorizzati sul disco)
|
||||
- *Sicurezza*: possono essere marcati come `secure`, obbligando lo scambio solo tramite HTTPS, e `HttpOnly`, impedendo di accedere al valore del cookie tramite JavaScript. Questo è un ulteriore strumento di protezione contro attacchi di furto d'identità (i cookie permettono di bypassare tutti i meccanismi di autenticazione)
|
||||
- *Scope*: definiscono il percorso (path) e il dominio (domain) per cui il cookie è valido
|
||||
|
||||
Hanno una dimensione limitata a 4 KB e possono essere bloccati dal browser o dai suoi plugin per motivi di privacy.
|
||||
|
||||
Le `sessioni`, invece, sono gestite lato server e identificano il client attraverso un ID di sessione. Questo approccio offre un ulteriore livello di sicurezza, poiché i dati sensibili non vengono memorizzati nel cookie, ma rimangono sul server.
|
||||
|
||||
Le sessioni sono generalmente utilizzate in combinazione con i cookie: il cookie contiene solo l'ID di sessione, mentre le informazioni associate all'utente sono archiviate sul server.
|
||||
|
||||
## URI, URL e URN
|
||||
|
||||
Un `URI` (*Uniform Resource Identifier*) è un meccanismo per identificare in modo univoco una risorsa generica. Esistono due specializzazioni principali:
|
||||
|
43
networking/024-crittografia.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Crittografia
|
||||
|
||||
La crittografia è una tecnica fondamentale per proteggere le informazioni, consentendo di mascherarle in modo che solo il destinatario autorizzato possa leggerle e decodificarle. Questo processo aumenta significativamente la confidenzialità e la riservatezza dei dati, impedendo a terzi non autorizzati di accedere a informazioni sensibili.
|
||||
|
||||
La crittografia si divide principalmente in due categorie: `simmetrica` e `asimmetrica`.
|
||||
|
||||

|
||||
|
||||
## Crittografia Simmetrica
|
||||
|
||||
La crittografia simmetrica utilizza una singola chiave per cifrare e decifrare le informazioni. Questa chiave è generata attraverso algoritmi di cifratura specifici e consiste in una sequenza di bit usati per cifrare e decifrare l'informazione.
|
||||
|
||||
Nella crittografia simmetrica, viene generata una chiave che deve essere condivisa in modo sicuro tra le parti coinvolte, ad esempio A e B. Questa chiave è fondamentale, poiché entrambe le parti la utilizzano per cifrare e decifrare le informazioni.
|
||||
|
||||
La sicurezza della crittografia simmetrica dipende fortemente dalla segretezza di questa chiave. Se un attaccante riesce a intercettare o ottenere la chiave durante il processo di scambio, può facilmente accedere alle informazioni protette, compromettendo la riservatezza dei dati.
|
||||
|
||||
Per garantire uno scambio sicuro della chiave, è essenziale utilizzare metodi di trasmissione sicuri.
|
||||
|
||||
## Crittografia Asimmetrica
|
||||
|
||||
La crittografia asimmetrica si basa sull'uso di *due chiavi* distinte: una `chiave pubblica`, utilizzata per *cifrare i messaggi*, e una `chiave privata`, utilizzata per *decifrarli*. Questo sistema elimina il problema dello scambio sicuro delle chiavi, poiché ogni entità, come Alice e Bob, genera una coppia di chiavi: una chiave privata, che deve rimanere segreta, e una chiave pubblica, che può essere condivisa liberamente.
|
||||
|
||||
Quando Alice desidera inviare un messaggio cifrato a Bob, utilizza la chiave pubblica di Bob per cifrare il messaggio. Una volta cifrato, il messaggio può essere decifrato solo con la chiave privata corrispondente di Bob. Questo significa che, anche se il messaggio cifrato viene intercettato da un attaccante, non potrà essere decifrato senza la chiave privata di Bob.
|
||||
|
||||
## Firma Digitale
|
||||
|
||||
La firma digitale consente di autenticare l'identità del mittente in una comunicazione, prevenendo così le impersonificazioni. Questo processo garantisce che il messaggio provenga effettivamente dalla persona che afferma di averlo inviato.
|
||||
|
||||
Quando un mittente, ad esempio Alice, desidera firmare digitalmente un messaggio, utilizza la sua chiave privata per cifrare un hash del messaggio stesso. La firma digitale risultante viene quindi allegata al messaggio.
|
||||
|
||||
Il destinatario, Bob, può verificare l'autenticità del messaggio utilizzando la chiave pubblica di Alice. Decifrando la firma digitale con la chiave pubblica, Bob può confrontare l'hash ottenuto con l'hash del messaggio ricevuto. Se i due hash corrispondono, Bob può essere certo che il messaggio è autentico e che proviene realmente da Alice, poiché solo lei possiede la sua chiave privata.
|
||||
|
||||
Grazie alla firma digitale, non è più possibile per un attaccante impersonare Alice, poiché non ha accesso alla sua chiave privata.
|
||||
|
||||

|
||||
|
||||
## Certification Authority (CA)
|
||||
|
||||
La `Certification Authority` (`CA`) è un'entità fondamentale nel contesto della crittografia asimmetrica, poiché affronta il problema della *verifica dell'identità associata a una chiave pubblica*. Quando un attaccante tenta di impersonare un mittente, ad esempio dichiarando di essere Alice e fornendo una chiave pubblica falsa, il destinatario, Bob, potrebbe erroneamente credere di avere la chiave pubblica corretta di Alice, mentre in realtà sta utilizzando quella di un'altra persona, come Charlie.
|
||||
|
||||
Per prevenire questo tipo di attacco, la Certification Authority verifica l'identità di un'entità e associa la sua chiave pubblica a questa identità in modo sicuro. Quando Alice richiede un certificato, la CA esegue una serie di controlli per confermare che lei sia effettivamente chi afferma di essere. Una volta completata questa verifica, la CA emette un certificato digitale che include la chiave pubblica di Alice e altre informazioni identificative, firmato digitalmente dalla CA stessa.
|
||||
|
||||
Quando Bob riceve la chiave pubblica di Alice, può anche ricevere il certificato digitale emesso dalla CA. Verificando la firma della CA sul certificato, Bob può essere certo che la chiave pubblica appartiene realmente ad Alice e non a un attaccante.
|
28
networking/025-https.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# HTTPS
|
||||
|
||||
L'HTTP non è sicuro poiché trasmette le informazioni in chiaro. Per garantire la sicurezza nello scambio di dati, è necessario un livello di cifratura. Come l'HTTP, `HTTPS` si basa sul protocollo TCP e utilizza la porta 443.
|
||||
|
||||
La `S` di `secure` deriva dall'uso di protocolli di cifratura, inizialmente l'SSL (*Secure Socket Layer*) e attualmente il `TLS` (*Transport Layer Security*). Questi protocolli garantiscono la cifratura dei dati, proteggendo così la privacy e l'integrità delle informazioni trasmesse.
|
||||
|
||||
L'instaurazione di una connessione sicura tramite TLS è conosciuta come `TLS Handshake`.
|
||||
|
||||
Durante il TLS Handshake, viene utilizzato un certificato digitale, il quale è emesso da una *Certification Authority* (`CA`). Questo certificato attesta l'identità del sito web, consentendo di stabilire una connessione sicura e assicurando che i dati trasmessi siano cifrati e protetti da accessi non autorizzati.
|
||||
|
||||
## Processo di richiesta di un certificato
|
||||
|
||||
1. **Inizio della richiesta**: un richiedente desidera abilitare la comunicazione sicura HTTPS per il proprio sito. Per farlo, ha bisogno di un `certificato SSL/TLS` valido, che viene emesso da una CA
|
||||
2. **Generazione delle chiavi**: il richiedente deve generare una coppia di chiavi, una pubblica e una privata. La chiave pubblica sarà presentata alla CA e inclusa nel certificato SSL/TLS rilasciato, mentre la chiave privata rimarrà segreta e sarà utilizzata per la cifratura
|
||||
3. **Creazione della CSR**: il richiedente può quindi inviare la propria richiesta alla CA, nota come `Certificate Signing Request` (`CSR`). Questo file contiene informazioni essenziali, tra cui la chiave pubblica, dettagli sul richiedente e la firma digitale del richiedente
|
||||
4. **Verifica dell'identità**: la CA riceve la CSR e avvia un processo di verifica dell'identità del richiedente. Questo include la verifica del dominio (domain validation), dell'organizzazione e, in alcuni casi, una validazione estesa (extended validation)
|
||||
5. **Emissione del certificato**: se la CA riesce a confermare l'identità del richiedente, rilascia il certificato SSL/TLS. Questo certificato contiene informazioni come la chiave pubblica del richiedente, la firma digitale della CA (necessaria per la verifica dell'autenticità del certificato), e dettagli sulla validità e sulla scadenza del certificato
|
||||
|
||||
## Instaurazione della Connessione Sicura
|
||||
|
||||
1. **Avvio della connessione**: un client che desidera connettersi a un server tramite HTTPS inizia con la `Three-way Handshake`. Dopo aver stabilito la connessione (*SYN/SYN-ACK/SYN*), si procede al `TLS Handshake`, che riguarda lo scambio del certificato e l'implementazione della crittografia
|
||||
2. **Client Hello**: Il client invia un messaggio al server, noto come *Client Hello*. Questo messaggio include informazioni come la versione del protocollo TLS supportata, una lista di Cipher Suites (metodi o algoritmi di cifratura) che il client è in grado di utilizzare, e un numero casuale generato dal client, utilizzato per la generazione successiva delle chiavi
|
||||
3. **Server Hello**: il server risponde con un *Server Hello*, specificando la versione di TLS preferita, la suite di cifratura scelta, un numero casuale generato dal server e il certificato SSL/TLS
|
||||
4. **Verifica del certificato**: il client verifica il certificato SSL/TLS ricevuto dal server. Controlla innanzitutto la scadenza, quindi verifica se è stato firmato da una CA riconosciuta. I browser contengono le chiavi pubbliche delle CA comuni e standard, utilizzando queste chiavi per verificare la firma. Se la CA non è standard, deve essere importata nel browser. Infine, il client confronta il nome di dominio del certificato con quello richiesto
|
||||
5. **Generazione della chiave segreta**: se tutte le verifiche sono positive, il client genera una chiave segreta per la crittografia simmetrica dei dati. Questa chiave segreta viene cifrata utilizzando la chiave pubblica del server, garantendo che solo il server possa decifrarla. Questo metodo sicuro utilizza la crittografia asimmetrica per inviare una chiave destinata alla crittografia simmetrica
|
||||
6. **Crittografia dei Dati**: Una volta stabilita la chiave segreta, sia il client che il server la utilizzano per criptare le informazioni. L'uso della crittografia asimmetrica per ogni singolo scambio di dati sarebbe troppo oneroso e rallenterebbe significativamente la comunicazione
|
||||
|
||||

|
129
networking/026-dns.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Domain Name System (DNS)
|
||||
|
||||
Il Domain Name System o `DNS` è un protocollo del livello applicativo (layer 7) nel modello ISO/OSI (layer 5 nel modello TCP/IP). Utilizza il protocollo UDP a livello di trasporto ed è associato alla *well-know port 53*.
|
||||
|
||||
La funzione principale del DNS è quella di tradurre i nomi di dominio in indirizzi IP, facilitando così la navigazione degli utenti. Oltre a questa funzione principale, il DNS offre anche altre due importanti caratteristiche:
|
||||
|
||||
- **Aliasing**: consente di creare alias per un dominio principale (ad esempio, per il dominio *miosito.com*, è possibile avere alias come *blog.miosito.com*)
|
||||
- **Load Balancing**: il DNS può anche fungere da bilanciatore di carico. Quando un client richiede l'indirizzo IP di un web server, il DNS può inviare la richiesta a un server specifico in base al carico di lavoro attuale, smistando così le richieste tra più indirizzi IP associati allo stesso dominio
|
||||
|
||||
## Gerarchia DNS
|
||||
|
||||
Quando il processo di risoluzione DNS viene avviato, si seguono diversi passaggi per ottenere l'indirizzo IP associato a un nome di dominio.
|
||||
|
||||
Il primo passo consiste nell'interrogare la **memoria locale del dispositivo**, la quale può contenere sia entry manuali inserite dall'utente sia informazioni precedentemente risolte e memorizzate nella cache.
|
||||
|
||||
### DNS Resolver locale
|
||||
|
||||
Se l'informazione non è presente nella memoria locale, il sistema si rivolge al *DNS resolver locale*, che può essere:
|
||||
|
||||
- un server DNS configurato localmente sulla macchina o sul proprio router
|
||||
- un server DNS locale nella LAN
|
||||
- un server DNS fornito dal proprio Internet Service Provider (`ISP`)
|
||||
|
||||
### Server DNS root
|
||||
|
||||
Se il resolver locale non riesce a fornire la risposta, la richiesta viene inoltrata ai `server DNS root`, che rappresentano *il primo livello della gerarchia DNS*. Non contengono informazioni specifiche sui nomi di dominio, ma il loro compito principale è quello di indirizzare la risoluzione verso i server dei **Top Level Domain** (`TLD`), che si trovano al *secondo livello della gerarchia*. Questi server gestiscono i domini di primo livello, come ad esempio `.com`, `.org`, ecc.
|
||||
|
||||
### Server TLD
|
||||
|
||||
I `server TLD` ricevono la richiesta e, a loro volta, indirizzano il resolver verso i server DNS autoritativi per il dominio specifico richiesto.
|
||||
|
||||
### Server DNS Autoritativi
|
||||
|
||||
Infine, al terzo livello della gerarchia, ci sono i `server DNS autoritativi`. Questi server contengono le informazioni definitive riguardanti il dominio richiesto e sono gestiti dal proprietario del dominio o da un ente di fiducia a cui il proprietario si affida. Solo questi server possono fornire la risposta finale, ovvero l'indirizzo IP associato al nome di dominio.
|
||||
|
||||

|
||||
|
||||
## Risoluzione DNS
|
||||
|
||||
La risoluzione DNS può avvenire attraverso due modalità principali:
|
||||
|
||||
- `Interattiva`: nella modalità interattiva, il DNS resolver locale richiede direttamente l'informazione a ciascun livello della gerarchia DNS, partendo dal server DNS root fino ai server autoritativi. Questo approccio presenta diversi vantaggi in termini di sicurezza. Il resolver locale quindi:
|
||||
- invia richieste ai server DNS root per ottenere indicazioni sui server TLD appropriati
|
||||
- prosegue a interrogare i server TLD per ottenere informazioni sui server autoritativi specifici del dominio richiesto
|
||||
- contatta i server autoritativi per ottenere l'indirizzo IP associato al nome di dominio
|
||||
- `Ricorsiva`: nella modalità ricorsiva, il resolver locale delega la responsabilità di trovare l'informazione a altri server DNS, partendo dal server DNS root di primo livello. Questo processo continua in modo ricorsivo, con ogni server che fornisce indicazioni al successivo, fino a quando il resolver non ottiene la risposta finale
|
||||
|
||||
## Zona DNS
|
||||
|
||||
Una zona DNS è una sottosezione della gerarchia DNS che comprende un insieme di server DNS responsabili di un determinato dominio e dei suoi sottodomini. Questa zona contiene tutte le informazioni relative ai nomi di dominio e ai relativi `Resource Records` (RR).
|
||||
|
||||
Il `namespace` di una zona DNS è l'insieme completo di tutte le informazioni contenute in quella zona. Ogni zona DNS ha un server DNS autoritativo, che è responsabile di fornire informazioni accurate e aggiornate sulla zona stessa.
|
||||
|
||||
## Records DNS
|
||||
|
||||
I `Resource Records` (RR) o records DNS sono informazioni strutturate in quattro macro campi: (`nome, tipo, valore, TTL`). Esistono diversi tipi di record DNS, ognuno con uno scopo specifico:
|
||||
|
||||
- `Tipo A` (Address Record): associa un nome di dominio a un indirizzo IPv4, un processo noto come `DNS lookup`. Ad esempio, `(www.sito.com,A,X.X.X.X,100)`
|
||||
- `Tipo AAAA` (Address Record): simile al tipo A, ma associa un nome di dominio a un indirizzo IPv6
|
||||
- `Tipo MX` (Mail Exchange Record): indica il server di posta autorizzato a ricevere email per un dominio `(www.gmail.com,MX,smtp.gmail.com,100)`
|
||||
- `Tipo CNAME` (Canonical Name Record): associa un nome di dominio canonico a un alias `(www.sito.com,CNAME,blog.sito.com,100)`
|
||||
- `Tipo NS` (Name Server Record): identifica i server responsabili per una zona di dominio (detti `name server`), mappando il dominio al nome di un ns `(www.sito.com,NS,ns1.dnsprovider.com,100)`
|
||||
- `Tipo PTR` (Pointer Record): utilizzato per la `reverse DNS lookup`, associa un indirizzo IP a un nome di dominio `(152.152.142.12.in-addr.arpa,PTR,www.sito.com,100)`
|
||||
- `Tipo SOA` (Start of Authority): fornisce informazioni amministrative sulla zona DNS, inclusi i server autoritativi. Un esempio di record SOA:
|
||||
|
||||
```txt
|
||||
@ IN SOA ns.example.com. admins.siteground.com. (
|
||||
2022010101 ; Serial
|
||||
86400 ; Refresh
|
||||
7200 ; Retry
|
||||
3600000 ; Expire
|
||||
86400 ; Minimum TTL
|
||||
)
|
||||
```
|
||||
|
||||
- `Tipo TXT`: Associa una stringa di testo a un dominio. I record TXT sono spesso utilizzati per configurazioni relative alla posta elettronica, come SPF, DKIM e DMARC, per migliorare la sicurezza e l'autenticità delle comunicazioni email
|
||||
|
||||
## Pacchetto DNS
|
||||
|
||||
Il pacchetto DNS è costituito da diverse componenti, alcune delle quali vengono utilizzate se il pacchetto è una richiesta DNS (DNS request) e altre nella risposta (DNS response). La struttura principale del pacchetto include:
|
||||
|
||||
### Intestazione (Header)
|
||||
|
||||
L'intestazione, lunga 12 byte, contiene vari campi:
|
||||
|
||||
- `Transaction ID`: un identificatore univoco della richiesta, che consente di associare una specifica query alla sua risposta
|
||||
- `Flags`: un insieme di valori rappresentati da singoli bit, ciascuno dei quali può essere acceso (1) o spento (0):
|
||||
- `QR`: indica se il pacchetto è una query (0) o una risposta (1)
|
||||
- `AA` (Authoritative Answer): indica se la risposta è autoritativa (1) o meno (0)
|
||||
- `RCODE` (Response Code): un campo di 4 bit che riporta codici di risposta per eventuali errori
|
||||
- `QDCount`: il numero di richieste presenti nella sezione *Question*, che indica quante domande sono state formulate
|
||||
- `ANCount`: il numero di record di risposta presenti nella sezione *Answer*
|
||||
- `NSCount`: il numero di RR presenti nella sezione *Authority*, che indica quanti record provengono da un server autoritativo
|
||||
- `ARCount`: il numero di record presenti nella sezione *Additional*, che fornisce informazioni supplementari utili per la risoluzione della richiesta
|
||||
|
||||
### Sezione Questions
|
||||
|
||||
La sezione Questions contiene la/e richiesta/e DNS e include i seguenti campi:
|
||||
|
||||
- `QNAME`: il nome di dominio per il quale si sta effettuando la richiesta
|
||||
- `QTYPE`: indica il tipo di record richiesto, rappresentato da un codice associato al tipo di RR specificato in QNAME.
|
||||
- A (1)
|
||||
- AAAA (28)
|
||||
- MX (15)
|
||||
- CNAME (5)
|
||||
- `QCLASS`: indica la classe della query, specificando il contesto/luogo in cui si sta cercando l'informazione per il nome di dominio. Per un contesto ampio, come Internet, si utilizza la QCLASS IN (Internet).
|
||||
|
||||
Questi campi forniscono le informazioni necessarie per elaborare la richiesta e ottenere la risposta desiderata.
|
||||
|
||||
### Sezione Answers (Risposte)
|
||||
|
||||
La sezione Answers fornisce le risposte alla/e richiesta/e DNS e include i seguenti campi:
|
||||
|
||||
- `Name`: rappresenta il dominio per il quale è stata effettuata la richiesta
|
||||
- `Type`: indica il tipo di record restituito, come A, AAAA, MX, CNAME, ecc.
|
||||
- `CLASS`: rappresenta la classe di risposta, che è quasi sempre IN (Internet).
|
||||
- `TTL` (Time to Live): indica il tempo di vita della risposta. Una volta scaduto, l'informazione viene considerata obsoleta e viene eliminata
|
||||
- `RD Length`: indica la lunghezza dei dati di risposta, specificando quanti byte occupa l'informazione restituita
|
||||
- `RDATA`: contiene i dati effettivi della risposta, che variano a seconda del tipo di record richiesto
|
||||
|
||||
### Sezione Authority
|
||||
|
||||
La sezione Authority indica le risposte provenienti da server DNS autoritativi.
|
||||
|
||||
### Sezione Additional
|
||||
|
||||
La sezione Additional può contenere informazioni extra che non rientrano nelle altre sezioni.
|
||||
|
||||

|
98
networking/027-dns-tools.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# DNS Tools
|
||||
|
||||
`dig` e `nslookup` sono strumenti di rete utilizzati per interrogare i server DNS. `dig` fornisce informazioni dettagliate e formattate sulle query DNS, mentre `nslookup` è un'interfaccia più semplice e interattiva per ottenere informazioni sui nomi di dominio. Entrambi sono utili per diagnosticare problemi di risoluzione dei nomi e per ottenere dettagli su record DNS specifici.
|
||||
|
||||
## nslookup
|
||||
|
||||
```bash
|
||||
nslookup novemila.org
|
||||
Server: 192.168.0.1 ## Server DNS locale, in questo casso il default gateway
|
||||
Address: 192.168.0.1#53
|
||||
|
||||
Non-authoritative answer: ## Le risposte non provengono da un server autoritativo
|
||||
Name: novemila.org
|
||||
Address: 95.111.234.107 ## Record di tipo A
|
||||
```
|
||||
|
||||
Una reverse lookup:
|
||||
|
||||
```bash
|
||||
nslookup 95.111.234.107
|
||||
;; Got recursion not available from 194.242.2.9, trying next server
|
||||
107.234.111.95.in-addr.arpa name = vmi1757309.contaboserver.net. ## Record di tipo PTR, che associano un IP a un hostname
|
||||
|
||||
Authoritative answers can be found from:
|
||||
```
|
||||
|
||||
Infine, é possibile impostare il tipo di RR da richiedere:
|
||||
|
||||
```bash
|
||||
nslookup -query=A continuity.space
|
||||
Server: 192.168.0.1
|
||||
Address: 192.168.0.1#53
|
||||
|
||||
Non-authoritative answer:
|
||||
Name: continuity.space
|
||||
Address: 92.245.188.161
|
||||
|
||||
nslookup -query=MX continuity.space
|
||||
Server: 192.168.0.1
|
||||
Address: 192.168.0.1#53
|
||||
|
||||
Non-authoritative answer:
|
||||
continuity.space mail exchanger = 1 mailgate.continuity.srl.
|
||||
|
||||
Authoritative answers can be found from:
|
||||
```
|
||||
|
||||
## dig
|
||||
|
||||
```bash
|
||||
dig @1.1.1.1 continuity.space MX
|
||||
|
||||
; <<>> DiG 9.20.9-2-Debian <<>> @1.1.1.1 continuity.space MX
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64794
|
||||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 1232
|
||||
;; QUESTION SECTION:
|
||||
;continuity.space. IN MX
|
||||
|
||||
;; ANSWER SECTION:
|
||||
continuity.space. 900 IN MX 1 mailgate.continuity.srl.
|
||||
|
||||
;; Query time: 103 msec
|
||||
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
|
||||
;; WHEN: Thu Jun 19 21:17:40 CEST 2025
|
||||
;; MSG SIZE rcvd: 84
|
||||
```
|
||||
|
||||
Oppure, per richiedere un RR SOA:
|
||||
|
||||
```bash
|
||||
dig @1.1.1.1 continuity.space SOA
|
||||
|
||||
; <<>> DiG 9.20.9-2-Debian <<>> @1.1.1.1 continuity.space SOA
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1072
|
||||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 1232
|
||||
;; QUESTION SECTION:
|
||||
;continuity.space. IN SOA
|
||||
|
||||
;; ANSWER SECTION:
|
||||
continuity.space. 900 IN SOA dns17.ovh.net. tech.ovh.net. 2025053000 86400 3600 3600000 300
|
||||
|
||||
;; Query time: 64 msec
|
||||
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
|
||||
;; WHEN: Thu Jun 19 21:18:57 CEST 2025
|
||||
;; MSG SIZE rcvd: 99
|
||||
```
|
35
networking/028-ntp.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Network Time Protocol (NTP)
|
||||
|
||||
`NTP` è un protocollo dell'Application Layer, progettato per sincronizzare gli orologi dei dispositivi all'interno di una rete. Utilizza un punto centrale di riferimento, rappresentato da un server NTP, per garantire che i timestamp siano accurati e coerenti.
|
||||
|
||||
## Gerarchia
|
||||
|
||||
NTP si basa sul protocollo UDP e utilizza la *well-known port 123*. Esistono numerosi server NTP distribuiti in tutto il mondo, gestiti da vari enti, e sono organizzati gerarchicamente in livelli, noti come `strati`.
|
||||
|
||||
- **Strato 1**: i server NTP di primo livello sincronizzano i loro orologi interni con fonti esterne estremamente precise, come gli orologi atomici. Queste informazioni vengono poi trasmesse a cascata ai server NTP degli strati inferiori, che si scambiano anche informazioni tra di loro, garantendo una continua sincronizzazione temporale
|
||||
- **Client finali**: all'ultimo strato si trovano i client, che inviano richieste NTP per ottenere la sincronizzazione temporale dai server
|
||||
|
||||

|
||||
|
||||
### Algoritmi di Sincronizzazione
|
||||
|
||||
NTP utilizza diversi algoritmi per regolare il tempo ricevuto, tenendo conto di varie problematiche legate al tempo, come il ritardo nella trasmissione della risposta.
|
||||
|
||||
## Pacchetto NTP
|
||||
|
||||
Il pacchetto NTP ha una dimensione fissa di 48 byte e contiene diversi campi, alcuni dei quali sono utilizzati nella richiesta NTP, mentre altri sono presenti nella risposta.
|
||||
|
||||
- `LI` (Leap Indicator): indica se ci sono stati aggiustamenti nel timestamp, ovvero un intervento per correggere l'ora e garantire l'accuratezza
|
||||
- `VN` (Version Number): specifica la versione di NTP utilizzata per la comunicazione
|
||||
- `Mode`: indica il ruolo del dispositivo, specificando se si tratta di una richiesta da parte del client, di una risposta del server, ecc.
|
||||
- `Stratum`: indica da quale strato viene prelevata l'informazione temporale
|
||||
- `Precision`: indica la precisione del clock locale di un dispositivo, ossia la sua capacità di mantenere il tempo in modo accurato rispetto a quello ricevuto dalla sorgente
|
||||
- `Root Delay`: tempo stimato di andata e ritorno al server di riferimento, utilizzato per calcolare il ritardo temporale tra la richiesta e la risposta
|
||||
- `Root Dispersion`: Rappresenta l'errore massimo atteso nella sincronizzazione temporale.
|
||||
- `Reference ID`: identificativo del server sorgente
|
||||
- `Reference Timestamp`: timestamp dell'ultima sincronizzazione del server NTP con una fonte affidabile
|
||||
- `Originate Timestamp`: timestamp che indica quando il client ha originato la richiesta
|
||||
- `Receive Timestamp`: timestamp che indica quando la richiesta è stata ricevuta dal server NTP
|
||||
- `Transmit Timestamp`: timestamp che indica quando il server ha inviato la risposta al client
|
||||
|
||||

|
20
networking/029-email.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Posta Elettronica
|
||||
|
||||
Nel sistema della posta elettronica, ci sono diverse entità che svolgono ruoli fondamentali nel processo di invio e ricezione delle email.
|
||||
|
||||
- Il `MUA` (`Mail User Agent`) è l'applicazione utilizzata dagli utenti per inviare e ricevere email. Può essere accessibile tramite un browser web, come nel caso di servizi come Gmail o Tutanota, oppure tramite applicazioni installate localmente, come Thunderbird. Il MUA fornisce un'interfaccia utente per gestire la corrispondenza elettronica, consentendo agli utenti di comporre, inviare, ricevere e organizzare le email
|
||||
- L'`MTA` (`Mail Transfer Agent`) è il server responsabile dello smistamento delle email inviate dai client verso i corretti relay di mezzo e, infine, al destinatario finale, che è rappresentato dal server di posta del destinatario
|
||||
- L'`MDA` (`Mail Delivery Agent`) si trova solitamente sui server MTA di destinazione e ha il compito di prendere le email e depositarle nella casella di posta dell'utente finale
|
||||
|
||||
## Flusso di Posta Elettronica
|
||||
|
||||
Immaginiamo un scenario in cui abbiamo due host: **A** e **B**. Sull'host A è configurata l'email `mario@email.com`, mentre sull'host B è configurata l'email `luigi@server.com`. Dopo il simbolo `@`, troviamo il nome di dominio, e attraverso la risoluzione DNS dei record MX possiamo identificare i mail server di riferimento per ciascun dominio.
|
||||
|
||||
1. Mario decide di inviare un'email a Luigi
|
||||
2. Il MUA di Mario utilizza il protocollo `SMTP` (`Simple Mail Transfer Protocol`) per inviare l'email al primo MTA responsabile per il dominio **email.com**
|
||||
3. Per determinare a quale server inviare la mail, l'MTA effettua una risoluzione DNS per ottenere il record MX associato al dominio **server.com**. Questi record indicano quali server sono responsabili per la ricezione delle email per quel dominio.
|
||||
4. La mail viene quindi trasferita attraverso la rete fino a raggiungere l'MTA del destinatario
|
||||
5. All'arrivo presso l'MTA del destinatario, la mail viene passata all'MDA, che si occupa di depositare il messaggio nella casella di posta dell'utente finale, in questo caso, Luigi
|
||||
6. Luigi, utilizzando il suo MUA, si interfaccia con l'MDA per scaricare la mail. Questo avviene tramite protocolli come `POP3` o `IMAP4`.
|
||||
|
||||

|
53
networking/030-smtp.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Simple Mail Transfer Protocol
|
||||
|
||||
`SMTP` è un protocollo utilizzato per l'invio di email. Basato sul protocollo di trasmissione TCP, garantisce una comunicazione affidabile.
|
||||
|
||||
SMTP può operare su diverse porte:
|
||||
|
||||
- `25`: questa è la porta standard per SMTP. È utilizzata per l'invio di email senza crittografia, il che significa che le informazioni vengono trasmesse in chiaro. Per questo motivo, l'uso della porta 25 è spesso limitato o bloccato dai provider di servizi Internet per prevenire abusi e spam
|
||||
- `465`: questa porta è utilizzata per `SMTPS` (SMTP Secure), che implementa la crittografia tramite `TLS` (Transport Layer Security)
|
||||
- `587`: questa porta è utilizzata per SMTP con il comando `STARTTLS`, che consente di avviare una connessione sicura utilizzando TLS. Inizialmente, la connessione avviene in chiaro, ma può essere successivamente crittografata
|
||||
|
||||
## Comandi SMTP
|
||||
|
||||
SMTP è un protocollo basato su comandi e codici di risposta, similmente a HTTP. Utilizza vari comandi per gestire l'invio delle email e fornisce codici di stato come feedback per indicare il risultato delle operazioni.
|
||||
|
||||
- `HELP`: quando un client invia questo comando, il server risponde fornendo un elenco dei comandi supportati
|
||||
- `HELO`: inviato dal client per l'autoidentificazione. Questo comando è solitamente accompagnato da un indirizzo email o nome di dominio che identifica il mittente
|
||||
- `MAIL FROM`: seguito da un indirizzo email, questo comando identifica l'effettivo mittente del messaggio
|
||||
- `RCPT TO`: utilizzato per specificare uno o più indirizzi email che rappresentano i destinatari del messaggio
|
||||
- `DATA`: questo comando indica al server che il client è pronto a inviare il corpo del messaggio. Il server risponde con il codice 354, `Enter message, ending with '.' on a line by itself`. Questo significa che il client può inviare il messaggio e che il server considererà la trasmissione terminata quando riceverà un punto su una riga da solo
|
||||
- `QUIT`: inviato dal client per terminare la comunicazione con il server. Il server risponde con il codice 221, confermando la chiusura della connessione
|
||||
- `AUTH LOGIN`: comando utilizzato dal client per l'autenticazione sul server SMTP. Se l'autenticazione ha successo, il server risponde con il codice 235, indicando *Authentication successful*
|
||||
|
||||

|
||||
|
||||
## Codici di risposta SMTP
|
||||
|
||||
I codici di risposta SMTP sono suddivisi in cinque categorie principali:
|
||||
|
||||
- `1XX`: *risposte informative*. Sono molto rari e non vengono utilizzati frequentemente
|
||||
- `2XX`: *comando eseguito con successo*. Alcuni esempi comuni includono:
|
||||
- `250`: comando eseguito con successo
|
||||
- `235`: autenticazione riuscita
|
||||
- `221`: il server sta chiudendo la connessione
|
||||
- `3XX`: questi codici indicano che *il server richiede ulteriori informazioni* al client per completare la richiesta. Ad esempio:
|
||||
- `334`: il server chiede le credenziali per l'autenticazione
|
||||
- `354`: il server è pronto a ricevere i dati della mail (comando DATA)
|
||||
- `4XX`: *errori temporanei*, che possono essere risolti con un nuovo tentativo. Alcuni esempi includono:
|
||||
- `421`: il server chiude la connessione per sovraccarico o manutenzione
|
||||
- `450`: la casella di posta del destinatario non è disponibile
|
||||
- `451`: errore del server
|
||||
- `452`: troppe mail inviate in poco tempo
|
||||
- `5XX`: *errori permanenti*.
|
||||
- `500`: errore di sintassi di un comando smtp
|
||||
- `501`: parametri errati
|
||||
- `503`: sequenza di comandi errata
|
||||
- `504`: comando non supportato dal server
|
||||
- `550`: indirizzo email del destinatario inesistente
|
||||
- `552`: casella del destinatario piena
|
||||
- `554`: il server rifiuta il messaggio, classificandolo come spam o phishing
|
||||
|
||||
## MIME
|
||||
|
||||
`MIME`, acronimo di *Multipurpose Internet Mail Extensions*, è uno standard che amplia le funzionalità del protocollo SMTP, permettendo l'invio di contenuti più complessi via email. Supporta caratteri non ASCII, inclusi caratteri accentati e simboli di diverse lingue. Inoltre, consente di allegare file di vari tipi, come immagini, audio, video e documenti, e di inviare email in formato HTML.
|
18
networking/031-pop3.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Protocolli per il ritiro delle email
|
||||
|
||||
Esistono due protocolli principali per il ritiro delle email: `POP3` e `IMAP4`. POP3 è un protocollo più semplice e datato, mentre IMAP4 offre funzionalità avanzate.
|
||||
|
||||
## POP3
|
||||
|
||||
POP3 (*Post Office Protocol*) è un protocollo di tipo *pull* utilizzato per scaricare le email sul client in locale.
|
||||
|
||||
A differenza dei protocolli moderni che usano la sincronizzazione bidirezionale, POP3 supporta solo la sincronizzazione unidirezionale della posta elettronica, consentendo agli utenti solo di scaricare messaggi di posta elettronica da un server a un client.
|
||||
|
||||
I messaggi di posta elettronica, per essere letti, devono essere **scaricati in locale** (questa è una notevole differenza rispetto all'IMAP), anche se è possibile lasciarne una copia sull'host. In pratica, il client, attraverso un account configurato POP, accede al server remoto e salva in locale i messaggi (definitivamente e non, come fa il protocollo IMAP, in una sorta di cache).
|
||||
|
||||
Utilizza la porta standard *110* e si basa su TCP. Di default, POP3 non è cifrato, ma esiste una versione sicura che utilizza TLS sulla porta *995*.
|
||||
|
||||
- Il MUA si connette e si autentica al server POP
|
||||
- Il MUA recupera e scarica le email in locale
|
||||
- Il client può scegliere di eliminare le email dal server (opzionale)
|
||||
- La connessione viene chiusa dal MUUA
|
10
networking/032-imap4.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# IMAP4
|
||||
|
||||
`IMAP4` (*Internet Message Access Protocol*) è un protocollo di ricezione/pull delle email che utilizza il TCP. Opera sulla porta *143* per le connessioni non crittografate e sulla porta *993* per quelle crittografate tramite certificati SSL/TLS.
|
||||
|
||||
A differenza di POP3, IMAP4 è più recente e offre funzionalità avanzate:
|
||||
|
||||
- **Lavoro offline**: consente di accedere alle email anche senza connessione, sincronizzando le modifiche al suo ripristino
|
||||
- **Supporto multi-utente**: permette connessioni simultanee alla medesima mailbox. Tutte le modifiche apportate alla cassetta postale verranno sincronizzate su più dispositivi e i messaggi verranno rimossi dal server solo se l'utente elimina la posta elettronica
|
||||
- **Ricerca avanzata**: offre la possibilità di cercare email in base a criteri specifici, come oggetto, mittente e destinatario, ecc.
|
||||
- **Personalizzazione**: consente di creare cartelle, impostare filtri e organizzare le email in modo flessibile
|
36
networking/033-ftp.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# File Transfer Protocol
|
||||
|
||||
Il *File Transfer Protocol* (`FTP`) è un protocollo che consente il trasferimento di file da una sorgente A a una sorgente B. A livello di trasporto, utilizza il TCP.
|
||||
|
||||
Di base, FTP non prevede crittografia, e per questo motivo il suo utilizzo è sconsigliato in contesti in cui la sicurezza è fondamentale. Il protocollo si basa su due canali di comunicazione:
|
||||
|
||||
- *Canale di controllo*: questo canale è specializzato nell'invio di comandi e risposte. La connessione stabilita per questo canale è persistente e rimane attiva per tutta la durata della comunicazione tra i due host. Si tratta di una classica connessione client/server, basata su TCP, che utilizza la *well-known port 21* per il server
|
||||
- *Canale dati*: questo canale è dedicato esclusivamente al trasferimento dei file. A differenza del canale di controllo, non è persistente; per ogni file trasferito viene creata una nuova connessione. Anche questo canale è basato su TCP e può essere stabilito in due modalità:
|
||||
- *Modalità passiva*: in questa modalità, il server FTP riceve passivamente una connessione da parte del client. Il client richiede l'attivazione della modalità passiva per il canale dati utilizzando i comandi `PASV` o `EPSV`. Il server, a questo punto, apre una porta di un numero maggiore di 1023 e comunica al client, tramite il canale di controllo, l'indirizzo di questa porta
|
||||
- *Modalità attiva*: in questa modalità, il server FTP si connette attivamente al client. Il client utilizza i comandi `PORT` o `EPRT`, specificando una porta X che ha aperto appositamente. Attraverso questi comandi, il client informa il server, tramite il canale di controllo, che esiste una porta alla quale il server deve connettersi attivamente. In questo caso, il server utilizza la *well-known port 20*
|
||||
|
||||
## Funzionalità del Server FTP
|
||||
|
||||
Un server FTP offre diverse funzionalità utili per la gestione dei file:
|
||||
|
||||
- Download e upload di file
|
||||
- Ripresa di trasferimenti interrotti
|
||||
- Rimozione o rinomina di file
|
||||
- Creazione di directory
|
||||
- Navigazione tra directory
|
||||
|
||||
## Autenticazione FTP
|
||||
|
||||
Un client FTP accede a un server FTP attraverso un processo di autenticazione.
|
||||
|
||||
- *Autenticazione classica*: molti server FTP utilizzano un sistema di autenticazione basato su credenziali, richiedendo agli utenti di inserire un nome utente e una password.
|
||||
- *Server FTP pubblici*: alcuni server FTP sono configurati come archivi pubblici e non richiedono un vero meccanismo di autenticazione
|
||||
|
||||
## Versioni di FTP
|
||||
|
||||
Esistono diverse versioni del protocollo FTP:
|
||||
|
||||
- `FTP` (File Transfer Protocol): utilizza TCP senza crittografia. Opera sulla porta 21 per il canale di controllo e sulla porta 20 per il canale dati in modalità attiva. È la versione standard
|
||||
- `SFTP` (SSH File Transfer Protocol): Si tratta di FTP over SSH. Utilizza TCP e offre crittografia, operando sulla porta 22.
|
||||
- `FTPS` (FTP Secure): aggiunge crittografia al protocollo FTP attraverso l'uso di certificati SSL/TLS. Utilizza la porta 990
|
||||
- `TFTP` (Trivial File Transfer Protocol): una versione semplificata e primordiale dell'FTP. Utilizza UDP e opera sulla porta 69. TFTP non prevede autenticazione né crittografia
|
19
networking/034-telnet.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Protocolli di accesso remoto
|
||||
|
||||
I protocolli di accesso remoto rappresentano una categoria di protocolli appartenenti al livello applicativo, progettati per consentire l'accesso a sistemi remoti. A differenza di protocolli specifici, come HTTP, il cui scopo principale è il trasporto di pagine web, i protocolli di accesso remoto non sono limitati a un utilizzo verticale o a un'applicazione particolare. Essi offrono la possibilità di interagire con sistemi remoti, consentendo agli utenti di eseguire comandi e ricevere risposte, come se stessero operando fisicamente sul dispositivo stesso.
|
||||
|
||||
## Telnet
|
||||
|
||||
Telnet è un protocollo di accesso remoto che opera a livello di trasporto utilizzando il protocollo TCP, ed è associato alla *well-known port 23*. La sua architettura è basata sul modello client-server. Supporta anche l'autenticazione mediante username/password.
|
||||
|
||||
Il comando utilizzato dal client per connettersi al server è:
|
||||
|
||||
```txt
|
||||
telnet [ip\hostname] [port]
|
||||
|
||||
telnet mail.server.com 25
|
||||
```
|
||||
|
||||
Sebbene la porta predefinita sia la 23, non vi è alcun divieto nell'utilizzare Telnet per collegarsi ad altre porte, come ad esempio la 25. In passato, Telnet è stato utilizzato anche per connettersi a switch e router al fine di effettuare configurazioni.
|
||||
|
||||
Tuttavia, uno dei principali difetti di Telnet è la mancanza di crittografia. Tutti i dati trasmessi attraverso questo protocollo viaggiano in chiaro, rendendoli vulnerabili a intercettazioni e attacchi.
|
76
networking/035-ssh.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# SSH
|
||||
|
||||
`SSH`, acronimo di *Secure Shell*, è un protocollo dell'Application layer che consente l'accesso remoto sicuro a host remoti.
|
||||
|
||||
## Caratteristiche principali
|
||||
|
||||
- SSH *utilizza la crittografia* per proteggere le comunicazioni tra il client e il server
|
||||
- Si basa su TCP ed è associato alla *well-known port 22*
|
||||
- Supporta diversi metodi di autenticazione, tra cui:
|
||||
- Username/password
|
||||
- Chiave pubblica
|
||||
|
||||
## Architettura SSH
|
||||
|
||||
SSH è un protocollo dell'application layer, ma la sua architettura è strutturata in moduli distinti che operano tra l'Application layer e il Transport layer.
|
||||
|
||||
### Connection Layer Protocol
|
||||
|
||||
Questo modulo gestisce le sessioni e la comunicazione client/server all'interno della connessione SSH. Sfrutta il protocollo SSH per implementare diverse funzionalità, come SFTP (Secure File Transfer Protocol), tunneling SSH ecc.
|
||||
|
||||
### User Authentication Protocol
|
||||
|
||||
Questo modulo si occupa dell'**autenticazione degli utenti**, implementando diversi metodi:
|
||||
|
||||
- Autenticazione classica con **username/password**
|
||||
- Autenticazione tramite **chiave pubblica**: lato client, viene sempre utilizzata la crittografia asimmetrica. Il client genera una coppia di chiavi (pubblica e privata) e memorizza la chiave pubblica nel file `.ssh/authorized_keys` del server. Durante il processo di autenticazione, il server crea un messaggio randomico, cifrato con la chiave pubblica del client, e lo invia a quest'ultimo. Solo il client, utilizzando la sua chiave privata, putrá decifrare il messaggio. Se il messaggio decifrato corrisponde a quello inviato, il server può confermare l'identità del client, a meno che la chiave privata non sia stata compromessa
|
||||
|
||||
### Transport Layer Protocol
|
||||
|
||||
Questo modulo è specifico di SSH e non deve essere confuso con il Transport layer del modello ISO/OSI. È un insieme di standard e procedure finalizzate a stabilire un canale di comunicazione cifrato. Le sue principali funzionalità includono:
|
||||
|
||||
- **Autenticazione del server**: il server verifica la propria identità mediante crittografia asimmetrica. Genera una coppia di chiavi, fornendo la chiave pubblica ai client che desiderano connettersi. La chiave privata rimane sul server e viene utilizzata per autenticarlo. Durante lo scambio delle chiavi, il server invia un messaggio randomico, firmato con la chiave privata, al client. Il client utilizza la chiave pubblica per decifrare il messaggio, confermando così l'identità del server. Questo processo protegge il client da attacchi man-in-the-middle, anche se non offre una garanzia assoluta, poiché le chiavi potrebbero essere state rigenerate o il server manomesso.
|
||||
- **Scambio dei messaggi**: viene utilizzata la crittografia simmetrica a chiave singola per lo scambio dei messaggi, in quanto meno onerosa dal punto di vista computazionale
|
||||
- **Cifratura**: SSH supporta vari algoritmi di cifratura
|
||||
- **Compressione**: Vengono utilizzati algoritmi di compressione per ottimizzare lo scambio dei dati
|
||||
- **Integrità dei pacchetti**: SSH implementa meccanismi per garantire che i pacchetti di dati non vengano alterati durante la trasmissione
|
||||
|
||||
## File di Configurazione SSH
|
||||
|
||||
Tutti i client si connettono a un server remoto utilizzando il protocollo SSH tramite il programma `ssh`. Il processo sul server che gestisce le richieste dei client è `sshd` (*Secure Shell Daemon*).
|
||||
|
||||
Il file di configurazione per il `server` SSH si trova in `/etc/ssh/sshd_config`, mentre il file di configurazione per i client SSH è situato in `/etc/ssh/ssh_config`.
|
||||
|
||||
I permessi consigliati per garantire la sicurezza delle chiavi SSH e delle configurazioni associate sono i seguenti:
|
||||
|
||||
- `.ssh`: 700
|
||||
- `authorized_keys`: 600
|
||||
|
||||
### Servizio SSH
|
||||
|
||||
Per controllare lo stato del servizio SSH, avviare o fermare il daemon, utilizzare i seguenti comandi:
|
||||
|
||||
```bash
|
||||
systemctl status ssh.service # Verifica lo stato del servizio SSH
|
||||
systemctl start ssh.service # Avvia il servizio SSH
|
||||
systemctl stop ssh.service # Ferma il servizio SSH
|
||||
```
|
||||
|
||||
## Creazione e gestione di chiavi SSH
|
||||
|
||||
Le chiavi generate lato server e utilizzate nel processo di validazione dell'identità si trovano nella directory `/etc/ssh` del server. In particolare:
|
||||
|
||||
```bash
|
||||
> ll /etc/ssh/
|
||||
Permissions Size User Group Date Modified Name
|
||||
.rw------- 505 root root 4 Jan 15:46 ssh_host_ecdsa_key
|
||||
.rw-r--r-- 173 root root 4 Jan 15:46 ssh_host_ecdsa_key.pub
|
||||
.rw------- 399 root root 4 Jan 15:46 ssh_host_ed25519_key
|
||||
.rw-r--r-- 93 root root 4 Jan 15:46 ssh_host_ed25519_key.pub
|
||||
.rw------- 2.6k root root 4 Jan 15:46 ssh_host_rsa_key
|
||||
.rw-r--r-- 565 root root 4 Jan 15:46 ssh_host_rsa_key.pub
|
||||
```
|
||||
|
||||
Quando un client si connette per la prima volta a un server tramite SSH, poiché non ha ancora chiavi associate a questo target nel file `known_hosts`, situato nella directory `~/.ssh`, viene richiesto di accettare e memorizzare il fingerprint, che corrisponde alle chiavi pubbliche del server.
|
||||
|
||||
Per ulteriori informazioni sulla creazione e gestione delle chiavi lato client, riferirsi all'articolo [Creazione e gestione di chiavi SSH](https://www.novemila.org/posts/2024-07-06-ssh/).
|
BIN
networking/asset/img/cavo-coassiale.png
Normal file
After Width: | Height: | Size: 156 KiB |
BIN
networking/asset/img/digital-signature.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
networking/asset/img/dns-hierarchy.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
networking/asset/img/dns-response-example.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
networking/asset/img/doppino-rame.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
networking/asset/img/email-flow.png
Normal file
After Width: | Height: | Size: 151 KiB |
BIN
networking/asset/img/fiber-cable.png
Normal file
After Width: | Height: | Size: 239 KiB |
BIN
networking/asset/img/fiber-optic-connectors.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
networking/asset/img/fttc-ftth.png
Normal file
After Width: | Height: | Size: 148 KiB |
BIN
networking/asset/img/ntp-package.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
networking/asset/img/ntp-stratum.png
Normal file
After Width: | Height: | Size: 392 KiB |
BIN
networking/asset/img/osi-parallel.png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
networking/asset/img/osi-protocol.png
Normal file
After Width: | Height: | Size: 542 KiB |
BIN
networking/asset/img/router-switch.png
Normal file
After Width: | Height: | Size: 229 KiB |
BIN
networking/asset/img/smtp-commands.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
networking/asset/img/symmetric-asymmetric-cryptography.png
Normal file
After Width: | Height: | Size: 218 KiB |
BIN
networking/asset/img/tls-handshake.png
Normal file
After Width: | Height: | Size: 94 KiB |