<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Marco Lazzarotto</title><link>https://lazzarotto.dev/blog/</link><description>Recent content on Marco Lazzarotto</description><generator>Hugo -- gohugo.io</generator><language>it</language><managingEditor>postmaster@mlazzarotto.it (Marco Lazzarotto)</managingEditor><webMaster>postmaster@mlazzarotto.it (Marco Lazzarotto)</webMaster><copyright>Marco Lazzarotto</copyright><lastBuildDate>Fri, 01 May 2026 00:00:00 +0100</lastBuildDate><atom:link href="https://lazzarotto.dev/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Mitigare la vulnerabilità 'Copy Fail' (CVE-2026-31431) con un semplice Playbook Ansible</title><link>https://lazzarotto.dev/blog/mitigare-la-vulnerabilit%C3%A0-copy-fail-cve-2026-31431-con-un-semplice-playbook-ansible/</link><pubDate>Fri, 01 May 2026 00:00:00 +0100</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/mitigare-la-vulnerabilit%C3%A0-copy-fail-cve-2026-31431-con-un-semplice-playbook-ansible/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Mitigare la vulnerabilità 'Copy Fail' (CVE-2026-31431) con un semplice Playbook Ansible" /&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/mlazzarotto/copy-fail-CVE-2026-31431-mitigation-ansible-playbook" target="_blank" rel="noopener"
&gt;Link diretto al repo Github&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="in-poche-parole-cè-un-nuovo-bug-critico-per-linux-in-circolazione"&gt;In poche parole: c&amp;rsquo;è un nuovo bug critico per Linux in circolazione
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://copy.fail/" target="_blank" rel="noopener"
&gt;&amp;lsquo;Copy Fail&amp;rsquo;&lt;/a&gt; è un nuovo e fastidioso bug di local privilege escalation, &lt;a class="link" href="https://cert.europa.eu/publications/security-advisories/2026-005/" target="_blank" rel="noopener"
&gt;CVE-2026-31431&lt;/a&gt;, trovato dal team di analisti &lt;a class="link" href="https://xint.io/products/xint-code" target="_blank" rel="noopener"
&gt;Xint Code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Questo bug in pratica permette all&amp;rsquo;attaccante di ottenere i permessi di &lt;em&gt;root&lt;/em&gt; su molti sistemi operativi Linux (Ubuntu, Debian, RHEL, Suse, Alma, Amazon Linux), con uno script Python di soli 732 bytes.&lt;/p&gt;
&lt;p&gt;&amp;lsquo;Copy Fail&amp;rsquo; richiede solo un account utente locale senza privilegi: nessun accesso alla rete, nessuna funzionalità di debug del kernel, nessuna libreria preinstallata. L&amp;rsquo;API di crittografia del kernel (AF_ALG) è abilitata di default praticamente in tutte le distribuzioni principali, quindi l&amp;rsquo;intero intervallo di patch dal 2017 in poi è vulnerabile.&lt;/p&gt;
&lt;h2 id="capire-bene-la-vulnerabilità-copy-fail"&gt;Capire bene la vulnerabilità &amp;lsquo;Copy Fail&amp;rsquo;
&lt;/h2&gt;&lt;p&gt;In poche parole, immaginate il kernel Linux che per evitare di leggere sempre da disco i file, ne tiene una copia in memoria: la cosiddetta &lt;em&gt;page cache&lt;/em&gt;. Questa cache viene usata normalmente per velocizzare alcune operazioni da parte del kernel. Tutto in regola.&lt;/p&gt;
&lt;p&gt;Poi però, entra in gioco &lt;code&gt;algif_aead&lt;/code&gt;, uno dei moduli del kernel Linux che espone il sottosistema crittografico allo &lt;em&gt;userspace&lt;/em&gt; mediante l&amp;rsquo;interfaccia &lt;strong&gt;AF_ALG&lt;/strong&gt;. In parole povere? Una &lt;strong&gt;API&lt;/strong&gt; per i servizi crittografici, usata per esempio in protocolli come &lt;strong&gt;IPsec&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Nel lontano &lt;strong&gt;2017&lt;/strong&gt; è stato modificato questo modulo del kernel per renderlo più &amp;ldquo;efficiente&amp;rdquo; e gli hanno detto &amp;ldquo;Invece di fare una fotocopia del documento (il file) su cui devi lavorare, scrivi direttamente sull&amp;rsquo;originale che il kernel ti passa nella &lt;strong&gt;page cache&lt;/strong&gt;&amp;rdquo; grazie a una chiamata di sistema chiamata &lt;code&gt;splice()&lt;/code&gt; che passa i dati per riferimento invece di copiarli.&lt;/p&gt;
&lt;p&gt;Questa ottimizzazione &lt;em&gt;in-place&lt;/em&gt; è la radice del problema, perché ha permesso a un utente di scrivere dati dove non avrebbe assolutamente dovuto.&lt;/p&gt;
&lt;p&gt;E quali dati può scrivere un attaccante? Può andare a riscrivere una piccola parte di &lt;code&gt;/usr/bin/su&lt;/code&gt; per fare in modo di poter eseguire &lt;code&gt;su&lt;/code&gt; e diventare quindi l&amp;rsquo;utente &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="laspetto-fantasma"&gt;L&amp;rsquo;aspetto &amp;lsquo;fantasma&amp;rsquo;
&lt;/h3&gt;&lt;p&gt;Una delle cose più subdole di questa vulnerabilità è che la modifica avviene solo in &lt;em&gt;RAM&lt;/em&gt;. Il file su disco rimane intatto.&lt;/p&gt;
&lt;p&gt;Ciò significa che tutti i classici sistemi di controllo dell&amp;rsquo;integrità dei file (come Tripwire, AIDE, Wazuh, ecc.) non vedono nulla di strano.
Questo è molto pericoloso perché non lascia tracce su disco.&lt;/p&gt;
&lt;h3 id="la-fuga-dai-container"&gt;La fuga dai container
&lt;/h3&gt;&lt;p&gt;Prima parlavamo della &lt;strong&gt;page cache&lt;/strong&gt;, quella parte di memoria che serve a velocizzare le operazioni del kernel. Ebbene, la &lt;strong&gt;page cache&lt;/strong&gt; è condivisa tra tutti i container su uno stesso host (Podman, Docker, Kubernetes, etc.).&lt;/p&gt;
&lt;p&gt;Questo significa che un container vulnerabile o infettato da un attacco di tipo &lt;strong&gt;supply chain&lt;/strong&gt;, può fare &lt;strong&gt;container escape&lt;/strong&gt; in una maniera spaventosamente semplice.&lt;/p&gt;
&lt;h2 id="il-playbook-ansible-per-la-mitigazione-immediata"&gt;Il playbook Ansible per la mitigazione immediata
&lt;/h2&gt;&lt;p&gt;Traendo spunto dalla &lt;a class="link" href="https://kb.morrolinux.ovh/books/iac/page/playbook-di-mitigazione-cve-2026-31431" target="_blank" rel="noopener"
&gt;KB di Morrolinux&lt;/a&gt; e da questo &lt;a class="link" href="https://gist.github.com/m3nu/c19269ef4fd6fa53b03eb388f77464da" target="_blank" rel="noopener"
&gt;gist su Github dell&amp;rsquo;utente m3nu&lt;/a&gt; ho creato un playbook Ansible disponibile a questo link &lt;a class="link" href="https://github.com/mlazzarotto/copy-fail-CVE-2026-31431-mitigation-ansible-playbook" target="_blank" rel="noopener"
&gt;copy-fail-CVE-2026-31431-mitigation-ansible-playbook&lt;/a&gt; che permette di applicare la mitigazione e di fare rollback in seguito all&amp;rsquo;aggiornamento del kernel.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Apply Mitigation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;mitigation]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;not (rollback | bool)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# --- Debian family modprobe blacklist + unload ---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Apply modprobe blacklist (Debian family)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ansible_facts[&amp;#39;os_family&amp;#39;] == &amp;#39;Debian&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Create modprobe blacklist for {{ target_module }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible.builtin.copy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ modprobe_conf_path }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; # Generated by Ansible — CVE-2026-31431 mitigation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; install {{ target_module }} /bin/false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0644&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Unload module {{ target_module }} if currently loaded&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;community.general.modprobe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ target_module }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;absent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;register&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rmmod_result&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;failed_when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;rmmod_result is failed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#39;not currently loaded&amp;#39; not in (rmmod_result.msg | default(&amp;#39;&amp;#39;))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; and &amp;#39;not currently loaded&amp;#39; not in (rmmod_result.stderr | default(&amp;#39;&amp;#39;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#39;is in use&amp;#39; not in (rmmod_result.msg | default(&amp;#39;&amp;#39;))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; and &amp;#39;is in use&amp;#39; not in (rmmod_result.stderr | default(&amp;#39;&amp;#39;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Remind operator to reboot if module was in use (Debian)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#39;is in use&amp;#39; in (rmmod_result.msg | default(&amp;#39;&amp;#39;))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; or &amp;#39;is in use&amp;#39; in (rmmod_result.stderr | default(&amp;#39;&amp;#39;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible.builtin.debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;REMINDER: Module was in use and could not be unloaded. Reboot required to complete mitigation.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# --- kernel initcall blacklist (RHEL/Alma 9 and 10 only) ---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Apply kernel initcall blacklist (Red Hat family)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ansible_facts[&amp;#39;os_family&amp;#39;] == &amp;#39;RedHat&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ansible_facts[&amp;#39;distribution_major_version&amp;#39;] in [&amp;#39;9&amp;#39;, &amp;#39;10&amp;#39;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Check current grubby kernel args (pre-change)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible.builtin.command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;grubby --info=ALL&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;register&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;grubby_info_pre&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;changed_when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;check_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Add &amp;#39;{{ target_kernel_arg }}&amp;#39; to all kernels via grubby&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible.builtin.command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;grubby --update-kernel=ALL --args=&amp;#39;{{ target_kernel_arg }}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;register&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;grubby_add_result&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;changed_when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;target_kernel_arg not in grubby_info_pre.stdout&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Remind operator to reboot (RHEL)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;grubby_add_result.changed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ansible.builtin.debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;REMINDER: Kernel args changed. Reboot required to activate mitigation.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="analizziamo-il-playbook"&gt;Analizziamo il playbook
&lt;/h3&gt;&lt;p&gt;Il playbook è compatibile con sistemi operativi basati su RHEL (CentOS, Rocky, Alma) e basati su Debian (Ubuntu e Mint).
Di base utilizza la funzione &lt;code&gt;serial&lt;/code&gt; per eseguire il playbook solo su un numero limitato di host simultaneamente, di default il &lt;strong&gt;25%&lt;/strong&gt;. Ad esempio, avendo 100 host nell&amp;rsquo;&lt;em&gt;inventory&lt;/em&gt;, la mitigazione sarà applicata a 25 host nel primo batch, 25 nel secondo e così via.&lt;/p&gt;
&lt;p&gt;La funzione &lt;code&gt;max_fail_percentage&lt;/code&gt; invece, tollera un tasso di errori del 20%. Ad esempio, se ci sono 25 host nel batch, se 6 o più host falliscono, il job sarà abortito.&lt;/p&gt;
&lt;p&gt;Il &lt;strong&gt;Pre Task&lt;/strong&gt; mostra alcune informazioni sul sistema operativo e sul kernel per ogni host e raccoglie informazioni sullo stato del sistema.&lt;/p&gt;
&lt;p&gt;Il &lt;strong&gt;Task&lt;/strong&gt; per le distribuzioni Debian-based disabilita il modulo kernel e lo mette in blacklist, e se il modulo è in uso, ricorda all&amp;rsquo;utente di riavviare il sistema.
Per le distribuzioni RHEL-based invece, usa il comando &lt;code&gt;grubby&lt;/code&gt; per disabilitare il modulo e ricorda sempre all&amp;rsquo;utente di riavviare il sistema.&lt;/p&gt;
&lt;p&gt;Il &lt;strong&gt;Post Task&lt;/strong&gt; raccoglie ulteriori informazioni e presenta all&amp;rsquo;utente un sommario delle azioni eseguite.&lt;/p&gt;
&lt;h3 id="come-eseguirlo"&gt;Come eseguirlo
&lt;/h3&gt;&lt;p&gt;Innanzitutto è necessario preparare il file di configurazione di Ansible e l&amp;rsquo;inventory come in ogni playbook Ansible. Successivamente lanciare un ping per controllare la raggiungibilità dei server.
Infine, usare &lt;code&gt;ansible-playbook mitigation-playbook.yaml&lt;/code&gt; per lanciare la mitigazione su tutti i server, o usare l&amp;rsquo;opzione &lt;code&gt;--limit webservers&lt;/code&gt; per limitare il playbook solo a un determinato gruppo di host.
Per il &lt;strong&gt;rollback&lt;/strong&gt;, come sopra, ma si userà l&amp;rsquo;opzione &lt;code&gt;--tags rollback&lt;/code&gt; per eseguire solo i task di rollback.&lt;/p&gt;
&lt;h2 id="verificare-che-la-mitigazione-funzioni"&gt;Verificare che la mitigazione funzioni
&lt;/h2&gt;&lt;p&gt;In seguito all&amp;rsquo;esecuzione del playbook, è necessario verificare che la mitigazione abbia avuto effetto.
Per fare ciò usare questi due metodi, in base alla distribuzione dei vostri host:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sulle distribuzioni Debian-based usare &lt;code&gt;lsmod | grep algif_aead&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sulle distribuzioni RHEL-based usare &lt;code&gt;grep initcall_blacklist /proc/cmdline&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="la-mia-opinione-un-passo-in-più-per-i-container"&gt;La mia opinione: un passo in più per i container
&lt;/h2&gt;&lt;p&gt;Personalmente, la mia opinione è che fermarsi alla configurazione dell&amp;rsquo;host non sia sufficiente se fai girare dei container. Poiché i container condividono il kernel della macchina host, un riavvio o un errore di configurazione che ricarica il modulo vulnerabile per sbaglio lascerebbe i tuoi workload di nuovo esposti.&lt;/p&gt;
&lt;p&gt;Sappiamo che questo exploit ha bisogno di aprire un socket della famiglia AF_ALG per poter comunicare con la Crypto API del kernel. Per questo motivo, vi consiglio caldamente di implementare un approccio &amp;ldquo;defense in depth&amp;rdquo; (difesa su più livelli) utilizzando &lt;strong&gt;seccomp&lt;/strong&gt;. Se configurate un profilo personalizzato per il vostro container runtime, potete dire al sistema di bloccare del tutto le syscall di tipo socket dirette verso AF_ALG. In questo modo, anche se il modulo algif_aead dovesse magicamente riattivarsi sull&amp;rsquo;host, il kernel &amp;ldquo;segherà&amp;rdquo; in tronco qualsiasi tentativo del container di sfruttarlo.&lt;/p&gt;
&lt;p&gt;Un&amp;rsquo;esempio di policy &lt;strong&gt;seccomp&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;defaultAction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SCMP_ACT_ALLOW&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;syscalls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;names&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;socket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SCMP_ACT_ERRNO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;op&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SCMP_CMP_EQ&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;comment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Blocca i socket AF_ALG (famiglia 38) per mitigare Copy Fail&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="non-abbassate-la-guardia"&gt;Non abbassate la guardia!
&lt;/h2&gt;&lt;p&gt;Eccoci arrivati alla fine. C&amp;rsquo;è una cosa fondamentale che ci tengo a precisare: la soluzione basata su Ansible e modprobe che abbiamo appena visto è un&amp;rsquo;ottima &amp;ldquo;pezza&amp;rdquo; per proteggersi nell&amp;rsquo;immediato, ma ricordatevi che non è la cura definitiva.&lt;/p&gt;
&lt;p&gt;La mia opinione personale è che i workaround di sicurezza non dovrebbero mai essere dimenticati sui server a prendere polvere. Tenete d&amp;rsquo;occhio i bollettini di sicurezza dei vostri vendor (che sia Canonical, Red Hat, SUSE o altri).
Non appena rilasceranno i pacchetti del kernel aggiornati con la patch ufficiale per la CVE-2026-31431, programmate l&amp;rsquo;installazione e un bel riavvio delle macchine.
Una volta che i sistemi avranno il kernel patchato, potrete fare pulizia e rimuovere i file creati da questo playbook.&lt;/p&gt;
&lt;p&gt;Spero che questa guida vi abbia fatto risparmiare qualche mal di testa! Se avete dubbi, domande o se volete condividere come state gestendo questa CVE nei vostri ambienti, contattatemi pure su &lt;a class="link" href="https://www.linkedin.com/in/marco-lazzarotto/" target="_blank" rel="noopener"
&gt;LinkedIn&lt;/a&gt; o se avete bisogno di una consulenza personalizzata, potete prenotare una call nel footer di questa pagina.&lt;/p&gt;</description></item><item><title>Wall Street si affida all'IA, l'Europa costruisce il suo fortino digitale: due futuri a confronto</title><link>https://lazzarotto.dev/blog/wall-street-si-affida-allia-leuropa-costruisce-il-suo-fortino-digitale-due-futuri-a-confronto/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0100</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/wall-street-si-affida-allia-leuropa-costruisce-il-suo-fortino-digitale-due-futuri-a-confronto/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Wall Street si affida all'IA, l'Europa costruisce il suo fortino digitale: due futuri a confronto" /&gt;&lt;p&gt;La notizia è di quelle che definiscono un&amp;rsquo;epoca: la Casa Bianca sta spingendo le più grandi banche d&amp;rsquo;affari del mondo&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; — parliamo di colossi come Goldman Sachs, Bank of America, e Citigroup — a usare l&amp;rsquo;intelligenza artificiale di Anthropic (Claude Mythos) per la loro cybersicurezza. Un&amp;rsquo;alleanza tra governo, finanza e big tech che sembra un trailer di un film di fantascienza.&lt;/p&gt;
&lt;p&gt;Ma dietro i riflettori di questa mossa apparentemente avveniristica, si nascondono due domande fondamentali che ci riguardano tutti, da Trento a San Francisco:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L&amp;rsquo;IA sta per rendere obsoleti gli esperti di sicurezza informatica?&lt;/li&gt;
&lt;li&gt;Mentre gli USA si legano a un&amp;rsquo;unica &amp;ldquo;scatola nera&amp;rdquo;, cosa sta facendo l&amp;rsquo;Europa per non rimanere a guardare?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Spoiler: le risposte sono molto più complesse e interessanti di un semplice &amp;ldquo;sì&amp;rdquo; o &amp;ldquo;no&amp;rdquo;.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="il-mito-dellia-ladra-di-lavoro-i-dati-dicono-altro"&gt;Il mito dell&amp;rsquo;IA &amp;ldquo;ladra&amp;rdquo; di lavoro: i dati dicono altro
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&amp;ldquo;Ok Google, trovami un bug&amp;rdquo;: il mito dell&amp;rsquo;IA che ci ruba il lavoro&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La prima reazione istintiva è la paura. Se un&amp;rsquo;IA può fare red teaming e scovare vulnerabilità, che ne sarà delle decine di migliaia di professionisti che oggi lo fanno come lavoro?&lt;/p&gt;
&lt;p&gt;Qui, per fortuna, i dati ci vengono in soccorso e dipingono un quadro completamente diverso. Partiamo da un numero che fa impressione: secondo il Fortinet Global Cybersecurity Skills Gap Report del 2025&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, a livello globale mancano all&amp;rsquo;appello 4,7 milioni di professionisti della cybersecurity. Non è un errore di battitura. In Italia, il divario è altrettanto serio, con circa 136.000 annunci di lavoro all&amp;rsquo;anno nel settore ICT contro solo 73.000 nuovi talenti in ingresso&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;IA non arriva in un mercato saturo per rubare posti, ma in un settore in piena emergenza dove le forze umane non bastano più.&lt;/p&gt;
&lt;h2 id="il-vero-gioco-monopolio-usa-contro-sovranità-europea"&gt;Il vero gioco: Monopolio USA contro Sovranità Europea
&lt;/h2&gt;&lt;p&gt;Secondo Gartner&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;, entro il 2026 il 50% dei Centri Operativi di Sicurezza (SOC) userà l&amp;rsquo;IA come supporto decisionale. L&amp;rsquo;obiettivo non è sostituire l&amp;rsquo;analista, ma dargli un &amp;ldquo;superpotere&amp;rdquo;: automatizzare i compiti ripetitivi, analizzare quantità di dati ingestibili per un umano e segnalare solo le anomalie che richiedono intuito e creatività. L&amp;rsquo;IA diventa un alleato, un force multiplier che permette ai team, oggi sotto organico e stressati, di concentrarsi sulla strategia anziché sulla routine.&lt;/p&gt;
&lt;p&gt;La mia opinione è che il profilo del professionista della sicurezza evolverà: da tecnico iper-specializzato a stratega e supervisore di sistemi intelligenti. Il suo compito non sarà più trovare l&amp;rsquo;ago nel pagliaio, ma insegnare all&amp;rsquo;IA come si cerca l&amp;rsquo;ago e, soprattutto, capire se quello che ha trovato è davvero un ago.&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Il vero gioco: USA vs. Europa, Monopolio vs. Sovranità&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;E qui arriviamo al cuore geopolitico della faccenda.&lt;/p&gt;
&lt;h3 id="atto-primo-la-scommessa-americana-sul-tutto-e-subito"&gt;Atto Primo: La scommessa americana sul &amp;ldquo;tutto e subito&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;Da una parte abbiamo il &lt;strong&gt;Team USA&lt;/strong&gt;. Il governo fa da sponsor, Wall Street adotta in massa una soluzione proprietaria e potentissima. Veloce, efficiente, centralizzato. La quintessenza dell&amp;rsquo;approccio americano. Persino Jamie Dimon di JPMorgan, noto scettico, è stato invitato al tavolo &lt;sup id="fnref1:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;(anche se non ha partecipato). Il rischio? Un vendor lock-in spaventoso. Affidare la sicurezza dell&amp;rsquo;infrastruttura finanziaria più critica del pianeta a un unico fornitore privato crea un singolo punto di fallimento (un single point of failure) dalle conseguenze inimmaginabili. E, non dimentichiamolo, un precedente storico che ci insegna a essere prudenti quando agenzie governative (come l&amp;rsquo;NSA) e colossi tecnologici dialogano troppo intimamente.&lt;/p&gt;
&lt;h3 id="atto-secondo-la-maratona-europea-per-lautonomia"&gt;Atto Secondo: La maratona europea per l&amp;rsquo;autonomia
&lt;/h3&gt;&lt;p&gt;Dall&amp;rsquo;altra parte c&amp;rsquo;è il &lt;strong&gt;Team Europa&lt;/strong&gt;, che gioca una partita completamente diversa. Più lenta, più frammentata, ma con un obiettivo chiarissimo: la sovranità digitale. L&amp;rsquo;Europa ha capito che la dipendenza tecnologica è la nuova dipendenza energetica. E si sta muovendo.&lt;/p&gt;
&lt;p&gt;Contrariamente a quanto si pensa, non sono solo parole.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La rete dei Poli Europei per l&amp;rsquo;Innovazione Digitale (EDIH), con oltre 200 hub attivi, sta aiutando le piccole e medie imprese a digitalizzarsi scegliendo soluzioni tecnologiche europee. Non si tratta solo di innovare, ma di farlo costruendo un ecosistema autonomo.&lt;/li&gt;
&lt;li&gt;E anche se un &amp;ldquo;Fondo per la Sovranità Digitale&amp;rdquo; a livello UE non ha ancora cifre definite, iniziative nazionali come il Fondo per la Repubblica Digitale in Italia (con circa 220 milioni di euro) dimostrano che si sta investendo per colmare il gap di competenze.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cosa significa tutto questo? Due visioni del futuro&lt;/p&gt;
&lt;h2 id="due-filosofie-una-sola-scelta-quale-futuro-digitale-vogliamo"&gt;Due filosofie, una sola scelta: quale futuro digitale vogliamo?
&lt;/h2&gt;&lt;p&gt;Quello a cui stiamo assistendo non è solo un dibattito tecnico, ma uno scontro tra due filosofie.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;approccio americano privilegia la velocità e la potenza, anche a costo di centralizzare il potere nelle mani di pochi giganti e creare dipendenze strategiche.
L&amp;rsquo;approccio europeo è più cauto. Punta a costruire un&amp;rsquo;alternativa resiliente, aperta e distribuita, anche se questo richiede più tempo e coordinamento.&lt;/p&gt;
&lt;p&gt;Per chi lavora nel settore, la lezione è duplice. Primo: l&amp;rsquo;IA non è una minaccia, ma lo strumento che definirà il prossimo decennio. Ignorarla non è un&amp;rsquo;opzione. Secondo: la scelta degli strumenti che usiamo non è mai neutrale. Dietro un software c&amp;rsquo;è un modello di business, un&amp;rsquo;ideologia e una strategia geopolitica.&lt;/p&gt;
&lt;p&gt;La vera domanda, quindi, non è se useremo l&amp;rsquo;IA per la nostra sicurezza, ma quale IA sceglieremo: quella chiusa e centralizzata o quella aperta e federata?&lt;/p&gt;
&lt;p&gt;La risposta a questa domanda deciderà chi controllerà le chiavi del nostro futuro digitale.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a class="link" href="https://www.theguardian.com/technology/2026/apr/10/us-summoned-bank-bosses-to-discuss-cyber-risks-posed-by-anthropic-latest-ai-model" target="_blank" rel="noopener"
&gt;https://www.theguardian.com/technology/2026/apr/10/us-summoned-bank-bosses-to-discuss-cyber-risks-posed-by-anthropic-latest-ai-model&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a class="link" href="https://www.digitalic.it/tech-news/global-cybersecurity-skills-gap-report-di-fortinet-la-ricerca-che-rivela-la-crisi-di-competenze-nella-security" target="_blank" rel="noopener"
&gt;https://www.digitalic.it/tech-news/global-cybersecurity-skills-gap-report-di-fortinet-la-ricerca-che-rivela-la-crisi-di-competenze-nella-security&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a class="link" href="https://culturedigitali.eu/notizie/ruoli-nella-cybersecurity-i-piu-richiesti-nel-2026/" target="_blank" rel="noopener"
&gt;https://culturedigitali.eu/notizie/ruoli-nella-cybersecurity-i-piu-richiesti-nel-2026/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a class="link" href="https://www.lanazione.it/pubbliredazionali/in-italia-mancano-236mila-professionisti-digitali-i-lavori-ict-piu-richiesti-e-le-nuove-competenze-da-sviluppare-fgf06asj" target="_blank" rel="noopener"
&gt;https://www.lanazione.it/pubbliredazionali/in-italia-mancano-236mila-professionisti-digitali-i-lavori-ict-piu-richiesti-e-le-nuove-competenze-da-sviluppare-fgf06asj&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a class="link" href="https://www.securityopenlab.it/news/6131/gartner-le-mosse-dei-ciso-per-lai.html" target="_blank" rel="noopener"
&gt;https://www.securityopenlab.it/news/6131/gartner-le-mosse-dei-ciso-per-lai.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>Perché ho spostato il mio blog da Cloudflare Pages a Kubernetes: una storia di sub-directory e libertà</title><link>https://lazzarotto.dev/blog/perch%C3%A9-ho-spostato-il-mio-blog-da-cloudflare-pages-a-kubernetes-una-storia-di-sub-directory-e-libert%C3%A0/</link><pubDate>Mon, 13 Apr 2026 00:00:00 +0100</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/perch%C3%A9-ho-spostato-il-mio-blog-da-cloudflare-pages-a-kubernetes-una-storia-di-sub-directory-e-libert%C3%A0/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Perché ho spostato il mio blog da Cloudflare Pages a Kubernetes: una storia di sub-directory e libertà" /&gt;&lt;h2 id="lidillio-iniziale-perché-cloudflare-pages-sembrava-la-scelta-perfetta"&gt;L&amp;rsquo;idillio iniziale: perché Cloudflare Pages sembrava la scelta perfetta
&lt;/h2&gt;&lt;p&gt;25 luglio 2022, questo è stato il primo commit sul repo Github del mio blog. In precedenza usavo Wordpress con soddisfazione, ma mi sono accorto che usavo meno del 10% delle funzionalità del CMS per il mio blog, che richiedeva manutenzione continua per evitare rischi di sicurezza. Ho cominciato a vagliare diversi strumenti che mi potessero dare la possibilità di scrivere un blog in formato semplice (Markdown), senza necessità di un backend e di un database e con una manutenzione minima.&lt;/p&gt;
&lt;p&gt;Fu durante quella ricerca che scoprii &lt;strong&gt;&lt;a class="link" href="https://lazzarotto.dev/blog/hugo-generatore-di-siti-statici/" &gt;Hugo&lt;/a&gt;&lt;/strong&gt; e ne fui subito molto soddisfatto sotto diversi punti di vista e decisi quindi di salvere i miei articoli su Github e fare l&amp;rsquo;hosting del sito su &lt;strong&gt;Cloudflare Pages&lt;/strong&gt;, visto che il mio dominio era gia&amp;rsquo; configurato li'.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;integrazione era perfetta: un push di un nuovo articolo sul branch &lt;code&gt;master&lt;/code&gt; (allora il branch di default aveva ancora quel nome, poi sostituito con &lt;em&gt;main&lt;/em&gt;) dava il segnale a Cloudflare Pages (ora chiamato &lt;em&gt;Workers &amp;amp; Pages&lt;/em&gt;) che era il momento di usare Hugo per rigenerare il contenuto statico del sito e pubblicarlo.&lt;/p&gt;
&lt;p&gt;Perfetto, non sbagliava mai un colpo e una volta sistemato, era la cosa piu&amp;rsquo; comoda e semplice del mondo.&lt;/p&gt;
&lt;h2 id="leggera-deviazione-unificare-i-domini-per-attrarre-piu-traffico-sul-portfolio"&gt;Leggera deviazione: unificare i domini per attrarre piu&amp;rsquo; traffico sul portfolio
&lt;/h2&gt;&lt;p&gt;Passano gli anni, arriviamo nel 2026 e inizio la mia carriera da freelancer in ambito networking e devops e ho bisogno di portare piu&amp;rsquo; traffico sul mio sito portfolio &lt;a class="link" href="https://lazzarotto.dev" target="_blank" rel="noopener"
&gt;lazzarotto.dev&lt;/a&gt; per attrarre potenziali clienti.&lt;/p&gt;
&lt;p&gt;Uno dei suggerimenti migliori che ho ricevuto, è quello di spostare il blog da &lt;em&gt;mlazzarotto.it&lt;/em&gt; (che ha portato 1000 visite negli ultimi 90 giorni) e unirlo al dominio &lt;em&gt;lazzarotto.dev&lt;/em&gt; per uniformare i domini.&lt;/p&gt;
&lt;p&gt;Il motivo era piuttosto semplice: agli occhi di Google avevo due siti web distinti e in competizione tra loro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mlazzarotto.it (il blog)&lt;/li&gt;
&lt;li&gt;lazzarotto.dev (il portfolio)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Qui avevo due strade:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;spostare il blog nel sottodominio &lt;code&gt;blog.lazzarotto.dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;spostare il blog nel path &lt;code&gt;lazzarotto.dev/blog&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Facendo qualche ricerca online, ho capito che la seconda opzioni era quella consigliata da tutti i &amp;ldquo;pro&amp;rdquo; del campo web design e SEO.&lt;/p&gt;
&lt;h2 id="lostacolo-inaspettato-il-problema-del-miodominiodevblog"&gt;L&amp;rsquo;ostacolo inaspettato: il problema del miodominio.dev/blog
&lt;/h2&gt;&lt;p&gt;Cloudflare &lt;em&gt;Workers &amp;amp; Pages&lt;/em&gt; funziona benissimo quando il sito statico da pubblicare viene esposto nella root del dominio (o sottodominio) come &lt;code&gt;https://mlazzarotto.it/&lt;/code&gt;, ma diventa velocemente un inferno cercare di pubblicare il sito web sul subpath &lt;code&gt;https://lazzarotto.dev/blog&lt;/code&gt; per via della logica di Cloudflare.&lt;/p&gt;
&lt;p&gt;Non nego di aver speso diverse ore a cercare di far funzionare i &lt;strong&gt;workers&lt;/strong&gt; per pubblicare il sito nel modo giusto, e ci sono anche arrivato vicino, ma c&amp;rsquo;era sempre qualche problema di alcune risorse (CSS e JS) che non venivano referenziate correttamente da Hugo. E quindi il sito era visibile, ma senza styling e senza componenti dinamici.&lt;/p&gt;
&lt;h2 id="il-momento-della-decisione-valutare-le-alternative"&gt;Il momento della decisione: valutare le alternative
&lt;/h2&gt;&lt;p&gt;Anche se il mio focus professionale non è primariamente sui servizi di hosting per siti statici, ho esplorato le alternative più comuni per il mio caso d&amp;rsquo;uso.&lt;/p&gt;
&lt;p&gt;Una delle prime alternative che ho scartato è stata GitHub Pages, principalmente per via di un uptime non sempre impeccabile per i miei standard. A questo si aggiunge una mia preferenza personale a distanziarmi dall&amp;rsquo;ecosistema Microsoft e dalla sua attuale direzione.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;immagine qui sotto e&amp;rsquo; stata presa da &lt;a class="link" href="https://mrshu.github.io/github-statuses/" target="_blank" rel="noopener"
&gt;https://mrshu.github.io/github-statuses/&lt;/a&gt; il giorno 11 aprile 2026 e oggettivamente non mi fa impazzire, per quanto il mio blog non necessiti di di uptime al 99.9999%.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/github_last_90_days_uptime_11042026.png"
loading="lazy"
alt="Github uptime last 90 days"
&gt;&lt;/p&gt;
&lt;p&gt;Esistono poi altre soluzioni come &lt;strong&gt;Netlify&lt;/strong&gt; e &lt;strong&gt;Vercel&lt;/strong&gt; ma rimaneva comunque il problema dell&amp;rsquo;uso di una &lt;em&gt;subpath&lt;/em&gt; per rendere disponibile questo blog su &lt;code&gt;https://lazzarotto.dev/blog&lt;/code&gt;.
Pertanto, visto che sto gia&amp;rsquo; facendo hosting del mio portfolio su Kubernetes usando Traefik come reverse proxy, ho deciso di tenere anche il blog nel mio homelab.&lt;/p&gt;
&lt;h2 id="la-nuova-architettura-unocchiata-al-nuovo-setup"&gt;La nuova architettura: un&amp;rsquo;occhiata al nuovo setup
&lt;/h2&gt;&lt;p&gt;La nuova architettura prevede l&amp;rsquo;uso di Gitea come repository e per la parte di &lt;strong&gt;Continuos Integration&lt;/strong&gt;, Kubernetes per il deployment del blog e ArgoCD per la parte di &lt;strong&gt;Continuos Delivery&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Con questi 3 strumenti sono riuscito a replicare in maniera soddisfacente la combinazione che usavo precedentemente, ovvero Github + Cloudflare Pages, in modo piuttosto semplice (relativamente) e che mi permette comunque di avere la pubblicazione di un nuovo post in meno di 5 minuti.&lt;/p&gt;
&lt;p&gt;Di seguito illustrero&amp;rsquo; come funziona la pipeline.&lt;/p&gt;
&lt;h3 id="gitea-il-controllo-del-mio-codice"&gt;Gitea: il controllo del mio codice
&lt;/h3&gt;&lt;p&gt;Utilizzo Gitea gia&amp;rsquo; da un po&amp;rsquo; di tempo per tenere in locale i miei progetti personali, tra i quali anche il codice del mio sito portfolio, e lo uso anche come software di Continuous Integration grazie alla funzionalita&amp;rsquo; &lt;strong&gt;Gitea Actions&lt;/strong&gt; che e&amp;rsquo; praticamente una copia di Github Actions.&lt;/p&gt;
&lt;p&gt;Nel repo del blog ho create quindi un workflow che crea un&amp;rsquo;immagine Docker, la carica sul registry Docker (sempre su Gitea) e poi modifica il manifest di Kubernetes in modo che ArgoCD aggiorni il deployment.&lt;/p&gt;
&lt;p&gt;La configurazione del workflow e&amp;rsquo; piuttosto semplice e usa alcuni packages esterni da Github.&lt;/p&gt;
&lt;h3 id="kubernetes-lorchestratore-di-tutto"&gt;Kubernetes: l&amp;rsquo;orchestratore di tutto
&lt;/h3&gt;&lt;p&gt;Mentre Gitea si occupa di gestire il codice sorgente, Kubernetes ha il compito di orchestrate i pod (2 repliche) ed assicurarsi che l&amp;rsquo;applicazione sia sempre funzionante grazie all&amp;rsquo;implementazione di healt-check.&lt;/p&gt;
&lt;p&gt;Il deploy avviene automaticamente grazie all&amp;rsquo;integrazione di ArgoCD che fa il deploy del nuovo &lt;strong&gt;replicaSet&lt;/strong&gt; appena Gitea modifica il manifest.&lt;/p&gt;
&lt;p&gt;Il tutto avviene mantenendo un&amp;rsquo;alta affidabilita&amp;rsquo; e senza downtime.&lt;/p&gt;
&lt;h3 id="il-quadro-generale"&gt;Il quadro generale
&lt;/h3&gt;&lt;p&gt;Di seguito potete vedere lo schema di come funziona il mio workflow e la pipeline tra Gitea, ArgoCD e Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/blog_workflow.webp"
loading="lazy"
alt="Workflow diagram"
&gt;&lt;/p&gt;
&lt;h2 id="riflessioni-finali-era-la-mossa-giusta"&gt;Riflessioni finali: era la mossa giusta?
&lt;/h2&gt;&lt;p&gt;Quindi, era la mossa giusta? Assolutamente sì.
Ho barattato la semplicità di un servizio gestito con la totale flessibilità di una soluzione mia, risolvendo il mio problema specifico e costruendo una piattaforma su cui potrò sperimentare ancora a lungo. Per me, è una vittoria su tutti i fronti.&lt;/p&gt;
&lt;p&gt;Ora confrontiamo i pro e i contro di questa soluzione.&lt;/p&gt;
&lt;h3 id="pro"&gt;Pro
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Controllo completo del workflow&lt;/li&gt;
&lt;li&gt;Codice sorgente privato nel mio homelab, cio&amp;rsquo; significa che non verra&amp;rsquo; usato da Github per il training di &lt;strong&gt;Copilot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Nessun costo (ovviamente, in questo calcolo non considero il costo più grande: il mio tempo; ma dato che l&amp;rsquo;obiettivo era anche fare pratica con nuovi strumenti, lo considero un investimento formativo a tutti gli effetti)&lt;/li&gt;
&lt;li&gt;Possibilita&amp;rsquo; di testare differenti tipi di workflow e fare pratica con gli strumenti&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="contro"&gt;Contro
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Uptime non allo stesso livello di Cloudflare (SPOF ovunque, del resto e&amp;rsquo; il mio laboratorio e non ho nessuna ridondanza)&lt;/li&gt;
&lt;li&gt;Velocita&amp;rsquo; forse leggermente minore (ma uso comunque Cloudflare per il caching)&lt;/li&gt;
&lt;li&gt;Piu&amp;rsquo; elementi che possono rompersi e quindi potenzialmente piu&amp;rsquo; tempo da perdere per sistemare cio&amp;rsquo; che si rompe.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="prossimamente-come-ho-automatizzato-tutto-con-argocd"&gt;Prossimamente: come ho automatizzato tutto con ArgoCD
&lt;/h2&gt;&lt;p&gt;Nel prossimo articolo di questo blog analizzero&amp;rsquo; nel dettaglio come ho implementato il deploy automatico tramite ArgoCD.&lt;/p&gt;</description></item><item><title>Attacco a LiteLLM: Perché pip install ti ha tradito e requirements.txt ti ha salvato</title><link>https://lazzarotto.dev/blog/attacco-a-litellm-perch%C3%A9-pip-install-ti-ha-tradito-e-requirements.txt-ti-ha-salvato/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0100</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/attacco-a-litellm-perch%C3%A9-pip-install-ti-ha-tradito-e-requirements.txt-ti-ha-salvato/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Attacco a LiteLLM: Perché pip install ti ha tradito e requirements.txt ti ha salvato" /&gt;&lt;h2 id="introduzione-lillusione-di-sicurezza-di-un-comando-innocente"&gt;Introduzione: L&amp;rsquo;illusione di sicurezza di un comando innocente
&lt;/h2&gt;&lt;p&gt;Chi non conosce il comando &lt;code&gt;pip&lt;/code&gt;? E&amp;rsquo; uno dei comandi piu&amp;rsquo; utilizzati per chi sviluppa codice in Python o per chi utilizza regolarmente software open-source distribuiti sul repository &lt;strong&gt;PyPi&lt;/strong&gt;. &lt;code&gt;pip&lt;/code&gt; e&amp;rsquo; quel comando che (almeno nella mia esperienza) non delude mai ed e&amp;rsquo; praticamente essenziale (anche se ultimamente sta cedendo il posto ad altri strumenti come &lt;strong&gt;Poetry&lt;/strong&gt; e &lt;strong&gt;uv&lt;/strong&gt;) per chi ha bisogno di installare librerie per sviluppare con Python, ma talvolta, questo senso di sicurezza puo&amp;rsquo; farci cadere in un brutto tranello.&lt;/p&gt;
&lt;p&gt;Ma cosa succede quando questa fiducia viene tradita? E&amp;rsquo; esattamente quello che e&amp;rsquo; successo il 24 marzo 2026.
Un tranello preparato con cura da un gruppo di hacker conosciuto come &lt;strong&gt;&lt;a class="link" href="https://www.redhotcyber.com/post/il-piu-grande-supply-chain-attack-e-servito-1000-ambienti-saas-compromessi/" target="_blank" rel="noopener"
&gt;TeamPCP&lt;/a&gt;&lt;/strong&gt; che ha trasformato &lt;code&gt;pip install&lt;/code&gt; in un&amp;rsquo;arma per raccogliere secrets (come variabili di sistema, chiavi SSH, credenziali di provider cloud) e tentare lateral movement tramite cluster Kubernetes.&lt;/p&gt;
&lt;h2 id="anatomia-di-un-disastro-annunciato-cosa-è-successo-a-litellm"&gt;Anatomia di un disastro annunciato: Cosa è successo a LiteLLM?
&lt;/h2&gt;&lt;p&gt;Il payload iniettato non era uno scherzo: era un credential stealer progettato per scandagliare l&amp;rsquo;ambiente alla ricerca di env vars, chiavi SSH, credenziali AWS/GCP/Azure, token Kubernetes, per poi esfiltrare tutto verso un dominio malevolo (models.litellm.cloud).&lt;/p&gt;
&lt;p&gt;Il team dietro a &lt;strong&gt;LiteLLM&lt;/strong&gt; ha infatti dei workflow CI/CD per portare il proprio software dallo stato di codice sorgente a pacchetto sul repo PyPi. Uno di questi workflow si occupa di eseguire una scansione del proprio codice e delle dipendenze (tramite &lt;strong&gt;Trivy&lt;/strong&gt;) prima di andare a distribuire il pacchetto.&lt;/p&gt;
&lt;p&gt;Ed e&amp;rsquo; stato proprio &lt;strong&gt;Trivy&lt;/strong&gt; (a quanto pare) ad aver permesso al gruppo &lt;strong&gt;TeamPCP&lt;/strong&gt; di bypassare questo workflow di sicurezza per caricare su PyPi le due versioni di LiteLLM vulnerabili.&lt;/p&gt;
&lt;h2 id="il-tradimento-di-pip-install-package"&gt;Il Tradimento di pip install &amp;lt;package&amp;gt;
&lt;/h2&gt;&lt;p&gt;Come scrivevo sopra, il comando &lt;strong&gt;pip&lt;/strong&gt; e&amp;rsquo; proprio quel comando di cui si ha solitamente fiducia cieca, a cui si affida il compito di aggiornare o installare le varie librerie necessarie e usandolo, pero&amp;rsquo;, diamo lasciamo il &amp;ldquo;controllo&amp;rdquo; a lui.&lt;/p&gt;
&lt;p&gt;Lasciando il controllo a pip, almeno in questo caso, ha causato pero&amp;rsquo; l&amp;rsquo;ingresso delle versioni vulnerabili di LiteLLM in miglia di sistemi, che sono diventati insicuri e potenzialmente compromessi. Cio&amp;rsquo; e&amp;rsquo; successo semplicemente perche&amp;rsquo; e&amp;rsquo; stato deciso di aggiornare le librerie senza curarsi di quale versione venisse installata.&lt;/p&gt;
&lt;p&gt;E non e&amp;rsquo; solo teoria. Il team di LiteLLM ha confermato che chi usava la loro immagine Docker ufficiale non e&amp;rsquo; stato colpito. Perché? Semplice: quell&amp;rsquo;immagine usava un file &lt;code&gt;requirements.txt&lt;/code&gt; con le versioni pinnate! È la prova concreta che questa pratica, da sola, ha fatto da scudo a chissà quante aziende.&lt;/p&gt;
&lt;h3 id="esempio-di-un-dockerfile-insicuro"&gt;Esempio di un Dockerfile insicuro
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# Dockerfile VULNERABILE
FROM python:3.11-slim
WORKDIR /app
RUN pip install litellm fastapi uvicorn
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Una build basata su un Dockerfile come questo, eseguita nella finestra temporale dell&amp;rsquo;attacco, avrebbe installato la versione 1.82.7 senza battere ciglio, aprendo una falla enorme nella sicurezza dell&amp;rsquo;infrastruttura.&lt;/p&gt;
&lt;h2 id="leroe-che-non-ti-aspetti-requirementstxt-e-il-potere-del-pinning"&gt;L&amp;rsquo;Eroe che non ti aspetti: requirements.txt e il potere del pinning
&lt;/h2&gt;&lt;p&gt;Con il &lt;strong&gt;pinning&lt;/strong&gt; andiamo a dire a pip &amp;ldquo;installa questa versione e non aggiornarla, mai&amp;rdquo;. In pratica stiamo fissare virtualmente una specifica versione con una puntina da disegno. Questa non e&amp;rsquo; solo una best practice (in Python, cosi&amp;rsquo; come in Docker o in altri software di gestione pacchetti) per evitare problemi di &lt;strong&gt;breaking changes&lt;/strong&gt; introdotte nei pacchetti nuovi, ma anche evita l&amp;rsquo;installazione scosiderata di nuove versioni con potenziali &lt;em&gt;problemi&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Uno di quei problemi che va a prevenire, infatti, (anche se in modo relativo) e&amp;rsquo; l&amp;rsquo;installazione di versioni nuove e non testate e che potenzialmente sono affette da bug importanti o da vulnerabilta'.&lt;/p&gt;
&lt;h2 id="alziamo-il-livello-dalla-toppa-del-momento-a-una-strategia-di-supply-chain-security"&gt;Alziamo il livello: Dalla toppa del momento a una strategia di Supply-Chain Security
&lt;/h2&gt;&lt;p&gt;La sicurezza della supply-chain e&amp;rsquo; una delle sfide piu&amp;rsquo; critiche per le aziende moderne che si occupano di distribuire software. Parte della sfida e&amp;rsquo; che non esiste una definizione univoca e funzionale di sicurezza della supply-chain ed e&amp;rsquo; una sfida che si estende su un&amp;rsquo;area estremamente ampia che include tutto, dalle minacce fisiche alle minacce informatiche (come in questo caso).&lt;/p&gt;
&lt;p&gt;Se prendiamo ad esempio un software con LiteLLM che nel file &lt;a class="link" href="https://github.com/BerriAI/litellm/blob/main/requirements.txt" target="_blank" rel="noopener"
&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/a&gt; contiene circa &lt;strong&gt;80 righe di dipendenze&lt;/strong&gt; e se pensiamo che ogni dipendenza usera&amp;rsquo; con tutta probabilita&amp;rsquo; altre dipendenze, si crea una catena di opportunita&amp;rsquo; per un attaccante di infiltrarsi potenzialmente in decine o centinaia di migliaia di host diversi.&lt;/p&gt;
&lt;p&gt;Ma allora quali sono i comportamenti da attuare per prevenire un attacco di questo tipo?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Valutazione dei vendor e delle librerie: e&amp;rsquo; necessario valutare attentamente ogni libreria (che sia open-source o commerciale) prima dell&amp;rsquo;integrazione, controllando la reputazione del maintainer;&lt;/li&gt;
&lt;li&gt;Pratiche di sviluppo sicuro: adottare il framework NIST SSDF per definire requisiti di sicurezza e scansioni automatiche con strumenti quali Dependabot o Snyk e integrare strumenti di code signing per garantire che il software distribuito non sia stato manomesso durante la build o la distribuzione;&lt;/li&gt;
&lt;li&gt;Soluzioni pratiche immediate: usare Sigstore e Codign per code signing nelle pipeline CI/CD per firmare container e binari.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusioni-la-fiducia-è-bene-il-controllo-è-meglio"&gt;Conclusioni: La fiducia è bene, il controllo è meglio
&lt;/h2&gt;&lt;p&gt;La fiducia nel mondo open-source e&amp;rsquo; sicuramente fondamentale, ma va abbinata a pratiche di sicurezza robuste, come il &lt;strong&gt;pinning&lt;/strong&gt; o tool come &lt;strong&gt;Dependabot&lt;/strong&gt; che verificano le dipendenze usate.&lt;/p&gt;
&lt;p&gt;Secondo voi, attacchi di questo tipo diventeranno la nuova normalità nel mondo open-source?&lt;/p&gt;
&lt;p&gt;Proteggere la supply-chain del software non è un&amp;rsquo;opzione, ma una necessità. Se la sicurezza delle tue pipeline di CI/CD è una priorità e vuoi capire come implementare strategie robuste come quelle descritte in questo articolo, visita il mio &lt;a class="link" href="https://lazzarotto.dev" target="_blank" rel="noopener"
&gt;portfolio&lt;/a&gt; per scoprire come posso aiutarti.&lt;/p&gt;</description></item><item><title>Kubernetes, Longhorn e immagini non-root: cronaca di un fix di permessi</title><link>https://lazzarotto.dev/blog/kubernetes-longhorn-e-immagini-non-root-cronaca-di-un-fix-di-permessi/</link><pubDate>Sun, 08 Feb 2026 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/kubernetes-longhorn-e-immagini-non-root-cronaca-di-un-fix-di-permessi/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Kubernetes, Longhorn e immagini non-root: cronaca di un fix di permessi" /&gt;&lt;h1 id="intro"&gt;Intro
&lt;/h1&gt;&lt;p&gt;Per la mia nuova attivita&amp;rsquo; da freelancer come &lt;strong&gt;DevOps Engineer&lt;/strong&gt;, ho pensato di sviluppare un sito web utilizzando &lt;strong&gt;Flask&lt;/strong&gt; come backend e un template (il cui nome e&amp;rsquo; &amp;ldquo;Simone - Personal Portfolio Template&amp;rdquo;), acquistato da ThemeForest come frontend.&lt;br&gt;
Niente di troppo complicato; HTML, CSS e Javascript fanno il 90% del lavoro, e il restante 10% e&amp;rsquo; composto dal backend in Flask che si occupa di gestire il funzionamento interno come il contact form con Captcha, il routing delle pagine, l&amp;rsquo;endpoint per il &lt;em&gt;livenessProbe&lt;/em&gt; di Kubernetes e tutta quella parte per i motori di ricerca (robots.txt e sitemap).&lt;/p&gt;
&lt;p&gt;E&amp;rsquo; da un paio di mesi che sto hostando questo sito web &lt;a class="link" href="https://lazzarotto.dev/?utm_source=mlazzarotto.it&amp;amp;utm_medium=hugo_post&amp;amp;utm_campaign=internal_referral" target="_blank" rel="noopener"
&gt;lazzarotto.dev&lt;/a&gt; sul mio homelab tramite Kubernetes sul mio cluster di 3 nodi K3S, con due repliche per HA (decisamente overkill) e &lt;strong&gt;Longhorn&lt;/strong&gt; come storage (in realta&amp;rsquo; usato solo per i file di log di Flask).
Fino alla settimana scorsa utilizzavo l&amp;rsquo;immagine piu&amp;rsquo; comune per un sito web in Flask, ovvero &lt;code&gt;python:3.14-slim&lt;/code&gt;; si tratta di un&amp;rsquo;immagine Docker basata sulla famosissima distro Linux &lt;strong&gt;Debian Trixie&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id="immagine-non-root-e-distroless"&gt;Immagine Non-Root e Distroless
&lt;/h1&gt;&lt;p&gt;Il sito web funzionava bene con l&amp;rsquo;immagine Docker menzionata in precedenza, ma era da parecchio tempo che su Reddit (e non solo) sentivo parlare di queste immagini &lt;em&gt;distroless&lt;/em&gt; e senza utente &amp;ldquo;root&amp;rdquo;, che permettevano di avere un livello di sicurezza maggiore rispetto alle classiche immagini Docker.&lt;br&gt;
E per questo motivo, oltre al fatto che volevo &amp;ldquo;mettere le mani in pasta&amp;rdquo; e imparare, ho deciso di convertire il mio &lt;strong&gt;Dockerfile&lt;/strong&gt; per avere un&amp;rsquo;immagine Docker del mio sito web root-less e distro-less.&lt;/p&gt;
&lt;p&gt;Ho pertanto utilizzato comunque l&amp;rsquo;immagine &lt;code&gt;python:3.14-slim&lt;/code&gt; come &lt;strong&gt;builder&lt;/strong&gt; nel mio Dockerfile, ma, ho usato &lt;code&gt;gcr.io/distroless/python3-debian13:nonroot&lt;/code&gt; come &lt;strong&gt;release&lt;/strong&gt;.&lt;br&gt;
Quindi, immagine costruita, fatto il deploy su Kubernetes con la nuova immagine e il pod partiva, ma dopo qualche secondo andava in crash. Guardando tra i log del pod, scoprivo che &lt;em&gt;loguru&lt;/em&gt; (la libreria per il logging) non riusciva a scrivere il file di log nella cartella che avrebbe dovuto essere &amp;ldquo;montata&amp;rdquo; dal PVC di Longhorn.&lt;/p&gt;
&lt;h1 id="troubleshooting-su-un-container-distroless"&gt;Troubleshooting su un Container Distroless
&lt;/h1&gt;&lt;p&gt;Se avete mai lavorato con un container &lt;em&gt;distroless&lt;/em&gt;, sicuramente saprete quanto sia complicato fare troubleshooting di un&amp;rsquo;app in un container del genere. Per chi non lo sapesse, un&amp;rsquo;immagine &lt;em&gt;distroless&lt;/em&gt; e&amp;rsquo; un&amp;rsquo;immagine Docker in cui manca qualsiasi programma basilare di Linux, tra cui: &lt;code&gt;apt&lt;/code&gt;/&lt;code&gt;yum&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;tar&lt;/code&gt;, &lt;code&gt;sh&lt;/code&gt; o &lt;code&gt;bash&lt;/code&gt;. E quindi e&amp;rsquo; impossibile usare &lt;code&gt;docker exec&lt;/code&gt; o &lt;code&gt;kubectl exec&lt;/code&gt; per entrare nel container e controllare lo stato del mountpoint in questione.&lt;/p&gt;
&lt;p&gt;A questo punto, il mio pensiero era &amp;ldquo;ho cambiato due cose: distro e utente che fa girare l&amp;rsquo;app&amp;rdquo;. E non avevo idea di quale delle due modifiche effettuate sull&amp;rsquo;immagine avesse introdotto il problema della scrittura dei log.&lt;br&gt;
Cio&amp;rsquo; che mi rimaneva da fare era ricreare l&amp;rsquo;immagine Docker, comunque senza utente &amp;ldquo;root&amp;rdquo;, ma con una distro di base in modo da avere accesso quantomeno a &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;touch&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;Tengo a sottolineare che tutto cio&amp;rsquo; avveniva mentre il mio sito web era offline perche&amp;rsquo; non ho un ambiente di test nel mio homelab (non ancora, almeeno).&lt;/p&gt;
&lt;p&gt;Una volta fatto il deploy del pod con la nuova immagine di &amp;ldquo;debug&amp;rdquo;, riuscivo a loggarmi nel pod (anzi, nel container del pod) e a rendermi conto che la cartella &lt;code&gt;/app/logs&lt;/code&gt; non era di proprieta&amp;rsquo; dell&amp;rsquo;utente corrente (se ricordo dovrebbe essere un utente con UID 1000), ma bensi&amp;rsquo; di proprieta&amp;rsquo; di &lt;strong&gt;root&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id="come-perdere-tempo-chiedendo-a-gemini-la-soluzione"&gt;Come Perdere Tempo Chiedendo a Gemini la Soluzione
&lt;/h1&gt;&lt;p&gt;Mi sono rivolto inizialmente a Gemini 2.5 Flash (lo so, avrei dovuto usare il modello Pro, ma pensavo che la soluzione fosse semplice) per trovare la soluzione al problema dei permessi della cartella &lt;code&gt;logs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le sue risposte sembravano veramente buone ed era sempre molto &lt;em&gt;self confident&lt;/em&gt;, come succede sempre con le sue allucinazioni, ça va sans dire.
Ci sono stato dietro per mezz&amp;rsquo;ora circa, ma alla fine mi sono arreso e mi sono rimesso a cercare con Google, in maniera &amp;ldquo;vecchio stile&amp;rdquo;.&lt;/p&gt;
&lt;h1 id="la-soluzione"&gt;La Soluzione
&lt;/h1&gt;&lt;p&gt;La soluzione e&amp;rsquo; arrivata tramite una &lt;em&gt;&lt;a class="link" href="https://github.com/longhorn/longhorn/issues/8088#issuecomment-1986701122" target="_blank" rel="noopener"
&gt;issue&lt;/a&gt;&lt;/em&gt; del repo Github del progetto &lt;strong&gt;Longhorn&lt;/strong&gt; che mi ha salvato.&lt;/p&gt;
&lt;p&gt;In breve, il problema nasce dal fatto che Longhorn, quando &amp;ldquo;monta&amp;rdquo; il PVC nel container, imposta l&amp;rsquo;utente e il gruppo owner a &lt;em&gt;root&lt;/em&gt;, e questo fa in modo che l&amp;rsquo;utente &lt;em&gt;non-root&lt;/em&gt; della mia immagine non possa accedere a tale PVC.&lt;/p&gt;
&lt;p&gt;Ci ho messo comunque un po&amp;rsquo; di tempo a mettere assieme i pezzi, lo devo ammettere, ma alla fine ho scelto la soluzione numero 7 (&lt;strong&gt;Case 7&lt;/strong&gt;) che era la migliore per il mio caso d&amp;rsquo;uso perche&amp;rsquo; non mi richiedeva di creare &lt;em&gt;StorageClass&lt;/em&gt; custom o stravolgere i manifest, ma di agire direttamente sul &lt;em&gt;securityContext&lt;/em&gt; del mio Deployment.&lt;br&gt;
In pratica, si tratta di dire a Kubernetes: &amp;lsquo;Ehi, quando monti questo volume, per favore assicurati che appartenga a un gruppo a cui il mio utente applicativo può scrivere&amp;rsquo;. Semplice ed efficace.&lt;/p&gt;
&lt;h1 id="conclusioni-e-manifest"&gt;Conclusioni e Manifest
&lt;/h1&gt;&lt;p&gt;Ecco qua, un intero pomeriggio di debug per aggiungere tre righe di YAML al mio &lt;em&gt;securityContext&lt;/em&gt;. Ma al di là della soluzione tecnica, questa esperienza mi ha ricordato due cose importanti.&lt;br&gt;
Primo: le immagini minimali e non-root sono fantastiche per la sicurezza, ma possono rendere il debug un vero incubo se non si è preparati. Secondo: mai sottovalutare il potere di una ricerca &amp;ldquo;vecchio stile&amp;rdquo; su GitHub issues quando l&amp;rsquo;AI ti manda fuori strada.&lt;/p&gt;
&lt;p&gt;Adesso il mio sito è di nuovo online, più sicuro di prima, e io ho imparato una lezione preziosa sui permessi dello storage in Kubernetes.&lt;/p&gt;
&lt;p&gt;Aggiungo qui sotto la parte utile del mio manifest che ho usato per il deployment dell&amp;rsquo;app.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lazzarotto-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dmz&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lazzarotto-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replicas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lazzarotto-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;revisionHistoryLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lazzarotto-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;securityContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsNonRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runAsUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fsGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;lazzarotto-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;git.mlazzarotto.it/marco/lazzarotto_dev:20260205-113032&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;...]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Aumentare La Sicurezza Di Navidrome: Autenticazione SSO con Traefik e Authentik</title><link>https://lazzarotto.dev/blog/aumentare-la-sicurezza-di-navidrome-autenticazione-sso-con-traefik-e-authentik/</link><pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/aumentare-la-sicurezza-di-navidrome-autenticazione-sso-con-traefik-e-authentik/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Aumentare La Sicurezza Di Navidrome: Autenticazione SSO con Traefik e Authentik" /&gt;&lt;h1 id="introduzione"&gt;Introduzione
&lt;/h1&gt;&lt;p&gt;I servizi di streaming musicale come Navidrome offrono un modo fantastico per accedere alla propria collezione musicale personale da qualsiasi luogo. Tuttavia, l&amp;rsquo;esposizione di tali servizi a Internet comporta problemi di sicurezza.&lt;/p&gt;
&lt;p&gt;Questa guida mostra come proteggere l&amp;rsquo;istanza di Navidrome utilizzando le funzionalità di Single Sign-On (SSO) di Authentik dietro il reverse proxy Traefik.&lt;/p&gt;
&lt;p&gt;Implementando questa configurazione, aggiungerete un ulteriore livello di sicurezza al vostro server musicale, mantenendo al contempo un comodo accesso per gli utenti legittimi.&lt;/p&gt;
&lt;h2 id="presupposti-e-record-dns"&gt;Presupposti e record DNS
&lt;/h2&gt;&lt;p&gt;Questa guida presuppone che abbiate già installato e configurato&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authentik come identity provider&lt;/li&gt;
&lt;li&gt;Traefik come reverse proxy&lt;/li&gt;
&lt;li&gt;Navidrome come server di streaming musicale&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Per gli scopi di questo tutorial, utilizzeremo i seguenti domini:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;music.example.com&lt;/code&gt;: L&amp;rsquo;istanza di Navidrome rivolta al pubblico&lt;/li&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt;: Il vostro dominio esterno&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal.example.com&lt;/code&gt;: Il vostro sottodominio interno&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="comprendere-il-flusso-di-autenticazione"&gt;Comprendere il flusso di autenticazione
&lt;/h1&gt;&lt;p&gt;Il flusso di autenticazione funziona come segue:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Un utente tenta di accedere a &lt;code&gt;music.example.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Traefik intercetta la richiesta e la inoltra ad Authentik tramite il middleware &lt;code&gt;authentik-forward-auth&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Se l&amp;rsquo;utente non è autenticato, viene reindirizzato alla pagina di login di Authentik&lt;/li&gt;
&lt;li&gt;Dopo l&amp;rsquo;autenticazione, Authentik rimanda l&amp;rsquo;utente a Navidrome con le intestazioni di autenticazione&lt;/li&gt;
&lt;li&gt;Navidrome legge queste intestazioni per identificare l&amp;rsquo;utente e concede l&amp;rsquo;accesso di conseguenza&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;È importante notare che la nostra configurazione esclude deliberatamente l&amp;rsquo;autenticazione per due percorsi specifici:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/share/&lt;/code&gt;: Permette l&amp;rsquo;accesso anonimo ai link musicali condivisi&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/rest/&lt;/code&gt;: Permette l&amp;rsquo;accesso alle API per applicazioni mobili come Symfonium o DSub&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Questa autenticazione selettiva fornisce sia sicurezza che funzionalità, laddove necessario.&lt;/p&gt;
&lt;h1 id="configurazione-di-authentik"&gt;Configurazione di Authentik
&lt;/h1&gt;&lt;h2 id="application-e-provider"&gt;Application e Provider
&lt;/h2&gt;&lt;p&gt;Per impostare Navidrome in Authentik:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Dal cruscotto di amministrazione di Authentik, selezionare “Applications” e fare clic su “Create with Provider”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nella schermata “Application”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inserire “Navidrome” come nome&lt;/li&gt;
&lt;li&gt;Impostare uno slug appropriato (ad esempio, “navidrome”)&lt;/li&gt;
&lt;li&gt;Aggiungere una descrizione e un&amp;rsquo;icona opzionale&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nella schermata &amp;ldquo;Choose a provider”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Selezionare “Proxy Provider”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Nella schermata “Configure Provider”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inserire un nome per il provider (ad esempio, “navidrome-proxy”)&lt;/li&gt;
&lt;li&gt;Selezionare il flusso di autenticazione che si utilizza di solito&lt;/li&gt;
&lt;li&gt;Scegliere &amp;ldquo;Forward auth (single application)”&lt;/li&gt;
&lt;li&gt;Inserire &lt;code&gt;https://music.example.com&lt;/code&gt; come host esterno&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Saltare la schermata “Configure Bindings” e completare la procedura guidata.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="outpost"&gt;Outpost
&lt;/h2&gt;&lt;p&gt;Quindi, collegare l&amp;rsquo;applicazione all&amp;rsquo;avamposto Authentik:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Andate su &amp;ldquo;Outpost” nell&amp;rsquo;interfaccia di amministrazione di Authentik&lt;/li&gt;
&lt;li&gt;Modificare il “authentik Embedded Outpost”&lt;/li&gt;
&lt;li&gt;Nella sezione “Applications”, aggiungere l&amp;rsquo;applicazione Navidrome appena creata&lt;/li&gt;
&lt;li&gt;Salvare le modifiche&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="configurazione-di-traefik"&gt;Configurazione di Traefik
&lt;/h1&gt;&lt;p&gt;La configurazione di Traefik gestisce l&amp;rsquo;instradamento del traffico e l&amp;rsquo;autenticazione. Ecco il setup:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Configurazione di Traefik per Navidrome con Authentik SSO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to-authentik-outpost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;webSecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`music.example.com`) &amp;amp;&amp;amp; PathPrefix(`/outpost.goauthentik.io/`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;authentik&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;authentik-forward-auth&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to-protected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;webSecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`music.example.com`) &amp;amp;&amp;amp; !(PathPrefix(`/share/`) || PathPrefix(`/rest/`))&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;navidrome&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;authentik-forward-auth&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to-subsonic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;webSecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`music.example.com`) &amp;amp;&amp;amp; PathPrefix(`/rest/`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;navidrome&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to-navidrome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;webSecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`music.example.com`) &amp;amp;&amp;amp; PathPrefix(`/share/`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;navidrome&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;navidrome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://navidrome.internal.example.com:4533&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authentik&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://authentik.internal.example.com:9443&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authentik-forward-auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;forwardAuth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://authentik.internal.example.com:9000/outpost.goauthentik.io/auth/traefik&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;trustForwardHeader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;authResponseHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-username&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-groups&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-entitlements&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-email&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-uid&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-jwt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-meta-jwks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-meta-outpost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-meta-provider&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-meta-app&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;X-authentik-meta-version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="spiegazione-della-configurazione"&gt;Spiegazione della Configurazione
&lt;/h2&gt;&lt;p&gt;La configurazione di Traefik è composta da diversi componenti chiave:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;to-authentik-outpost&lt;/code&gt;: Gestisce i percorsi specifici per le autorizzazioni con la massima priorità (200)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to-protected&lt;/code&gt;: Indirizza il traffico generale di Navidrome attraverso l&amp;rsquo;autenticazione&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to-subsonic&lt;/code&gt;: Consente l&amp;rsquo;accesso non autenticato alle API Subsonic (&lt;code&gt;/rest/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to-navidrome&lt;/code&gt;: Permette l&amp;rsquo;accesso diretto ai link condivisi (&lt;code&gt;/share/&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Services:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;navidrome&lt;/code&gt;: Punta alla tua istanza Navidrome&lt;/li&gt;
&lt;li&gt;&lt;code&gt;authentik&lt;/code&gt;: Punta alla tua istanza Authentik&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Middleware:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;authentik-forward-auth&lt;/code&gt;: Il componente critico che inoltra le richieste di autenticazione ad Authentik e passa le informazioni sull&amp;rsquo;utente tramite intestazioni a Navidrome&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La configurazione utilizza le priorità di instradamento per garantire che le eccezioni di autenticazione funzionino correttamente; i numeri più alti hanno la precedenza.&lt;/p&gt;
&lt;h1 id="configurazione-di-navidrome"&gt;Configurazione di Navidrome
&lt;/h1&gt;&lt;p&gt;Affinché Navidrome si integri correttamente con questa configurazione di autenticazione, è necessario configurare due importanti impostazioni:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ReverseProxyWhitelist&lt;/code&gt;: Impostare l&amp;rsquo;indirizzo IP del server Traefik per garantire che Navidrome si fidi delle intestazioni di autenticazione&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReverseProxyUserHeader&lt;/code&gt;: Impostare questo parametro su &lt;code&gt;X-authentik-username&lt;/code&gt;, in modo che Navidrome sappia quale header contiene il nome utente&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;È possibile configurare queste impostazioni nelle variabili d&amp;rsquo;ambiente o nel file di configurazione di Navidrome:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ND_REVERSEPROXYWHITELIST=&amp;lt;il_tuo_ip_traefik&amp;gt;
ND_REVERSEPROXYUSERHEADER=X-authentik-username
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Per ulteriori opzioni di configurazione, consultare la &lt;a class="link" href="https://www.navidrome.org/docs/usage/configuration-options/#advanced-configuration" target="_blank" rel="noopener"
&gt;documentazione di Navidrome&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id="conclusione"&gt;Conclusione
&lt;/h1&gt;&lt;p&gt;Una volta completata la configurazione, l&amp;rsquo;istanza di Navidrome è ora protetta da Authentik SSO. Quando gli utenti visiteranno &lt;code&gt;music.example.com&lt;/code&gt;, verrà presentata loro la pagina di login di Authentik. Dopo l&amp;rsquo;autenticazione, otterranno l&amp;rsquo;accesso a Navidrome.&lt;/p&gt;
&lt;p&gt;Uno degli aspetti più comodi di questa integrazione è il provisioning automatico degli utenti. Se un utente si autentica tramite Authentik ma non esiste ancora in Navidrome, verrà creato automaticamente un nuovo account utilizzando il nome utente di Authentik (e una password randomica).&lt;/p&gt;
&lt;p&gt;Questo approccio garantisce una solida sicurezza, pur mantenendo un accesso comodo per gli utenti legittimi, con l&amp;rsquo;esclusione dell&amp;rsquo;autenticazione selettiva per funzionalità specifiche come i link condivisi e l&amp;rsquo;accesso alle app mobili.&lt;/p&gt;
&lt;h1 id="risorse-utilizzate"&gt;Risorse Utilizzate
&lt;/h1&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/brokenscripts/authentik_traefik" target="_blank" rel="noopener"
&gt;https://github.com/brokenscripts/authentik_traefik&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.navidrome.org/docs/usage/reverse-proxy/" target="_blank" rel="noopener"
&gt;https://www.navidrome.org/docs/usage/reverse-proxy/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.goauthentik.io/docs/add-secure-apps/providers/proxy/server_traefik" target="_blank" rel="noopener"
&gt;https://docs.goauthentik.io/docs/add-secure-apps/providers/proxy/server_traefik&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Esporre Seafile 12 dietro Traefik: La Guida Completa Alla configurazione</title><link>https://lazzarotto.dev/blog/esporre-seafile-12-dietro-traefik-la-guida-completa-alla-configurazione/</link><pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/esporre-seafile-12-dietro-traefik-la-guida-completa-alla-configurazione/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Esporre Seafile 12 dietro Traefik: La Guida Completa Alla configurazione" /&gt;&lt;h1 id="introduzione"&gt;Introduzione
&lt;/h1&gt;&lt;p&gt;Seafile è una potente piattaforma open-source per la sincronizzazione e la condivisione di file che offre un&amp;rsquo;alternativa ai servizi di archiviazione cloud commerciali. Quando si implementa Seafile in un ambiente di produzione, solitamente si desidera posizionarlo dietro un reverse proxy come Traefik per gestire la terminazione SSL, il routing e funzionalità di sicurezza aggiuntive.&lt;/p&gt;
&lt;p&gt;In questa guida, ti illustrerò la configurazione esatta di Traefik necessaria per esporre correttamente Seafile 12 su internet. Questa configurazione gestisce tutti e tre i componenti essenziali di Seafile: l&amp;rsquo;interfaccia web, il servizio di trasferimento file (seafhttp) e l&amp;rsquo;accesso WebDAV (seafdav).&lt;/p&gt;
&lt;h1 id="comprendere-larchitettura-di-seafile"&gt;Comprendere l&amp;rsquo;Architettura di Seafile
&lt;/h1&gt;&lt;p&gt;Prima di addentrarci nella configurazione, è importante capire che Seafile è costituito da più servizi che devono essere instradati correttamente:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Interfaccia Web Principale&lt;/strong&gt; - L&amp;rsquo;interfaccia primaria con cui gli utenti interagiscono con Seafile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seafhttp&lt;/strong&gt; - Gestisce il caricamento e il download dei file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seafdav&lt;/strong&gt; - Fornisce accesso WebDAV ai file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ciascuno di questi servizi necessita delle proprie regole di routing in Traefik.&lt;/p&gt;
&lt;h1 id="configurazione-di-traefik"&gt;Configurazione di Traefik
&lt;/h1&gt;&lt;p&gt;Iniziamo con la configurazione completa di Traefik necessaria per Seafile 12:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routerSeafile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;websecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;seafile&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`sf.mydomain.com`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;HSTS&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routerSeafHttp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;websecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;seafhttp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`sf.mydomain.com`) &amp;amp;&amp;amp; PathPrefix(`/seafhttp`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;HSTS&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;seafhttp-strip-prefix&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;removeDuplicateSlashes&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;routerSeafdav&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;websecure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;seafdav&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Host(`sf.mydomain.com`) &amp;amp;&amp;amp; PathPrefix(`/seafdav`)&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;HSTS&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seafile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://seafile.local:8000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serversTransport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insecureTransport&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seafhttp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://seafile.local:8082&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serversTransport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insecureTransport&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seafdav&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loadBalancer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://seafile.local:8080&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serversTransport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;insecureTransport&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="configurazione-del-middleware"&gt;Configurazione del Middleware
&lt;/h1&gt;&lt;p&gt;Oltre alle regole di routing principali, dobbiamo definire alcuni middleware per gestire la sicurezza e la manipolazione dei percorsi:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;HSTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stsSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;15552000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stsIncludeSubdomains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;forceSTSHeader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stsPreload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;frameDeny&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;browserXssFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;seafhttp-strip-prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stripPrefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;/seafhttp&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;forceSlash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;removeDuplicateSlashes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replacePathRegex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/{2,}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;serversTransports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureTransport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;insecureSkipVerify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="analisi-della-configurazione"&gt;Analisi della Configurazione
&lt;/h1&gt;&lt;p&gt;Analizziamo le parti principali di questa configurazione:&lt;/p&gt;
&lt;h2 id="1-definizioni-dei-router"&gt;1. Definizioni dei Router
&lt;/h2&gt;&lt;p&gt;Definiamo tre router separati, ciascuno gestisce un componente diverso di Seafile:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;routerSeafile&lt;/strong&gt;: Instrada le richieste all&amp;rsquo;interfaccia utente principale di Seafile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;routerSeafHttp&lt;/strong&gt;: Instrada le richieste di trasferimento file al servizio seafhttp&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;routerSeafdav&lt;/strong&gt;: Instrada le richieste WebDAV al servizio seafdav&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-regole-di-routing"&gt;2. Regole di Routing
&lt;/h2&gt;&lt;p&gt;Ogni router utilizza una combinazione di regole basate su nome host e percorso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interfaccia principale: Corrisponde alle richieste a &lt;code&gt;sf.mydomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Seafhttp: Corrisponde alle richieste a &lt;code&gt;sf.mydomain.com/seafhttp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Seafdav: Corrisponde alle richieste a &lt;code&gt;sf.mydomain.com/seafdav&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-servizi"&gt;3. Servizi
&lt;/h2&gt;&lt;p&gt;Ogni router è collegato al suo servizio corrispondente, che definisce dove Traefik dovrebbe effettuare il proxy delle richieste:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interfaccia principale: Proxy a &lt;code&gt;http://seafile.local:8000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Seafhttp: Proxy a &lt;code&gt;http://seafile.local:8082&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Seafdav: Proxy a &lt;code&gt;http://seafile.local:8080&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4-middleware"&gt;4. Middleware
&lt;/h2&gt;&lt;p&gt;Applichiamo diversi middleware importanti:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HSTS&lt;/strong&gt;: Impone l&amp;rsquo;uso di HTTPS da parte dei client&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;seafhttp-strip-prefix&lt;/strong&gt;: Rimuove il prefisso &lt;code&gt;/seafhttp&lt;/code&gt; prima dell&amp;rsquo;inoltro al backend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;removeDuplicateSlashes&lt;/strong&gt;: Pulisce gli URL con slash duplicati. Questo è diventato necessario per me dopo la migrazione da Seafile 11 a 12, ma potrebbe non essere necessario per te.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="5-considerazioni-sulla-sicurezza"&gt;5. Considerazioni sulla Sicurezza
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;L&amp;rsquo;impostazione &lt;code&gt;insecureTransport&lt;/code&gt; consente a Traefik di comunicare con i servizi interni utilizzando HTTP&lt;/li&gt;
&lt;li&gt;Gli header HSTS garantiscono che i client utilizzino sempre HTTPS per le connessioni future&lt;/li&gt;
&lt;li&gt;Header di sicurezza aggiuntivi proteggono da vulnerabilità web comuni&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="conclusione"&gt;Conclusione
&lt;/h1&gt;&lt;p&gt;Questa configurazione fornisce un modo sicuro ed efficiente per esporre Seafile 12 dietro Traefik. La configurazione gestisce correttamente tutti e tre i componenti di Seafile, garantendo che gli utenti possano accedere all&amp;rsquo;interfaccia web, caricare/scaricare file e utilizzare la funzionalità WebDAV.&lt;/p&gt;
&lt;p&gt;Utilizzando Traefik come reverse proxy, si ottengono diversi vantaggi, tra cui la gestione automatica dei certificati SSL (se configurata), potenti capacità di routing e livelli di sicurezza aggiuntivi. Questa specifica configurazione si concentra sulle esigenze di routing specifiche di Seafile implementando al contempo le migliori pratiche di sicurezza.&lt;/p&gt;
&lt;p&gt;Ricorda che questa configurazione presuppone che tu abbia già configurato Seafile correttamente e che sia accessibile internamente agli indirizzi definiti. La configurazione presuppone inoltre che tu abbia configurato correttamente Traefik con certificati SSL per il dominio specificato.&lt;/p&gt;</description></item><item><title>Aumentare La Sicurezza Di Seafile: Nascondere I Campi Di Accesso Quando Si Usa SSO</title><link>https://lazzarotto.dev/blog/aumentare-la-sicurezza-di-seafile-nascondere-i-campi-di-accesso-quando-si-usa-sso/</link><pubDate>Sat, 26 Apr 2025 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/aumentare-la-sicurezza-di-seafile-nascondere-i-campi-di-accesso-quando-si-usa-sso/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Aumentare La Sicurezza Di Seafile: Nascondere I Campi Di Accesso Quando Si Usa SSO" /&gt;&lt;h1 id="potenziare-la-sicurezza-di-seafile-nascondere-i-campi-di-accesso-quando-si-utilizza-sso"&gt;Potenziare la Sicurezza di Seafile: Nascondere i Campi di Accesso Quando si Utilizza SSO
&lt;/h1&gt;&lt;p&gt;Quando si tratta di proteggere la tua istanza Seafile, i piccoli dettagli fanno una grande differenza. Oggi condivido un miglioramento di sicurezza semplice ma potente che richiede solo pochi minuti per essere implementato, ma fornisce una protezione significativa per la tua fortezza di dati.&lt;/p&gt;
&lt;h2 id="il-problema-i-metodi-di-accesso-duplici-creano-rischi"&gt;Il Problema: I Metodi di Accesso Duplici Creano Rischi
&lt;/h2&gt;&lt;p&gt;Se hai configurato il Single Sign-On (SSO) con servizi come Authentik o Authelia per la tua istanza Seafile, congratulazioni! Hai fatto un passo importante verso il miglioramento della tua postura di sicurezza. Tuttavia, esiste una vulnerabilità subdola che spesso viene trascurata.&lt;/p&gt;
&lt;p&gt;Anche con SSO configurato, Seafile continua a visualizzare per impostazione predefinita i campi di accesso nativi con nome utente e password. Questo crea un vettore di attacco non necessario – è come installare un sistema di sicurezza all&amp;rsquo;avanguardia per la tua casa ma lasciare una porta laterale sbloccata.&lt;/p&gt;
&lt;p&gt;I potenziali attaccanti possono ignorare la tua brillante implementazione SSO e martellare l&amp;rsquo;accesso tradizionale, tentando di forzare l&amp;rsquo;ingresso nel tuo sistema. Questo è particolarmente preoccupante perché:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mina i benefici di sicurezza della tua implementazione SSO&lt;/li&gt;
&lt;li&gt;L&amp;rsquo;accesso tradizionale potrebbe avere una protezione più debole contro tentativi ripetuti&lt;/li&gt;
&lt;li&gt;Gli utenti potrebbero confondersi su quale metodo di accesso utilizzare&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="la-soluzione-css-al-soccorso"&gt;La Soluzione: CSS al Soccorso
&lt;/h2&gt;&lt;p&gt;La soluzione è piacevolmente semplice – alcune righe di CSS possono rimuovere completamente dalla vista quei campi di accesso vulnerabili. La bellezza di questo approccio è che non si limita a nascondere visivamente i campi; impedisce qualsiasi interazione con essi.&lt;/p&gt;
&lt;p&gt;Ecco il magico frammento CSS di cui hai bisogno:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;login-panel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;login-form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;login-panel-hd&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="come-implementare-questa-soluzione"&gt;Come Implementare Questa Soluzione
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Accedi al pannello di amministrazione di Seafile&lt;/li&gt;
&lt;li&gt;Naviga nella sezione impostazioni di sistema&lt;/li&gt;
&lt;li&gt;Cerca il campo CSS personalizzato sotto &lt;strong&gt;Impostazioni&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Incolla il frammento CSS mostrato sopra&lt;/li&gt;
&lt;li&gt;Salva le modifiche&lt;/li&gt;
&lt;li&gt;Aggiorna la pagina di accesso per confermare che i campi di accesso tradizionali siano scomparsi&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="perché-questo-è-importante-per-la-sicurezza"&gt;Perché Questo è Importante per la Sicurezza
&lt;/h2&gt;&lt;p&gt;Considera questa modifica come la chiusura di una porta non necessaria nel tuo firewall. Rimuovendo l&amp;rsquo;interfaccia di accesso tradizionale, stai eliminando un&amp;rsquo;intera superficie di attacco. Gli attaccanti non possono più tentare di indovinare combinazioni di nome utente/password perché quei campi semplicemente non esistono più.&lt;/p&gt;
&lt;p&gt;Questo approccio segue il principio del minimo privilegio – se SSO è il tuo metodo di autenticazione scelto, non c&amp;rsquo;è motivo di esporre percorsi di accesso alternativi.&lt;/p&gt;
&lt;h2 id="il-vantaggio-per-lesperienza-utente"&gt;Il Vantaggio per l&amp;rsquo;Esperienza Utente
&lt;/h2&gt;&lt;p&gt;Oltre alla sicurezza, questa modifica semplifica anche l&amp;rsquo;esperienza utente. I tuoi utenti non affronteranno la confusione di vedere molteplici opzioni di accesso – verranno guidati direttamente al tuo provider SSO, riducendo potenziali confusioni e ticket di supporto.&lt;/p&gt;
&lt;h2 id="considerazioni-finali"&gt;Considerazioni Finali
&lt;/h2&gt;&lt;p&gt;La sicurezza non riguarda sempre implementazioni complesse. A volte, le misure di sicurezza più efficaci sono le più semplici – come rimuovere punti di ingresso non necessari. Questa piccola modifica CSS rappresenta la perfetta intersezione tra maggiore sicurezza e migliore esperienza utente.&lt;/p&gt;
&lt;p&gt;Ricorda: nel mondo della sicurezza, ciò che non può essere visto spesso non può essere sfruttato. Buona protezione!&lt;/p&gt;</description></item><item><title>Installazione di Zabbix-agent in Home Assistant OS</title><link>https://lazzarotto.dev/blog/installazione-di-zabbix-agent-in-home-assistant-os/</link><pubDate>Fri, 13 Dec 2024 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/installazione-di-zabbix-agent-in-home-assistant-os/</guid><description>&lt;h1 id="introduzione"&gt;Introduzione
&lt;/h1&gt;&lt;p&gt;Home Assistant OS è una distribuzione Linux altamente specializzata e ottimizzata per l&amp;rsquo;esecuzione della piattaforma domotica Home Assistant.&lt;/p&gt;
&lt;p&gt;Una delle sue caratteristiche principali, che può rappresentare sia un vantaggio in termini di sicurezza che uno svantaggio in termini di flessibilità, è l&amp;rsquo;impossibilità di accedere direttamente alla console del sistema operativo.&lt;/p&gt;
&lt;p&gt;Questa limitazione rende particolarmente complessa l&amp;rsquo;installazione di software aggiuntivo come l&amp;rsquo;agent di Zabbix, strumento essenziale per il monitoraggio del sistema.&lt;/p&gt;
&lt;h1 id="la-soluzione"&gt;La Soluzione
&lt;/h1&gt;&lt;p&gt;Per fortuna, la comunità open source viene ancora una volta in nostro aiuto.&lt;/p&gt;
&lt;p&gt;Grazie al prezioso contributo dell&amp;rsquo;utente GitHub &lt;a class="link" href="https://github.com/pschmitt/" target="_blank" rel="noopener"
&gt;pschmitt&lt;/a&gt;, è stata sviluppata una soluzione elegante che permette di aggirare questa limitazione.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;approccio proposto consiste nell&amp;rsquo;installare l&amp;rsquo;agent di Zabbix come add-on nativo di Home Assistant, integrandosi perfettamente con l&amp;rsquo;ecosistema esistente.&lt;/p&gt;
&lt;h1 id="il-repository"&gt;Il Repository
&lt;/h1&gt;&lt;p&gt;L&amp;rsquo;utente &lt;strong&gt;pschmitt&lt;/strong&gt; mantiene un repository GitHub pubblico, accessibile all&amp;rsquo;indirizzo &lt;a class="link" href="https://github.com/pschmitt/home-assistant-addons/" target="_blank" rel="noopener"
&gt;https://github.com/pschmitt/home-assistant-addons/&lt;/a&gt;, dove ha reso disponibile il codice necessario per l&amp;rsquo;installazione dell&amp;rsquo;agent Zabbix.&lt;/p&gt;
&lt;p&gt;Questo repository è stato specificamente progettato per essere compatibile con il sistema di add-on di Home Assistant, garantendo un&amp;rsquo;installazione pulita e sicura.&lt;/p&gt;
&lt;h1 id="procedura-di-installazione"&gt;Procedura di Installazione
&lt;/h1&gt;&lt;p&gt;Per integrare il repository nel vostro sistema Home Assistant, avete a disposizione due metodi:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Metodo Manuale&lt;/strong&gt;:
Potete seguire la procedura standard per l&amp;rsquo;aggiunta di repository di terze parti, dettagliatamente descritta nella documentazione ufficiale di Home Assistant all&amp;rsquo;indirizzo: &lt;a class="link" href="https://www.home-assistant.io/common-tasks/os#installing-third-party-add-ons" target="_blank" rel="noopener"
&gt;https://www.home-assistant.io/common-tasks/os#installing-third-party-add-ons&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Metodo Automatico&lt;/strong&gt;:
Per una procedura più rapida e a prova di errore, potete utilizzare il link diretto che automatizza l&amp;rsquo;intero processo di aggiunta del repository:
&lt;a class="link" href="https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fpschmitt%2Fhome-assistant-addons" target="_blank" rel="noopener"
&gt;&lt;img src="https://camo.githubusercontent.com/f165b9b02bc37394563bf986b42dbad5cd3715746b71e8332fc5746064480f14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4164642532307265706f7369746f7279253230746f2532306d792d486f6d65253230417373697374616e742d3431424446353f6c6f676f3d686f6d652d617373697374616e74267374796c653d666f722d7468652d6261646765"
loading="lazy"
alt="Add addon to Home Assistant"
&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="completamento-dellinstallazione"&gt;Completamento dell&amp;rsquo;Installazione
&lt;/h1&gt;&lt;p&gt;Una volta completata con successo l&amp;rsquo;aggiunta del repository, all&amp;rsquo;interno del vostro Home Assistant saranno disponibili due nuovi add-on: &lt;strong&gt;zabbix-agent&lt;/strong&gt; e &lt;strong&gt;zabbix-agent2&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Questi add-on rappresentano rispettivamente la versione classica e la versione più recente dell&amp;rsquo;agent Zabbix. Dopo aver scelto e installato l&amp;rsquo;add-on più adatto alle vostre esigenze e averlo configurato correttamente, sarete in grado di monitorare il vostro server Home Assistant attraverso la piattaforma Zabbix.&lt;/p&gt;
&lt;p&gt;Questa integrazione vi permetterà di mantenere sotto controllo tutti i parametri critici del vostro sistema Home Assistant, garantendo una supervisione professionale della vostra installazione domotica.&lt;/p&gt;</description></item><item><title>Hugo - Generatore di Siti Statici</title><link>https://lazzarotto.dev/blog/hugo-generatore-di-siti-statici/</link><pubDate>Sat, 13 Aug 2022 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/hugo-generatore-di-siti-statici/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Hugo - Generatore di Siti Statici" /&gt;&lt;h1 id="cosè-un-generatore-di-siti-web-statici"&gt;Cos&amp;rsquo;è un generatore di siti web statici
&lt;/h1&gt;&lt;p&gt;Un generatore di siti web statici è un software che genera un sito web HTML statico usando come &amp;ldquo;input&amp;rdquo; dei dati grezzi e del codice come templates.&lt;/p&gt;
&lt;p&gt;In sostanza, un generatore di siti statici automatizza il compito di generare le singole pagine HTML e le rende pronte per essere servite agli utenti in anticipo.
&lt;img src="https://lazzarotto.dev/blog/img/static_site_generator_diagram_high_level.png"
loading="lazy"
alt="static site generator"
&gt;&lt;/p&gt;
&lt;h2 id="siti-web-dinamici-e-statici"&gt;Siti web dinamici e statici
&lt;/h2&gt;&lt;p&gt;Un sito web statico quindi è un sito web composto di una o più pagine web HTML che vengono caricate sempre nello stesso modo, in modo piuttosto basico in quanto non viene utilizzato codice Javascript o eseguite operazioni su database.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;opposto di un sito web statico, è il sito web dinamico (o CMS). Quest&amp;rsquo;ultimo genera le pagine HTML da servire all&amp;rsquo;utente in maniera dinamica e cioè quando l&amp;rsquo;utente ne fa richiesta. Può utilizzare variabili come ora, data, cookies o geolocalizzazione, per fornire all&amp;rsquo;utente un&amp;rsquo;esperienza d&amp;rsquo;uso personalizzata.
Tutto questo viene supportato da codice Javascript.&lt;/p&gt;
&lt;p&gt;Esempi di generatori di siti web statici:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hugo&lt;/li&gt;
&lt;li&gt;Jekyll&lt;/li&gt;
&lt;li&gt;Gatsby&lt;/li&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esempi di siti web dinamici:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wordpress&lt;/li&gt;
&lt;li&gt;Joomla&lt;/li&gt;
&lt;li&gt;Drupal&lt;/li&gt;
&lt;li&gt;Magento&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="come-funziona"&gt;Come funziona
&lt;/h1&gt;&lt;p&gt;Un generatore di siti web statici come &lt;a class="link" href="https://gohugo.io" target="_blank" rel="noopener"
&gt;Hugo&lt;/a&gt;, non è altro che un programma il cui scopo è generare pagine web a partire da codice &lt;em&gt;Markdown&lt;/em&gt; e un template a scelta.&lt;/p&gt;
&lt;p&gt;Il codice &lt;a class="link" href="https://it.wikipedia.org/wiki/Markdown" target="_blank" rel="noopener"
&gt;Markdown&lt;/a&gt;, utilizzato sotto forma di file, serve al programma come sorgente dal quale ottenere il testo delle varie pagine del sito.
Il template invece è un codice di sviluppatori terzi che si occupa della formattazione delle pagine web.&lt;/p&gt;
&lt;p&gt;Unendo i due componenti, si ottengono delle pagine in formato HTML con all&amp;rsquo;interno testo e formattazione.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/static_site_generator_diagram_low_level.png"
loading="lazy"
alt="static site generation"
&gt;&lt;/p&gt;
&lt;p&gt;Per utilizzare Hugo basta un computer (anche offline), Hugo infatti può funzionare come web server standalone, ma solo per motivi di test.
All&amp;rsquo;esecuzione del comando &lt;code&gt;hugo publish&lt;/code&gt; il software genererà tutte le pagine web.&lt;/p&gt;
&lt;h1 id="perché-ho-scelto-hugo"&gt;Perché ho scelto Hugo
&lt;/h1&gt;&lt;p&gt;Precedentemente utilizzavo Wordpress, un potentissimo CMS adatto a mille utilizzi diversi, ma per me anche troppo.
Per il mio tipico utilizzo era troppo potente, direi addirittura &lt;strong&gt;overkill&lt;/strong&gt;, con le centinaia di opzioni diverse a volte era difficile trovare la pagina giusta per cambiare questa o quella impostazione.&lt;/p&gt;
&lt;p&gt;Inoltre, l&amp;rsquo;ho scelto anche per un motivo di &lt;strong&gt;sicurezza&lt;/strong&gt; e soprattutto &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Già, perché intanto il codice HTML statico è &lt;strong&gt;inattaccabile&lt;/strong&gt; &lt;em&gt;sotto il punto di vista informatico&lt;/em&gt; visto che non basandosi su Javascript e database, non è proprio possibile utilizzare &lt;em&gt;falle per ottenere il controllo&lt;/em&gt; del sito (o peggio ancora, del server).&lt;/p&gt;
&lt;p&gt;Inoltre, il funzionamento intrinseco delle pagine HTML statiche permette una &lt;em&gt;velocità di accesso senza pari&lt;/em&gt;. Infatti, su &lt;strong&gt;&lt;a class="link" href="https://pagespeed.web.dev" target="_blank" rel="noopener"
&gt;PageSpeed Insights&lt;/a&gt;&lt;/strong&gt; ottengo un punteggio superiore a 90 nella home e superiore a 95 sui singoli articoli (il collo di bottiglia sta nelle immagini, devo ancora lavorarci su).&lt;/p&gt;
&lt;h1 id="pro-e-contro"&gt;Pro e contro
&lt;/h1&gt;&lt;h2 id="pro"&gt;Pro
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Velocità&lt;/li&gt;
&lt;li&gt;Semplicità: una volta configurato permette di concentrarsi sulla scrittura degli articoli&lt;/li&gt;
&lt;li&gt;Flessibilità, facilità di personalizzazione con temi&lt;/li&gt;
&lt;li&gt;Nessun software da mantenere&lt;/li&gt;
&lt;li&gt;Sicurezza&lt;/li&gt;
&lt;li&gt;Possibilità di scrivere i post ovunque senza usare il CMS&lt;/li&gt;
&lt;li&gt;Hosting gratuito (a breve un articolo a proposito)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="contro"&gt;Contro
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Possibilità d&amp;rsquo;utilizzo limitate a blog o semplice sito web&lt;/li&gt;
&lt;li&gt;Nessun editor con funzionalità di formattazione (non nativamente)&lt;/li&gt;
&lt;li&gt;Plugin limitati e non installabili con un singolo click&lt;/li&gt;
&lt;li&gt;Configurazione iniziale non proprio banale&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="considerazioni"&gt;Considerazioni
&lt;/h1&gt;&lt;p&gt;Come avete potuto vedere Hugo, ma i generatori di siti statici in generale, sono adatti a chi ha poche pretese dal punto di vista di plugin e aggiunta di funzionalità, ma c&amp;rsquo;è anche da dire che i temi non si limitano all&amp;rsquo;aspetto grafico (come invece avviene su Wordpress), ma portano funzionalità al sito.&lt;/p&gt;
&lt;p&gt;Un esempio è il tema che uso su questo sito, che per dirne una supporta la ricerca e il cambio di modalità chiaro/scuro.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;altra parte è anche vero che la configurazione iniziale non è banale. La documentazione c&amp;rsquo;è, ma in inglese e talvolta non è proprio immediata da trovare.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Crediti: &lt;a class="link" href="https://www.flaticon.com/authors/freepik" target="_blank" rel="noopener"
&gt;Icons created by Freepik - Flaticon&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Demo di Nextcloud Hub – come provarlo</title><link>https://lazzarotto.dev/blog/demo-di-nextcloud-hub-come-provarlo/</link><pubDate>Thu, 28 Jul 2022 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/demo-di-nextcloud-hub-come-provarlo/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Demo di Nextcloud Hub – come provarlo" /&gt;&lt;p&gt;&lt;em&gt;Avete sempre voluto testare Nextcloud ma non avete voglia di installarlo perché troppo complicato? Oppure volete giusto dare un&amp;rsquo;occhiata per capire cosa c&amp;rsquo;è di nuovo nella versione 18 (Hub)? Oppure volete farlo vedere a un amico?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In questo articolo vi spiegherò come poter mettere le mani e &lt;strong&gt;testare un&amp;rsquo;istanza completamente funzionante di Nextcloud Hub&lt;/strong&gt;, potendo provare così tutte le funzionalità offerte da questo potente strumento.&lt;/p&gt;
&lt;p&gt;Su questo sito scrissi in passato un paio d&amp;rsquo;articoli su come provare delle versioni demo di Nextcloud senza necessità di doverlo installare.&lt;/p&gt;
&lt;p&gt;I precedenti articoli però facevano riferimento al sito di un certo &lt;a class="link" href="https://bayton.org/2017/02/introducing-nextcloud-demo-servers" target="_blank" rel="noopener"
&gt;Jason Bayton&lt;/a&gt;, che purtroppo non ha più mantenuto queste istanze demo, e sono ferme alla versione 14.&lt;/p&gt;
&lt;p&gt;In ogni caso non c&amp;rsquo;è da disperare, perché l&amp;rsquo;omonima software house ha reso disponibile online una versione demo dell&amp;rsquo;ultima versione di Nextcloud.&lt;/p&gt;
&lt;h2 id="come"&gt;Come
&lt;/h2&gt;&lt;p&gt;Semplicissimo, andate su &lt;a class="link" href="https://try.nextcloud.com" target="_blank" rel="noopener"
&gt;questo link&lt;/a&gt; e cliccate sul pulsante &lt;strong&gt;Take me there!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cliccando su quel pulsante vi si aprirà una pagine con un modulo di registrazione, e dopo aver completato i campi vi arriverà un&amp;rsquo;email da parte di Nextcloud con un link per avviare l&amp;rsquo;istanza demo.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;ora in poi quello che vedrete sullo schermo sarà una versione demo di Nextcloud Hub, completamente funzionante con molte app attive, compresa Collabora Online.&lt;/p&gt;
&lt;p&gt;Collabora Online è la suite office open source utilizzata di default da Nextcloud.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ATTENZIONE&lt;/strong&gt;: vi informo che &lt;strong&gt;dopo 60 minuti l&amp;rsquo;utente di prova verrà eliminato&lt;/strong&gt;, quindi non caricate niente di personale perché altrimenti sarà tutto eliminato per lasciare spazio agli altri utenti.&lt;/p&gt;</description></item><item><title>CentOS 8 - Bind di logstash su porta 514</title><link>https://lazzarotto.dev/blog/centos-8-bind-di-logstash-su-porta-514/</link><pubDate>Sun, 28 Nov 2021 00:00:00 +0200</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/centos-8-bind-di-logstash-su-porta-514/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post CentOS 8 - Bind di logstash su porta 514" /&gt;&lt;p&gt;La situazione: è necessario inviare i log da un vecchio apparecchio a &lt;a class="link" href="https://www.elastic.co/logstash/" target="_blank" rel="noopener"
&gt;logstash&lt;/a&gt; in esecuzione su un &lt;strong&gt;CentOS 8&lt;/strong&gt;, per archiviare i log su ElasticSearch.&lt;/p&gt;
&lt;h2 id="il-problema"&gt;Il problema
&lt;/h2&gt;&lt;p&gt;Il dispositivo è vecchio e non supporta la modifica della porta syslog predefinita da &lt;strong&gt;514/udp&lt;/strong&gt; a qualcosa di diverso, come la porta &lt;strong&gt;5140/udp&lt;/strong&gt;.
Purtroppo questo può accadere, ad esempio su appliance virtuali come &lt;strong&gt;ZeroShell&lt;/strong&gt;, dove non c&amp;rsquo;è modo di cambiare la porta syslog da quella predefinita, ma c&amp;rsquo;è una soluzione rapida a questo problema!&lt;/p&gt;
&lt;p&gt;Quello che vi mostrerò è &lt;strong&gt;come fare il binding di qualsiasi processo su qualsiasi porta privilegiata&lt;/strong&gt;, mentre lo si esegue come utente non privilegiato&lt;/p&gt;
&lt;h2 id="perché"&gt;Perché
&lt;/h2&gt;&lt;p&gt;Si tratta di una funzione di sicurezza, in quanto se ci si connette a un servizio su una di queste porte si può essere abbastanza sicuri di essere in presenza di un servizio vero e non di un falso messo in piedi da qualche hacker. Sarebbe davvero pericoloso permettere a tutto il sistema di collegarsi a qualsiasi servizio su una porta non privilegiata, perché le porte da 1 a 1023 sono effettivamente &lt;strong&gt;privilegiate!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Comunque, questa non è una guida su come impostare la porta di ascolto di logstash, ma piuttosto per consentire a &lt;strong&gt;java&lt;/strong&gt; di effettuare il binding su una porta &amp;lt; 1024.&lt;/p&gt;
&lt;h2 id="come"&gt;Come
&lt;/h2&gt;&lt;p&gt;La procedura è molto semplice. Prima di tutto dobbiamo &lt;strong&gt;trovare il percorso&lt;/strong&gt; del processo &lt;strong&gt;java&lt;/strong&gt; fornito con logstash e il percorso della libreria &lt;strong&gt;libjli.so&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I due percorsi dovrebbero assomigliare a questo:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/usr/share/logstash/jdk/bin/java
/usr/share/logstash/jdk/lib/jli
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Una volta ottenuto il percorso dei due file, è possibile iniziare.
Immettere i seguenti comandi come root.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;setcap &lt;span class="nv"&gt;CAP_NET_BIND_SERVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;+eip /usr/share/logstash/jdk/bin/java&lt;span class="p"&gt;;&lt;/span&gt; getcap /usr/share/logstash/jdk/bin/java &lt;span class="c1"&gt;# questo permette a java di fare il bind su porta &amp;lt; 1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/usr/share/logstash/jdk/lib/jli&amp;#34;&lt;/span&gt; &amp;gt; /etc/ld.so.conf.d/java.conf &lt;span class="c1"&gt;# questo sarà usato da ldconfig&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ldconfig&lt;span class="p"&gt;;&lt;/span&gt; ldconfig -v -p &lt;span class="p"&gt;|&lt;/span&gt; grep libjli &lt;span class="c1"&gt;# controllo se la libreria è nella cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quando il sistema si carica, avviare il servizio e verificare lo stato e se è collegato alla porta giusta.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start logstash&lt;span class="p"&gt;;&lt;/span&gt; journalctl -xef -u logstash &lt;span class="c1"&gt;# avvia il servizio e controlla il servizio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status logstash &lt;span class="c1"&gt;# controlla lo stato del servizio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;514&lt;/span&gt; &lt;span class="c1"&gt;# controlla se logstash ha il bind sulla 514&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A questo punto si dovrebbe avere logstash attivo e funzionante, e soprattutto in ascolto sulla porta 514.&lt;/p&gt;</description></item><item><title>Generazione anteprime automatica su Nextcloud con Preview Generator</title><link>https://lazzarotto.dev/blog/generazione-anteprime-automatica-su-nextcloud-con-preview-generator/</link><pubDate>Sat, 06 Feb 2021 08:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/generazione-anteprime-automatica-su-nextcloud-con-preview-generator/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Generazione anteprime automatica su Nextcloud con Preview Generator" /&gt;&lt;p&gt;Ciao, oggi vi spiegherò come generare anteprime su Nextcloud delle vostre foto in anticipo, per rendere l&amp;rsquo;esperienza d&amp;rsquo;uso più piacevole.&lt;/p&gt;
&lt;h2 id="a-cosa-servono-le-anteprime"&gt;A cosa servono le anteprime?
&lt;/h2&gt;&lt;p&gt;Le anteprime, o &lt;em&gt;thumbnail&lt;/em&gt;, sono delle versioni più piccole delle immagini che caricate su Nextcloud (qui la guida su &lt;a class="link" href="https://www.mlazzarotto.it/installare-nextcloud-20-su-ubuntu" target="_blank" rel="noopener"
&gt;come installare Nextcloud su Ubuntu&lt;/a&gt;).
Le anteprime sono molto utili nella navigazione delle cartelle di Nextcloud.
Facciamo un esempio: abbiamo caricato 200 foto nella cartella &lt;strong&gt;Londra&lt;/strong&gt; su Nextcloud. Se non esistessero le anteprime e volessimo entrare nella cartella &lt;strong&gt;Londra&lt;/strong&gt;, non potremmo vedere l&amp;rsquo;&lt;strong&gt;anteprima&lt;/strong&gt; delle foto per capire al volo quale di questa vogliamo aprire.&lt;/p&gt;
&lt;h2 id="ma-non-vengono-generate-automaticamente"&gt;Ma non vengono generate automaticamente?
&lt;/h2&gt;&lt;p&gt;Sì, è vero, ma&amp;hellip; Nextcloud genera le anteprime solo nel momento in cui è necessario. Ad esempio quando entriamo in una cartella in cui sono state caricate diverse foto.
Ma cosa succederebbe se entrassi nella cartella &lt;strong&gt;Parigi&lt;/strong&gt;, la quale contiene più di 1000 foto?
Nextcloud sarebbe costretto a generare più di 1000 anteprime al momento, e le anteprime verrebbero visualizzate lentamente una alla volta.&lt;/p&gt;
&lt;h2 id="ecco-la-soluzione"&gt;Ecco la soluzione!
&lt;/h2&gt;&lt;p&gt;La soluzione al problema è abbastanza semplice e richiede solo pochissimi comandi!
Ci vieni in aiuto l&amp;rsquo;applicazione &lt;strong&gt;&lt;!-- raw HTML omitted --&gt;Preview Generator&lt;!-- raw HTML omitted --&gt;&lt;/strong&gt;. Questa applicazione ci permette di generare le anteprime in anticipo e definire ogni quanto Nextcloud andrà a generarle per i nuovi files.&lt;/p&gt;
&lt;p&gt;E ora ovviamente vi spiego come installarla e configurarla!&lt;/p&gt;
&lt;h2 id="prima-di-cominciare"&gt;Prima di cominciare
&lt;/h2&gt;&lt;p&gt;Colleghiamoci in SSH, con l&amp;rsquo;utente &lt;em&gt;root&lt;/em&gt;, sulla macchina dov&amp;rsquo;è installato Nextcloud.&lt;/p&gt;
&lt;p&gt;Diamo il seguente comando per rendere eseguibile lo script &lt;em&gt;occ&lt;/em&gt; che ci servirà più avanti (il percorso di installazione di Nextcloud può variare):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x /var/www/nextcloud/occ
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="alcuni-dettagli-sulla-generazione-delle-anteprime"&gt;Alcuni dettagli sulla generazione delle anteprime
&lt;/h2&gt;&lt;p&gt;Di default Nextcloud per ogni foto genera diverse anteprime ognuna con una diversa dimensione, per esempio se andate a vedere i file, per la visualizzazione a griglia, la visualizzazione a elenco o ancora la visualizzazione tramite l&amp;rsquo;app &lt;strong&gt;Foto&lt;/strong&gt;, saranno mostrate anteprime di dimensioni tutte diverse.&lt;/p&gt;
&lt;p&gt;Questo comporta il fatto che per ogni file vengono create diverse anteprime e di conseguenza la generazione di centinaia o migliaia di files comporta un certo utilizzo di spazio sul disco.&lt;/p&gt;
&lt;p&gt;Esistono però dei parametri che è possibile definire per limitare la dimensione massima delle anteprime, o per quali file generarle. Per ulteriori dettagli vi invito a leggere la documentazione ufficiale di Nextcloud &lt;a class="link" href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html#previews" target="_blank" rel="noopener"
&gt;qui&lt;/a&gt; e &lt;a class="link" href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/previews_configuration.html" target="_blank" rel="noopener"
&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Per esempio, per limitare la dimensione massima delle anteprime più grandi, che di &lt;strong&gt;default è 4096x4096 pixel&lt;/strong&gt;, è possibile usare i seguenti comandi (ovviamente i valori sono in pixel).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u www-data php /var/www/nextcloud/occ config:system:set preview_max_x --value &lt;span class="m"&gt;2048&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u www-data php /var/www/nextcloud/occ config:system:set preview_max_y --value &lt;span class="m"&gt;2048&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Un altro parametro che è possibile configurare per ridurre le dimensioni delle anteprime, è la qualità delle stesse (di default è &lt;strong&gt;90&lt;/strong&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u www-data php /var/www/nextcloud/occ config:system:set jpeg_quality --value &lt;span class="m"&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NB: se non avete voglia di modificare i parametri, potete ovviamente lasciare tutto di default!
Inoltre, per controllare i parametri appena impostati, basterà aprire il file &lt;em&gt;config.php&lt;/em&gt; di Nextcloud.&lt;/p&gt;
&lt;h2 id="ecco-come-generare-tutte-le-anteprime"&gt;Ecco come generare tutte le anteprime
&lt;/h2&gt;&lt;p&gt;Iniziamo accedendo a Nextcloud, clicchiamo sull&amp;rsquo;icona del nostro utente e poi su &lt;strong&gt;Applicazioni&lt;/strong&gt;. Andiamo quindi nella sezione &lt;strong&gt;Multimedia&lt;/strong&gt; e cerchiamo &lt;strong&gt;Preview Generator&lt;/strong&gt;, infine clicchiamo sul bottone &lt;strong&gt;Scarica e abilita&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Bene, una volta installata l&amp;rsquo;app dovremo dare solo un comando da terminale per generare tutte le anteprime per le immagini già presenti, ma questo sarà fatto solo la prima volta. Vedremo più avanti come automatizzare il processo.
Diamo il seguente comando per generare tutte le anteprime:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u www-data php /var/www/nextcloud/occ preview:generate-all -vvv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il comando potrebbe durare da pochi secondi a diversi minuti in base al numero di foto presenti e alle risorse del sistema.&lt;/p&gt;
&lt;h2 id="pianificazione-automatica"&gt;Pianificazione automatica
&lt;/h2&gt;&lt;p&gt;E ora vi spiego come pianificare la generazione delle anteprime usando &lt;strong&gt;cron&lt;/strong&gt;, in modo che vengano generate tutte le anteprime periodicamente per le nuove immagini.&lt;/p&gt;
&lt;p&gt;Aprite il crontab con il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;crontab -u www-data -e
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inserite all&amp;rsquo;interno, nell&amp;rsquo;ultima riga, il seguente comando che avvierà la generazione delle nuove anteprime ogni 30 minuti (ovviamente è possibile impostarlo con maggiore o minore frequenza):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;*/30 * * * * php /var/www/nextcloud/occ preview:pre-generate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="considerazioni-finali"&gt;Considerazioni finali
&lt;/h2&gt;&lt;p&gt;Ottimo! D&amp;rsquo;ora in poi vedrete che navigando su Nextcloud tutte le foto saranno molto più veloci ad aprirsi, in quanto Nextcloud avrà già pronte le anteprime per le immagini.
Se non vedete miglioramenti per le nuove foto, significa che la pianificazione impostata sopra dev&amp;rsquo;essere ancora eseguita, quindi basterà aspettare.&lt;/p&gt;
&lt;p&gt;In caso di dubbi o domande non esitate a commentare.
Per altri dettagli potete guardare oltre alla documentazione ufficiale di Nextcloud linkata sopra, anche la pagina Github del progetto &lt;a class="link" href="https://github.com/rullzer/previewgenerator" target="_blank" rel="noopener"
&gt;Preview Generator&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Cos’è Nextcloud – Il Cloud personale e open source</title><link>https://lazzarotto.dev/blog/cos%C3%A8-nextcloud-il-cloud-personale-e-open-source/</link><pubDate>Thu, 28 Jan 2021 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/cos%C3%A8-nextcloud-il-cloud-personale-e-open-source/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Cos’è Nextcloud – Il Cloud personale e open source" /&gt;&lt;h2 id="cosè-nextcloud"&gt;Cos&amp;rsquo;è Nextcloud
&lt;/h2&gt;&lt;p&gt;Nextcloud è un software che permette di ospitare su un computer, server o addirittura un &lt;a class="link" href="https://www.raspberrypi.org" target="_blank" rel="noopener"
&gt;Raspberry Pi&lt;/a&gt; un&amp;rsquo;infrastruttura simile a quella dei servizi di cloud storage. È un’alternativa interessante anche ai tradizionali file server, sia in ambito casalingo sia in ambito professionale.&lt;/p&gt;
&lt;h2 id="nextcloud-come-alternativa-a-google-drive-dropbox-o-onedrive"&gt;Nextcloud come alternativa a Google Drive, Dropbox o OneDrive
&lt;/h2&gt;&lt;p&gt;I servizi di file storage come Google Drive, Dropbox o OneDrive sono diventati molto popolari ultimamente. Essi permettono infatti di sincronizzare automaticamente i vostri files con il cloud e attraverso diversi dispositivi in modo del tutto automatico.&lt;/p&gt;
&lt;p&gt;Questi servizi di cloud storage offrono nei loro piani gratuiti solo pochi gigabyte per l&amp;rsquo;archiviazione dei dati ma offrono anche diversi piani a pagamento per chi necessitasse ulteriore spazio.&lt;/p&gt;
&lt;p&gt;Nextcloud si propone come alternativa gratuita a Google Drive, Dropbox e OneDrive.&lt;/p&gt;
&lt;h2 id="vantaggi"&gt;Vantaggi
&lt;/h2&gt;&lt;p&gt;I vantaggi sono molteplici: il &lt;strong&gt;costo molto basso&lt;/strong&gt; e l&amp;rsquo;assenza di costi mensili, il &lt;strong&gt;controllo completo&lt;/strong&gt;, la gestione dei dati (cosa che non è sempre scontata) e lo &lt;strong&gt;spazio&lt;/strong&gt; limitato solo dalla dimensione degli hard disks a vostra disposizione.&lt;/p&gt;
&lt;p&gt;I vantaggi di avere un server personale con Nextcloud sono i seguenti:&lt;/p&gt;
&lt;h3 id="costi-di-partenza-molto-bassi-senza-rinnovi-mensili"&gt;Costi di partenza molto bassi senza rinnovi mensili
&lt;/h3&gt;&lt;p&gt;Esatto, i costi iniziali sono bassissimi se non nulli, in quanto per poter installare un proprio server con Nextcloud non serve hardware potente. Infatti è possibile utilizzare anche un semplicissimo Raspberry Pi (il cui prezzo parte da €35 per la versione da 2GB di RAM) e poi è possibile usare i dispositivi di archiviazione che si hanno già in casa, come chiavette USB, dischi esterni, o HDD/SSD.&lt;/p&gt;
&lt;h3 id="privacy-e-controllo-completo-dei-dati"&gt;Privacy e controllo completo dei dati
&lt;/h3&gt;&lt;p&gt;Privacy, questa sconosciuta.
Sempre più frequentemente veniamo a conoscenza di attacchi informatici mirati all&amp;rsquo;esposizione di dati sensibili, anche chiamati &lt;em&gt;data breach&lt;/em&gt;, presso i più famosi servizi web al mondo. Purtroppo non è una cosa che possiamo controllare, a meno che non decidiamo di tenere i nostri file in casa.&lt;/p&gt;
&lt;p&gt;Utilizzando Nextcloud come cloud storage avremo il controllo completo dei nostri dati. Come? Facile, avendo un server in casa e mettendo in atto le giuste misure di sicurezza, come l&amp;rsquo;uso di una VPN, sarà impossibile che qualche malintenzionati riesca a rubarci i dati.&lt;/p&gt;
&lt;p&gt;Inoltre, Nextcloud supporta nativamente la &lt;a class="link" href="https://nextcloud.com/endtoend" target="_blank" rel="noopener"
&gt;crittografia End-to-End&lt;/a&gt; dei documenti. Ciò significa che nel caso qualche malintenzionato riesca ad avere accesso al nostro server, non riuscirà a leggere i file caricati, perché non saranno visibile in quanto crittografati.&lt;/p&gt;
&lt;h3 id="spazio-illimitato"&gt;Spazio illimitato
&lt;/h3&gt;&lt;p&gt;Lo spazio sarà illimitato o quasi, dipende da quali dischi utilizzeremo. E se un giorno dovessimo decidere che lo spazio che abbiamo non è abbastanza, basterà spostare i file su un disco più capiente.&lt;/p&gt;
&lt;h2 id="svantaggi"&gt;Svantaggi
&lt;/h2&gt;&lt;p&gt;Nonostante l&amp;rsquo;hosting in casa di Nextcloud sembra la soluzione a tutto, ha degli svantaggi e dei limiti.
Alcuni degli svantaggi sono:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sarà vostro dovere fare manutenzione al server e sistemarlo in caso di problemi (molto rari) e per questo sarà necessario avere una minima conoscenza del sistema operativo Linux&lt;/li&gt;
&lt;li&gt;altresì sarete voi a dover eseguire dei backup periodici dei documenti, in caso di guasto dell&amp;rsquo;hard disk o peggio, del furto dello stesso&lt;/li&gt;
&lt;li&gt;la velocità dei download/upload sarà limitata ovviamente dalla connessione Internet di casa e dalla velocità dei dischi&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="le-features-di-nextcloud"&gt;Le features di Nextcloud
&lt;/h2&gt;&lt;p&gt;Vediamo ora alcune delle principali funzionalità di Nextcloud:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creazione di utenti multipli e gestione dei privilegi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Condivisione&lt;/strong&gt; tra utenti e tramite url pubblici&lt;/li&gt;
&lt;li&gt;Accesso tramite web browser, client software e app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sincronizzazione automatica&lt;/strong&gt; dei files tramite il client&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sicurezza&lt;/strong&gt;, con possibilità di 2FA (autenticazione a 2 fattori) e &lt;strong&gt;End-to-end encryption&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Controllo delle versioni&lt;/strong&gt; delle modifiche dei files&lt;/li&gt;
&lt;li&gt;Possibilità di &lt;strong&gt;creazione e modifica di files di Office&lt;/strong&gt; (Word, Excel e PowerPoint) tramite &lt;a class="link" href="https://nextcloud.com/collaboraonline" target="_blank" rel="noopener"
&gt;Collabora&lt;/a&gt;, che viene installato di default&lt;/li&gt;
&lt;li&gt;Decine e decine di &lt;strong&gt;app&lt;/strong&gt; ufficiali e di terze parti per estendere le funzionalità di Nextcloud (qui c&amp;rsquo;è lo &lt;a class="link" href="https://apps.nextcloud.com" target="_blank" rel="noopener"
&gt;store&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Possibilità di collegamento con storage esterno (Google Drive, Dropbox, Amazon, ecc.)&lt;/li&gt;
&lt;li&gt;Gestione del calendario, contatti e email&lt;/li&gt;
&lt;li&gt;Chat e sistema di videoconferenza tramite &lt;a class="link" href="https://nextcloud.com/talk" target="_blank" rel="noopener"
&gt;Nextcloud Talk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="e-ora"&gt;E ora?
&lt;/h2&gt;&lt;p&gt;Spero di avervi dato un&amp;rsquo;anteprima su cos&amp;rsquo;è Nextcloud e cosa può fare per voi. Se avete deciso di provarlo, potete vedere la mia guida a come installarlo su Ubuntu 20.&lt;/p&gt;</description></item><item><title>Installare Nextcloud 20 su Ubuntu – Il Metodo “Lungo”</title><link>https://lazzarotto.dev/blog/installare-nextcloud-20-su-ubuntu-il-metodo-lungo/</link><pubDate>Sat, 23 Jan 2021 08:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/installare-nextcloud-20-su-ubuntu-il-metodo-lungo/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Installare Nextcloud 20 su Ubuntu – Il Metodo “Lungo”" /&gt;&lt;p&gt;Ciao a tutti, in questo articolo cercherò di spiegarvi nel modo più completo possibile come installare Nextcloud 20 su Ubuntu. I passaggi descritti sono stati testati su Ubuntu 20.04 LTS.&lt;/p&gt;
&lt;p&gt;La modalità per installare Nextcloud 20 su Ubuntu della quale vi spiegherò i passi da seguire, sarà l&amp;rsquo;installazione più &amp;ldquo;difficile&amp;rdquo; e lunga, e cioè installando separatamente MySQL, Apache e PHP.&lt;/p&gt;
&lt;p&gt;Per chi invece non avesse o non potesse seguire tutti i passaggi descritti di seguito, potrà installare Nextcloud in altri modi, ad esempio con i pacchetti &lt;strong&gt;snap&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="cosè-nextcloud"&gt;Cos&amp;rsquo;è Nextcloud?
&lt;/h2&gt;&lt;p&gt;Se non sapete ancora cos&amp;rsquo;è Nextcloud e quali sono le sue fantastiche funzionalità, vi invito a leggere prima di tutto il mio post al riguardo &lt;a class="link" href="https://lazzarotto.dev/blog/cos%C3%A8-nextcloud-il-cloud-personale-e-open-source/" &gt;Cos’è Nextcloud – Il Cloud personale e open source&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="prerequisiti"&gt;Prerequisiti
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Una macchina fisica o virtuale con &lt;strong&gt;Ubuntu 20.04 LTS o superiori&lt;/strong&gt; (potrebbe funzionare anche con versioni meno recenti), con almeno &lt;strong&gt;1GB di RAM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Tempo necessario: circa 20/30 minuti.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tutti i comandi qui di seguito dovranno essere eseguiti come utente &lt;strong&gt;root&lt;/strong&gt; oppure tramite il comando &lt;strong&gt;sudo&lt;/strong&gt; da anteporre ad ogni comando.&lt;/p&gt;
&lt;h2 id="installazione-pacchetti"&gt;Installazione pacchetti
&lt;/h2&gt;&lt;p&gt;Di seguito trovate un comando (bello lungo) che permetterà di installare tutti i pacchetti necessari al funzionamento di Nextcloud. Nel caso utilizziate una versione meno recente di Ubuntu, è possibile che non troviate la versione 7.4 di PHP, e dovrete ricorrere a una versione minore come la 7.3 o 7.2.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install apache2 php7.4 php7.4-fpm php7.4-mysql php7.4-zip php7.4-curl php7.4-apcu php-dompdf php7.4-xml php7.4-mbstring php7.4-intl php-imagick php7.4-bcmath php7.4-gmp libapache2-mod-php7.4 mariadb-server unzip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; come potete vedere ho inserito tra gli altri pacchetti anche MariaDB, che utilizzeremo come database server. Per chi non volesse utilizzare &lt;strong&gt;MariaDB&lt;/strong&gt; come database potrà usare &lt;strong&gt;MySQL&lt;/strong&gt;, in quanto tutti i comandi della guida sono validi su entrambi i database.&lt;/p&gt;
&lt;h2 id="configurazione-di-apache"&gt;Configurazione di Apache:
&lt;/h2&gt;&lt;p&gt;Cominciamo con l&amp;rsquo;attivazione dei moduli di Apache necessari al nostro scopo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;a2enmod rewrite headers env dir mime ssl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apache per funzionare ha bisogno di alcuni file di configurazione che gli indichino quali pagine mostrare. Possiamo usare un programma come WinSCP o FileZilla per creare e modificare il file o direttamente da terminale &lt;strong&gt;nano&lt;/strong&gt; o &lt;strong&gt;vi&lt;/strong&gt;. Creiamo quindi il file &lt;strong&gt;/etc/apache2/sites-available/nextcloud.conf&lt;/strong&gt; e all&amp;rsquo;interno del file appena creato inseriamo il testo seguente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;*:80&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;DocumentRoot&lt;/span&gt; &lt;span class="sx"&gt;/var/www/nextcloud/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ServerName&lt;/span&gt; your.server.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Directory&lt;/span&gt; &lt;span class="s"&gt;/var/www/nextcloud/&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Require&lt;/span&gt; &lt;span class="k"&gt;all&lt;/span&gt; granted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;AllowOverride&lt;/span&gt; &lt;span class="k"&gt;All&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Options&lt;/span&gt; FollowSymLinks MultiViews
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span class="s"&gt;mod_dav.c&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Dav&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/Directory&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span class="s"&gt;mod_ssl.c&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;_default_:443&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;DocumentRoot&lt;/span&gt; &lt;span class="sx"&gt;/var/www/nextcloud&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/error.log
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/access.log combined
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLEngine&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateFile&lt;/span&gt; &lt;span class="sx"&gt;/etc/ssl/certs/ssl-cert-snakeoil.pem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;SSLCertificateKeyFile&lt;/span&gt; &lt;span class="sx"&gt;/etc/ssl/private/ssl-cert-snakeoil.key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span class="s"&gt;mod_headers.c&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Header&lt;/span&gt; always set Strict-Transport-Security &lt;span class="s2"&gt;&amp;#34;max-age=15552000; includeSubDomains&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il testo qui sopra, per chi non lo comprendesse, in poche parole indica ad Apache di mostrare il contenuto della cartella &lt;strong&gt;/var/www/nextcloud&lt;/strong&gt; quando aprirete il sito tramite browser. In aggiunta alla &lt;strong&gt;porta 80&lt;/strong&gt;, il sito sarà raggiungibile anche tramite il protocollo &lt;strong&gt;HTTPS&lt;/strong&gt; sulla &lt;strong&gt;porta 443&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Il certificato usato è quello di default e di conseguenza self-signed, pertanto all&amp;rsquo;accesso della pagina di Nextcloud il browser mostrerà un avviso di sicurezza, ma potete ignorarlo.&lt;/p&gt;
&lt;p&gt;A questo punto attiviamo il nuovo sito e disattiviamo quello di default che non utilizzeremo con i seguenti comandi:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;a2dissite 000-default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;a2ensite nextcloud.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart apache2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configurazione-di-mariadb"&gt;Configurazione di MariaDB
&lt;/h2&gt;&lt;h3 id="wizard-iniziale"&gt;Wizard iniziale
&lt;/h3&gt;&lt;p&gt;Prima di poter utilizzare MariaDB, sarà necessario eseguire un primo wizard per &amp;ldquo;mettere in sicurezza&amp;rdquo; l&amp;rsquo;istanza del database, in modo da evitare eventuali accessi non autorizzati.&lt;/p&gt;
&lt;p&gt;Ora vi spiegherò come eseguire e rispondere al wizard.&lt;/p&gt;
&lt;p&gt;Per lanciare il wizard utilizziamo il seguente comando: &lt;code&gt;mysql_secure_installation&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Essendo una procedura guidata, ci verranno chieste alcune informazioni.&lt;/p&gt;
&lt;p&gt;Io vi consiglio di rispondere nel modo seguente, ovviamente come password dovrete inserirne una vostra personalizzata.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prima domanda: premete INVIO (la password non è ancora stata definita)&lt;/li&gt;
&lt;li&gt;Seconda domanda: inserite una password a vostra scelta per l&amp;rsquo;account &lt;strong&gt;root&lt;/strong&gt; del database. Da conservare per i passaggi successivi.&lt;/li&gt;
&lt;li&gt;Terza domanda: inserire la stessa password.&lt;/li&gt;
&lt;li&gt;Dalla quarta domanda in poi: confermare le impostazioni di default con il tasto INVIO.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="creazione-utente-e-schema"&gt;Creazione utente e schema
&lt;/h3&gt;&lt;p&gt;A questo punto andiamo a creare lo schema sul db e un utente con i privilegi sullo schema. Questi ci serviranno per far comunicare Nextcloud con il database.&lt;/p&gt;
&lt;p&gt;Per prima cosa apriamo la shell di MariaDB, in questo modo. La password da utilizzare per fare entrare è quella impostata durante il wizard sopra.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysql -uroot -p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Una volta entrati creiamo lo schema, l&amp;rsquo;utente e diamo i permessi completi all&amp;rsquo;utente appena creato. Al posto di &lt;code&gt;password&lt;/code&gt; inseriamo una password a nostra scelta, abbastanza complessa.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nextcloud&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CHARACTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8mb4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COLLATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf8mb4_general_ci&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nextcloud&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nextcloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nextcloud&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="installazione-nextcloud"&gt;Installazione Nextcloud
&lt;/h2&gt;&lt;p&gt;Bene, arrivati a questo punto avremo Apache e MariaDB configurati. Non ci resta che scaricare il pacchetto di Nextcloud e configurarlo.&lt;/p&gt;
&lt;p&gt;Andiamo sul sito di &lt;a class="link" href="https://nextcloud.com/install/#instructions-server" target="_blank" rel="noopener"
&gt;Nextcloud&lt;/a&gt;, andiamo nella sezione &lt;strong&gt;COMMUNITY PROJECTS&lt;/strong&gt; e clicchiamo col tasto destro su &lt;strong&gt;Get ZIP file&lt;/strong&gt;, quindi copiamo il collegamento al file.&lt;/p&gt;
&lt;p&gt;Ora torniamo sul terminale di Ubuntu e diamo il seguente comando per scaricare l&amp;rsquo;archivio contenente i file di Nextcloud.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://download.nextcloud.com/server/releases/latest.zip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ora diamo i seguenti comandi per scompattare la cartella e dare i permessi giusti:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;unzip latest.zip -d /var/www
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown -R www-data:www-data /var/www/nextcloud
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Come vedete sopra, la cartella in cui ho scompattato l&amp;rsquo;archivio è &lt;em&gt;/var/www&lt;/em&gt;. Questa è solo la cartella che contiene il &amp;ldquo;motore&amp;rdquo; di Nextcloud. Possiamo scegliere quindi dove mettere la cartella che conterrà effettivamente i nostri dati che andremo a caricare. Il percorso può essere sullo stesso disco o su un disco esterno. In ogni caso è sempre &lt;strong&gt;sconsigliato&lt;/strong&gt; usare la cartella &lt;em&gt;/var/www/nextcloud&lt;/em&gt; come contenitore dei dati, per motivi di sicurezza.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir /opt/nextcloud_data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown -R www-data:www-data /opt/nextcloud_data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ottimo, a questo punto basterà collegarsi al server Apache tramite il browser per iniziare il wizard di setup. Nel mio caso sarà https://192.168.1.219/.&lt;/p&gt;
&lt;h2 id="wizard-di-nextcloud"&gt;Wizard di Nextcloud
&lt;/h2&gt;&lt;p&gt;Siamo arrivati quasi alla fine, ora rimane solo da utilizzare il wizard per configurare Nextcloud. Qui sotto potete vedere come si presenta.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/wizard_nc_20.png#center"
loading="lazy"
alt="wizard"
&gt;&lt;/p&gt;
&lt;p&gt;Nelle prime due caselle dovrete inserire il nome e la password del nuovo utente (che sarà anche amministratore). Nella terza casella sarà da inserire il percorso della cartella che conterrà tutti i file e cartelle caricati in futuro.&lt;/p&gt;
&lt;p&gt;Infine, nelle ultime quattro caselle dovrete inserire i dati del database: nome utente (nel nostro caso &lt;em&gt;nextcloud&lt;/em&gt;), la password che avete scelto, il nome del database (nel nostro caso sempre &lt;em&gt;nextcloud&lt;/em&gt;) e nell&amp;rsquo;ultima casella potete lasciare il valore di default in quanto il database server è installato sulla stessa macchina che contiene anche Apache.&lt;/p&gt;
&lt;p&gt;Cliccate quindi sul pulsante &lt;strong&gt;Termina configurazione&lt;/strong&gt; e attendete che Nextcloud finisca la sua installazione. Al termine vi sarà proposta la seguente schermata di benvenuto.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/welcome_nc_20.png#center"
loading="lazy"
alt="welcome"
&gt;&lt;/p&gt;
&lt;h2 id="ultimi-ritocchi"&gt;Ultimi ritocchi
&lt;/h2&gt;&lt;p&gt;Giunti a questo punto, Nextcloud sarà configurato e pronto per poter essere utilizzato. Rimangono però alcuni azioni da eseguire per configurarlo al meglio e ottimizzare il sistema. Di seguito inserirò alcuni comandi da eseguire.&lt;/p&gt;
&lt;h3 id="php"&gt;PHP
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;s/output_buffering = 4096/output_buffering = Off/g&amp;#39;&lt;/span&gt; /etc/php/7.4/apache2/php.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;s/memory_limit = 128M/memory_limit = 512M/g&amp;#39;&lt;/span&gt; /etc/php/7.4/apache2/php.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;s/memory_limit = 128M/memory_limit = 512M/g&amp;#39;&lt;/span&gt; /etc/php/7.4/cli/php.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;s/upload_max_filesize = 2M/upload_max_filesize = 16G/g&amp;#39;&lt;/span&gt; /etc/php/7.4/apache2/php.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;s/post_max_size = 8M/post_max_size = 16G/g&amp;#39;&lt;/span&gt; /etc/php/7.4/apache2/php.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl restart apache
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="caching"&gt;Caching
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/);/ &amp;#39;memcache.local&amp;#39; =&amp;gt; &amp;#39;\\\OC\\\Memcache\\\APCu&amp;#39;,\n);/g&amp;#34;&lt;/span&gt; /var/www/nextcloud/config/config.php
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown -R www-data:www-data /var/www/nextcloud/config/config.php
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="controllo-indici-database"&gt;Controllo indici database
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x /var/www/nextcloud/occ
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u www-data /var/www/nextcloud/occ db:add-missing-indices
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="considerazioni-finali"&gt;Considerazioni finali
&lt;/h2&gt;&lt;p&gt;Bene, ora che avete visto come installare Nextcloud 20 su Ubuntu a questo punto avete Nextcloud funzionante e pronto. Non vi resta che utilizzarlo per caricare i vostri documenti.
Ricordate comunque di fare un backup, sopratutto del database e della cartella &lt;em&gt;nextcloud_data&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Come eliminare password e altro da un repo su Github</title><link>https://lazzarotto.dev/blog/come-eliminare-password-e-altro-da-un-repo-su-github/</link><pubDate>Sun, 01 Dec 2019 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/come-eliminare-password-e-altro-da-un-repo-su-github/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Come eliminare password e altro da un repo su Github" /&gt;&lt;p&gt;Oggi vi spiegherò come eliminare dati sensibili come password da un repository Github in modo veloce e facile.&lt;/p&gt;
&lt;p&gt;Potreste chiedermi:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Per quale motivo hai messo delle password in bella vista su Github?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Effettivamente è una bella domanda.&lt;/p&gt;
&lt;h2 id="il-problema"&gt;Il problema
&lt;/h2&gt;&lt;p&gt;In questi giorni sto sperimentando con qualche script in &lt;strong&gt;Python&lt;/strong&gt; e al momento sto lavorando su uno &lt;a class="link" href="https://github.com/mlazzarotto/amazon-price-scraper" target="_blank" rel="noopener"
&gt;script&lt;/a&gt; che controlla il prezzo su Amazon di un articolo e mi manda un&amp;rsquo;email se il prezzo scende sotto ad un certo costo.&lt;/p&gt;
&lt;p&gt;Per spedire le email sto usando &lt;strong&gt;Gmail&lt;/strong&gt; e come ben saprete, per usare il servizio di Google è necessario inserire username e password.&lt;/p&gt;
&lt;p&gt;Il repository che ho creato è &lt;strong&gt;privato&lt;/strong&gt;, quindi solo io posso accederci e vedere il codice, ma nell&amp;rsquo;ottica di renderlo &lt;strong&gt;pubblico&lt;/strong&gt; è sicuramente consigliabile rimuovere la password del mio account Gmail (nonostante abbia usato una &lt;a class="link" href="https://support.google.com/accounts/answer/185833?hl=it" target="_blank" rel="noopener"
&gt;password per le app&lt;/a&gt;, anche se ormai l&amp;rsquo;ho già distrutta).&lt;/p&gt;
&lt;h2 id="come-rimediare"&gt;Come rimediare
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create un file di testo, col nome che volete (esempio passwords.txt), con all&amp;rsquo;interno le parole chiavi da rimuovere.Importante! Le parole chiavi devono essere 1 per riga.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pas5word123
s3cr3t
c1scol1fe
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scaricate lo strumento &lt;a class="link" href="https://rtyley.github.io/bfg-repo-cleaner/#download" target="_blank" rel="noopener"
&gt;BFG Repo-Cleaner&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clonate il repo in una cartella (ad esempio &lt;code&gt;C:\TEMP\repo-da-pulire&lt;/code&gt;) con il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone --mirror https://github.com/mlazzarotto/amazon-price-scraper.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Ovviamente sostituendo l&amp;rsquo;url con quello del vostro repo.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aprite una finestra Prompt o PowerShell e date il seguente comando sostituendo ovviamente il nome del file con le password da rimuovere e la cartella dove avete clonato il repo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bat" data-lang="bat"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;java -jar d:\mlazz\Downloads\bfg-1.13.0.jar --replace-text passwords.txt my-repo.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Una volta eseguita l&amp;rsquo;operazione, per applicare le modifiche su Github date il comando seguente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; amazon-price-scraper.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git reflog expire --expire&lt;span class="o"&gt;=&lt;/span&gt;now --all &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git gc --prune&lt;span class="o"&gt;=&lt;/span&gt;now --aggressive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In questo modo avrete rimosso tutte le password scomode dal repository di Github e &lt;strong&gt;da tutti i commit precedenti&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Questo significa che se qualcuno dovesse andare a controllare la cronologia di tutti i commit precedenti che avete fatto, non troverà la password, ma la parola ***REMOVED***, come potete vedere nell&amp;rsquo;immagine qui sotto.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/password_rimosse_github.png"
loading="lazy"
alt="Data removed"
&gt;&lt;/p&gt;</description></item><item><title>Nextcloud Security Scan</title><link>https://lazzarotto.dev/blog/nextcloud-security-scan/</link><pubDate>Tue, 11 Apr 2017 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/nextcloud-security-scan/</guid><description>&lt;p&gt;Nextcloud ha rilasciato un utile strumento, la cui funzione è la scansione di un&amp;rsquo;installazione Nextcloud per trovare eventuali problemi di sicurezza.&lt;/p&gt;
&lt;p&gt;Lo strumento è disponibile a questo indirizzo: &lt;a class="link" href="https://scan.nextcloud.com" target="_blank" rel="noopener"
&gt;Nextcloud Security Scan&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Utilizzarlo è semplicissimo: basta inserire l&amp;rsquo;indirizzo pubblico della propria installazione e cliccare su &lt;strong&gt;Scan&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/nextcloud_security_scan_1.png"
loading="lazy"
alt="screen 1"
&gt;&lt;/p&gt;
&lt;p&gt;Una volta cliccato su &lt;strong&gt;Scan&lt;/strong&gt; dopo pochi secondi vedrete il risultato della scansione:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://lazzarotto.dev/blog/img/nextcloud_security_scan_2.png"
loading="lazy"
alt="screen 2"
&gt;&lt;/p&gt;
&lt;p&gt;Poco più sotto potrete vedere se e quali miglioramenti alla sicurezza sono necessari per avere un punteggio più alto:
&lt;img src="https://lazzarotto.dev/blog/img/nextcloud_security_scan_3.png"
loading="lazy"
alt="screen 3"
&gt;
&lt;img src="https://lazzarotto.dev/blog/img/nextcloud_security_scan_4.png"
loading="lazy"
alt="screen 4"
&gt;&lt;/p&gt;</description></item><item><title>Come installare Transmission su Ubuntu 16</title><link>https://lazzarotto.dev/blog/come-installare-transmission-su-ubuntu-16/</link><pubDate>Fri, 10 Mar 2017 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/come-installare-transmission-su-ubuntu-16/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Come installare Transmission su Ubuntu 16" /&gt;&lt;p&gt;In questa guida vi spiegherò come installare il demone (ovvero il server) di Transmission su Ubuntu 16.&lt;/p&gt;
&lt;p&gt;Tramite questo software sarete in grado di gestire i vostri torrent sia da interfaccia Web, che da Android, iOS, Linux, Windows e Mac.&lt;/p&gt;
&lt;p&gt;Questo può non sembrare molto utile ai più, ma è sicuramente utile se avete a casa un vecchio muletto su cui installare Transmission, o un server VPS in &lt;a class="link" href="https://contabo.com/?show=vps" target="_blank" rel="noopener"
&gt;hosting&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="installazione-pacchetti"&gt;Installazione pacchetti
&lt;/h2&gt;&lt;p&gt;Prima di tutto aggiungiamo il repository di Transmission con il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo add-apt-repository ppa:transmissionbt/ppa
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alla domanda successiva date INVIO.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; nel caso il comando sopra non venisse riconosciuto, installare il pacchetto &lt;em&gt;software-properties-common&lt;/em&gt; con il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quindi aggiorniamo la cache di apt e installiamo i pacchetti necessari:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install transmission-cli transmission-common transmission-daemon
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configurazione"&gt;Configurazione
&lt;/h2&gt;&lt;p&gt;Transmission è quasi pronto all&amp;rsquo;uso così com&amp;rsquo;è, ma per configurarlo al meglio basterà modificare il file &lt;em&gt;/var/lib/transmission-daemon/info/settings.json&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Ora vi spiegherò quali sono le voci più importanti.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nota bene&lt;/strong&gt;: prima di cominciare a modificare i file di configurazione è buona cosa fare una copia del file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp /var/lib/transmission-daemon/info/settings.json /var/lib/transmission-daemon/info/settings.json.ORIGINALE
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Prima di procedere assicuratevi che il servizio sia fermo in modo da evitare che il file di configurazione venga sovrascritto usando il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;service transmission-daemon stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cartella-di-destinazione-dei-downloads"&gt;Cartella di destinazione dei downloads
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;&amp;quot;download-dir&amp;quot;: &amp;quot;/var/lib/transmission-daemon/downloads&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Questa è la cartella dove finiranno i download completati. Se decidete di cambiarla, ricordati di assegnare come proprietario della nuova cartella l&amp;rsquo;utente debian-transmission e il gruppo omonimo.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;incomplete-dir&amp;quot;: &amp;quot;/var/lib/transmission-daemon/Downloads&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Questa cartella è dove finiranno i files non completi. L&amp;rsquo;unica differenza con l&amp;rsquo;opzione dei download completati è la &lt;strong&gt;D&lt;/strong&gt; maiuscola. Io non ho avuto modo di provarlo, ma vi consiglio di scrivere la &lt;strong&gt;d&lt;/strong&gt; minuscola per sicurezza.&lt;/p&gt;
&lt;h3 id="porta-in-uso"&gt;Porta in uso
&lt;/h3&gt;&lt;p&gt;&lt;code&gt; &amp;quot;peer-port&amp;quot;: 51413,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Questa è la porta da aprire sul firewall, oppure da fare il NAT.&lt;/p&gt;
&lt;h3 id="username-e-password"&gt;Username e password
&lt;/h3&gt;&lt;p&gt;Le credenziali di default sono &lt;em&gt;transmission&lt;/em&gt; come utente e &lt;em&gt;transmission&lt;/em&gt; come password.&lt;/p&gt;
&lt;p&gt;Per cambiare la password inserite una password a scelta al posto dei caratteri alfanumerici, inserendola all&amp;rsquo;interno dei doppi apici.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;rpc-password&amp;quot;: &amp;quot;{8a8ff244e16b626fbf4eeb02f51516b1a08dcc54oX2OV9Gb&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ad esempio&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;rpc-password&amp;quot;: &amp;quot;mia_password&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Stessa cosa per lo username&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &amp;quot;rpc-username&amp;quot;: &amp;quot;transmission&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="whitelist"&gt;Whitelist?
&lt;/h3&gt;&lt;p&gt;&lt;code&gt; &amp;quot;rpc-whitelist-enabled&amp;quot;: true,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Con la riga qui sopra è possibile definire se abilitare l&amp;rsquo;accesso a tutti i client o solo a quelli specificati nella riga qui sotto.&lt;/p&gt;
&lt;p&gt;Se volete permettere l&amp;rsquo;accesso a qualsiasi indirizzo ip, impostate il parametro su &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;rpc-whitelist&amp;quot;: &amp;quot;127.0.0.1&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Questa invece è la lista degli indirizzi ip abilitati. Funziona ovviamente solo se la whitelist è impostata su &lt;em&gt;true&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Alcuni esempi:&lt;br&gt;
&lt;code&gt;&amp;quot;rpc-whitelist&amp;quot;: &amp;quot;127.0.0.1,192.168.*.*&amp;quot;,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;&amp;quot;rpc-whitelist&amp;quot;: &amp;quot;127.0.0.1,192.168.1.*&amp;quot;,&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="limiti-di-velocità"&gt;Limiti di velocità
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;&amp;quot;speed-limit-down&amp;quot;: 100,&lt;/code&gt;
&lt;code&gt;&amp;quot;speed-limit-down-enabled&amp;quot;: false,&lt;/code&gt;
&lt;code&gt;&amp;quot;speed-limit-up&amp;quot;: 100,&lt;/code&gt;
&lt;code&gt;&amp;quot;speed-limit-up-enabled&amp;quot;: false,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Tramite le righe qui sopra è possibile abilitare e definire i limiti di velocità. È comunque possibili modificarli successivamente dal client o interfaccia web.&lt;/p&gt;
&lt;h3 id="umask"&gt;Umask
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;  &amp;quot;umask&amp;quot;: 2,&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Questa impostazione serve per definire i permessi sui file scaricati da Transmission.&lt;/p&gt;
&lt;p&gt;Impostiamola a &lt;em&gt;2&lt;/em&gt; per dare pieno accesso sui file al programma.
Per concludere la configurazione, diamo all&amp;rsquo;utente &lt;em&gt;debian-transmission&lt;/em&gt; il possesso della cartella &lt;em&gt;/var/lib/transmission-daemon&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo chown -R debian-transmission:debian-transmission /var/lib/transmission-daemon&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In questo modo direttamente dall&amp;rsquo;interfaccia web o dai vari clients sarà possibile modificare molte impostazioni, senza dover modificare a mano il file &lt;em&gt;settings.json&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Infine avviamo il servizio&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo service transmission-daemon start&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="accedere-allinterfaccia-web"&gt;Accedere all&amp;rsquo;interfaccia web
&lt;/h3&gt;&lt;p&gt;Per accedere all&amp;rsquo;interfaccia web basta aprire un browser e digitare &lt;em&gt;http://&amp;lt;indirizzo_del_computer&amp;gt;:9091&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Vi saranno quindi richieste le credenziali e verrete accolti da una schermata come questa:&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h3 id="alcuni-client-di-terze-parti"&gt;Alcuni client di terze parti
&lt;/h3&gt;&lt;p&gt;Elenco qui sotto alcuni client di terze parti per gestire i vostri torrent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://sourceforge.net/projects/transgui" target="_blank" rel="noopener"
&gt;Transmission Remote Gui&lt;/a&gt; (Windows, Mac e Linux)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://play.google.com/store/apps/details?id=net.yupol.transmissionremote.app" target="_blank" rel="noopener"
&gt;Transmission Remote&lt;/a&gt; (Android)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cambiare-tema-allinterfaccia-web"&gt;Cambiare tema all&amp;rsquo;interfaccia web
&lt;/h3&gt;&lt;p&gt;Per cambiare tema all&amp;rsquo;interfaccia web possiamo scaricare una skin gratuita da &lt;a class="link" href="https://github.com/ronggang/transmission-web-control" target="_blank" rel="noopener"
&gt;questo sito&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ecco i comandi da inserire:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/share/transmission
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mv web web_BAK
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; web
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo wget https://github.com/ronggang/transmission-web-control/blob/master/release/transmission-control-full.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tar xzvf transmission-control-full.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ecco fatto. Se il browser dovesse mostrarvi ancora la vecchia interfaccia, premete &lt;code&gt;CTRL + R&lt;/code&gt;.
&lt;img src="https://lazzarotto.dev/blog/img/interfaccia_web_transmission_nuova_ui.png"
loading="lazy"
alt="nuova interfaccia transmission"
&gt;&lt;/p&gt;
&lt;h3 id="in-conclusione"&gt;In conclusione
&lt;/h3&gt;&lt;p&gt;A questo punto se avete seguito i passaggi scritti qui sopra avrete un server con Transmission installato e configurato. Se volete altra documentazione potete dare uno sguardo alla documentazione di Ubuntu liberamente accessibile a questo indirizzo &lt;a class="link" href="https://help.ubuntu.com/community/TransmissionHowTo" target="_blank" rel="noopener"
&gt;TransmissionHowTo&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Contatti</title><link>https://lazzarotto.dev/blog/contatti/</link><pubDate>Tue, 28 Feb 2017 19:02:23 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/contatti/</guid><description>&lt;p&gt;Per contatti mi trovate su &lt;a class="link" href="https://www.linkedin.com/in/marco-lazzarotto-43b0707b/" target="_blank" rel="noopener"
&gt;LinkedIn&lt;/a&gt;,&lt;/p&gt;
&lt;p&gt;oppure al mio indirizzo email mlazzarotto91 at gmail.com.&lt;/p&gt;</description></item><item><title>Come installare LAMP su Ubuntu 16</title><link>https://lazzarotto.dev/blog/come-installare-lamp-su-ubuntu-16/</link><pubDate>Tue, 28 Feb 2017 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/come-installare-lamp-su-ubuntu-16/</guid><description>&lt;img src="https://lazzarotto.dev/blog/" alt="Featured image of post Come installare LAMP su Ubuntu 16" /&gt;&lt;p&gt;Questa vuole essere una semplice guida su come installare LAMP su un computer o macchina virtuale con Ubuntu Linux.&lt;/p&gt;
&lt;p&gt;La versione di Ubuntu che ho utilizzato per testare questa guida è la 16.04, ma è compatibile anche con le versioni precedenti di Ubuntu, a patto che tale versione sia ancora supportata (cioè che siano ancora disponibili i server da cui scaricare i pacchetti).&lt;/p&gt;
&lt;h2 id="cosè-lamp"&gt;Cos&amp;rsquo;è LAMP?
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://it.wikipedia.org/wiki/LAMP" target="_blank" rel="noopener"
&gt;Wikipedia&lt;/a&gt; utilizza la seguente definizione:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LAMP è un acronimo che indica una piattaforma software per lo sviluppo di applicazioni web che prende il nome dalle iniziali dei componenti software con cui è realizzata.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In parole povere, LAMP è un acronimo che indica una piattaforma di sviluppo utilizzata come base per moltissime applicazioni web.&lt;/p&gt;
&lt;p&gt;Può essere utile per installare complessi siti web (ad esempio WordPress, Joomla, Redmine, Drupal e molti altri) oppure per cominciare a creare il proprio sito da zero.&lt;/p&gt;
&lt;h2 id="composizione-di-lamp"&gt;Composizione di LAMP
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;installazione di LAMP prevede l&amp;rsquo;installazione di questi quattro programmi, a cui possono essere aggiunti molti altri a seconda della necessità del sito web che si desidera utilizzare.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;Apache&lt;/li&gt;
&lt;li&gt;MySQL o MariaDB&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pacchetti opzionali&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;phpMyAdmin&lt;/li&gt;
&lt;li&gt;Perl&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="le-varianti-più-comuni"&gt;Le varianti più comuni
&lt;/h2&gt;&lt;p&gt;Oltre a LAMP esistono alcune varianti. Di seguito ne elenco alcune:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XAMPP: è un pacchetto &amp;ldquo;portable&amp;rdquo; multipiattaforma. Non necessita di installazione, è piuttosto semplice da usare ma è consigliato solo per ambienti di test.&lt;/li&gt;
&lt;li&gt;WAMP: è simile a LAMP tranne per il fatto che è stato creato per  funzionare su sistemi Windows.&lt;/li&gt;
&lt;li&gt;MAMP: simile a WAMP ma su sistema operativo Mac OS.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mysql-o-mariadb"&gt;MySQL o MariaDB?
&lt;/h2&gt;&lt;p&gt;Questa è la domanda che alcuni di voi potrebbero farsi.
Entrambi sono dei &lt;a class="link" href="https://it.wikipedia.org/wiki/Relational_database_management_system" target="_blank" rel="noopener"
&gt;sistemi di gestione di database relazionali&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le principali motivazioni per scegliere MariaDB sono il numero maggiore di funzionalità, le migliori performance e la maggior scelta di motori.&lt;/p&gt;
&lt;p&gt;Io personalmente da qualche tempo scelgo MariaDB per i motivi che ho scritto qui sopra, oltre al fatto che nelle varie community e forum viene preferito a MySQL.&lt;/p&gt;
&lt;p&gt;In questa guida sarà utilizzato MariaDB, ma l&amp;rsquo;installazione di MySQL è molto simile: basterà sostituire &lt;em&gt;mysql&lt;/em&gt; a &lt;em&gt;mariadb&lt;/em&gt; durante l&amp;rsquo;installazione dei pacchetti.&lt;/p&gt;
&lt;h2 id="installazione"&gt;Installazione
&lt;/h2&gt;&lt;p&gt;Aprite da Ubuntu una shell e digitate la seguente riga per installare Apache, MariaDB e PHP 7.0.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install apache2 php7.0 mariadb-server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In alternativa è possibile installare i suddetti pacchetti da &lt;strong&gt;Ubuntu Software Center&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ecco fatto. Ora vediamo come gli strumenti disponibili per amministrare MariaDB (o MySQL).&lt;/p&gt;
&lt;h2 id="come-amministrare-mariadb"&gt;Come amministrare MariaDB
&lt;/h2&gt;&lt;p&gt;Per amministrare MariaDB esistono diversi strumenti, tutti molto validi, la cui differenza sta nella semplicità d&amp;rsquo;uso e nelle funzionalità. Alcuni di questi strumenti sono: il client di MariaDB, phpMyAdmin e MySQL Workbench.&lt;/p&gt;
&lt;p&gt;Per ognuno di essi scriverò una breve descrizione.&lt;/p&gt;
&lt;h4 id="il-client-a-riga-di-comando"&gt;Il client a riga di comando
&lt;/h4&gt;&lt;p&gt;Come si può intuire è un client che si utilizza dalla &lt;em&gt;shell&lt;/em&gt; o riga di comando. A mio parere il più potente dei tre ma anche il meno &lt;em&gt;user-friendly&lt;/em&gt;. È adatto a utenti che conoscono bene MariaDB e il linguaggio SQL oppure per chi vuole imparare.&lt;/p&gt;
&lt;p&gt;Il client viene installato con il pacchetto &lt;em&gt;mariadb-server&lt;/em&gt;.&lt;/p&gt;
&lt;h4 id="phpmyadmin"&gt;&lt;a class="link" href="https://it.wikipedia.org/wiki/PhpMyAdmin" target="_blank" rel="noopener"
&gt;phpMyAdmin&lt;/a&gt;
&lt;/h4&gt;&lt;p&gt;È un&amp;rsquo;applicazione web scritta in PHP. È la più semplice da usare delle tre opzioni in quanto non è necessario conoscere la sintassi di SQL perché tutto (o quasi) il database è gestibile tramite l&amp;rsquo;interfaccia web, oltre a questo è possibile visualizzare alcuni grafici e diverse statistiche del database.&lt;/p&gt;
&lt;p&gt;Si installa con il seguente comando:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get install phpmyadmin&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Una volta installato (richiede Apache o lighthttpd come web server) è possibile accedere tramite &lt;em&gt;http://&amp;lt;indirizzo_ip_del_server&amp;gt;/phpmyadmin&lt;/em&gt;.&lt;/p&gt;
&lt;h4 id="mysql-workbench"&gt;&lt;a class="link" href="https://it.wikipedia.org/wiki/MySQL_Workbench" target="_blank" rel="noopener"
&gt;MySQL Workbench&lt;/a&gt;
&lt;/h4&gt;&lt;p&gt;È un software disponibile per Windows, Linux e Mac OS.&lt;/p&gt;
&lt;p&gt;Come livello di semplicità d&amp;rsquo;uso si posizione a metà strada tra phpMyAdmin e il client a riga di comando.&lt;/p&gt;
&lt;p&gt;Similmente a phpMyAdmin è possibile avere alcune informazioni sullo stato del database e grafici, anche dell&amp;rsquo;utilizzo delle risorse del sistema.&lt;/p&gt;
&lt;p&gt;A differenza di quanto si può pensare, è possibile utilizzarlo anche con MariaDB, ma con alcune limitazioni.&lt;/p&gt;
&lt;h2 id="come-mettere-in-sicurezza-mariadb"&gt;Come mettere in sicurezza MariaDB
&lt;/h2&gt;&lt;p&gt;Durante l&amp;rsquo;installazione di MariaDB non viene richiesta una password per l&amp;rsquo;utente root, che è vuota. Per impostarla e modificare altre impostazioni per mettere in sicurezza MariaDB, diamo il comando&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mysql_secure_installation&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Dopo aver dato INVIO ci saranno poste alcune domande.&lt;/p&gt;
&lt;p&gt;Alla prima domanda ci sarà chiesta la password attuale dell&amp;rsquo;utente &lt;em&gt;root&lt;/em&gt;. Diamo INVIO per inserire la password attuale che è vuota.&lt;/p&gt;
&lt;p&gt;Alla seconda domanda rispondiamo &lt;code&gt;Y&lt;/code&gt; per impostare la password dell&amp;rsquo;utente &lt;em&gt;root&lt;/em&gt;. Inseriamo quindi 2 volte la nuova password dando INVIO per confermare.&lt;/p&gt;
&lt;p&gt;Successivamente rispondiamo ancora &lt;code&gt;Y&lt;/code&gt; per rimuovere l&amp;rsquo;utente anonimo.&lt;/p&gt;
&lt;p&gt;Alla prossima domanda rispondiamo &lt;code&gt;N&lt;/code&gt; se vogliamo usare strumenti quali MySQL Workbench dal un computer remoto, altrimenti rispondiamo &lt;code&gt;Y&lt;/code&gt; se usiamo il client a riga di comando o phpMyAdmin.&lt;/p&gt;
&lt;p&gt;Infine rispondiamo 2 volte &lt;code&gt;Y&lt;/code&gt; per rimuovere il database di test e per ricaricare la tabella dei privilegi.&lt;/p&gt;
&lt;h2 id="apache"&gt;Apache
&lt;/h2&gt;&lt;p&gt;Di default, dopo l&amp;rsquo;installazione di Apache è possibile collegarsi a &lt;em&gt;http://&amp;lt;indirizzo_ip_del_server&amp;gt;&lt;/em&gt; per vedere una pagina di esempio.&lt;/p&gt;
&lt;p&gt;Apache lavora con i &amp;ldquo;Virtual Hosts&amp;rdquo;, ovvero dei file che specificano cosa far vedere in base a cosa si digita nella barra degli indirizzi.&lt;/p&gt;
&lt;p&gt;Il file di configurazione che regola cosa Apache &amp;ldquo;mostra&amp;rdquo; si trova in &lt;em&gt;/etc/apache2/sites-enabled&lt;/em&gt; con il nome &lt;em&gt;000-default.conf&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Quel file è un collegamento del file originale in &lt;em&gt;/etc/apache2/sites-available&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Se decidete di modificarlo, vi consiglio di fare una copia dell&amp;rsquo;originale nel caso qualcosa andasse storto.&lt;/p&gt;
&lt;p&gt;Per applicare le modifiche effettuate digitate il seguente comando:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;service apache2 reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Archivio</title><link>https://lazzarotto.dev/blog/archivio/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>postmaster@mlazzarotto.it (Marco Lazzarotto)</author><guid>https://lazzarotto.dev/blog/archivio/</guid><description/></item></channel></rss>