Let’s encrypt e nginx

22 Dicembre 2015

Durante l’ultima workweek Mozilla a Orlando ho assistito a una breve presentazione di Let’s Encrypt da parte di Eric Rescorla (:ekr). Mi ero ripromesso di fare qualche prova al ritorno e, complice il passaggio da dedicato+debian+apache a vps+ubuntu+nginx, mi sono finalmente deciso a farlo.

Che cos’è “Let’s Encrypt”: un’autorità di certificazione indipendente e aperta che permette al proprietario di un sito web di ottenere gratuitamente dei certificati. Per ulteriori dettagli consiglio la lettura del post inaugurale del blog.

Veniamo al dunque: come ottenere un certificato per il dominio che ospita questo blog e configurare nginx per utilizzarlo.

Per prima cosa bisogna clonare il repository (non esiste ancora un pacchetto per Ubuntu):

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Come spiegato nella documentazione: letsencrypt-auto è un wrapper che si occupa di installare le dipendenze e creare un ambiente virtuale per Python, e il plugin per nginx è ancora altamente sperimentale (al contrario di Apache).

Nel mio caso voglio:

  • ottenere solamente il certificato senza modificare alcuna configurazione;
  • utilizzare il webserver “standalone” per recuperare il certificato. Siccome il plugin occupa la porta 80 o la 443, potrebbe essere necessario bloccare temporaneamente il server nginx.

Questo è il contenuto del file di configurazione per evitare una linea di comando infinita (modificare l’indirizzo email)

# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096
email = YOUREMAIL@EXAMPLE.COM

# Standalone authenticator on port 443
authenticator = standalone
standalone-supported-challenges = tls-sni-01

E questo il comando da lanciare (modificare il dominio e il percorso al file di configurazione)

./letsencrypt-auto certonly --config /root/cli.ini -d EXAMPLE.COM

La prima volta verrà chiesto di accettare le condizioni di servizio. Dopo pochi istanti il certificato verrà salvato in una sottocartella di /etc/letsencrypt/live/.

A questo punto bisogna aggiornare la configurazione del dominio in nginx. Personalmente ho utilizzato il generatore messo a disposizione da Mozilla, modificando

    ssl_dhparam /etc/nginx/dhparam.pem;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

E rimuovendo la linea ssl_session_tickets off; (non compatibile con la mia versione di nginx).

Per utilizzare questa configurazione, la prima volta bisogna generare una chiave Diffie-Hellman:

cd /etc/nginx
openssl dhparam -out dhparam.pem 2048

Se riuscite a leggere questo post, significa che non è esploso nulla.


Normalmente utilizzo Debian stable e Apache su tutte le mie VM. In questi giorni sto facendo qualche prova in locale con Ubuntu Server LTS (14.04) e NGINX, giusto per capire come funzionano le cose.

La prova è semplice: prendi una VM con risorse limitate (1 core, 2GB di RAM), installaci sopra WordPress (per la precisione un backup di questo blog), e prova a vedere come gira.

$ siege -c 100 -r 10 -b http://localvm/blog

Transactions:               2000 hits
Availability:             100.00 %
Elapsed time:               3.24 secs
Data transferred:          14.23 MB
Response time:              0.16 secs
Transaction rate:         617.28 trans/sec
Throughput:             4.39 MB/sec
Concurrency:               96.03
Successful transactions:        2000
Failed transactions:               0
Longest transaction:            0.69
Shortest transaction:           0.00

Poi mi è venuto in mente di provare a disattivare WP Super Cache.

$ siege -c 100 -r 10 -b http://localvm/blog

Transactions:               2000 hits
Availability:             100.00 %
Elapsed time:             138.59 secs
Data transferred:          14.15 MB
Response time:              6.61 secs
Transaction rate:          14.43 trans/sec
Throughput:             0.10 MB/sec
Concurrency:               95.39
Successful transactions:        2000
Failed transactions:               0
Longest transaction:           14.90
Shortest transaction:           0.00

Mentre nel primo caso il load era intorno a 0.2, nel secondo ha raggiunto piuttosto rapidamente 5. Morale della favola: utilizzate un plugin per la cache, c’è l’imbarazzo della scelta.


Oggi un’installazione di WordPress ospitata su Aruba ha iniziato a dare errori in area di amministrazione: impossibile accedere alla pagina degli aggiornamenti e alla gestione dei plugin, errori salvando nuove bozze.

Provato nell’ordine a:

  • Rinominare la cartella wp-content/plugins, nel dubbio disattivati anche i plugin via database.
  • Ripristinare i permessi in Aruba da Pannello di controllo hosting Linux → Strumenti e impostazioni → Riparazione Permissions [sigh].
  • Sostituire tutti i file del core di WordPress con quelli di un pacchetto pulito.

Il log di errori, accessibile via Pannello di controllo hosting Linux → Strumenti e impostazioni → Mostra log degli errori, riporta “End of script output before headers” per ogni pagina di errore visualizzata.

A questo punto ho aperto un ticket di assistenza con scarse speranze di soluzione.

Nel frattempo l’illuminazione è arrivata via Twitter da San Beggi: controlla la versione di PHP.

L’ho trovata impostata a 5.2.x, e visto che il tutto ha sempre funzionato dubito sia mai stata impostata a quel valore, considerato anche questo post di “solo” 4 anni fa.

Morale della favola: controllate la versione di PHP, anche a prescindere da eventuali errori.


Questa mattina ho scoperto che il codice utilizzato da anni per visualizzare in WordPress i video recuperati da un feed RSS di YouTube ha smesso di funzionare. Invece di visualizzare il video corretto, ci si trova davanti a questo avviso.

Ecco il codice aggiornato e ripulito. Il videoId è disponibile direttamente nell’XML del feed.

<?php
include_once(ABSPATH . WPINC . '/feed.php');

$get_videos = function ($feed_data) {
    $output = "<ul>\n";
    if (! $feed_data) {
        $output .= "<li>Nessun video disponibile</li>\n";
    } else {
        foreach ($feed_data as $item) {
            $youtubetitle = $item->get_title();
            $video_id = $item->get_item_tags(
                'http://www.youtube.com/xml/schemas/2015',
                'videoId'
            );
            $youtubeid = $video_id[0]['data'];

            $output .= "<li>\n";
            $output .= '<iframe width="240" height="176" src="https://www.youtube.com/embed/' .
                       $youtubeid . '?controls=0&amp;showinfo=0" frameborder="0"></iframe>';
            $output .= "<span>{$youtubetitle}</span>\n";
            $output .= "</li>\n";
        }
    }
    $output .= "</ul>\n";

    return $output;
};

?>

<h3>Video</h3>
<?php
    $url = **** URL del feed RSS****;
    $rss = fetch_feed($url);
    if (! is_wp_error($rss)) {
        // Verifica se l'oggetto è stato creato correttamente
        // Individua il numero di video presenti, al massimo leggine 3.
        $maxitems = $rss->get_item_quantity(3);
        // Crea un array di tutti gli elementi (il primo elemento ha indice 0).
        $rss_items = $rss->get_items(0, $maxitems);
    }
    echo $get_videos($rss_items)
?>

Ho iniziato a lavorarci per capire i limiti delle idee che ho in testa. La strada è ancora molto lunga e irta di ostacoli, considerando anche che dalla prossima settimana avrò un nuovo lavoro da seguire, ma almeno è un inizio 😉

Mozilla Italia 2013-05-01 10-54-45

P.S: c’è anche l’immagine non ridimensionata da 1,5 MB, se proprio ci tieni a vederla è qui.


WordPress multilingua

17 Dicembre 2012

Tempo fa avevo accennato al discorso blog multilingua con WordPress. Fino alla versione 3.4 ho sempre utilizzato il plugin qTranslate, scoperto ereditando in gestione una vecchia installazione di WordPress (mannenews.com). Il problema è che lo sviluppatore di questo plugin è praticamente sparito dalla circolazione e ci sono evidenti problemi di funzionamento con WordPress 3.5 (aggirabili mettendo pezze al codice fornite da un utente del forum).

Per il momento ho deciso di provare WPML. È un plugin a pagamento, il costo è ragionevole e ci sono 30 giorni per valutarne il funzionamento, sembra essere ben fatto anche se per il momento sono bloccato con l’importazione dei contenuti da qTranslate (ticket in sospeso con l’assistenza): il plugin di importazione funziona correttamente per “pulire” il codice lasciando una sola lingua, crea invece parecchio caos quando vengono mantenute più lingue. Il numero elevato di utenti del plugin e il fatto che sia a pagamento dovrebbe garantire la continuità e la tempestività dello sviluppo, cosa non da poco quando ti trovi con un sito con 600 articoli e 70 pagine…

P.S. non c’entra nulla, ma dopo 8 anni di attività ho finalmente un logo aziendale decente 🙂