Quando più utenti devono collaborare su un progetto in un ambiente Linux, nasce l’esigenza di gestire correttamente i permessi su file e directory. Per evitare che i file creati da un singolo utente assumano come owner e group il suo gruppo primario, possiamo sfruttare il bit SGID (Set Group ID) sulle directory condivise.
In questo articolo vedremo come impostare il bit SGID solo sulle directory — perché è pensato esclusivamente per gestire l’ereditarietà del gruppo —, così da semplificare la collaborazione in una struttura come /var/www/html.
Il problema
Supponiamo che un utente (es. user1) carichi o modifichi file via FTP nella directory /var/www/html. Di default, ogni file nuovo assume come proprietario user1 e come gruppo il gruppo primario di user1 (es. user1 stesso). Se vogliamo che il gruppo di questi file sia invece www-data (tipico in ambiente web), dobbiamo configurare correttamente i permessi e impostare il bit SGID sulle directory.
Obiettivi
Far sì che tutte le directory sotto /var/www/html abbiano il gruppo www-data e il bit SGID attivo, in modo che qualsiasi file creato o caricato al loro interno eredi automaticamente il gruppo www-data.
Applicare permessi ragionevoli per directory (2775) e file (0644), così da garantire che i membri del gruppo www-data possano interagire correttamente con il contenuto, mantenendo un livello di sicurezza adeguato.
Verificare che tutti i file e le directory appartengano effettivamente al gruppo www-data.
Passo 1: Assegnare proprietà e gruppo a /var/www/html
Per prima cosa, se non l’hai già fatto, assegna ricorsivamente owner e gruppo www-data:www-data a /var/www/html:
1
sudochown -R www-data:www-data /var/www/html
Questo fa sì che l’utente e il gruppo su tutti i file e directory all’interno di /var/www/html siano ora www-data:www-data.
Passo 2: Impostare i permessi sui file e sulle directory
Distinguiamo due situazioni: directory e file.
Directory: vogliamo che abbiano i permessi 2775 (rwxrwsr-x).
Il “2” all’inizio indica il bit SGID, così che tutti i nuovi file/dir ereditino il gruppo della cartella madre (in questo caso, www-data).
“775” permette al proprietario (www-data) e al gruppo di leggere, scrivere ed entrare nella directory; gli “altri” possono solo leggere ed entrare (r-x).
File: vogliamo che abbiano i permessi 0644 (rw-r--r--).
In questo modo, il proprietario e il gruppo possono leggere e scrivere, mentre gli altri possono solo leggere (nessuna esecuzione di default).
Per applicare questi permessi ricorsivamente:
1 2 3 4 5
# Imposta 2775 su tutte le directory sudo find /var/www/html -type d -execchmod 2775 {} \;
# Imposta 0644 su tutti i file sudo find /var/www/html -type f -execchmod 0644 {} \;
In questo modo, ogni directory avrà: rwxrwsr-x www-data www-data (2775), mentre ogni file avrà: rw-r--r-- www-data www-data (0644).
Passo 3: Verificare che il bit SGID sia applicato solo alle directory
Il bit SGID va usato solo sulle directory, non sui file. Se vuoi controllare che nelle directory sia attivo, puoi eseguire:
1
ls -ld /var/www/html
Vedrai un output simile:
1
drwxrwsr-x 5 www-data www-data 4096 Jan 22 12:34 /var/www/html
dove la presenza di s nella sezione dei permessi del gruppo (rws) indica che la directory ha il bit SGID attivo.
Se accidentalmente hai applicato SGID anche ai file, puoi rimuoverlo dai soli file con:
1
sudo find /var/www/html -type f -execchmod g-s {} \;
Passo 4: Verificare l’appartenenza al gruppo www-data
Infine, se vuoi controllare che tutti i file e le directory appartengano al gruppo www-data (e segnalare se qualcosa non va), puoi usare un comando find dedicato:
Se non viene stampato nulla, significa che tutti gli elementi presenti in /var/www/html hanno già il gruppo www-data.
Conclusioni
Configurare correttamente i permessi e il bit SGID in /var/www/html è fondamentale per gestire un ambiente di sviluppo o produzione in cui più utenti collaborano sui file. Impostando i permessi 2775 sulle directory e 0644 sui file, e assicurandoti che il bit SGID sia attivo solo sulle directory, potrai lavorare in modo coerente e ordinato, senza dover correggere manualmente le impostazioni di proprietà ogni volta che vengono caricati nuovi file.
Le password sono la prima linea di difesa per proteggere dati, account personali e risorse sensibili. Tuttavia, creare e ricordare password sufficientemente forti non è sempre semplice: è diffusa la cattiva abitudine di riutilizzare la stessa password per più servizi, oppure di crearne una troppo semplice e prevedibile.
Inoltre, quando si tratta di condividere queste credenziali con un collega, un collaboratore o un familiare, spesso vengono utilizzati canali non sicuri come email non cifrate o messaggistica istantanea. Questo tipo di condivisione espone a notevoli rischi, poiché chi intercetta il messaggio potrà potenzialmente utilizzare quella password. Per mitigare questi problemi, esistono strumenti online che semplificano sia la creazione di password complesse sia la loro condivisione in modo sicuro e temporaneo.
Generatore di Password: Caratteristiche e Utilizzo
Il primo strumento è un generatore di password disponibile su GitHub Pages. Questo servizio permette di creare password casuali di diversa complessità. L’utente può personalizzare i parametri in base alle proprie necessità: lunghezza, utilizzo di caratteri speciali, maiuscole, minuscole e numeri.
Accesso allo Strumento: Il generatore è disponibile qui: https://geegeek.github.io/password/index.html Una volta aperta la pagina, è possibile selezionare i parametri desiderati (ad esempio, una lunghezza compresa tra 12 e 16 caratteri, includendo numeri e simboli) e generare una password complessa.
Esempio di Generazione: Supponiamo di voler creare una password robusta di 16 caratteri, contenente lettere maiuscole, minuscole, numeri e simboli. Lo strumento restituirà una stringa casuale, ad esempio:
XyZ!9mLpQ3r#1BdT
Questa password, lunga e complessa, non è facile da indovinare e rappresenta un buon punto di partenza per garantire un livello di sicurezza medio.
One-Time Password Link: Condivisione Sicura e Temporanea
Il secondo strumento consente di condividere in modo sicuro la password generata, creando un link monouso attraverso cui il destinatario potrà visualizzare la password una sola volta. Questo meccanismo riduce la probabilità che la password resti esposta a lungo in chiaro su un canale di comunicazione insicuro.
Funzionamento: Una volta ottenuta la password dal generatore, è possibile trasferirla allo strumento 1timepassword, che creerà un link univoco. Chi riceve questo link potrà visualizzare la password una sola volta; dopodiché, il link non sarà più valido. In questo modo si riducono notevolmente i rischi legati alla condivisione diretta del testo.
Vantaggi della Condivisione Monouso:
Evita di scrivere la password in chiaro su un canale di comunicazione.
La password non rimane disponibile online a lungo.
Una volta visualizzata, il link si “autodistrugge”, minimizzando l’esposizione.
Integrazione tra i due Strumenti
Una delle caratteristiche più interessanti di questi due servizi è la possibilità di integrarli tra loro. Il flusso può essere riassunto così:
L’utente genera una password complessa con il primo strumento.
La password viene automaticamente passata allo strumento one-time password.
Si genera un link monouso, che l’utente può inviare al destinatario.
Questo processo semplifica notevolmente la fase di condivisione. Non si deve copiare e incollare manualmente la password, riducendo errori e garantendo un flusso più lineare.
Condividere il link con il destinatario in modo sicuro.
Benefici dell’Integrazione:
Facilità d’uso: non serve copiare e incollare.
Riduzione degli errori: la password passa direttamente dall’uno all’altro strumento.
Maggiore sicurezza: il link monouso limita l’esposizione della password.
Aspetti Tecnici e Codice di Base
Entrambi gli strumenti sono hostati su GitHub Pages, una soluzione semplice per pubblicare siti statici. Le pagine si basano su HTML, CSS e JavaScript. Il codice di integrazione può essere facilmente analizzato e modificato a seconda delle esigenze.
Struttura dei File: In genere, si hanno file HTML per la struttura della pagina, CSS per il layout e JS per la logica di generazione e passaggio delle password. Uno schema generico potrebbe essere:
index.html ├── style.css └── script.js
Esempio di Integrazione del Codice: Nella pagina del generatore di password (index.html) potrebbe esserci un codice JavaScript che, una volta generata la password, effettua un redirect o invoca un endpoint della pagina del one-time password.
Ad esempio:
// Generazione della password const password = generatePassword({ length: 16, symbols: true, numbers: true }); // Invio la password allo strumento one-time attraverso un parametro GET const oneTimeUrl = “https://geegeek.github.io/password/1timepassword/index.html?pwd=“ + encodeURIComponent(password); console.log(“Visita questo link per la password monouso:”, oneTimeUrl);
Questa è una semplice illustrazione. In pratica, il codice effettivo potrebbe essere più complesso.
Configurazioni di Base Consigliate:
Lunghezza della password: almeno 12 caratteri.
Caratteri inclusi: lettere minuscole, maiuscole, numeri e simboli.
HTTPS obbligatorio: assicurarsi che la condivisione del link avvenga sempre tramite protocollo HTTPS.
Aggiornamenti periodici: mantenere il codice aggiornato per includere eventuali fix di sicurezza.
Buone Pratiche di Sicurezza
L’impiego di strumenti come questi non elimina la necessità di attenersi a buone pratiche di sicurezza:
Non riutilizzare le password: Non utilizzare la stessa password per più account.
Cambiare periodicamente le password: Aggiornare le credenziali ogni tre-sei mesi.
Utilizzare password manager riconosciuti: Se necessario, impiegare un password manager affidabile.
Verificare la provenienza dei link: Non cliccare su link sospetti. Il link monouso per la password deve provenire da una fonte fidata.
Conclusioni e Sviluppi Futuri
Gli strumenti presentati offrono una soluzione semplice per migliorare la sicurezza nella creazione e condivisione delle password. La combinazione tra un generatore affidabile e un servizio di link monouso riduce al minimo i rischi legati alla divulgazione non autorizzata delle credenziali.
Guardando al futuro, sarebbe possibile integrare ulteriormente queste funzionalità con API di messaggistica sicura o aggiungere restrizioni temporali più raffinate (ad esempio, il link è valido per un numero limitato di minuti).
In conclusione, l’approccio è semplice, non richiede particolari competenze tecniche e può migliorare la vita di chiunque debba gestire e condividere password in modo più sicuro e consapevole.
NOTA BENE: Pur essendo un metodo pratico e immediato per condividere informazioni sensibili senza l’ausilio di infrastrutture complesse, è importante considerare attentamente le implicazioni di sicurezza e le limitazioni di questo approccio, tenendo presente che – anche se crittografata – la password viene comunque trasmessa nell’URL, con i relativi rischi.
Quando lo spazio su disco inizia a ridursi, diventa importante individuare quali directory o file consumano grandi quantità di spazio di archiviazione. Disporre dei giusti comandi da riga di comando è essenziale per una manutenzione quotidiana del proprio HomeLab, permettendo di affrontare con calma ed efficienza situazioni potenzialmente critiche.
In questo articolo vedremo alcuni comandi utili per analizzare lo spazio su disco su sistemi Linux. Verranno illustrate anche alcune strategie per liberare spazio, mantenendo un livello di sicurezza medio-alto e operando in modo ragionevole. Nessuna pratica eccessivamente rischiosa verrà proposta, e suggeriremo sempre di operare con la massima cautela.
Panoramica sullo spazio su disco
Prima di tutto, è utile avere una panoramica generale dell’utilizzo delle partizioni:
1
df -h
L’opzione -h (human-readable) converte i valori in unità facilmente leggibili (KB, MB, GB). Da questo output, potrai vedere subito se una partizione è vicina al limite della sua capacità.
Identificare le directory più grandi
Quando individui una partizione critica (ad esempio /opt/NOME_DIRECTORY), puoi analizzare la struttura delle directory al suo interno:
1
du -h /opt/NOME_DIRECTORY --max-depth=1 2>/dev/null | sort -hr | head -n 10
du -h: mostra la dimensione delle directory in modo leggibile
--max-depth=1: limita la profondità dell’analisi a un solo livello
sort -hr: ordina i risultati dal più grande al più piccolo
head -n 10: mostra le prime 10 linee
L’opzione 2>/dev/null viene utilizzata per ignorare i messaggi di errore relativi a directory non accessibili, semplificando l’analisi dell’output. In alcuni contesti potresti ometterla, se preferisci vedere quali percorsi non possono essere letti.
Se individui una sottodirectory di grandi dimensioni, puoi approfondire ulteriormente nello stesso modo:
1
du -h /opt/NOME_DIRECTORY/GRANDE_CARTELLA_1 --max-depth=1 2>/dev/null | sort -hr | head -n 10
Queste analisi a imbuto ti consentono di scendere gradualmente fino ai singoli file più ingombranti.
Cercare file di grandi dimensioni
Se desideri individuare direttamente i file più pesanti, puoi utilizzare:
1
find / -type f -size +100M 2>/dev/null | head -n 20
find /: inizia la ricerca dalla radice
-type f: cerca solo file
-size +100M: limita la ricerca ai file maggiori di 100MB
2>/dev/null: sopprime i messaggi di errore su directory non accessibili
head -n 20: mostra solo i primi 20 risultati
In questo modo otterrai una rapida lista dei maggiori responsabili del consumo di spazio.
Strumenti interattivi: ncdu
Se puoi installare nuovi tool nel tuo HomeLab, ncdu è uno strumento interattivo molto utile:
1 2
apt update apt install ncdu
Una volta installato, puoi eseguirlo con:
1
ncdu /home/utente
ncdu fornisce un’interfaccia testuale per navigare tra le directory, visualizzarne le dimensioni e, se necessario, eliminare i file direttamente dall’interfaccia. Eccone simile esempio:
du -sh * nella directory corrente Mostra la dimensione di ogni directory e file nel percorso corrente, per una rapida panoramica.
lsof +aL1 /NOME_MONTAGGIO A volte lo spazio è occupato da file già cancellati ma ancora aperti da qualche processo. Questo comando mostra i file aperti con link count zero, evidenziando i casi in cui è sufficiente terminare il processo per liberare spazio.
df -i Se sospetti che non sia lo spazio ad esaurirsi, ma gli inode, df -i ti mostrerà quanti inode sono utilizzati. Gli inode sono strutture dati utilizzate per gestire informazioni sui file, come metadati, permessi e puntatori al contenuto; un eccesso di file molto piccoli può saturare il numero di inode disponibili.
Caso reale: avviso da un servizio di monitoraggio (Nagios)
Vediamo ora un esempio pratico di come questi comandi possano risultare utili, sia in un’infrastruttura aziendale complessa che in un semplice HomeLab. È una pratica diffusa configurare uno o più servizi di monitoraggio, come Nagios o Zabbix, per tenere sotto controllo lo stato delle macchine. Questi strumenti possono raccogliere dati in modi diversi:
Con agent: Il sistema monitorato esegue un software agente (come NRPE per Nagios o l’agente nativo di Zabbix) che invia periodicamente informazioni sullo stato delle risorse (utilizzo CPU, RAM, spazio disco, servizi attivi) al server di monitoraggio.
Senza agent (agentless): Il server di monitoraggio interroga direttamente i sistemi target usando protocolli standard come SNMP, WMI (per macchine Windows) o SSH. In questo caso non è necessario installare nulla sul sistema da controllare, riducendo così la complessità dell’infrastruttura.
Nel mio HomeLab, ad esempio, ho ricevuto un avviso da Nagios, che segnalava una situazione critica su un host generico (NOME_HOST). Ecco un esempio del messaggio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
***** Nagios Monitor XI Alert *****
Notification Type: PROBLEM
Service: Check linux disk usage Host: NOME_HOST Address: NOME_INDIRIZZO_IP State: CRITICAL
Date/Time: NOME_DATA_ORA
Additional Info:
CRITICAL. DISK STATS: / al 90%, /opt/NOME_DIRECTORY al 100%.
Questa notifica mi ha spinto a utilizzare i comandi sopra descritti, individuando con facilità i file e le directory più ingombranti. Ciò mi ha permesso di liberare spazio in modo mirato e sicuro, riducendo l’impatto sull’ambiente e prevenendo potenziali downtime.
In conclusione, utilizzare comandi come df, du, find, o tool interattivi come ncdu, ti permette di individuare rapidamente le aree problematiche del tuo spazio su disco, mantenendo un approccio umile, controllato e sicuro nel tempo. Queste pratiche diventano fondamentali per evitare situazioni di emergenza e mantenere il tuo HomeLab ottimizzato e funzionale.
In ambiente Linux/Unix, l’automazione di compiti ripetitivi e l’interazione non presidiata con programmi che richiedono input da tastiera sono attività frequenti. L’utilizzo di Expect offre una soluzione semplice e versatile: questo strumento consente di definire in anticipo le risposte a richieste interattive, evitando la necessità di sviluppare interi script in linguaggi più complessi come Python o PHP.
Garantire un buon livello di sicurezza nell’automazione è fondamentale. Gli esempi forniti di seguito mantengono un approccio prudente: utilizzeremo account non privilegiati o con le autorizzazioni minime necessarie, eviteremo l’uso diretto dell’utente root e ci assicureremo di non memorizzare password in chiaro su file non protetti. L’obiettivo è automatizzare task comuni in modo sicuro e affidabile.
Cosa è Expect?
Expect è un programma che permette di “dialogare” con altri programmi interattivi secondo uno script. In altre parole, con Expect si può:
Avviare un programma interattivo (come ssh o passwd)
Attendere determinate risposte, prompt o messaggi
Inviare input predefiniti in risposta a tali messaggi
Il linguaggio di scripting di Expect si basa su Tcl, un linguaggio interpretato, semplice ma potente, che fornisce strutture di controllo (if, for), definizione di procedure, manipolazione di stringhe e molto altro. Questa combinazione consente di creare script di automazione flessibili, capaci di gestire condizioni variabili e flussi logici complessi.
Quando e Perché Usare Expect?
Expect è utile in qualsiasi scenario in cui si necessiti di fornire risposte previste a input richiesti da un programma. Ad esempio:
Accesso remoto a sistemi via SSH senza dover inserire la password manualmente, utile quando si devono eseguire comandi su più server.
Gestione automatizzata delle password, ad esempio per aggiornare le credenziali di un account locale su più macchine.
Automazione di procedure interne a sistemi legacy o applicazioni non modernizzate.
Rispetto ad altre soluzioni come l’uso di librerie Python o di Ansible, Expect può risultare più semplice e immediato, specialmente per piccole automazioni quotidiane o integrazioni rapide all’interno di script Bash esistenti.
Installazione e Uso di Base
Prima di tutto, verificare che Expect sia installato:
1 2 3 4 5
which expect ``` Se non installato, utilizzare il gestore pacchetti della distribuzione per aggiungerlo. Ad esempio su Debian/Ubuntu: ```bash sudo apt-get update && sudo apt-get install expect
Per eseguire uno script Expect:
Creare il file con estensione .exp
Assicurarsi che abbia i permessi di esecuzione
Lanciare lo script con:
1
expect -f nome_script.exp
È anche possibile rendere lo script eseguibile e utilizzare il shebang:
1
#!/usr/bin/expect -f
In questo modo si potrà lanciare lo script direttamente, come un normale comando.
Per maggiori dettagli sulle opzioni, consultare la pagina man di Expect:
1
man expect
Esempio 1: Connessione SSH e Comando Remoto
Un caso tipico è l’accesso a un server remoto via SSH per eseguire un comando specifico. Immaginiamo di dover connetterci a un server senza inserire manualmente la password e lanciare un singolo comando remoto.
Prerequisiti di sicurezza:
Assicurarsi di utilizzare chiavi SSH protette da passphrase se possibile, oppure conservare la password in modo sicuro (ad esempio in un file con permessi limitati).
Non utilizzare l’utente root, ma un account non privilegiato.
Script di Esempio
Creare un file ssh_command.exp con il seguente contenuto:
Lo script effettuerà la connessione, inserirà la password per voi ed eseguirà il comando ls -l sul server remoto.
Esempio 2: Cambio Password Utente con Expect
Supponiamo di voler aggiornare la password di un account locale. L’uso di Expect consente di automatizzare questo processo senza inserire manualmente la password all’interno del prompt di passwd.
Nota di Sicurezza:
Non utilizzare l’utente root. Utilizzare un account con i permessi minimi sufficienti a modificare la password desiderata. In un contesto reale, valutare attentamente le autorizzazioni del proprio ambiente.
Evitare di lasciare password in chiaro su file non sicuri. Eventualmente usare variabili d’ambiente protette, o gestori di segreti sicuri.
Expect può essere facilmente integrato all’interno di script Bash più ampi. Ad esempio, potremmo avere uno script Bash che esegue aggiornamenti periodici su un server e successivamente richiama Expect per eseguire comandi remoti in modo automatizzato.
Esempio di snippet Bash che chiama lo script di connessione SSH:
1 2 3 4 5 6 7 8 9 10 11 12
#!/bin/bash
# Aggiornamenti o altre operazioni di contesto qui... # Variabili definite all’interno dello script Bash USERNAME="utente" PASSWORD="mypass" SERVER="server.example.com" PORT=22 COMMAND="uptime"
# Richiama lo script Expect ./ssh_command.exp "$USERNAME""$PASSWORD""$SERVER""$PORT""$COMMAND"
In questo modo è possibile combinare logica Bash, controllo di flussi, cicli e condizioni con la capacità interattiva di Expect.
Considerazioni Finali
Gli esempi presentati mostrano come Expect possa semplificare l’automazione di operazioni comuni:
Connettersi a un server remoto e dare comandi in autonomia.
Aggiornare la password di un utente locale senza interazioni manuali.
L’uso di Expect rimane flessibile: può essere applicato a numerosi altri scenari, dalla configurazione di dispositivi di rete all’interazione con applicazioni legacy. L’approccio basato su Tcl rende Expect potente e adattabile. È consigliabile esplorare la documentazione completa per scoprire funzionalità avanzate come la gestione dei timeout, l’uso di pattern più complessi e l’integrazione con altri strumenti.
Esempi aggiuntivi e progetti open source su GitHub e altri repository di script per l’automazione, dove potete trovare soluzioni reali e suggerimenti pratici.
In definitiva, l’obiettivo è mantenere un equilibrio tra automazione e sicurezza, adottando pratiche prudenziali come l’uso di account non privilegiati, la protezione delle credenziali e la verifica costante degli script prima di metterli in produzione.
Nel precedente articolo abbiamo esplorato come implementare una configurazione SSH modulare su un server Ubuntu/Debian, differenziando i metodi di accesso a seconda della provenienza (interna o esterna), degli utenti e dei metodi di autenticazione. Abbiamo separato la configurazione in file multipli all’interno di sshd_config.d, applicando politiche restrittive per l’accesso esterno e più permissive per la rete interna, oltre a integrare fail2ban, firewall (ufw) e il port forwarding su porte alte per aumentare la sicurezza.
In questo nuovo articolo ci concentreremo sull’automazione dello stesso identico approccio utilizzando Ansible, uno strumento di automazione dell’infrastruttura che ci consentirà di distribuire e mantenere le medesime configurazioni su uno o più server in modo semplice, ripetibile e privo di errori umani. L’uso di Ansible garantisce che le configurazioni siano idempotenti: eseguendo il playbook più volte otterremo sempre lo stato desiderato, senza dover ritoccare manualmente i file o rischiare inconsistenze.
Obiettivi principali:
Automatizzare l’installazione e configurazione di OpenSSH Server.
Gestire i file di configurazione (/etc/ssh/sshd_config e /etc/ssh/sshd_config.d/*.conf) tramite Ansible.
Impostare regole ufw e configurazione base di fail2ban.
Creare utenti, impostare chiavi SSH, differenziare l’accesso da interno ed esterno.
Integrare il port forwarding su porte alte e mostrare come questa configurazione rimane coerente nel tempo.
Mantenere la stessa logica del precedente articolo, ma ora tramite playbook Ansible.
Prerequisiti
Un controller Ansible (ad esempio un sistema locale con Ansible installato).
Connessione SSH al server o ai server bersaglio, con utente avente privilegi sudo.
Chiavi SSH già installate sul controller per l’utente amministrativo che si collegherà al target in modo da non dover usare password negli ansible-playbook.
Un server Ubuntu/Debian di destinazione, aggiornato e con un utente sudo.
Configurazione base di rete, con la possibilità di configurare il router per il port forwarding (come descritto nel precedente articolo).
Conoscenza base di Ansible e della struttura di un playbook.
Struttura del Progetto Ansible
Possiamo organizzare il nostro progetto con la seguente struttura:
Qui apriamo la 22 solo per la rete interna e per l’IP specificato per l’esterno. Questo riflette la logica precedente: da esterno accede solo un IP e uno specifico utente.
Abbiamo ignorato il range interno in modo che la LAN non venga bannata da tentativi multipli.
Esempio di tasks/users.yaml
Creiamo l’utente deploy e aggiungiamo la sua chiave pubblica. Presumiamo di avere una chiave pubblica pronta nel ruolo (in files/authorized_keys_deploy):
UsePAM yes PermitRootLogin no ChallengeResponseAuthentication no PasswordAuthentication yes PubkeyAuthentication yes Include /etc/ssh/sshd_config.d/*.conf
Template 00-internal.conf.j2
Consente da rete interna l’uso della password e delle chiavi a qualsiasi utente:
1 2 3
Match address {{ internal_network }} PasswordAuthentication yes PubkeyAuthentication yes
Template 01-external.conf.j2
Limitato all’utente deploy e all’indirizzo IP esterno, solo chiave:
1 2 3
Match User {{ external_user }}, Address {{ external_ip }} PasswordAuthentication no PubkeyAuthentication yes
Port Forwarding su Porta Alta (22222)
Dal lato del router, come nel precedente articolo, si configura il port forwarding della porta 22222 esterna verso la 22 interna del server. Ansible non può effettuare questa operazione sul router a meno di avere plugin specifici o un router programmabile (ad esempio via API). Presumiamo che questa modifica sia stata già fatta a mano sul router:
Dall’esterno: ssh -p 22222 deploy@mio_dominio Il router inoltra la 22222 → 22 del server interno.
Nella configurazione di Ansible non cambia nulla per sshd, rimane in ascolto sulla 22 interna. Il firewall filtra gli accessi, l’utente deploy può accedere solo dall’external_ip consentito con chiave, mentre la rete interna può accedere con password.
Se si volesse essere più coerenti, potremmo cambiare la Port in sshd_config.j2. Tuttavia, il port forwarding è una soluzione migliore, perché non richiede modifiche al demone SSH e non influisce sugli accessi LAN.
Eseguire il Playbook
Dopo aver preparato tutto:
1
ansible-playbook -i inventory.ini playbook.yaml
Se il vostro accesso SSH al server è pronto, Ansible applicherà in pochi secondi tutte le configurazioni descritte. Eseguite nuovamente il playbook in futuro per mantenere lo stato o dopo modifiche alle variabili: le configurazioni saranno sempre coerenti.
Possibili Estensioni e Conclusione
In questo articolo abbiamo replicato l’approccio modulare e differenziato dell’accesso SSH mediante la creazione e applicazione automatizzata di playbook Ansible. Questo consente di scalare la stessa configurazione su più server e di mantenere un controllo centralizzato, coerente e privo di rischi di errore umano.
Per ulteriori estensioni future, si potrebbero creare ruoli separati per la gestione delle chiavi SSH, per l’applicazione di policy di sicurezza più complesse, per l’integrazione con sistemi di gestione delle identità o per la distribuzione automatica di fail2ban con configurazioni personalizzate. Inoltre, si potrebbe integrare Ansible con strumenti CI/CD per testare automaticamente le configurazioni prima del deployment in produzione.
Con l’introduzione di Ansible, abbiamo compiuto un passo significativo verso l’automazione dell’infrastruttura e la riduzione del carico di lavoro amministrativo, garantendo un accesso SSH sicuro, modulare e facile da mantenere.
In questo articolo approfondiremo la configurazione di un server SSH su Ubuntu/Debian con un livello di sicurezza un po’ piu’ elevato. Non ci limiteremo alla semplice attivazione del servizio, ma esploreremo una strategia di configurazione modulare utilizzando la directory sshd_config.d. Questo approccio consente di creare differenti casistiche di accesso in base alla rete di provenienza, al metodo di autenticazione e all’utente che tenta di collegarsi. Inoltre, vedremo come:
Limitare gli accessi esterni a determinati utenti e chiavi pubbliche, filtrando per indirizzi IP di origine.
Permettere, da rete interna, l’accesso anche con password per tutti gli utenti.
Integrare firewall e fail2ban per mitigare i tentativi di accesso non autorizzati.
Esporre la porta SSH su una porta alta tramite port forwarding, aumentandone la sicurezza.
Preparare il terreno per automatizzare questi processi in futuro.
Assumeremo i seguenti prerequisiti:
Il server è basato su Ubuntu/Debian con sudo abilitato per l’utente di amministrazione.
OpenSSH Server è installato.
Un firewall (ad esempio ufw) è attivo e configurato.
Fail2ban è installato per prevenire i tentativi di brute-force.
Il server dispone di un IP interno (LAN) e di un IP pubblico (o di un router con port forwarding configurabile).
L’utente di amministrazione appartiene al gruppo sudo.
Perche’� adottare una configurazione modulare con sshd_config.d
Il file principale /etc/ssh/sshd_config definisce il comportamento globale del server SSH. Tuttavia, utilizzando la directory /etc/ssh/sshd_config.d, possiamo inserire file aggiuntivi che sovrascrivono o integrano la configurazione di base. Questo approccio modulare permette di mantenere il file principale pulito e di organizzare le diverse casistiche di accesso in file separati. È particolarmente utile quando si gestiscono scenari complessi e si ha necessità di apportare modifiche incrementali senza rischiare di compromettere l’intera configurazione.
Configurazione di base di OpenSSH
Installazione
Se non lo avete già fatto, procedete all’installazione:
1 2
sudo apt update sudo apt install openssh-server
Il servizio sshd sarà avviato e abilitato automaticamente.
Configurazione del firewall (UFW)
Assicuratevi che il firewall ufw sia installato e attivato:
1 2
sudo apt install ufw sudo ufw enable
Per consentire la connessione sulla porta SSH standard (22), eseguite:
1
sudo ufw allow 22/tcp
Successivamente, quando imposteremo un port forwarding su una porta differente, modificheremo le regole di conseguenza.
Configurazione di fail2ban
Fail2ban blocca gli indirizzi IP che tentano di eseguire accessi non autorizzati (brute-force). Se non presente:
1
sudo apt install fail2ban
Nella configurazione predefinita, fail2ban monitorerà il file di log di SSH e bloccherà automaticamente gli IP che generano troppi tentativi falliti. È possibile personalizzare /etc/fail2ban/jail.local per definire tempi di ban, numero di tentativi e altro. Un esempio basilare (da aggiungere o modificare in /etc/fail2ban/jail.local):
Modifichiamo /etc/ssh/sshd_config per disabilitare l’accesso root e alcune opzioni generali:
1 2 3 4 5 6 7
UsePAM yes PermitRootLogin no ChallengeResponseAuthentication no PasswordAuthentication yes # Abilitiamo qui la password come default, poi la limitiamo nei match esterni PubkeyAuthentication yes # Includiamo la directory di configurazione aggiuntiva Include /etc/ssh/sshd_config.d/*.conf
Salviamo e chiudiamo. Con Include /etc/ssh/sshd_config.d/*.conf abbiamo dato istruzioni a sshd di leggere file aggiuntivi nella directory sshd_config.d.
Creazione dei file di configurazione modulari
Creeremo due file all’interno di /etc/ssh/sshd_config.d:
Questa configurazione consente a chiunque si trovi all’interno della rete interna (es. 192.168.0.0/24) di autenticarsi con password:
1
sudo nano /etc/ssh/sshd_config.d/00-internal.conf
Inseriamo:
1 2 3 4
Match address 192.168.0.0/24 PasswordAuthentication yes PubkeyAuthentication yes # In questo scenario lasciamo qualsiasi utente della LAN entrare con password o chiave.
Per l’accesso esterno, supponiamo di avere un IP pubblico o di filtrare l’accesso tramite firewall. Ad esempio, immaginiamo che solo da un certo IP pubblico o da un range (ad esempio aa.bb.cc.dd) possa accedere l’utente deploy. Inoltre, vogliamo obbligare l’autenticazione solo tramite chiave.
1
sudo nano /etc/ssh/sshd_config.d/01-external.conf
Inseriamo:
1 2 3
Match User deploy, Address aa.bb.cc.dd PasswordAuthentication no PubkeyAuthentication yes
In questo modo, se la connessione proviene dall’indirizzo aa.bb.cc.dd e l’utente che tenta di accedere è deploy, la password non sarà accettata, ma solo la chiave pubblica. Nessun altro IP o utente potrà usufruire di queste impostazioni.
Riavviare il servizio SSH per applicare le modifiche
Dopo aver creato i file di configurazione, riavviamo SSH:
1
sudo systemctl restart ssh
Chiavi SSH
L’utente deploy che accede da remoto dovrà avere una coppia di chiavi. Sul client remoto, generiamo una chiave:
1
ssh-keygen -t ed25519 -C "deploy@example.com"
Copiare la chiave pubblica sul server (da remoto):
1
ssh-copy-id deploy@ip_o_dominio_del_server
Il comando ssh-copy-id aggiungerà la chiave a ~/.ssh/authorized_keys dell’utente deploy.
Configurazione del firewall per differenti casistiche
Poiché da esterno si deve accedere solo con chiave e da determinati IP, si puo’ò rafforzare il tutto tramite ufw, consentendo solo l’IP esterno specifico:
1
sudo ufw allow from aa.bb.cc.dd to any port 22
Se desiderate bloccare tutti gli altri tentativi di accesso esterni, assicuratevi di non eseguire un ufw allow 22/tcp generico, ma solo quello limitato all’IP sopra indicato. In caso foste costretti ad aprire a tutti l’accesso per qualche motivo, ricordate che fail2ban entra in azione per mitigare i tentativi di brute force.
Fail2ban e le due casistiche di accesso
Fail2ban non fa distinzioni tra accessi interni o esterni di default, ma grazie alla sua configurazione blocca gli IP che tentano numerosi accessi non autorizzati. Questo è utile specialmente per gli attacchi provenienti da Internet. Se notate che IP interni vengono bloccati, potete modificare la configurazione ignoreip in /etc/fail2ban/jail.local:
In questo modo gli IP interni non saranno bloccati, permettendo maggiore flessibilità nella LAN.
Dopo le modifiche:
1
sudo systemctl restart fail2ban
Spostare la porta SSH esterna su una porta alta con port forwarding
È una buona pratica non esporre la porta 22 direttamente su Internet. Si può configurare il router per effettuare un port forwarding da una porta alta (ad esempio 22222) verso la porta 22 del server.
Passi generali
Sul router/NAT: Accedete all’interfaccia di gestione del vostro router e individuate la sezione “Port Forwarding” o “Virtual Server”. Create una regola che inoltri la porta esterna 22222 (TCP) all’indirizzo IP interno del vostro server sulla porta 22.
Configurazione del firewall interno per la nuova porta:
Poiché la porta 22 rimane aperta internamente, nella rete LAN tutto rimane come prima. Dall’esterno, però, l’utente si collegherà a ssh -p 22222 deploy@mio_dominio (se avete un nome di dominio puntato sul vostro IP pubblico).
Se volete che il firewall accetti esplicitamente connessioni solo su 22 in LAN e non dall’esterno, potete chiudere la 22 dall’esterno e lasciare aperta solo tramite la regola del router:
1
sudo ufw deny 22/tcp
Ma questo bloccherebbe completamente SSH via 22 (anche internamente), quindi meglio gestire il firewall sul router o, se il server deve essere raggiungibile da LAN su 22, lasciare ufw allow 22/tcp ma consentire accesso esterno solo tramite l’IP specifico. Dipende dalla vostra topologia di rete. Se volete segmentare, potete usare regole UFW avanzate per differenziare l’accesso esterno/interno (ad esempio definendo allow from 192.168.0.0/24 to any port 22 per la LAN, e negare tutto il resto).
Collegamento esterno sulla porta alta
Da un host remoto:
1
ssh -p 22222 deploy@mio_dominio
La connessione arriverà al vostro router, che la inoltrerà alla porta 22 del server, passando le regole di sshd. Ricordate che l’utente deploy ha l’accesso da quell’IP autorizzato e soltanto con chiave.
Considerazioni finali e spunti per l’automazione
Abbiamo creato una configurazione modulare che differenzia gli accessi SSH sulla base della rete di provenienza, del metodo di autenticazione e dell’utente, utilizzando i file in sshd_config.d. Abbiamo integrato firewall, fail2ban e illustrato come effettuare un port forwarding per aumentare la sicurezza.
Questo approccio è solido, ma la sua gestione manuale puo’ò diventare complessa in ambienti di grandi dimensioni o con frequenti variazioni. Nel prossimo articolo potremmo esplorare meccanismi di automazione, utilizzando tool come Ansible, Puppet o Chef, per distribuire e mantenere queste configurazioni in maniera scalabile e ripetibile. L’automazione permetterebbe di applicare, testare e aggiornare queste configurazioni su un parco macchine esteso, riducendo il rischio di errori umani e semplificando il lavoro dell’amministratore di sistema.
Con questi spunti, si chiude questo lungo articolo, augurandoci che le informazioni fornite siano utili per implementare un accesso SSH sicuro, flessibile e ben organizzato.
Possibili Miglioramenti
Un ulteriore passo avanti verso una configurazione più robusta e scalabile potrebbe essere l’utilizzo di un reverse proxy posizionato davanti alla porta SSH esposta su Internet. In particolare, adottare un servizio come Cloudflare (gratuito nella fascia free per il traffico su porte HTTP/HTTPS, ma non per la porta SSH) consentirebbe di usufruire della loro rete globale di distribuzione, di strumenti di mitigazione avanzati contro attacchi DDoS, e di ulteriori livelli di filtraggio del traffico.
Tuttavia, questa configurazione introduce complessità aggiuntive: occorrerebbe consentire l’accesso solo agli indirizzi IP di Cloudflare, con una conseguente modifica delle regole firewall, una gestione più granulare delle liste di trusted IP e una combinazione di impostazioni su Cloudflare stesso.
Questa soluzione, pur più articolata, incrementa significativamente la resilienza del sistema e riduce l’esposizione diretta della vostra infrastruttura, rendendola meno vulnerabile alle minacce provenienti da Internet. Consideratela un’evoluzione del setup descritto in quest’articolo, una strada da intraprendere quando le esigenze di sicurezza e affidabilità diventano più stringenti.
Il comando ip su Linux è uno strumento estremamente versatile e potente per la gestione e la configurazione dei parametri di rete del sistema. Sostituisce gradualmente alcuni comandi più datati (come ifconfig, route, netstat) offrendo funzionalità più moderne e una sintassi coerente. Grazie a ip è possibile visualizzare, modificare e mantenere in efficienza la rete locale, le interfacce, i gateway e le rotte in modo sicuro, scalabile e senza ricorrere ad azioni rischiose.
In questo articolo esamineremo, in un ordine più coerente rispetto alla lista originale, come utilizzare il comando ip per coprire una serie di attività comuni in ambito di amministrazione di rete. Saranno illustrate le funzioni principali, la configurazione di base consigliata, alcune opzioni utili e le best practice per mantenere un livello di sicurezza medio-alto, senza ricorrere ad un accesso root diretto.
Perché usare il comando ip?
Il comando ip fa parte del pacchetto iproute2 e offre una sintassi modulare in cui le operazioni si esprimono come combinazioni di ip [oggetto] [comando] [parametri]. Gli oggetti principali sono link (le interfacce), addr (gli indirizzi IP), route (le rotte), neigh (gli ARP/neighbour), e così via.
Rispetto ad altri comandi datati, ip fornisce un output più chiaro, supporta funzionalità moderne (come tunnel e policy routing) e permette di integrare opzioni avanzate (es. gestione di MTU, queueing discipline, bridging, bonding).
Ordine logico delle operazioni con il comando ip
Di seguito una lista ordinata di 15 azioni comuni che si possono effettuare con il comando ip, riorganizzate in un ordine più coerente per un amministratore di sistema:
Individuare le interfacce di rete disponibili sul sistema Prima di qualsiasi operazione è fondamentale sapere quali interfacce siano presenti: Ethernet, Wi-Fi, loopback, virtuali ecc.
Consultare lo stato di una singola interfaccia IP Una volta individuata un’interfaccia, è utile controllarne stato, parametri e statistiche.
Configurare l’interfaccia di loopback, Ethernet e altre interfacce IP Il loopback e le interfacce fisiche o virtuali possono essere configurate con indirizzi IP, MTU, etichette, ecc.
Mettere un’interfaccia in stato attivo (up) o inattivo (down) Attivare o disattivare un’interfaccia senza rimuoverne la configurazione.
Modificare parametri aggiuntivi di un’interfaccia, ad esempio MTU o nome Non solo up/down, ma anche impostare l’MTU e, se supportato, rinominare l’interfaccia in modo coerente.
Assegnare, eliminare e configurare indirizzi IP, subnet e altre informazioni IP Aggiungere un indirizzo IP, rimuoverlo, configurare maschere di rete e gateway può essere fatto con pochi comandi.
Visualizzare e modificare l’elenco degli indirizzi IP e le loro proprietà Effettuare un inventario degli indirizzi configurati, controllare indirizzi multipli su una singola interfaccia, ecc.
Configurare e modificare rotte predefinite e statiche Impostare una route di default o aggiungere rotte statiche verso sottoreti specifiche.
Impostare o eliminare singole voci di routing Se necessario, aggiungere o rimuovere rotte individuali per un fine più granulare.
Verificare il percorso (traccia) che un indirizzo IP seguirà Controllare come i pacchetti raggiungono una destinazione, utile per diagnosticare problemi di rete.
Configurare tunnel su IP Creare e gestire tunnel IP (ad esempio GRE o IPIP) per connettere due reti remote attraverso un canale sicuro.
Gestire e visualizzare lo stato globale della rete Panoramica dello stato di tutte le interfacce e delle relative statistiche.
Raccogliere informazioni sugli indirizzi IP multicast Verificare quali gruppi multicast sono configurati sull’host.
Mostrare la cache ARP o NDISC Visualizzare i mapping tra indirizzi IP e MAC (ARP su IPv4) o NDISC (su IPv6).
Gestire gli oggetti neighbour: invalidare ARP cache, aggiungere entry ARP, ecc. Aggiungere manualmente voci ARP, rimuoverle o invalidarle per forzare la risoluzione dell’indirizzo in caso di problemi.
Comandi utili ed esempi di configurazione
Di seguito riportiamo alcuni esempi pratici, usando il comando ip. Nota: Evita di operare come root; utilizza invece sudo quando necessario. Prima di modificare configurazioni critiche di rete, sperimenta su macchine di test o sistemi non di produzione.
1. Individuare le interfacce disponibili
ip link show
### 2. Consultare lo stato di una singola interfaccia
```bash
ip link show dev eth0
Questo comando mostra lo stato di `eth0`, le sue proprietà e se è up o down.
### 3. Configurare l’interfaccia di loopback
L’interfaccia loopback `lo` è solitamente già configurata di default, ma per verificarne lo stato:
```bash
ip link set lo up
ip addr show dev lo
### 4. Attivare o disattivare un’interfaccia
```bash
sudo ip link set eth0 up
sudo ip link set eth0 down
### 5. Modificare parametri avanzati dell’interfaccia
Ad esempio, per modificare l’MTU:
```bash
sudo ip link set eth0 mtu 1400
### 6. Assegnare un indirizzo IP
```bash
sudo ip addr add 192.168.1.10/24 dev eth0
Per rimuoverlo:
```bash
sudo ip addr del 192.168.1.10/24 dev eth0
### 7. Visualizzare gli indirizzi IP configurati
```bash
ip addr show
### 8. Configurare una route di default
```bash
sudo ip route add default via 192.168.1.1 dev eth0
### 9. Eliminare una route
```bash
sudo ip route del 192.168.2.0/24 dev eth0
### 10. Verificare il percorso verso un host remoto
Questo non è un comando `ip` diretto, ma `ip route get` può fornire una traccia del percorso:
```bash
ip route get 8.8.8.8
### 11. Configurare un tunnel IP (esempio GRE)
```bash
sudo ip tunnel add gre1 mode gre remote 203.0.113.5 local 198.51.100.10 dev eth0
sudo ip link set gre1 up
sudo ip addr add 10.0.0.1/24 dev gre1
### 12. Stato globale della rete
```bash
ip -s link
Mostra statistiche di rete su tutte le interfacce.
### 13. Informazioni sugli indirizzi multicast
```bash
ip maddr show
### 14. Mostrare la cache ARP
```bash
ip neigh show
### 15. Gestire la ARP cache
Aggiungere una voce statica ARP:
```bash
sudo ip neigh add 192.168.1.50 lladdr 00:11:22:33:44:55 dev eth0 nud permanent
Rimuoverla:
```bash
sudo ip neigh del 192.168.1.50 dev eth0
## Configurazione di base consigliata
Una configurazione di rete di base consigliata potrebbe prevedere:
- Un’interfaccia Ethernet principale con IP statico e una route di default verso il gateway della LAN.
- Un indirizzo IP assegnato con il comando `ip addr add ...`.
- Una route di default impostata con `ip route add default via ...`.
- Niente accessi diretti come root: utilizzare sempre `sudo`.
- Mantenere l’MTU standard (1500) a meno di necessità specifiche.
- Verificare che la cache ARP non contenga entry obsolete e mantenere aggiornato l’elenco delle rotte.
Per rendere persistenti queste configurazioni, l’amministratore può utilizzare file di configurazione specifici della distribuzione (ad esempio `/etc/network/interfaces` su Debian/Ubuntu, o i file in `/etc/sysconfig/network-scripts/` su Red Hat/CentOS), riportando le stesse informazioni che abbiamo testato con `ip`.
## Conclusioni
Il comando **ip** mette a disposizione un set completo di strumenti per configurare, diagnosticare e mantenere in efficienza la rete di un host Linux. Prendere confidenza con le sue opzioni più importanti è un passo fondamentale per qualsiasi amministratore di sistema moderno. Aumentare la sicurezza e la stabilità della rete non richiede l’uso di pratiche rischiose, ma una buona comprensione degli strumenti a disposizione.
Con l’approccio presentato in questo articolo, è possibile migliorare la propria padronanza di `ip`, organizzare il lavoro in modo sistematico e mantenere un livello di sicurezza medio-alto anche nella gestione quotidiana del networking Linux.
SSH (Secure Shell) è uno strumento fondamentale per accedere in modo sicuro a un server remoto. In questa guida, condivido come ho configurato SSH su un server Ubuntu e come ho risolto alcuni errori che ho incontrato durante il processo.
Errori Riscontrati e Soluzioni
Ecco alcuni dei messaggi di errore che ritengo utili condividere durante la configurazione di SSH, insieme alle soluzioni applicate.
1. Autenticazione tramite chiave pubblica non funzionante
Messaggio di errore
1
Permission denied (publickey)
Causa Questo errore si verifica quando la chiave pubblica non è stata correttamente aggiunta al file authorized_keys sul server, oppure se i permessi dei file e delle directory coinvolte non sono conformi alle aspettative di sshd.
Soluzione
Verificare che la chiave pubblica dell’utente si trovi in ~/.ssh/authorized_keys sul server.
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ``` 3. Assicurarsi che la proprietà di `~/.ssh` e `~/.ssh/authorized_keys` sia correttamente assegnata all’utente interessato.
**Nota di approfondimento** È buona norma non rendere il file `authorized_keys` scrivibile da altri utenti per motivi di sicurezza.
# 2. Servizio ssh non avviabile a causa di chiavi host mancanti
**Messaggio di errore** ```plaintext Could not load host key: /etc/ssh/ssh_host_rsa_key ``` (e messaggi simili per altre chiavi host)
**Causa** La mancanza delle chiavi host o la loro corruzione impediscono al demone `sshd` di avviarsi correttamente.
**Soluzione** 1. Rigenerare le chiavi host: ```bash sudo ssh-keygen -A ``` 2. Riavviare il servizio: ```bash sudo systemctl restart ssh
Nota di approfondimento Le chiavi host identificano il server. Rigenerarle comporta che i client dovranno confermare nuovamente l’impronta del server.
3. Connessione rifiutata (Connection refused)
Messaggio di errore
1
ssh: connect to host 192.168.1.10 port 22: Connection refused
Causa Il servizio sshd non è in esecuzione, la porta 22 è bloccata da un firewall, o l’indirizzo IP non è corretto.
Soluzione
Assicurarsi che sshd sia attivo:
1 2 3 4 5 6 7 8 9
sudo systemctl status ssh ``` 2. In caso di servizio non attivo, avviarlo: ```bash sudo systemctl start ssh ``` 3. Verificare firewall e regole ufw: ```bash sudo ufw allow 22
Nota di approfondimento Verificare anche la correttezza dell’indirizzo IP del server e la configurazione di rete.
4. Timeout durante l’autenticazione
Messaggio di errore
1
ssh: connect to host esempio.com port 22: Operation timed out
Causa Il server potrebbe essere raggiungibile ma lento a rispondere, oppure ci sono problemi di rete. Potrebbe anche essere presente un MaxStartups troppo basso in /etc/ssh/sshd_config che limita le connessioni contemporanee.
Soluzione
Verificare la rete e la latenza con ping o traceroute.
1 2 3 4 5 6 7 8 9 10
ping esempio.com ``` 2. Aumentare `ClientAliveInterval` o `MaxStartups` in `/etc/ssh/sshd_config` se il problema è legato alla configurazione del server: ```plaintext # Esempio: MaxStartups 10:30:60 ``` 3. Riavviare `sshd`: ```bash sudo systemctl restart ssh
Nota di approfondimento In caso di server con molte connessioni simultanee, considerare l’ottimizzazione dei parametri in sshd_config.
5. Errore “Bad owner or permissions”
Messaggio di errore
1
Bad owner or permissions on /home/utente/.ssh/config
Causa Il file di configurazione SSH o le directory che lo contengono non hanno i permessi richiesti. SSH è molto rigido riguardo ai permessi di ~/.ssh e dei file in esso contenuti.
Soluzione
Impostare i permessi corretti:
1 2 3 4 5 6
chmod 700 ~/.ssh chmod 600 ~/.ssh/config ``` 2. Assicurarsi che la directory `~/.ssh` e i file all’interno siano di proprietà dell’utente stesso: ```bash chown utente:utente ~/.ssh ~/.ssh/config
Nota di approfondimento È fondamentale garantire che nessun altro utente possa scrivere in questi file per motivi di sicurezza.
6. Chiavi non leggibili da ssh-agent
Messaggio di errore
1
Error loading key "id_rsa": invalid format
Causa La chiave privata potrebbe essere corrotta, nel formato sbagliato o non essere stata convertita correttamente (ad esempio da PuTTY .ppk a OpenSSH).
Soluzione
Se si possiede una chiave nel formato .ppk, convertirla con puttygen:
1 2 3 4 5 6
puttygen key.ppk -O private-openssh -o id_rsa ``` 2. Assicurarsi che la chiave sia in formato OpenSSH. 3. Impostare i permessi adeguati: ```bash chmod 600 id_rsa
Nota di approfondimento L’uso di chiavi corrette e ben formattate è essenziale per garantire un accesso sicuro.
7. Password non accettata nonostante sia corretta
Messaggio di errore
1
Permission denied, please try again.
Causa Potrebbe essere disabilitato l’accesso via password in /etc/ssh/sshd_config con PasswordAuthentication no.
Nota di approfondimento L’accesso via password non è il più sicuro. Si consiglia di utilizzare chiavi pubbliche e private quando possibile.
8. “Host key verification failed”
Messaggio di errore
1
Host key verification failed.
Causa La chiave host del server è cambiata rispetto a quella conosciuta nel file ~/.ssh/known_hosts. Questo accade quando il server viene riconfigurato o rigenerato, oppure in caso di attacco di tipo “man-in-the-middle” (se la modifica non era attesa).
Soluzione
Rimuovere la vecchia chiave dal file known_hosts:
1 2 3 4 5 6 7 8 9 10 11 12 13
ssh-keygen -R hostname_del_server ``` 2. Connettersi nuovamente al server per accettare la nuova chiave.
**Nota di approfondimento** Se la modifica della chiave host non era prevista, indagare sulle cause per escludere intrusioni o alterazioni non autorizzate.
# 9. Errore "Could not resolve hostname"
**Messaggio di errore** ```plaintext ssh: Could not resolve hostname esempio.com: Name or service not known
Causa Il nome host non è risolvibile. Potrebbe essere un problema con i DNS o con la configurazione di /etc/hosts.
Soluzione
Controllare la connettività DNS:
1 2 3 4 5
nslookup esempio.com ``` 2. Se non risolvibile tramite DNS, aggiungere l’IP al file `/etc/hosts`: ```plaintext 192.168.1.10 esempio.com
Nota di approfondimento In ambienti interni o test, l’aggiunta al file hosts è rapida ma non scalabile. L’uso di DNS interni o server DNS dedicati è preferibile.
10. Errore “Too many authentication failures”
Messaggio di errore
1
Received disconnect from X.X.X.X: 2: Too many authentication failures for utente
Causa Il client sta presentando troppe chiavi o tentativi di autenticazione falliti in rapida successione. Ciò può accadere se l’agente SSH ha molte chiavi caricate o se la configurazione non è ottimale.
Soluzione
Limitare le chiavi caricate nell’agente SSH:
1 2 3 4 5 6 7 8 9 10 11 12 13
ssh-add -D ``` per scaricare tutte le chiavi e poi aggiungere solo quella necessaria: ```bash ssh-add ~/.ssh/id_rsa ``` 2. Aumentare `MaxAuthTries` in `/etc/ssh/sshd_config` se strettamente necessario: ```plaintext MaxAuthTries 6 ``` 3. Riavviare il servizio: ```bash sudo systemctl restart ssh
Nota di approfondimento Mantenere un numero limitato di tentativi riduce il rischio di attacchi brute-force. Meglio ottimizzare la configurazione e l’agente SSH piuttosto che aumentare drasticamente il limite.
Conclusione
Configurare SSH su Ubuntu può presentare alcune sfide, ma spero che condividere la mia esperienza possa aiutare a risolvere problemi simili. Assicurarsi sempre di controllare i log di SSH in caso di problemi e di verificare eventuali file di configurazione aggiuntivi che potrebbero sovrascrivere le impostazioni principali.
Quando si installa un server SSH su Ubuntu 22.04, è fondamentale comprendere le differenze tra i vari file di configurazione e come essi interagiscono tra loro. Questa guida ti aiuterà a navigare attraverso questi file, spiegando le loro funzioni e come applicare le impostazioni desiderate.
Introduzione ai File di Configurazione SSH
Dopo aver installato openssh-server, troverai diversi file e directory all’interno di /etc/ssh/:
ssh_config: Questo file contiene la configurazione del client SSH. Ogni volta che si utilizza un client SSH per connettersi a un server, le impostazioni vengono lette da questo file.
sshd_config: Questo file contiene la configurazione del server SSH. Definisce come il server SSH accetta e gestisce le connessioni in entrata.
È importante non confondere i due: modificare ssh_config influenzerà solo le connessioni in uscita dal tuo server, mentre modificare sshd_config cambierà il comportamento del server SSH stesso.
Il Ruolo della Directory sshd_config.d
All’interno di /etc/ssh/, noterai la presenza della directory sshd_config.d. Questa directory è stata introdotta per consentire una gestione modulare e più flessibile delle configurazioni.
File di override: I file all’interno di sshd_config.d possono sovrascrivere le impostazioni definite in sshd_config. Ad esempio, il file 50-cloud-init.conf potrebbe contenere configurazioni specifiche generate durante l’installazione del server.
Ordine di applicazione: Le configurazioni vengono lette in ordine alfabetico. Se hai più file, le impostazioni nei file successivi possono sovrascrivere quelle precedenti.
Questo meccanismo è utile per gestire configurazioni complesse o per applicare impostazioni specifiche senza modificare il file principale sshd_config, facilitando aggiornamenti e manutenzione.
Applicazione delle Impostazioni al Server SSH
Per configurare il tuo server SSH con le impostazioni desiderate, puoi seguire questi passi:
1. Modifica delle Impostazioni
Apri il file /etc/ssh/sshd_config con un editor di testo, ad esempio nano:
1
sudo nano /etc/ssh/sshd_config
Aggiungi o modifica le seguenti linee per applicare le tue configurazioni:
1 2 3 4 5
PermitRootLogin yes PasswordAuthentication yes PubkeyAuthentication yes ChallengeResponseAuthentication no UsePAM yes
2. Verifica dei File in sshd_config.d
Controlla se nella directory sshd_config.d esistono file che potrebbero sovrascrivere queste impostazioni. In particolare, verifica 50-cloud-init.conf o altri file presenti.
Questo mostrerà le impostazioni attualmente in uso per i parametri specificati.
Comprendere l’Evoluzione dei Permessi
L’introduzione della directory sshd_config.d rappresenta un’evoluzione nella gestione dei permessi e delle configurazioni. Permette agli amministratori di:
Modularizzare le configurazioni: Separare le impostazioni in file diversi per una migliore organizzazione.
Facilitare gli aggiornamenti: Evitare conflitti durante gli aggiornamenti del sistema che potrebbero sovrascrivere sshd_config.
Gestire le configurazioni in modo più sicuro: Ridurre il rischio di errori modificando solo i file necessari.
È essenziale comprendere come queste directory e file interagiscono per gestire efficacemente il tuo server SSH.
Conclusione
Configurare correttamente il server SSH è cruciale per la sicurezza e l’efficienza del tuo sistema. Comprendere le differenze tra ssh_config e sshd_config, così come il ruolo della directory sshd_config.d, ti permetterà di gestire le impostazioni in modo consapevole e sicuro.
Assicurati sempre di verificare le modifiche e di comprend
Da sistemista, ho sempre creduto che la base del progresso nel nostro campo risieda nella condivisione. Ogni giorno, ci troviamo di fronte a nuove sfide e a tecnologie in continua evoluzione. Ma come possiamo affrontarle efficacemente? La risposta è semplice: attingendo dalle esperienze e dalle conoscenze degli altri.
Il seme della curiosità
Quando entriamo in contatto con nuove idee o strumenti, spesso sperimentiamo un momento di rivelazione. È quel “clic” che ci spinge a voler sapere di più, a voler padroneggiare quella nuova conoscenza. Questo è ciò che chiamo il seme della curiosità.
Quando condividiamo il nostro sapere, piantiamo questi semi nella mente di altri, stimolando la loro curiosità. E, allo stesso tempo, possiamo raccogliere i frutti delle esperienze altrui, amplificando così le nostre competenze.
Condividere per crescere
Io credo fermamente che ogni linea di codice, ogni configurazione che realizzo, debba essere disponibile per altri. Non perché io sia sicuro che il mio lavoro sia perfetto, ma perché è un modo per archiviare le mie esperienze e facilitare l’apprendimento altrui.
La condivisione non è solo un atto altruistico; è un’opportunità per ricevere feedback e migliorare. Ogni volta che qualcuno utilizza ciò che ho condiviso, ho la possibilità di apprendere e crescere.
Dovrei condividere anche le mie soluzioni imperfette?
Assolutamente sì! È importante ricordare che nessuno di noi è perfetto. Ogni volta che scegliamo di non condividere le nostre soluzioni, perdiamo un’occasione preziosa di imparare e di contribuire a una comunità più ampia.
La verità è che le nostre esperienze, anche quelle imperfette, possono ispirare e aiutare gli altri a superare le loro sfide. Quindi, iniziamo a condividere! Ogni volta che lo facciamo, piantiamo nuovi semi di curiosità e alimentiamo il ciclo dell’apprendimento.
In conclusione, nel mondo IT, il progresso non è mai un viaggio solitario. È una rete di scambio continuo di idee e conoscenze. Abbracciamo la condivisione e vediamo dove ci porterà.