sabato, 23 Novembre 2024

[ubuntu] Installare Google PageSpeed Insights su server Apache

Su PageSpeed Insights Google mette a disposizione un utile strumento per verificare la velocità del proprio sito web, assieme a diversi parametri di ottimizzazione. Inutile dire che si tratta anzitutto di uno strumento di panoramica, che ci consente di verificare determinate caratteristiche tecniche del sito, che non devono essere per forza tutte soddisfatte (a volte è semplicemente impossibile, come quando segnala tra i javascript da ottimizzare quelli di Google Analytics stesso).

Vediamo come installarlo sul nostro server (come al solito nell’esempio utilizzo un Ubuntu Server 16.04).

Anzitutto apriamo il terminale e scarichiamo il file di installazione:

Questo comando scaricherà un file mod-pagespeed-stable_current_amd64.deb nella cartella che abbiamo selezionato.

Installiamo il pacchetto con:

A questo punto eseguiamo il controllo di tutte le dipendenze dei pacchetti installati con:

Se tutto è andato a dovere riavviamo apache.

Per attivare PageSpeed sarà sufficiente aggiungere, nella configurazione del virtual host, oppure in un file .htaccess l’istruzione:

Maggiori informazioni sui parametri di configurazione si trovano sul sito ufficiale.

 

[windows server] Spostare la cartella dei file di aggiornamento di WSUS

Obiettivo: spostare la cartella di archiviazione degli aggiornamenti di WSUS in una nuova posizione

Tipicamente i file di aggiornamento gestiti dal server WSUS si trovano nella posizione C:\Comsys WSUS.

Per cambiare tale cartella è sufficiente trovare il programma wsusutil.exe ed effettuare lo spostamento nel modo in cui segue:

  1. WIN+R per aprire ESEGUI e digitare CMD per aprire il prompt dei comandi
  2. Spostarsi nella cartella di wsusutil.exe tipicamente dovrebbe trovarsi in C:\Program Files\Update Services\Tools
  3. Digitare quindi CD C:\Program Files\Update Services\Tools
  4. Creare quindi la nuova cartella di destinazione dei file di aggiornamento, per esempio su un disco F creando una cartella F:\WSUS
  5. Digitare quindi wsusutil.exe movecontent F:\WSUS F:\move.log
  6. Questo comando avvierà lo spostamento dei file dalla posizione attuale a quella nuova

[c#] Creare una classe base generica con tipo aperto

Immaginiamo di voler creare in C# una classe generica che possa gestire dei tipi aperti, un po’ come succede per le liste. Per esercizio vogliamo creare una classe chiamata Materie che accetti diverse classi come tipo di materia gestito, per esempio una classe Matematica. L’oggetto che vogliamo creare sarà di questo tipo:

A questo punto vogliamo avere un metodo per aggiungere dei voti per gli studenti della data materia, nel modo seguente:

E infine vogliamo poter estrarre, dal nostro oggetto m, una media dei voti, passandogli una funzione che si occuperà di definire il meccanismo di estrazione del voto dall’oggetto generico sul tipo aperto.

Per cui creiamo anzitutto la classe Matematica:

E poi creiamo la classe Materie:

Faccio notare che il metodo getMediaVoti accetta come argomento un metodo generico che prenda che abbia come argomento il tipo aperto T e come restituzione un double (supponiamo che volendo calcolare dei voti essi dovranno essere comunque ricondotti a double).

Uniamo il tutto nel modo seguente:

In questo caso l’oggetto m si comporta in modo analogo ad una lista, permettendo l’aggiunta di n elementi del tipo T, nel nostro caso Matematica. Dal momento che noi non conosciamo i specifici parametri e metodi di T chiediamo, per calcolare la media, che ci venga passata una funzione a cui sarà delegata l’estrazione dei voti come double dall’oggetto aperto di tipo T, tale metodo è calcolaMedia che accetta come argomento un oggetto di tipo Matematica.

[python] Radiazione di Hawking e tempo che impiega un buco nero ad evaporare

In memoria di Stephen Hawking propongo un modesto esercizio in Python per calcolare il tempo di evaporazione di un buco nero, secondo la radiazione di Hawking.

In questo caso utilizzeremo le librerie scipy e numpy di Python.

Il mio esempio sarà fatto sotto Windows. Anzitutto installiamo quindi le librerie necessarie utilizzando pip, nella PowerShell digitiamo:

Una volta fatto avviamo un nuovo progetto in python e andiamo anzitutto a calcolare la suddetta formula. L’equazione di evaporazione di un buco nero, che si trovasse in una condizione ideale (ovvero nessuna aggiunta di energia, quindi ipoteticamente in un universo completamente vuoto e senza radiazione di fondo) è la seguente:

t_{ev} = \frac{5120 \pi G^2 M_0^3}{\hbar c^4}

Per scriverla in Python digitiamo:

Faccio notare che da scipy importiamo le costanti fisiche e matematiche che possiamo utilizzare secondo la seguente tabella.

M0 è l’ipotetica massa iniziale di un buco nero di massa solare, nello specifico di 1,98892 * 10^{30} kg .

Il risultato dovrebbe essere:

Il risultato è in secondi, possiamo convertirlo in miliardi di anni digitando:

Il risultato è qualcosa come 2 * 10^{58} miliardi di anni, molto più dell’attuale vita dell’universo stimata attorno ai 13 miliardi di anni.

Adesso proviamo ad inserire l’equazione in un grafico, dove vogliamo confrontare vari tipi di buco nero in base alla massa ed il tempo di evaporazione.

Per farlo anzitutto convertiamo la nostra precedente equazione in una funzione digitando:

Ricordiamoci che il risultato della funzione è in secondi. A questo punto prepariamo i valori del nostro asse x, che saranno le masse di diversi buchi neri. Prendiamo 100 valori tra 0 e 1030.

Sull’asse Y calcoliamo i corrispondenti valori:

Adesso impacchettiamo tutto in un grafico generato con matplotlib.

Il risultato sarà qualcosa di simile a questo:

[c#] Esempio di programma elementare da console

Oggi propongo un piccolo esercizio in C# per chiunque volesse avvicinarsi a questo fantastico linguaggio di programmazione.

Obiettivo: realizzare un programma elementare da console che permetta di inserire degli atleti, con nomi e punteggi, visualizzarli a monitor, rimuoverli e stampare la media dei loro punteggi.

Per programmare con C# è sufficiente disporre di Visual Studio 2017. (la Community edition sarà più che sufficiente, basterà scegliere C# tra i pacchetti da installare)

Una volta installato avviamo un nuovo progetto andando su File ⇒ Nuovo ⇒ Progetto…

A questo punto comparirà una finestra che ci permetterà di scegliere che tipo di progetto vogliamo realizzare. Nel nostro caso applicazione per Console.

In fondo diamo un nome a piacere al nostro progetto, io lo chiamerà EsempioAtleti, e prendiamo nota della posizione dove verrà salvato (tipicamente nella cartella che abbiamo scelto, in fase di installazione, come cartella predefinita per i progetti).

Se abbiamo fatto tutto correttamente dovremmo ritrovarci con aperto il file Program.cs con dentro un contenuto simile a questo:

Il metodo Main è quello che verrà eseguito automaticamente all’avvio dell’intero programma. Per fare una primissima prova e prendere leggermente confidenza con il programma possiamo digitare quanto segue:

Avviamo il programma premendo F5 (oppure il tasto avvia con la freccia verde). Quello che vedremo sarà un prompt dei comandi con scritto “Ciao, Mondo!” ed il cursore in attesa di input. Se premiamo invio il prompt si chiuderà. Questo lo abbiamo ottenuto con la riga di codice Console.ReadLine(), senza la quale il programma terminerebbe immediatamente. In questo modo invece si mette in attesa di un nostro input, ricevuto il quale chiude tutto quanto.

Adesso cominciamo a creare un paio di classi, necessarie al nostro progetto. Per aggiungere una nuova classe è sufficiente cliccare col destro sul progetto nella finestra di esplorazione, selezionare Aggiungi ⇒ Classe.

Creeremo due classi, chiamate rispettivamente Atleti ed Atleta. La classe Atleti gestirà un gruppo di oggetti singoli di tipo Atleta. Vediamo anzitutto come sarà composta la classe Atleta:

Notiamo come la classe Atleta possieda due proprietà, chiamate anche variabili, ovvero nome e punteggio, entrambe private. Essendo private non sono accessibili dall’esterno dell’oggetto, ma solo internamente. Perciò creiamo anche dei getter e setter, ovvero dei metodi che ci permettano di modificare ed interrogare le suddette proprietà; questi “metodi” appaiono come delle proprietà a loro volta, secondo lo stile di C#, e nel nostro caso sono state chiamate Nome e Punti. Faccio notare come ho chiamato Nome con la maiuscola, rispetto alla proprietà privata nome, ma nell’assegnazione di tale nomenclatura non c’è niente di speciale. Tant’è che a punteggio ho associato Punti. Diciamo che l’uso comune prevederebbe di chiamare il getter/setter Punteggio, ma non è obbligatorio.

Abbiamo inoltre creato un costruttore che accetta una stringa ed un intero che assegna a Nome e Punti, il che ci permetterà di creare degli oggetti di tipo Atleta senza dover per forza assegnare separatamente le due proprietà.

A questo punto creiamo una classe chiamata Atleti, che conterrà una lista di oggetto di tipo Atleta ed un paio di metodi per gestirli.

Vediamo i punti salienti di questa seconda classe. Anzitutto abbiamo creato una lista di oggetti di tipo Atleta:

Questa è una proprietà privata della classe, quindi per poter aggiungere nuovi oggetti alla lista creiamo un metodo apposito:

Il metodo accetta un argomento di tipo Atleta, chiamato a. Poi esegue il metodo .Add() sulla lista di oggetti di tipo Atleta, aggiungendo in fondo alla lista l’ultimo oggetto. Inoltre chiama anche un “evento” personalizzato, nello specifico il metodo raiseNuovoAtleta();

Questo metodo fa parte della seguente definizione:

Con questo piccolo trucchetto creiamo un evento personalizzato sulla nostra classe, cioè diamo la possibilità di aggiungere dei metodi all’oggetto, una volta creato, che saranno richiamati all’accadere dell’evento specifico.

Cerchiamo di capire meglio questa cosa.

Immaginiamo di voler aggiungere delle funzioni specifiche ad ogni volta che viene aggiunto un nuovo atleta. L’oggetto creato da Atleti potrebbe essere il seguente:

Adesso immaginiamo di voler far sì che, ogni volta che viene aggiunto un nuovo atleta, con il seguente metodo:

Venga anche richiamato un metodo personalizzato, creato fuori dalla classe, che esegua delle operazioni. Nel nostro caso manda un banale messaggio a schermo:

Faccio notare che gli argomenti di questo metodo personalizzato sono i medesimi, per tipo, del metodo delegato creato nella classe Atleti:

Per aggiungere tale metodo a quelli dell’evento creato sarà sufficiente scrivere:

Il metodo atletaAggiunto verrà richiamato dall’oggetto, assieme ad ogni altro eventuale metodo aggiunto, dal metodo raiseNuovoAtleta.

Finalizziamo il tutto costruendo la parte del Main del nostro programmino:

Una volta lanciato il risultato a video dovrebbe essere il seguente.

Da qui è possibile scaricare il progetto in visual studio: EsempioAtleti

Hash SHA256: BE81F3861195A817919DF4EF6938FC2DAB89D0E64A989BA21F41E1A45BB23841

[vba] Classe per interrogare in SQL un foglio excel

Obiettivo: creare una classe per poter interrogare tramite query SQL un foglio excel, leggendo e scrivendo i dati come se lavorassimo con tabelle SQL

Questo esercizio riprende il punto direttamente da questo precedente: Interrogare foglio di Excel con SQL in VBA

Dopo aver visto come poter interrogare con query SQL un foglio excel, vediamo come creare una classe ad hoc che ci permetta di leggere e scrivere i dati mediante query SQL. Per farlo anzitutto aggiungiamo una nuova classe:

Premendo ALT+F11 apriamo l’editor Visual Basic, ci posizioniamo su un qualunque punto del progetto a sinistra e clicchiamo col destro (per esempio su Form), poi scegliamo Inserisci ⇒ Modulo classe. A questo punto verrà creata una nuova classe. Per rinominarla è sufficiente selezionarla e poi spostarsi nel riquadro delle proprietà.

A questo punto incolliamo dentro la classe appena creata (tenendo presente poi il nome scelto) il seguente codice:

Faccio notare come nel metodo dbout dobbiamo fare un’operazione un po’ superflua in apparenza, ovvero contare prima le righe e le colonne, per poi ridimensionare il vettore result. Questa operazione è necessaria perché ReDim, in VBA, non permette di ridimensionare l’intera matrice (vettore di vettori), ma solo l’ultima dimensione. Quindi, per esempio, result(4,10) potrebbe diventare result(4,20), ma non result(5,10) oppure result(5,20). Un’alternativa sarebbe quella di creare una funzione che trasponga il vettore e lo modifichi, ritrasponendolo di nuovo, ma dal punto di vista del calcolo credo sarebbe molto più oneroso che fare così.

Fatto questo potremo utilizzare la nostra nuova classe nella maniera seguente.

Una volta creata la classe può essere esportata, oppure importata nel modo seguente:

Per chi volesse è possibile scaricare la classe già pronta cliccando qui: DbSQL.zip

Hash MD5: A2A18A42BB11AEA86DF1AB4F547B4414

La classe è stata testata su Excel 2016.

[bash] Disegnare fiocco di neve su terminale

Approfittando della giornata innevata e di un po’ di relax ecco un piccolo esercizio in bash per “disegnare” su terminale utilizzando semplicemente spazi e cancelletti (#).

Anzitutto creiamo una serie di funzioni che ci consentano di disegnare come se si stesse lavorando su un piano cartesiano. A tale proposito cerchiamo di disegnare una parabola con la seguente funzione:

y=x^2-5

Prima di proseguire installiamo il basic calculator, che ci permetterà di effettuare calcoli matematici elementari in bash (non è indispensabile, né l’unico modo, ma per quello che vogliamo fare dovrebbe essere sufficiente):

Una volta installato creiamo un file parabola.sh

Ed inseriamo dentro il seguente codice:

Ricordiamoci di rendere lo script eseguibile digitando:

Ed eseguiamolo:

Il risultato di questa operazione dovrebbe dare qualcosa di simile a questo:

Faccio notare che la funzione disegna accetta come terzo parametro il tipo di carattere che vorremo utilizzare.

Adesso che abbiamo verificato che il disegno sul piano cartesiano funziona possiamo scrivere la serie di istruzioni necessarie a generare il nostro simpatico fiocco di neve. Le funzioni matematiche necessarie le ho prese da qui: Snowflake Math.

Inutile dire che si potrebbero usare moltissime altre funzioni, oppure divertirci con un calcolo frattale. Notiamo però che il disegno accetterà solo valore naturali interi, quindi il risultato sarà comunque un po’ impreciso. Infatti non possiamo aumentare la densità di caratteri sul terminale, potendo così apprezzare altri dettagli. Lo script sarà dunque questo:

Il risultato dovrebbe essere qualcosa di simile a questo:

Non è bellissimo, ma è quello che stavamo cercando di fare. Perfezionando le equazioni probabilmente si può ottenere di meglio.

Liberare spazio su Ubuntu con errore apt-get “No space left on device”

Problema: non sembra esserci spazio sufficiente sul disco per eseguire installazioni ed aggiornamenti con apt-get

Per risolvere il problema è sufficiente cancellare i vecchi linux-headers e linux-image del Kernel. Questi file si trovano in /usr/src/

Per verificare le versioni installate anzitutto controlliamo il contenuto della suddetta cartella con:

Dovremmo vedere un elenco di file chiamati linux-headers, linux-image, linux-image-extra ed altri. Per esempio potremmo trovare un elenco come il seguente:

Nel mio caso vedo che ho installate le versioni 3.13.0-132, 3.13.0-1333.13.0-1353.13.0-137 del kernel.

Questo significa che posso cancellare, a meno di non averne bisogno per specifici motivi (ma se non li conosco, probabilmente non ne ho bisogno) le versioni 132, 133 e 135. Devo lasciare invece la versione 137.

Dopo svariate prove sono giunto alla conclusione che per cancellare una determinata versione, senza lasciare fastidiosi rimasugli, è sufficiente digitare la seguente serie di istruzioni (immaginiamo di voler eliminare la versione 132):

Per chi volesse cancellare più versioni in un colpo solo, senza stare a perdere tempo a modificare i numeri nelle precedenti righe, ho creato un piccolo script per Python (io uso questo per fare pulizia sul disco) che mi genera i comandi da incollare sul terminale.

L’unico parametro da modificare è il primo vettore, aggiungendo o togliendo le versioni.

Durante l’esecuzione ci verrà chiesto se mantenere la configurazione di grub, possiamo dirgli di sì.

[CentOS] Prima installazione e configurazione base per webserver (LAMP, fail2ban)

Oggi ho deciso di cimentarmi nell’installazione di quel obbrobrio modaiolo che è CentOS. Dico così perché è a tutti gli effetti utilizzato da meno del 20% dei webserver ed in generale mi sono convinto che venga scelto più per una questione di moda, che per qualche reale vantaggio rispetto ad Ubuntu/Debian.

Fonte w3techs.com

Lungi dal voler scatenare una guerra tra distribuzioni, questo resta naturalmente un mio personalissimo parere, corroborato da “qualche” statistica (cioè non toglie, che io stesso, in momenti di malignità, abbia installato CentOS, per il morboso gusto dell’esperimento sulla pelle d’altri).

Comunque sia avventuriamoci in questo mondo e vediamo un po’ di differenze rispetto ad Ubuntu e Debian.

Come al solito utilizziamo VirtualBox e putty, mentre per scaricare la ISO è sufficiente andare sul sito ufficiale.

1. Installazione

Anzitutto ci viene chiesto che cosa intendiamo fare, scegliamo la prima opzione (banalmente premiamo INVIO, oppure I) e proseguiamo.

A questo punto compare una schermata con interfaccia grafica dove scegliere la lingua di installazione.

Scegliamo l’italiano come nella figura seguente e poi proseguiamo.

Selezioniamo Continua e ci troviamo di fronte alla schermata di tutte le impostazioni possibili.

Notiamo come è segnalato un “problema” sulla destinazione dell’installazione, unica cosa che dobbiamo scegliere effettivamente. Tutti gli altri parametri sono preconfigurati nella versione minima predefinita e possiamo lasciarli tali. Clicchiamo quindi su destinazione di installazione.

Scegliamo il nostro disco (nel mio caso quello da 30GB) e lasciamo la configurazione automatica (come avremmo fatto per Ubuntu). Clicchiamo su FATTO.

Adesso è possibile scegliere Avvia installazione.

Mentre prosegue l’installazione, con tanto di banner pubblicitario non richiesto (e questo già la dice lunga su dove ci stiamo avventurando) possiamo configurare la password di root ed eventuali altri utenti. In questo caso creiamo soltanto il nostro utente root dandogli una password. Clicchiamo su password di root.

Se si trattasse di una vera installazione online ci converrebbe, naturalmente, scegliere una buona password. Io ne metto una semplice, che però non sia troppo semplice e venga accettata. Il fatto stesso che il sistema “protesti” all’inserimento di “password” è un altro dei punti che trovo detestabili, visto che ho scelto linux proprio per fare, e sbagliare anche, di testa mia. Ma procediamo. Io ho messo una password un po’ più complessa, anche se si tratta di un esempio.

Quando l’installazione è completata possiamo riavviare il sistema.

Adesso possiamo cominciare a lavorare.

2. Connessione in SSH e configurazione rete

Se avete scelto l’installazione minima prima di potersi collegare in SSH, dopo aver inoltrato le porte su VirtualBox, qualora stesse lavorando sotto NAT come sto facendo io, è necessario avviare il servizio di rete. Per farlo digitiamo:

Senza questo servizio avviato non ci si può nemmeno collegare a internet.

Apriamo putty (o il nostro client ssh) e colleghiamoci normalmente alla macchina che abbiamo appena installato.

A questo punto impostiamo la rete perché si avvii automaticamente ad ogni riavvio del sistema (altrimenti dovremmo farlo noi a mano). Per poter modificare il file avremo bisogno di un editor di testo, quindi installiamo nano (ce ne sono anche tanti altri):

Ci verrà chiesto di confermare l’installazione e sarà sufficiente premere y o s, in base a quello che viene proposto.

Fatto questo identifichiamo la nostra scheda di rete, ifconfig non funziona perché andrebbe installato, quindi digitiamo:

Nel mio caso vengono mostrate le seguenti due schede:

Faccio notare che la prima interfaccia di rete è quella locale, chiamata lo, mentre la seconda è la scheda di rete della macchina virtuale (in una configurazione su macchina fisica qui avremmo eth0 probabilmente) chiamata enp0s3.

Da qui possiamo anche vedere che alla scheda di rete è stato assegnato l’indirizzo IP 10.0.2.15 (classica configurazione di VirtualBox).

Quindi andiamo a vedere i file di configurazione di rete e digitiamo:

Questo ci mostrerà vari file di configurazione, come nella schermata seguente:

Notiamo i primi due file che hanno i nomi ifcfg-enp0s3 e ifcfg-lo. Modifichiamo quindi il file di configurazione della scheda di rete:

Ci dovremmo trovare di fronte a qualcosa di simile a questo:

Modifichiamo il parametro ONBOOT=no facendolo diventare ONBOOT=yes. Salviamo premendo CTRL+O e riavviamo il computer per accertarci che sia tutto andato bene.

Per riavviare digitiamo:

Se tutto è andato bene potremo accedere normalmente in SSH.

3. Installazione server LAMP

Adesso è il momento di installare il nostro server LAMP (Linux + Apache + MySQL + PHP). Anzitutto digitiamo:

Una volta completata l’installazione dobbiamo avviare il servizio e configurare il firewall perché sia accessibile.

Quindi per avviare il servizio digitiamo:

Mentre per configurare il firewall utilizziamo firewall-cmd digitando:

Faccio notare che quello che viene configurato sono 2 servizi, ovvero due porte, HTTP 80, HTTPS 443.

Andando all’indirizzo http://192.168.56.1/ (questo è il mio indirizzo della macchina virtuale) possiamo verificare che il server web funzioni correttamente (apparirà una pagina con scritto Testing 123…)

Adesso dobbiamo installare MySQL / MariaDB, MariaDB è l’evoluzione del MySQL, compatibile con quest’ultimo. Nel nostro caso installiamo MariaDB (giusto per variare un po’ sul tema, per il MySQL la procedura è analoga). Quindi digitiamo:

Faccio notare che il flag -y permette di installare tutto senza ulteriori richieste di conferma. In modo analogo a prima digitiamo poi:

In questo modo abilitiamo ed avviamo il servizio. Adesso però dobbiamo impostare la password dell’utente principale del database, che si chiama sempre root, anche se è diverso dal root di sistema. Oltre a questo vogliamo configurare alcuni parametri di sicurezza. Digitiamo:

Verranno poste le seguenti domande:

  1. Enter current password for root (enter for none): PREMIAMO INVIO, non c’è nessuna password di root per ora
  2. Set root password? [Y/n]: Y
  3. New password: METTIAMO UNA PASSWORD
  4. Re-enter new password: RIPETIAMO LA SUDDETTA PASSWORD
  5. Remove anonymous users? [Y/n] Y
  6. Disallow root login remotely? [Y/n] Y
  7. Remove test database and access to it? [Y/n] Y
  8. Reload privilege tables now? [Y/n] Y

In questo modo abbiamo messo in sicurezza e configurato il nostro database.

Adesso è il turno del PHP. Per assicurarci di scaricare la versione più recente, ovvero il PHP7, aggiorniamo la repository.

A questo punto digitiamo:

Questo installerà il PHP7.0.

A questo punto comincia una piccola avventura degna solo di CentOS. Anzitutto bisogna abilitare il PHP affinché venga eseguito dal motore php-fpm (il PHP è un linguaggio compilato sul momento e può essere eseguito da diversi motori). Per qualche ragione l’installazione con yum non si occupa di questa cosa. Spostiamoci quindi in /etc/httpd/conf.d/ dove andremo a creare un file di configurazione chiamato fpm.conf. Attenzione, nel nome non c’è niente di speciale, poteva anche essere ilmiophp.conf. L’importante è l’estensione *.conf. Digitiamo quindi:

In questo modo reindirizziamo le richieste dei documento PHP al server fcgi.

A questo punto dobbiamo avviare il servizio e riavviare Apache, digitando la seguente serie di comandi:

Eventualmente, se avessimo bisogno, possiamo visualizzare lo stato del servizio fpm-php digitando:

A questo punto creiamo la nostra solita pagina PHP di prova in /var/www/html (stesso percorso predefinito di Ubuntu):

Dentro il file incolliamo:

Salviamo premendo come al solito CTRL+O.

Adesso apriamo la nostra pagina web al solito indirizzo di prima http://192.168.56.1/. Quello che vediamo, per la nostra massima felicità, è quanto segue:

Questo dipende dal fatto che abbiamo creato il file index.php come root, e non gli abbiamo assegnato l’utente di Apache. Per farlo anzitutto controlliamo l’utente con cui gira Apache aprendo:

Scendendo nel file vedremo una voce simile a questa:

In questo caso (ma è così di solito) il nostro utente è apache ed il gruppo è apache. Quindi modifichiamo i permessi sul file appena creato:

A questo punto ricontrolliamo e scopriamo due cose:

1. l’errore si presenta uguale a prima

2. la guida di CentOS stesso fa totalmente schifo. Le istruzioni da incollare dentro ad fpm.conf le ho infatti copiate da qui, quello che però non viene detto è che andrebbe anche configurato index.php come pagina predefinita, altrimenti apache pensa che, non essendoci una index.html, non si possa accedere alla cartella

Quindi digitiamo:

E modifichiamo il file di prima in modo tale che risulti così (ho aggiunto solo l’ultima riga):

A questo punto riavviamo Apache:

E il risultato che otteniamo collegandoci a http://192.168.56.1/ dovrebbe essere così:

Controllando la pagina web precedente vedremo che non è installata l’estensione per gestiore MySQL/MariaDB. Per farlo è sufficiente digitare:

Una volta fatto riavviamo il servizio FPM PHP.

Adesso però verifichiamo se è andato davvero tutto bene collegandoci anche al database. Anzitutto creiamo un nuovo database.

Per farlo accediamo al MySQL/MariaDB che abbiamo installato prima. Digitiamo:

Attenzione! La medesima istruzione va digitata anche nel caso che si stia usando MariaDB, come sto facendo io, che vi ricordo è un aggiornamento di MySQL perfettamente retrocompatibile.

Digitiamo la password del database e ci troviamo nella console di gestione di MariaDB, che appare così:

Questo significa che non abbiamo selezionato alcun database. Adesso creiamo un database (io lo chiamerò petar):

Proviamo anche a creare un utente chiamato petar e che possa accedere a tale database solamente da localhost (quindi da connessione locale). Per farlo digitiamo:

La password per il nuovo utente sarà password123. Per uscire dalla console del MariaDB digitiamo:

Adesso torniamo sul nostro file /var/www/html/index.php di prima e modifichiamolo nella maniera seguente:

Se abbiamo fatto tutto bene andando su http://192.168.56.1/ vedremo qualcosa di simile a questo:

In caso che ci sia stato qualche errore (possiamo riprodurlo di proposito sbagliando la password nel suddetto codice php) dovremmo vedere qualcosa di simile:

Accertiamoci anche che, modificando il codice in questo modo:

Nella suddetta pagina appaia la seguente sezione dedicata al MySQL.

Se per qualunque ragione non dovesse esserci la libreria non è installata correttamente.

4. Configurazione Firewall

A questo punto controlliamo lo stato del firewall. Vediamo anzitutto alcuni comandi utili.

Per accertarci che sia attivo digitiamo:

A questo punto controlliamo lo stato della configurazione digitando:

Dovremmo vedere qualcosa di simile a questo:

Notiamo che l’interfaccia del firewall è su enp0s3 (la nostra unica scheda di rete, su una macchina fisica tipicamente eth0).

I servizi attivi sono invece ssh dhcpv6-client http https. Ricordiamoci che queste ultime due le abbiamo configurate al punto 3 precedente.

Come già detto, quindi, per aggiungere un nuovo servizio al firewall è sufficiente digitare:

Mentre per rimuoverlo, ad esempio rimuovere il servizio http, basta digitare:

In entrambi i casi, affinché le modifiche abbiano successo, è necessario riavviare il firewall:

Tutto questo è molto bello, ma sinceramente preferisco lavorare con iptables. Ricordiamoci che sia firewalld che iptables sono due software, distinti, che gestiscono il firewall vero che si chiama netfilter. Per verificare che sia installato, dovrebbe esserlo, digitiamo:

Il risultato dovrebbe essere qualcosa come: iptables-1.4.21-18.2.el7_4.x86_64

Questo ci indica l’ultima versione installata. Controlliamo quindi, con iptables, qual’è la configurazione attuale.

Quello che viene fuori è un casino simile a questo:

Personalmente trovo tragicomico che un’installazione minima di CentOS parta con una simile configurazione di iptables (e soprattutto parta con aperta solamente la porta SSH). Essendo un’installazione minima ci si potrebbe aspettare che il firewall non sia configurato e che tutte le porte siano aperte, per poi dovercene occupare noi.

Per tanto, siccome voglio avere una visione chiara della situazione del firewall, resetto tutto quanto impostando aperte solo le porte per SSH, HTTP e HTTPS. Per farlo mi è sufficiente eseguire il seguente codice da terminale (va bene anche un copia/incolla)

Per approfondimenti suggerisco: Lavorare con iptables su Ubuntu [per pinguini in erba]

Il risultato di questa purga, digitando iptables -L, dovrebbe essere così:

Per salvare la configurazione dobbiamo installare i servizi di iptables digitando:

Abilitiamo il servizio digitando:

Già che ci siamo sbarazziamoci di firewalld:

Riavviamo il servizio iptables (fino ad ora abbiamo usato solo il programma client):

E infine salviamo:

A questo punto dovremmo ricevere una conferma di questo tipo:

Per accertarci che tutto sia andato bene possiamo riavviare l’intera macchina con un reboot now e ricontrollare lo stato del firewall digitando iptables -L.

5. Installazione di fail2ban

Come ultima operazione installiamo fail2ban, onde limitare le possibilità di ricevere attacchi sulla porta 22 del protocollo SSH. In questo modo evitiamo che si possano fare numerosi tentativi per scoprire i dati di accesso, bannando via via gli indirizzi IP da cui arrivano gli attacchi.

Per installare fail2ban anzitutto aggiungiamo il pacchetto EPEL Project alla nostra repository.

Qualora risultasse già installato tanto meglio. Procediamo installando fail2ban:

Completata l’installazione abilitiamo fail2ban digitando:

Adesso configuriamo il programma. Per farlo possiamo modificare alcuni file. In particolare teniamo presente le seguenti cose:

  1. /etc/fail2ban/jail.conf questo il primo file di configurazione, è quello predefinito, lo possiamo modificare, ma se vogliamo fare un lavoro pulito ci conviene lasciarlo così com’è
  2. /etc/fail2ban/jail.d/*.conf, questi sono i file *.conf predefiniti, vengono accorpati al file precedente, sostituendo eventuali parametri equivalenti, anche questi file possono essere lasciati intatti così come sono
  3. /etc/fail2ban/jail.local questo è il file di configurazione locale, segue ai due file precedenti, e quindi ogni modifica apportata qui dentro potrà sovrascrivere le precedenti
  4. /etc/fail2ban/jail.d/*.local, infine questa è la cartella nella quale si troveranno i file *.local personalizzati che andranno a sostituire quelli precedenti e verranno accorpati in ordine alfabetico

Quindi anzitutto impostiamo i parametri base per fail2ban modificando il seguente file:

Il file risulterà vuoto, quindi ci possiamo incollare dentro i seguenti parametri. Questi andranno a sostituire quelli di default.

A questo punto creiamo un file per l’SSH digitando:

Ricordiamoci che i file verranno letti in ordine alfabetico, nel nome del file, a parte l’estensione *.local, non c’è niente di speciale. Si poteva anche chiamare 001-config.local.

Salviamo e riavviamo fail2ban:

Verifichiamo la situazione digitando:

Ci dovrebbe comparire qualcosa di simile:

Notiamo che è abilitata una jail per l’sshd. Stessa verifica la possiamo fare su iptables digitando iptables -L e controllando la presenza di una chain per fail2ban.

Per accertarci che tutto vada bene possiamo tentare di accedere in SSH sbagliando password. Inutile dire che una volta bannati dovremo poter accedere direttamente alla macchina per sbannarci.

Per visualizzare gli ip bannati è sufficiente digitare (per la chain f2b-sshd creata fa fail2ban dentro al firewall):

In questo caso il mio IP è il 10.0.2.2 e possiamo notare che appare tra quelli bannati:

Per rimuoverlo, ovvero sbloccare l’indirizzo ip bannato, basta digitare:

A questo punto possiamo accedere nuovamente mediante SSH.

Adesso abbiamo configurato CentOS per essere pronto ed operativo come server LAMP.

Lavorare con iptables su Ubuntu [per pinguini in erba]

Obiettivo: configurare il firewall su Ubuntu adatto ad un webserver, compresi servizi FTP e di posta, capendo come funzionano le regole ed i criteri principali

Contenuti

  1. Visualizzare lo stato del firewall (iptables)
  2. Accettare tutte le connessioni e ripristinare il firewall alla configurazione base
  3. Modificare il criterio della catena
  4. Aggiungere una nuova catena personalizzata
  5. Cambiare ordine ai filtri (anelli) sulla catena
  6. Eliminare un filtro (anello) della catena
  7. Aggiungere intervalli di porte ad iptables
  8. Bloccare un indirizzo IP
  9. Firewall su OUTPUT
  10. Configurare il firewall standard per server web con Apache, Webmin, FTP, POP3, SMTP, IMAP e SSH

 

Abbiamo già visto la configurazione base di iptables su Ubuntu, ora propongo una serie di esempi per capire in modo più approfondito come funziona.

Suggerimento: per testare la connessione possiamo usare il webserver creato con Apache e provare via via a collegarci alla porta 80, ovvero all’indirizzo del server tramite browser. Nell’esempio dell’altra volta tale indirizzo era http://192.168.56.1

Iptables è un programma che serve a gestire Netfilter, che è il vero firewall della maggior parte dei più moderni sistemi Linux. Su Wikipedia ci sono maggiori dettagli di base, per ora ne estraggo la citazione fondamentale:

Per configurare netfilter attualmente si usa il programma iptables, che permette di definire le regole per i filtri di rete e il reindirizzamento NAT. Spesso con il termine iptables ci si riferisce all’intera infrastruttura, incluso netfilter.

Iptables si basa su 3 catene principali:

  • INPUT traffico in entrata, per esempio collegarsi da fuori verso il PC in SSH oppure interrogare il server web in HTTP
  • FORWARD traffico reindirizzato, si usa solo nel caso in cui il PC effettui operazioni di routing
  • OUTPUT connessioni in uscita, per esempio operazioni di ping

E 3 criteri fondamentali:

  • ACCEPT permette
  • DROP blocca come se non esistesse
  • REJECT blocca inviando un errore

Ci sono anche altri criteri, ma per ora focalizziamoci su questi che sono essenziali per i nostri scopi.

Prima di proseguire capiamo meglio come funzionano le catene (chain). Sul firewall possono essere configurate diverse catene, che verranno visitate nell’ordine in cui sono inserite.

Immaginiamo di avere del traffico in ingresso e due catene come di seguito:

Alle catene vengono aggiunti anelli successivi, allungandole sempre di più. Un pacchetto che entra cerca di passare da un anello dove gli sia consentito, altrimenti, se non trova passaggi liberi, viene scartato. Per riuscire ad attraversare “indenne” il firewall deve visitare tutte le catene successive (devono essere referenziate, ma questo lo vedremo dopo).

Il primo anello rappresenta il criterio generale della catena, ma anche questo lo capiremo meglio dopo.

Questa è una spiegazione vagamente semplicistica, ma per il momento è sufficiente.

NOTA: E’ molto importante ricordare che mentre si apportano le modifiche ad iptables queste non saranno permanente finché non si salvano definitivamente; questo significa che se aggiungiamo dei criteri e poi riavviamo il computer, al riavvio questi non saranno più presenti. Perché diventino permanenti bisogna salvarli e vedremo come dopo.

1. Visualizzare lo stato del firewall (iptables)

Per visualizzare la configurazione del firewall è sufficiente digitare:

Nel mio caso viene visualizzato qualcosa di simile (ho già effettuato delle configurazioni):

Notiamo che nella prima chain, quella di INPUT (le prime 3 sono predefinite), c’è un comando inutile che tenta di bloccare i pacchetti dpt:http (dpt = destination port, http = 80), ovvero quelli passanti dalla porta 80 utilizzata per le connessioni web HTTP. Poche righe prima è infatti definita una regola che li fa passare attraverso la catena con ACCEPT, quindi questo DROP è inutile.

2. Accettare tutte le connessioni e ripristinare il firewall alla configurazione base

Per fare il reset del firewall è sufficiente digitare:

La -F sta per flush. Questo reimposterà tutte le catene effettuando la cancellazione di tutti gli anelli, lasciando solamente quelli in cima. Questo significa che se la regola per INPUT è ACCEPT resterà ACCEPT, se fosse stata DROP resterà DROP, senza tutte le altre regole a seguire.

Per reimpostare il primo anello della catena è necessario utilizzare:

In questo caso modifichiamo la catena predefinita degli INPUT, impostandola affinché faccia passare tutte le connessioni che non sono state definite. Il primo anello della catena, nel disegno precedente, è il criterio della catena.

Digitando il seguente comando si aprirà l’intero firewall e si cancelleranno tutti i criteri aggiuntivi.

Per non rischiare che il flush chiuda la connessione SSH possiamo concatenare i comandi con &&.

3. Modificare il criterio della catena

Immaginiamo di prendere la configurazione del firewall nel primo grafico, ma di cambiare il criterio della prima catena da DROP ad ACCEPT. Il risultato produrrà qualcosa di simile:

Quando il criterio della catena è ACCEPT significa che ogni pacchetto che non sia proibito, oppure sia esplicitamente accettato, passa, ovvero è ACCEPT di default. Se un pacchetto è DROP, al primo DROP è DROP per tutta la catena.

Per modificare il criterio di una catena, come quella di INPUT per esempio, è sufficiente digitare:

In questo caso l’intera catena è su ACCEPT come la catena1 del disegno. Se su INPUT volessimo riprodurre le medesime regole della catena precedente sarebbe sufficiente digitare, in questo ordine:

Con -A aggiungiamo un filtro (un anello) ad INPUT (o una catena scelta), -p definisce il protocollo da filtrare, per noi TCP, –dport definisce la porta di destinazione, per esempio la porta 80, -j imposta il jump, ovvero se si passa o si precipita.

NB: i protocolli accettati sono tcp, udp, udplite, icmp, esp, ah, sctp oppure all per prenderli tutti

Per visualizzare la configurazione digitiamo:

Il risultato assomiglierà al seguente:

Inutile dire come il criterio ACCEPT presupporrebbe di dover bloccare tutti i pacchetti eccetto quelli desiderati, quindi si preferisce di solito il criterio DROP, per cui sono bloccati tutti i pacchetti eccetto quello desiderati.

Il criterio ACCEPT è invece molto utile in fase di configurazione.

Immaginiamo di voler attivare il firewall solamente sulle seguenti porte: 80, 443, 20, 21, 22 (rispettivamente HTTP, HTTPS, FTP, FTP, SSH). Digitiamo in sequenza:

Interrogando iptables il risultato sarà:

4. Aggiungere una nuova catena personalizzata

Oltre alle catene predefinite, per ora abbiamo visto INPUT, OUTPUT e FORWARD, possiamo aggiungere delle ulteriori catene personalizzate.

Creiamo anzitutto la nostra nuova catena che io chiamerò Cerberus (niente di speciale nel nome, giusto per dare un tono fantasy all’esempio)

Adesso aggiungiamo, alla catena delle regole, ma prima di tutto una confessione:

ATTENZIONE! Solamente le catene predefinite possono avere dei criteri come ACCEPT, DROP, REJECT ecc., le catene personalizzate non possono averli, ma vanno collegate a quelle predefinite

Quindi sulla nostra catena personalizzata Cerberus blocchiamo la porta 80.

Assicuriamoci che la catena INPUT sia sul criterio ACCEPT e senza altri filtri. In tal caso il nostro server è ancora accessibile sulla porta 80.

Adesso colleghiamo la catena Cerberus alla catena predefinita INPUT, inserendo un jump (un salto potremmo dire)

A questo punto il server non è più accessibile dalla porta 80.

Se interroghiamo iptables per vedere le configurazioni presenti, vedremo qualcosa come questo:

Faccio notare come alla chain Cerberus è segnato un riferimento (1 references)

Per rimuovere il riferimento, e quindi riattivare la porta 80, è sufficiente eseguire:

ATTENZIONE! Bisogna tenere conto dell’ordine della catena e dove viene collegata ogni nuova catena. Immaginiamo di eseguire i seguenti comandi:

In questo modo ripristiniamo tutta la catena INPUT, impostando il criterio su ACCEPT, quindi permettiamo l’uscita dei pacchetti sulla porta 80. In questo caso, la catena Cerberus non serve a nulla.

5. Cambiare ordine ai filtri (anelli) sulla catena

Benché sia possibile eliminare i singoli filtri, non è possibile ordinarli. Esiste però un trucco, ed il seguente:

Questo creerà un file iptables.txt nella posizione nella quale ci troviamo. Apriamo e modifichiamo il file:

Quello che ci verrà mostrato è il set di tutte le regole impostate nel firewall. Nel mio caso, dopo le ultime modifiche le regole saranno:

A questo punto modifico il file invertendo tra di loro la riga 8 e la 9, ottenendo il seguente file:

A questo punto salviamo il file ed importiamolo nel firewall digitando:

Adesso controllando di nuovo la configurazione del firewall vedremo:

Adesso possiamo verificare che la porta 80 sia bloccata.

ATTENZIONE! Ricordarsi di cancellare il file iptables.txt se non si trova in un posto sicuro.

6. Eliminare un filtro (anello) della catena

Per eliminare un singolo filtro della catena è sufficiente dichiararlo al “contrario”. Se per esempio per aggiungere il suddetto filtro sulla porta 80 abbiamo digitato:

Per rimuoverlo è sufficiente digitare:

Faccio notare che l’unico parametro che cambia è la -A che diventa -D, che starebbe per delete, ovvero cancella.

La rimozione può essere anche effettuata in base al numero di riga nella catena interessata. La prima riga equivale ad 1.

Se avessi la seguente configurazione:

E volessi cancellare il filtro alla riga 2, ovvero

Mi basterebbe digitare:

Infine un modo ancora più veloce è quello illustrato al punto 5 per ordinare le regole, semplicemente rimuovendole dal file di testo e reimportandolo.

7. Aggiungere intervalli di porte ad iptables

Per aggiungere un intervallo di porte, per esempio dalla 6000 alla 6010, è sufficiente digitare:

Se si interroga iptables all’intervallo scelto si potrebbe vedere qualcosa di simile:

Nella colonna finale notiamo dpts che sta per destination ports, x11 che è il nome della porta 6000, utilizzata da X Windows System. Se la porta non avesse avuto un nome sarebbe comparso il numero.

Se volessimo invece abilitare diverse porte contemporaneamente sarebbe sufficiente digitare:

In questo caso attiviamo le porte 20, 21, 22, 80, 443 e l’intervallo delle porte comprese tra la 6000 e la 6010.

8. Bloccare un indirizzo IP

Per bloccare un indirizzo IP è sufficiente digitare:

-s sta per source (sorgente), ovvero origine della connessione.

Se volessimo bloccare un indirizzo IP ad una determinata porta potremmo digitare:

Questo blocca la porta 80 solo per l’indirizzo 10.0.2.30.

Adesso proviamo a digitare:

Questo bloccherà tutte le connessioni sulla porta 80, eccetto quelle provenienti dall’indirizzo 10.0.2.2.

9. Firewall su OUTPUT

Potremmo dire, per semplificare l’idea, che mentre le regole di INPUT si applicano al modello client ⇒ server (noi siamo il server) quelle di OUTPUT si applicano server ⇒ client. Ovvero al momento in cui il nostro server cerca di uscire verso l’esterno.

Questo avviene praticamente in tutte le connessioni, per esempio quando ci colleghiamo in SSH noi dobbiamo poter parlare da fuori al server (client ⇒ server), ma il server deve anche poterci rispondere (server ⇒ client).

Se digitassimo:

Praticamente nulla uscirebbe dal server.

Per capire meglio questa cosa proviamo a fare la seguente prova. Anzitutto assicuriamoci che l’OUTPUT non abbia filtri e sia su ACCEPT.

Proviamo a scaricare un file sul nostro server (per esempio il file zip di installazione di WordPress). Digitiamo:

Questo scaricherà nella cartella dove ci troviamo un file chiamato latest.tar.gz.

In questo momento non ci interessa tanto il file quanto il fatto che possa scaricarlo. Adesso proviamo a digitare i seguenti due comandi:

Questo aggiungerà due regole, la prima, che abbiamo già visto, per mantenere aperte le connessioni stabilite, la seconda per bloccare tutte le altre connessioni dall’interno. Questo significa che se un client interroga il server, quindi stabilisce una connessione del tipo client ⇒ server (come quando accediamo con putty al server), allora anche la relativa connessione server ⇒ client necessaria sarà permessa. Altrimenti sarà impossibile collegarsi da dentro al server verso l’esterno.

Se adesso tentiamo il comando precedente:

Incontriamo il seguente errore:

Questa connessione dovrebbe avvenire sulla porta 443 (HTTPS) quindi possiamo provare ad aprirla digitando:

Ma anche così facendo il download si blocca sulla risoluzione del dominio. Questo avviene perché il server deve potersi connettere anche in TCP e UDP al DNS sulla porta 53. Quindi è necessario abilitare anche tale filtro digitando:

A questo punto il download può avvenire.

Inutile dire che mantenere questo genere di blocco è di scarso interesse quando siamo noi i soli a gestire il server.

10. Configurare il firewall standard per server web con Apache, Webmin, FTP, POP3, SMTP, IMAP e SSH

Fatti tutti questi esperimenti scriviamo la configurazione per il nostro firewall standard, aprendo le porte per i suddetti servizi:

Il risultato dovrebbe apparire come quello seguente:

Per maggiori dettagli sull’associazione tra protocolli e fare riferimento a questa pagina di Wikipedia.

Le uniche porte non predefinite sono quelle per l’FTP passivo che ho messo, giusto per prova, dalla 6000 alla 6010. In realtà converrebbe associare un range più ampio, in base anche al numero di connessioni che si intende ricevere.

Per salvare il tutto installiamo iptables-persistent (se non lo abbiamo già fatto):

Ed infine digitiamo:

Vi ricordate che netfilter è il vero firewall di Linux e iptables “solo” un programma di gestione? Questo comando salva tutti i dati che abbiamo configurato.