<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>wireguard &amp;mdash; Cyberdyne Systems</title>
    <link>https://noblogo.org/aytin/tag:wireguard</link>
    <description>&#34;Fare o non fare. Non c&#39;è provare!&#34;</description>
    <pubDate>Thu, 30 Apr 2026 09:57:17 +0000</pubDate>
    <item>
      <title>Installazione di Cloudflare WARP su OSMC</title>
      <link>https://noblogo.org/aytin/installazione-di-cloudflare-warp-su-osmc</link>
      <description>&lt;![CDATA[cloudflare-warp&#xA;È noto come l&#39;uso dei resolver Cloudflare sia uno dei modi per anonimizzare il proprio IP all&#39;ISP.&#xA;&#xA;Cloudflare offre anche altre modalità di risoluzione ancora più efficaci:&#xA;&#xA;DNS over HTTPS (DoH)&#xA;DNS over TCP (DoT)&#xA;DNS over WARP (DoW)&#xA;&#xA;!--more--&#xA;I primi due sono relativi a richieste dns crittografate e incapsulate, in una richiesta https (porta 443) la prima, e in una connessione TLS (porta 853) la seconda.&#xA;&#xA;La terza modalità è una richiesta dns in chiaro ma all&#39;interno di un tunnel Wireguard o MASQUE (QUIC + HTTP/3 - rif. https://datatracker.ietf.org/meeting/interim-2021-masque-03/materials/slides-interim-2021-masque-03-sessa-masque-interim-2021-04-h3-dgram-00). Molto interessante ed è quella che approfondirò in seguito.&#xA;&#xA;Senza entrare nel merito, tutte le soluzioni anonimizzano le query dns. L&#39;ultima, quella che mi ha stutzzicato, è in realtà un tunnel vpn che crittografa TUTTO il traffico, non solo le richieste DNS.&#xA;&#xA;DoT è una cifratura TLS che lascia intatto il pacchetto UDP iniziale, è quindi più efficiente di DoH che converte una richieste DNS in una HTTP cifrata dal layer TLS.&#xA;&#xA;DoT di solito viene fatta a livello di dispositivo, DoH per singole applicazioni.&#xA;&#xA;DoT, basandosi su una porta specifica, 853, è facilmente identificabile (e bloccabile) come traffico DNS (benché cifrato), DoH è una richiesta HTTPS e si mescola col traffico che viaggia sulla porta 443 (difficilmente si invaliderà tutto quel tipo di traffico).&#xA;&#xA;DoT, DoH, DoW, mitigano notevolmente il cache poisoning dei resolver perché rendono quasi impossibilie per un attaccante alterare una richiesta che viene protetta per l&#39;intero percorso. Va detto che la soluzione ideale in questo contesto è la combinazione con DNSSEC, che fornisce autenticità e integrità alla riservatezza fornita da DoH/DoT.&#xA;&#xA;Anche se l&#39;obiettivo rimane l&#39;approfondimento di CLoudflare WARP, vale la pena di spendere due parole anche sulle altre modalità di risoluzione, DoT/DoH&#xA;Configurare risoluzioni DNS DoH&#xA;Configurare DoH è molto semplice perché è qualcosa legato all&#39;applicazione, il browser tipicamente. Se l&#39;applicazione lo supporta, di solito è poco di più di un flag da abilitare.&#xA;&#xA;Ad es. Firefox o Chrome permettono di attivare una sorte di &#34;protezione avanzata del DNS&#34; indicando semplicemente un resolver che la supporti (es. Cloudflare, NextDNS o Quad9).&#xA;Configurare risoluzioni DNS DoT&#xA;DoT, come detto, è una configurazione che avviene a livello di dispositivo, l&#39;anonimizzazione delle query DNS si ottiene quindi per ogni applicazione. Sul come farlo, dipende dal dispositivo.&#xA;&#xA;Ad es. su una linux box basta aggiungere due righe su systemd-resolved e riavviare il relativo servizio.&#xA;sudo vi /etc/systemd/resolved.conf&#xA;...&#xA;DNS=1.1.1.1&#xA;DNSOverTLS=yes&#xA;&#xA;dopo aver salvato il file&#xA;systemctl restart systemd-resolved&#xA;Un veloce test su https://1.1.1.1/help  (da qualunque browser) ci mostrerà qualcosa del tipo:&#xA;Connected to 1.1.1.1        Yes&#xA;Using DNS over HTTPS (DoH)  No&#xA;Using DNS over TLS (DoT)    Yes&#xA;Using DNS over WARP         No&#xA;AS Name                     Cloudflare, Inc.&#xA;AS Number                   13335&#xA;Cloudflare Data Center      MXP&#xA;indice che DoT è attivo e funzionante. Lo stesso test poteva essere fatto anche per DoH.&#xA;Cloudflare WARP&#xA;E poi c&#39;è DoW, che è qualcosa di ancora più estremo perché, all&#39;occorrenza, anonimizza non solo le richieste DNS ma tutto il nostro traffico (e infatti diversi servizi di streaming non lo consentono).&#xA;&#xA;Cloudflare Warp attiva diverse modalità di risoluzione dns fra cui DoH e DoT.&#xA;&#xA;Dal momento che Cloudflare Warp agisce su tutta la connessione, è il modo più semplice per avere risoluzione dns di tipo DoH o DoT, su qualunque dispositivo su cui è presente Cloudflare Warp senza gli sbattimenti di systemd o altro.&#xA;&#xA;Cloudflare Warp in modalità tunnel è un client che instaura un collegamento cifrato punto-punto (un tunnel) fra il nostro host e un endpoint Cloudflare. In questo modo ogni bit che esce dal nostro dispositivo viene cifrato prima della comunicazione, che diventa così totalmente schermata.&#xA;&#xA;La vpn di Coudflare si basa su wireguard o su MASQUE. Nel primo caso è una normale vpn con un setup roadwarrior, il secondo caso offre in più la possibilità di associare al tunnel anche le modalità DoH/DoT per le richieste dns.&#xA;Anonimato sì/no?&#xA;Cloudflare WARP è uno strumento incentrato sulla sicurezza, progettato per crittografare il traffico internet e proteggere la privacy dagli ISP, piuttosto che per garantire l&#39;anonimato completo o nascondere la posizione dell&#39;utente.&#xA;&#xA;Sostituisce l&#39;IP dell&#39;utente con un IP di Cloudflare che generalmente corrisponde alla sua reale area geografica, rendendolo inadatto a eludere le restrizioni basate sulla posizione.&#xA;&#xA;Non è una VPN tradizionale. WARP non maschera la nostra posizione ai siti web, che spesso possono visualizzare la tua posizione approssimativa.&#xA;&#xA;Per migliorare la privacy, si dovrebbe utilizzare il protocollo MASQUE, che offre anche una maggiore efficienza.&#xA;&#xA;In sintesi, WARP fornisce un &#34;tunnel sicuro&#34; per proteggere la privacy dei dati da amministratori di rete indiscreti, protegge il traffico perché eccelle nella crittografia del traffico su reti non sicure (ad esempio, Wi-Fi pubbliche), ma non offre le funzionalità di anonimato dei tradizionali servizi VPN incentrati sulla privacy.&#xA;&#xA;Fatta questa doverosa premessa, vediamo come può essere usato.&#xA;Configurare Cloudflare WARP&#xA;L&#39;installazione del client è molto semplice. Per Gnu/Linux c&#39;è la versione cli, per android un app, per altri sistemi, Win /MacOS, un installer.&#xA;La parte applicativa prima di tutto registra il dispositivo sulla rete Cloudflare generando degli ID e una chiave di licenza. In un secondo momento si generano le chiavi di cifratura.&#xA;&#xA;Per fissare le idee, una volta fatte le operazioni di inizializzazione, sulla linux box per tunnellizzare ogni nostra comunicazione con una risoluzione DoT, basta:&#xA;facoltativo&#xA;warp-cli mode warp+dot&#xA;&#xA;connessione&#xA;warp-cli connect&#xA;Per terminare:&#xA;warp-cli disconnect&#xA;Questo approccio torna molto comodo quando per es. vogliamo usare wifi pubbliche, in città o in aeroporto. A meno di non avere un&#39;installazione personale di una nostra vpn, questa è una soluzione immediata. Certo, bisogna fidarsi di Cloudflare ma è certamente meglio che fidarsi delle wifi free.&#xA;&#xA;E arriviamo al caso d&#39;uso che volevo approfondire riguardante l&#39;&#34;anonimizzazione&#34; di un mediacenter casalingo per il quale non vogliamo rendere noto il suo utilizzo.&#xA;&#xA;L&#39;esperienza che ho avuto al proposito è stata interessante, visto che uso da anni OSMC su una RasbPi 3 e ho deciso di metterla dietro Cloudflare.&#xA;&#xA;OSMC insieme a LibreELEC sono ottime soluzioni di mediacenter per SBC. La prima più &#34;general&#34;, essendo una debian customizzata per ospitare un mediacenter, la seconda invece meno elastica ma più essenziale ed efficiente.&#xA;&#xA;Nonostante la Raspberry Pi 3 sia dotata di un processore ARM64, la versione di OSMC che ho installato a suo tempo è a 32 bit e per quella non c&#39;è disponibilità per il client cloudflare (solo ARM64).&#xA;&#xA;Ho dovuto ricorrere ad un client &#34;unofficial&#34;, wgcf, che permette di registrare il dispositivo e di generare le chiavi ma solo per la modalità Wireguard, non MASQUE, quindi niente Warp+DoT/DoH (per inciso, wgcf rappresenta un&#39;ottima alternativa anche per chi non vuole usare il client Cloudflare su Gnu/Linux).&#xA;&#xA;A questo aggiungo che, sebbebe OSMC sia una Debian su cui posso installare e configurare tanta roba, l&#39;installazione di Wireguard, e penso di qualunque cosa che vada a toccare lo stack di rete, diventa qualcosa di estremamente complicato da fare, dal momento che OSMC si rifiuta categoricamente di eseguire operazione che metterebbero a rischio il suo essere un mediacenter, fondamentalmente.&#xA;&#xA;Tradotto in soldoni, il client wireguard si installa, sale su correttamente ma non c&#39;è verso di far funzionare la risoluzione. L&#39;unica via d&#39;usicta è stata configurare Wireguard attraverso il gestore di rete di OSMC che è connman.&#xA;&#xA;Una volta fatto questo, sono stati necessari solo un paio di piccoli accorgimenti per far si che, in seguito all&#39;avvio del mediacenter, la configurazione vpn venisse caricata automaticamente da connman, contestualmente alla connessione vpn.&#xA;Configurazione wgcf&#xA;Account cloudflare&#xA;curl -L https://github.com/ViRb3/wgcf/releases/latest/download/wgcf2.2.30linuxarmv7 -o /usr/local/bin/wgcf&#xA;chmod u+x /usr/local/bin/wgcf&#xA;wgcf register&#xA;wgcf generate&#xA;&#xA;status &amp; trace&#xA;wgcf status&#xA;curl https://www.cloudflare.com/cdn-cgi/trace&#xA;Configurazione connman&#xA;Su OSMC connman ha i suoi file di configurazione in /var/lib/connman e /var/lib/connman-vpn&#xA;&#xA;Nel file di configurazione, l&#39;host va indicato con l&#39;ip non con l&#39;fqdn (engage.cloudflareclients.com)&#xA;Configurazione wireguard cloudflare&#xA;La configurazione della vpn deve essere un file .config sotto /var/lib/connman-vpn&#xA;&#xA;vi /var/lib/connman-vpn/cloudflarewarp.config&#xA;[provider*]&#xA;Type = WireGuard&#xA;Name = CloudflareWARP&#xA;Host = 162.159.192.1&#xA;AutoConnect = true&#xA;WireGuard.Address = 172.16.0.2/24&#xA;WireGuard.ListenPort = 51280&#xA;WireGuard.PrivateKey = myprivatekey&#xA;WireGuard.PublicKey = cloudlarewgpublickey&#xA;WireGuard.DNS = 1.1.1.1, 1.0.0.1&#xA;WireGuard.AllowedIPs = 0.0.0.0/0&#xA;WireGuard.EndpointPort = 2408&#xA;WireGuard.PersistentKeepalive = 25&#xA;Dopo aver creato il file di configurazione, possiamo vedere il nuovo servizio pronto per essere richiamato da comman-vpnd&#xA;elenco servizi attivi&#xA;connmanctl services&#xA;AO SSID           wifiidmanagedpsk&#xA;R CloudflareWARP      vpn1621591921&#xA;Affinché la connessione alla vpn parta all&#39;avvio di OSMC, è necessario disporre di un servizio che:&#xA;&#xA;esegua common-vpnd per caricare il file di configurazione&#xA;effettui la connessione vpn&#xA;&#xA;Creazione nuovo servizio in /lib/systemd/system/connman-vpn.service&#xA;[Unit]&#xA;Description=ConnMan VPN service&#xA;After=network-online.target&#xA;Wants=network-online.target&#xA;&#xA;[Service]&#xA;Type=dbus&#xA;BusName=net.connman.vpn&#xA;ExecStart=/usr/sbin/connman-vpnd -n&#xA;ExecStop=/usr/local/bin/vpn-autoconnect.sh&#xA;StandardOutput=null&#xA;Restart=on-failure&#xA;&#xA;[Install]&#xA;WantedBy=multi-user.target&#xA;Script richiamato dal servizio per la connessione alla vpn:&#xA;connessione vpn&#xA;vi /usr/local/bin/vpn-autoconnect.sh&#xA;!/bin/bash&#xA;Attende che il demone VPN sia pronto&#xA;sleep 5&#xA;Tenta la connessione (usa il nome esatto che vedi in connmanctl services)&#xA;connmanctl connect vpn1621591921&#xA;Inifine si rende il file eseguibile e si avvia il servizio&#xA;chmod +x /usr/local/bin/vpn-autoconnect.sh&#xA;&#xA;avvio servizio&#xA;systemctl daemon-reload&#xA;systemctl enable connman-vpn.service&#xA;systemctl start connman-vpn.service&#xA;E il gioco è fatto.&#xA;&#xA;Da questo momento in poi, OSMC tunnellizza tutto il suo traffico verso Cloudflare.&#xA;&#xA;Come detto, in questo modo ho &#34;solo&#34; la configurazione di un tunnel wireguard verso l&#39;endpoint Cloudflare, non dispongo delle altre funzionalità che warp-cli offre.&#xA;&#xA;Tuttavia è un procedimento abbastanza trasparente che non prevede la convivenza con ulteriori servizi come nel caso di warp-cli e che può essere un&#39;alternativa anonimizzante valida anche su una linux box normale.&#xA;&#xA;#dns #doh #dot #warp #vpn #tunnel #cloudflare #wireguard #masque #osmc]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/31410d826-759a86/nDDNn0ObGm8H/bTjZEfazDrIzF1UqmzhRRGXWvH807nU98C2cdm16.jpg" alt="cloudflare-warp">
È noto come l&#39;uso dei resolver Cloudflare sia uno dei modi per anonimizzare il proprio IP all&#39;ISP.</p>

<p>Cloudflare offre anche altre modalità di risoluzione ancora più efficaci:</p>
<ol><li>DNS over HTTPS (<strong>DoH</strong>)</li>
<li>DNS over TCP (<strong>DoT</strong>)</li>
<li>DNS over WARP (<strong>DoW</strong>)</li></ol>



<p>I primi due sono relativi a richieste dns crittografate e incapsulate, in una richiesta https (porta 443) la prima, e in una connessione TLS (porta 853) la seconda.</p>

<p>La terza modalità è una richiesta dns <strong>in chiaro</strong> ma all&#39;interno di un tunnel <strong>Wireguard</strong> o <strong>MASQUE</strong> (<strong>QUIC</strong> + <strong>HTTP/3</strong> – rif. <a href="https://datatracker.ietf.org/meeting/interim-2021-masque-03/materials/slides-interim-2021-masque-03-sessa-masque-interim-2021-04-h3-dgram-00" rel="nofollow">https://datatracker.ietf.org/meeting/interim-2021-masque-03/materials/slides-interim-2021-masque-03-sessa-masque-interim-2021-04-h3-dgram-00</a>). Molto interessante ed è quella che approfondirò in seguito.</p>

<p>Senza entrare nel merito, tutte le soluzioni anonimizzano le query dns. L&#39;ultima, quella che mi ha stutzzicato, è in realtà un tunnel vpn che crittografa <strong>TUTTO</strong> il traffico, non solo le richieste DNS.</p>

<p><strong>DoT</strong> è una cifratura TLS che lascia intatto il pacchetto UDP iniziale, è quindi più efficiente di <strong>DoH</strong> che converte una richieste DNS in una HTTP cifrata dal layer TLS.</p>

<p><strong>DoT</strong> di solito viene fatta a livello di dispositivo, <strong>DoH</strong> per singole applicazioni.</p>

<p><strong>DoT</strong>, basandosi su una porta specifica, 853, è facilmente identificabile (e bloccabile) come traffico DNS (benché cifrato), <strong>DoH</strong> è una richiesta HTTPS e si mescola col traffico che viaggia sulla porta 443 (difficilmente si invaliderà tutto quel tipo di traffico).</p>

<p><strong>DoT</strong>, <strong>DoH</strong>, <strong>DoW</strong>, mitigano notevolmente il <strong>cache poisoning</strong> dei resolver perché rendono quasi impossibilie per un attaccante alterare una richiesta che viene protetta per l&#39;intero percorso. Va detto che la soluzione ideale in questo contesto è la combinazione con <strong>DNSSEC</strong>, che fornisce autenticità e integrità alla riservatezza fornita da DoH/DoT.</p>

<p>Anche se l&#39;obiettivo rimane l&#39;approfondimento di CLoudflare WARP, vale la pena di spendere due parole anche sulle altre modalità di risoluzione, DoT/DoH</p>

<h2 id="configurare-risoluzioni-dns-doh">Configurare risoluzioni DNS DoH</h2>

<p>Configurare <strong>DoH</strong> è molto semplice perché è qualcosa legato all&#39;applicazione, il browser tipicamente. Se l&#39;applicazione lo supporta, di solito è poco di più di un flag da abilitare.</p>

<p>Ad es. Firefox o Chrome permettono di attivare una sorte di “protezione avanzata del DNS” indicando semplicemente un resolver che la supporti (es. Cloudflare, NextDNS o Quad9).</p>

<h2 id="configurare-risoluzioni-dns-dot">Configurare risoluzioni DNS DoT</h2>

<p>DoT, come detto, è una configurazione che avviene a livello di dispositivo, l&#39;anonimizzazione delle query DNS si ottiene quindi per <strong>ogni</strong> applicazione. Sul come farlo, dipende dal dispositivo.</p>

<p>Ad es. su una linux box basta aggiungere due righe su <code>systemd-resolved</code> e riavviare il relativo servizio.</p>

<pre><code class="language-bash">sudo vi /etc/systemd/resolved.conf
...
DNS=1.1.1.1
DNSOverTLS=yes

# dopo aver salvato il file
systemctl restart systemd-resolved
</code></pre>

<p>Un veloce test su <a href="https://1.1.1.1/help" rel="nofollow">https://1.1.1.1/help</a>  (da qualunque browser) ci mostrerà qualcosa del tipo:</p>

<pre><code>Connected to 1.1.1.1        Yes
Using DNS over HTTPS (DoH)  No
Using DNS over TLS (DoT)    Yes
Using DNS over WARP         No
AS Name                     Cloudflare, Inc.
AS Number                   13335
Cloudflare Data Center      MXP
</code></pre>

<p>indice che DoT è attivo e funzionante. Lo stesso test poteva essere fatto anche per DoH.</p>

<h2 id="cloudflare-warp">Cloudflare WARP</h2>

<p>E poi c&#39;è <strong>DoW</strong>, che è qualcosa di ancora più estremo perché, all&#39;occorrenza, anonimizza non solo le richieste DNS ma tutto il <strong>nostro</strong> traffico (e infatti diversi servizi di streaming non lo consentono).</p>

<p><strong>Cloudflare Warp</strong> attiva diverse modalità di risoluzione dns fra cui DoH e DoT.</p>

<p>Dal momento che Cloudflare Warp agisce su tutta la connessione, è il modo più semplice per avere risoluzione dns di tipo DoH o DoT, su qualunque dispositivo su cui è presente Cloudflare Warp senza gli sbattimenti di systemd o altro.</p>

<p><strong>Cloudflare Warp</strong> in modalità tunnel è un client che instaura un collegamento cifrato punto-punto (un tunnel) fra il nostro host e un endpoint Cloudflare. In questo modo ogni bit che esce dal nostro dispositivo viene cifrato prima della comunicazione, che diventa così totalmente schermata.</p>

<p>La vpn di Coudflare si basa su wireguard o su MASQUE. Nel primo caso è una normale vpn con un setup roadwarrior, il secondo caso offre in più la possibilità di associare al tunnel anche le modalità DoH/DoT per le richieste dns.</p>

<h3 id="anonimato-sì-no">Anonimato sì/no?</h3>

<p>Cloudflare WARP è uno strumento incentrato sulla sicurezza, progettato per crittografare il traffico internet e proteggere la privacy dagli ISP, piuttosto che per garantire l&#39;anonimato completo o nascondere la posizione dell&#39;utente.</p>

<p>Sostituisce l&#39;IP dell&#39;utente con un IP di Cloudflare che generalmente corrisponde alla sua reale area geografica, rendendolo inadatto a eludere le restrizioni basate sulla posizione.</p>

<p>Non è una VPN tradizionale. WARP non maschera la nostra posizione ai siti web, che spesso possono visualizzare la tua posizione approssimativa.</p>

<p>Per migliorare la privacy, si dovrebbe utilizzare il protocollo MASQUE, che offre anche una maggiore efficienza.</p>

<p>In sintesi, WARP fornisce un “tunnel sicuro” per proteggere la privacy dei dati da amministratori di rete indiscreti, protegge il traffico perché eccelle nella crittografia del traffico su reti non sicure (ad esempio, Wi-Fi pubbliche), ma non offre le funzionalità di anonimato dei tradizionali servizi VPN incentrati sulla privacy.</p>

<p>Fatta questa doverosa premessa, vediamo come può essere usato.</p>

<h3 id="configurare-cloudflare-warp">Configurare Cloudflare WARP</h3>

<p>L&#39;installazione del client è molto semplice. Per Gnu/Linux c&#39;è la versione cli, per android un app, per altri sistemi, Win /MacOS, un installer.
La parte applicativa prima di tutto registra il dispositivo sulla rete Cloudflare generando degli ID e una chiave di licenza. In un secondo momento si generano le chiavi di cifratura.</p>

<p>Per fissare le idee, una volta fatte le operazioni di inizializzazione, sulla linux box per tunnellizzare ogni nostra comunicazione con una risoluzione DoT, basta:</p>

<pre><code class="language-bash"># facoltativo
warp-cli mode warp+dot

#connessione
warp-cli connect
</code></pre>

<p>Per terminare:</p>

<pre><code class="language-bash">warp-cli disconnect
</code></pre>

<p>Questo approccio torna molto comodo quando per es. vogliamo usare wifi pubbliche, in città o in aeroporto. A meno di non avere un&#39;installazione personale di una nostra vpn, questa è una soluzione immediata. Certo, bisogna fidarsi di Cloudflare ma è certamente meglio che fidarsi delle wifi free.</p>

<p>E arriviamo al caso d&#39;uso che volevo approfondire riguardante l&#39;“anonimizzazione” di un mediacenter casalingo per il quale non vogliamo rendere noto il suo utilizzo.</p>

<p>L&#39;esperienza che ho avuto al proposito è stata interessante, visto che uso da anni OSMC su una RasbPi 3 e ho deciso di metterla dietro Cloudflare.</p>

<p><strong>OSMC</strong> insieme a <strong>LibreELEC</strong> sono ottime soluzioni di mediacenter per SBC. La prima più “general”, essendo una debian customizzata per ospitare un mediacenter, la seconda invece meno elastica ma più essenziale ed efficiente.</p>

<p>Nonostante la Raspberry Pi 3 sia dotata di un processore ARM64, la versione di OSMC che ho installato a suo tempo è a 32 bit e per quella non c&#39;è disponibilità per il client cloudflare (solo ARM64).</p>

<p>Ho dovuto ricorrere ad un client “unofficial”, <strong>wgcf</strong>, che permette di registrare il dispositivo e di generare le chiavi ma solo per la modalità Wireguard, non MASQUE, quindi niente Warp+DoT/DoH (per inciso, wgcf rappresenta un&#39;ottima alternativa anche per chi non vuole usare il client Cloudflare su Gnu/Linux).</p>

<p>A questo aggiungo che, sebbebe OSMC sia una Debian su cui posso installare e configurare tanta roba, l&#39;installazione di Wireguard, e penso di qualunque cosa che vada a toccare lo stack di rete, diventa qualcosa di estremamente complicato da fare, dal momento che OSMC si rifiuta categoricamente di eseguire operazione che metterebbero a rischio il suo essere un mediacenter, fondamentalmente.</p>

<p>Tradotto in soldoni, il client wireguard si installa, sale su correttamente ma non c&#39;è verso di far funzionare la risoluzione. L&#39;unica via d&#39;usicta è stata configurare Wireguard attraverso il gestore di rete di OSMC che è <strong>connman</strong>.</p>

<p>Una volta fatto questo, sono stati necessari solo un paio di piccoli accorgimenti per far si che, in seguito all&#39;avvio del mediacenter, la configurazione vpn venisse caricata automaticamente da connman, contestualmente alla connessione vpn.</p>

<h3 id="configurazione-wgcf">Configurazione wgcf</h3>

<pre><code class="language-bash"># Account cloudflare
curl -L https://github.com/ViRb3/wgcf/releases/latest/download/wgcf_2.2.30_linux_armv7 -o /usr/local/bin/wgcf
chmod u+x /usr/local/bin/wgcf
wgcf register
wgcf generate

# status &amp; trace
wgcf status
curl https://www.cloudflare.com/cdn-cgi/trace
</code></pre>

<h3 id="configurazione-connman">Configurazione connman</h3>

<p>Su OSMC connman ha i suoi file di configurazione in <code>/var/lib/connman</code> e <code>/var/lib/connman-vpn</code></p>

<p>Nel file di configurazione, l&#39;host va indicato con l&#39;ip non con l&#39;fqdn (engage.cloudflareclients.com)</p>

<pre><code class="language-bash"># Configurazione wireguard cloudflare
# La configurazione della vpn deve essere un file .config sotto /var/lib/connman-vpn

vi /var/lib/connman-vpn/cloudflare_warp.config
[provider_*]
Type = WireGuard
Name = Cloudflare_WARP
Host = 162.159.192.1
AutoConnect = true
WireGuard.Address = 172.16.0.2/24
WireGuard.ListenPort = 51280
WireGuard.PrivateKey = &lt;my_private_key&gt;
WireGuard.PublicKey = &lt;cloudlare_wg_public_key&gt;
WireGuard.DNS = 1.1.1.1, 1.0.0.1
WireGuard.AllowedIPs = 0.0.0.0/0
WireGuard.EndpointPort = 2408
WireGuard.PersistentKeepalive = 25
</code></pre>

<p>Dopo aver creato il file di configurazione, possiamo vedere il nuovo servizio pronto per essere richiamato da <code>comman-vpnd</code></p>

<pre><code class="language-bash"># elenco servizi attivi
connmanctl services
* AO &lt;SSID&gt;           wifi_&lt;id&gt;_managed_psk
* R Cloudflare_WARP      vpn_162_159_192_1
</code></pre>

<p>Affinché la connessione alla vpn parta all&#39;avvio di OSMC, è necessario disporre di un servizio che:</p>
<ol><li>esegua <code>common-vpnd</code> per caricare il file di configurazione</li>
<li>effettui la connessione vpn</li></ol>

<pre><code class="language-bash"># Creazione nuovo servizio in /lib/systemd/system/connman-vpn.service
[Unit]
Description=ConnMan VPN service
After=network-online.target
Wants=network-online.target

[Service]
Type=dbus
BusName=net.connman.vpn
ExecStart=/usr/sbin/connman-vpnd -n
ExecStop=/usr/local/bin/vpn-autoconnect.sh
StandardOutput=null
Restart=on-failure

[Install]
WantedBy=multi-user.target
</code></pre>

<p>Script richiamato dal servizio per la connessione alla vpn:</p>

<pre><code class="language-bash"># connessione vpn
vi /usr/local/bin/vpn-autoconnect.sh
#!/bin/bash
# Attende che il demone VPN sia pronto
sleep 5
# Tenta la connessione (usa il nome esatto che vedi in connmanctl services)
connmanctl connect vpn_162_159_192_1
</code></pre>

<p>Inifine si rende il file eseguibile e si avvia il servizio</p>

<pre><code class="language-bash">chmod +x /usr/local/bin/vpn-autoconnect.sh

# avvio servizio
systemctl daemon-reload
systemctl enable connman-vpn.service
systemctl start connman-vpn.service
</code></pre>

<p>E il gioco è fatto.</p>

<p>Da questo momento in poi, OSMC tunnellizza tutto il suo traffico verso Cloudflare.</p>

<p>Come detto, in questo modo ho “solo” la configurazione di un tunnel wireguard verso l&#39;endpoint Cloudflare, non dispongo delle altre funzionalità che <code>warp-cli</code> offre.</p>

<p>Tuttavia è un procedimento abbastanza trasparente che non prevede la convivenza con ulteriori servizi come nel caso di <code>warp-cli</code> e che può essere un&#39;alternativa anonimizzante valida anche su una linux box normale.</p>

<p><a href="/aytin/tag:dns" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dns</span></a> <a href="/aytin/tag:doh" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">doh</span></a> <a href="/aytin/tag:dot" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dot</span></a> <a href="/aytin/tag:warp" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">warp</span></a> <a href="/aytin/tag:vpn" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">vpn</span></a> <a href="/aytin/tag:tunnel" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">tunnel</span></a> <a href="/aytin/tag:cloudflare" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cloudflare</span></a> <a href="/aytin/tag:wireguard" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">wireguard</span></a> <a href="/aytin/tag:masque" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">masque</span></a> <a href="/aytin/tag:osmc" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">osmc</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/installazione-di-cloudflare-warp-su-osmc</guid>
      <pubDate>Fri, 03 Apr 2026 22:33:32 +0000</pubDate>
    </item>
    <item>
      <title>Script per la gestione della configurazione di una vpn wireguard</title>
      <link>https://noblogo.org/aytin/script-per-la-gestione-della-configurazione-di-una-vpn-wireguard</link>
      <description>&lt;![CDATA[vpn&#xA;&#xA;Cos&#39;è wireguard e come si configura, lo sappiamo ma mi serviva qualcosa che mi permettesse di fare provisioning e deprovisioning dei certificati in maniera più semplice di quanto già si faccia con i tool disponibili nella userland, wg e wg-quick.&#xA;&#xA;E questo è il motivo principale per cui è nato questo script.&#xA;!--more--&#xA;Prende come riferimento una configurazione road warrior, il primo scenario di una topologia point-to-site, quella più comune.&#xA;&#xA;Alcune considerazioni&#xA;Lo script definisce una workdir dove deposita tutte le configurazioni e i certificati.&#xA;Le precondizioni sono legate alla presenza dei tool userland wg-tools (ovviamente) e di ufw. Vengono comunque verificate nello script.&#xA;&#xA;Altra semplificazione è data dal fatto di allocare una /24 come rete wireguard. 254 host per una rete domestica sono più che sufficienti.&#xA;&#xA;L&#39;allocazione degli ip viene fatta con un progressivo memorizzato nel file &#39;ip\renew&#39;. Gli ip dei certificati revocati vengono mantenuti in un file, &#39;ip\release&#39;.&#xA;Quando si crea un nuovo certificato, si controlla prima che ci sia un ip da recuperare in ip\release. Se la lista è vuota si ricorre al progressivo.&#xA;&#xA;La creazione della configurazione lato server passa da due file di configurazione: una configurazione globale ottenuta tracciando l&#39;evoluzione iniziale in termini di aggiunta o rimozione dei client peer e destinata al rilascio in esecuzione. L&#39;altra contenente la sola configurazione del server e usata unicamente per la rigenerazione della configurazione globale a partire dai peer esistenti.&#xA;&#xA;L&#39;operazione di init è propedeutica per addclient, removeclient, rebuild, deploy, share.&#xA;&#xA;Le operazioni a disposizione sono:&#xA;&#xA;init: inizializza la configurazione di un server wireguard&#xA;addclient: crea il certificato lato client e aggiunge il relativo peer sulla configurazione del server&#xA;removeclient: cancella il certificato lato client e rimuove il relativo peer sulla configurazione del server&#xA;rebuild: rigenera la configurazione del server usando i certificati client esistenti&#xA;deploy: finalizza la configurazione riavviando il servizio con le nuove impostazioni&#xA;share: crea i qr-code per i certificati client da utilizzare nelle configurazioni&#xA;&#xA;Per tutto il resto, i commenti nel codice sono abbastanza esplicativi.&#xA;Lo script&#xA;!/bin/bash&#xA;&#xA;Questo è il file di configurazione globale, i dati sono fittizi.&#xA;Può essere mantenuto nello script o nella home dell&#39;utente &#xA;(es. $HOME/.config/wgman.conf) e importato &#xA;con &#39;source&#39; all&#39;inizio.&#xA;WGINTERFACE=wg0&#xA;PHYSICALINTERFACE=eth0&#xA;NETWORK=&#34;192.168.15.0&#34;&#xA;SUBNETMASK=&#34;24&#34;&#xA;SERVERIPADDRESS=&#34;192.168.15.1&#34;&#xA;DNS=&#34;1.1.1.1&#34;&#xA;LISTENPORT=&#34;51820&#34;&#xA;ENDPOINT=wireguard.nodns.net:51820&#34;&#xA;WORKDIR=&#34;$HOME/wireguard&#34;&#xA;&#xA;checkdependency() {&#xA;    if test -e /usr/sbin/ufw; then&#xA;        if test -e /usr/bin/wg; then&#xA;            return 0&#xA;        else&#xA;            return 2&#xA;        fi&#xA;    else&#xA;        return 1&#xA;    fi&#xA;}&#xA;&#xA;isinit() {&#xA;    test -e ${WORKDIR}/conf.d/serverwg.conf &amp;&amp; return 0 || return 1&#xA;}&#xA;&#xA;Genera la chiave privata&#xA;genprivkey() {&#xA;    wg genkey | tee ${WORKDIR}/keys/$1privkey&#xA;}&#xA;&#xA;Genera la pre-shared key&#xA;genclientpsk() {&#xA;    # Evita il warning sui permessi del file che devono essere 600&#xA;    umask 077&#xA;    wg genpsk | tee ${WORKDIR}/psk/$1psk&#xA;}&#xA;&#xA;Rilascio di un nuovo indirizzo ip. Questa funziona viene invocata da&#xA;addclient().&#xA;&#xA;I primi 3 ottetti li ottengo dalla variabile globale NETWORK.&#xA;L&#39;ultimo ottetto, relativo all&#39;host, lo ricavo dalla lista degli ip&#xA;riutilizzabili (&#34;iprelease&#34;).&#xA;&#xA;Se non è vuota, prelevo il primo e lo rimuovo dalla lista. Se è vuota,&#xA;prelevo l&#39;ultimo ottetto da &#34;iprenew&#34; e lo incremento per il successivo&#xA;assegnamento.&#xA;iprenew() {&#xA;    # Selezioni i primi 3 ottetti del network&#xA;    SUBIP=$(echo ${NETWORK}|awk -F &#34;.&#34; &#39;{print $1&#34;.&#34;$2&#34;.&#34;$3}&#39;)&#xA;&#xA;    if [[ ! -e ${WORKDIR}/conf.d/iprelease || ! -s ${WORKDIR}/conf.d/iprelease ]]; then&#xA;        # Genero il nuovo ip (Incremento di 1 l&#39;ultimo ottetto)&#xA;        IP=$(cat ${WORKDIR}/conf.d/iprenew)&#xA;        echo $((++IP))   ${WORKDIR}/conf.d/iprenew&#xA;&#xA;        # Restituisco i 3 ottetti + il quarto&#xA;        #echo -n ${SUBIP};cat ${WORKDIR}/conf.d/iprenew&#xA;    else&#xA;        IP=$(head -n 1 ${WORKDIR}/conf.d/iprelease)&#xA;        sed -i &#34;1d&#34; ${WORKDIR}/conf.d/iprelease&#xA;    fi&#xA;    echo -n ${SUBIP}&#34;.&#34;${IP}&#xA;}&#xA;&#xA;Riallocazione di un indirizzo ip. Questa funzione viene invocata da&#xA;removeclient().&#xA;Aggiungo l&#39;ultimo ottetto alla lista degli ip riallocabili.&#xA;@par 1: ultimo ottetto.&#xA;iprelease() {&#xA;    echo $1|cut -d&#34;.&#34; -f 4     ${WORKDIR}/conf.d/iprelease&#xA;}&#xA;&#xA;Aggiunge il nuovo peer al file di configurazione del server&#xA;@par 1: CLIENTPUBLICKEY&#xA;@par 2: CLIENTPSK&#xA;@par 3: CLIENTIPADDRESS&#xA;@par 4: CLIENTNAME&#xA;addpeertoserver() {&#xA;    cat     ${WORKDIR}/conf.d/serverwg.conf &lt;&lt; EOF&#xA;$4&#xA;[Peer]&#xA;PublicKey = $1&#xA;PresharedKey = $2&#xA;AllowedIPs = $3/32&#xA;PersistentKeepalive = 25&#xA;&#xA;EOF&#xA;}&#xA;&#xA;Inizializza la configurazione del server wireguard.&#xA;&#xA;Questa operazione può essere fatta una sola volta a meno che non si&#xA;cancelli tutta la workdir.&#xA;&#xA;Verranno creati due file  di configurazione: serverwg.conf e &#xA;serverwgraw.conf&#xA;&#xA;Il primo conterrà la configurazione completa del server e dei peer,&#xA;verrà aggiornato ad ogni modifica dei client (aggiunta o rimozione) e&#xA;verrà usato per il deploy della configurazione.&#xA;&#xA;Il secondo conterrà la configurazione del solo server e verrà usato&#xA;solo per rigenerare il primo file di configurazione.&#xA;init() {&#xA;    # Controllo che wireguard sia almeno abilitato&#xA;    echo -n &#34;Inserire la password di Amministratore: &#34;; read -s PASSWORD&#xA;    sudo -k&#xA;    if echo $PASSWORD|sudo -S echo &#34;got a root&#34;   /dev/null; then&#xA;        if ! sudo systemctl is-enabled --quiet wg-quick@${WGINTERFACE}; then&#xA;            echo -en &#34;\nAttivazione servizio wireguard... &#34;&#xA;            #sudo systemctl enable --quiet wg-quick@${WGINTERFACE}&#xA;            echo &#34;fatto.&#34;&#xA;        fi&#xA;        sudo -k &#xA;        &#xA;        #Verifico che queste cartelle esistano. Se lo sono, non faccio nulla, se no le creo.&#xA;        echo -n &#34;Creazione workdir... &#34;&#xA;        [[ ! -e ${WORKDIR}/conf.d || ! -e ${WORKDIR}/psk  || ! -e ${WORKDIR}/keys ]] \&#xA;            &amp;&amp; { mkdir -p ${WORKDIR}/{conf.d,keys,psk}; } \&#xA;            || { echo &#34;inizializzazione già effettuata.&#34;; exit; }&#xA;        echo &#34;fatto.&#34;&#xA;        &#xA;        # Genero la chiave privata per il server&#xA;        echo -n &#34;Creazione chiave private del server...&#34;&#xA;        SERVERPRIVKEY=$(genprivkey &#34;serverwg&#34;)&#xA;        echo &#34;fatto.&#34;&#xA;&#xA;        # Genero il file di configurazione&#xA;        echo -n &#34;Inizializzazione del server... &#34;&#xA;        cat   ${WORKDIR}/conf.d/serverwg.conf &lt;&lt; EOF&#xA;[Interface]&#xA;Address = ${SERVERIPADDRESS}/${SUBNETMASK}&#xA;SaveConfig = true&#xA;&#xA;PreUp = ufw route allow in on ${WGINTERFACE} out on ${PHYSICALINTERFACE} log from ${NETWORK}/${SUBNETMASK} to 0.0.0.0/0&#xA;PostDown = ufw route delete allow in on ${WGINTERFACE} out on ${PHYSICALINTERFACE} log from ${NETWORK}/${SUBNETMASK} to 0.0.0.0/0&#xA;&#xA;IP masquerading&#xA;PreUp = iptables -t nat -A POSTROUTING -o ${PHYSICALINTERFACE} -s ${NETWORK}/${SUBNETMASK} -j MASQUERADE&#xA;PostDown = iptables -t nat -D POSTROUTING -o ${PHYSICALINTERFACE} -s ${NETWORK}/${SUBNETMASK} -j MASQUERADE&#xA;&#xA;IP filtering&#xA;PreUp = ufw allow in on ${PHYSICALINTERFACE} log to 0.0.0.0/0 app Wireguard&#xA;PostDown = ufw delete allow in on ${PHYSICALINTERFACE} log to 0.0.0.0/0 app Wireguard&#xA;&#xA;ListenPort = ${LISTENPORT}&#xA;PrivateKey = ${SERVERPRIVKEY}&#xA;&#xA;EOF&#xA;        echo &#34;fatto.&#34;&#xA;        cp ${WORKDIR}/conf.d/serverwg.conf ${WORKDIR}/conf.d/serverwgraw.conf&#xA;        # Inizializza l&#39;erogatore di ip&#xA;        echo 1   ${WORKDIR}/conf.d/iprenew&#xA;    else&#xA;        echo &#34;Sono necessarie le credenziali di amministrazione per eseguire questo comando.&#34;&#xA;        exit 1&#xA;    fi&#xA;}&#xA;&#xA;Genera un certificato per il client composto da:&#xA;chiave privata del client&#xA;chiave pre-condivisa&#xA;client ip&#xA;chiave pubblica del server&#xA;nome simbolico del client&#xA;&#xA;Dopo la creazione e il salvataggio in WORKDIR/conf.d, verrà aggiunto&#xA;il relativo peer nella configurazione del server (serverwg.conf).&#xA;@par1 @par2 @par3...: lista di nomi relativi ai certificati da creare.&#xA;addclient() {&#xA;    if isinit; then&#xA;        # Se non c&#39;è alcun input, esco.&#xA;        if [[ $# -lt 1 ]]; then&#xA;            echo -e &#34;Devi inserire almeno un nome.&#34;&#xA;            exit 1&#xA;        else&#xA;            # Per ogni nome presente in input, creo una configurazione &#xA;            # client e l&#39;aggiungo alla configurazione del server.&#xA;            for CLIENTNAME in &#34;$@&#34;; do&#xA;                echo -n &#34;Creazione certificato per il client \&#34;${CLIENTNAME}\&#34;... &#34;&#xA;                &#xA;                # Controllo se la configurazione esista già discriminando&#xA;                # in base al nome del file.&#xA;                if [[ -e ${WORKDIR}/conf.d/client${CLIENTNAME}.conf ]]; then&#xA;                    echo &#34;già esistente.&#34;&#xA;                else&#xA;                    # Creo la configurazione del client&#xA;                    CLIENTPRIVKEY=$(genprivkey ${CLIENTNAME})&#xA;                    CLIENTPUBLICKEY=$(echo ${CLIENTPRIVKEY} | wg pubkey)&#xA;                    CLIENTPSK=$(genclientpsk ${CLIENTNAME})&#xA;                    CLIENTIPADDRESS=$(iprenew)&#xA;                    SERVERPUBLICKEY=$(grep PrivateKey ${WORKDIR}/conf.d/serverwg.conf | cut -d &#34; &#34; -f 3 | tr -d &#34; &#34; | wg pubkey)&#xA;                    CLIENTNAMEUPPER=$(echo ${CLIENTNAME} | tr &#39;[:lower:]&#39; &#39;[:upper:]&#39;)&#xA;                    cat   ${WORKDIR}/conf.d/client${CLIENTNAME}.conf &lt;&lt; EOF&#xA;    # ${CLIENTNAMEUPPER}&#xA;    [Interface]&#xA;    Address = ${CLIENTIPADDRESS}/${SUBNETMASK}&#xA;    DNS = ${DNS}&#xA;    PrivateKey = ${CLIENTPRIVKEY}&#xA;&#xA;    [Peer]&#xA;    PublicKey = ${SERVERPUBLICKEY}&#xA;    PresharedKey = ${CLIENTPSK}&#xA;    AllowedIPs = 0.0.0.0/0&#xA;    Endpoint = ${ENDPOINT}&#xA;    PersistentKeepalive = 25&#xA;EOF&#xA;                    echo &#34;fatto.&#34;&#xA;                    echo -n &#34;Aggiunta peer \&#34;${CLIENTNAME}\&#34; al file di configurazione del server... &#34;&#xA;                    &#xA;                    # Aggiungo il peer alla configurazione del server.&#xA;                    addpeertoserver ${CLIENTPUBLICKEY} ${CLIENTPSK} ${CLIENTIPADDRESS} ${CLIENTNAMEUPPER}&#xA;                    echo -e &#34;fatto.\n&#34;                &#xA;                fi&#xA;            done&#xA;        fi&#xA;    else&#xA;        echo &#34;È necessario inizializzare il server con &#39;wginit.sh init&#39;.&#34;&#xA;        echo &#34;L&#39;operazione richiesta non sarà completata&#34;&#xA;    fi&#xA;}&#xA;&#xA;Rimuove file di configurazioni, chiavi e pre-shared key realtive a file&#xA;dati in input.&#xA;Rimuove inoltre il peer dal file di configurazione serverwg.conf.&#xA;@par1 @par2 @par3...: lista di nomi relativi ai certificati da rimuovere.&#xA;removeclient() {&#xA;    if isinit; then&#xA;        if [[ $# -lt 1 ]]; then&#xA;            echo -e &#34;Devi inserire almeno un nome.&#34;&#xA;            exit 1&#xA;        else&#xA;            for CLIENTNAME in &#34;$@&#34;; do&#xA;                echo -n &#34;Rimozione client \&#34;${CLIENTNAME}\&#34;... &#34;&#xA;                if [[ ! -e ${WORKDIR}/conf.d/client${CLIENTNAME}.conf ]]; then&#xA;                    echo &#34;non esistente.&#34;&#xA;                else&#xA;                    # Estraggo l&#39;ultimo ottetto dell&#39;ip del client.&#xA;                    IP=$(grep &#34;Address&#34; ${WORKDIR}/conf.d/client${CLIENTNAME}.conf|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;|cut -d &#34;/&#34; -f 1)&#xA;                    &#xA;                    # Lo inserisco nella lista degli ip riallocabili.&#xA;                    iprelease ${IP}&#xA;                    &#xA;                    # Cancello file di configurazione, chiave e psk del client.&#xA;                    rm ${WORKDIR}/conf.d/client${CLIENTNAME}.conf ${WORKDIR}/keys/${CLIENTNAME}privkey ${WORKDIR}/psk/${CLIENTNAME}psk&#xA;                    echo &#34;terminata con successo.&#34;&#xA;                    echo -n &#34;Rimozione peer \&#34;${CLIENTNAME}\&#34; dal file di configurazione del server... &#34;&#xA;                    &#xA;                    # Rimuovo il peer dalla configurazione del server.&#xA;                    CLIENTNAMEUPPER=$(echo ${CLIENTNAME} | tr &#39;[:lower:]&#39; &#39;[:upper:]&#39;)&#xA;                    sed -i &#34;/# ${CLIENTNAMEUPPER}/,+6d&#34; ${WORKDIR}/conf.d/serverwg.conf&#xA;                    echo -e &#34;terminata con successo.\n&#34;   &#xA;                fi&#xA;            done&#xA;        fi&#xA;    else&#xA;        echo &#34;È necessario inizializzare il server con &#39;wginit.sh init&#39;.&#34;&#xA;        echo &#34;L&#39;operazione richiesta non sarà completata&#34;&#xA;    fi&#xA;}&#xA;&#xA;rebuild() {&#xA;    if isinit; then&#xA;        # Rigenero il file di configurazione del server da serverwgraw.conf.&#xA;        echo -n &#34;Ripristino del file di configurazione del server... &#34;&#xA;        cat ${WORKDIR}/conf.d/serverwgraw.conf   ${WORKDIR}/conf.d/serverwg.conf&#xA;        echo &#34;fatto.&#34;&#xA;        &#xA;        # Per ogni file di configurazione client, aggiungo il relativo peer&#xA;        # nel file di configurazione serverwg.conf.&#xA;        for FILECONF in ${WORKDIR}/conf.d/client.conf; do&#xA;            CLIENTPUBLICKEY=$(grep &#34;PrivateKey&#34; ${FILECONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34; | wg pubkey)&#xA;            CLIENTPSK=$(grep &#34;PresharedKey&#34; ${FILECONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;)&#xA;            CLIENTIPADDRESS=$(grep &#34;Address&#34; ${FILECONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;|cut -d &#34;/&#34; -f 1)&#xA;            CLIENTNAMEUPPER=$(grep &#34;#&#34; ${FILECONF} | cut -d &#34; &#34; -f 2)&#xA;            echo -n &#34;Aggiunta peer \&#34;$(echo ${CLIENTNAMEUPPER} | tr &#39;[:upper:]&#39; &#39;[:lower:]&#39;)\&#34;... &#34;&#xA;            addpeertoserver ${CLIENTPUBLICKEY} ${CLIENTPSK} ${CLIENTIPADDRESS} ${CLIENTNAMEUPPER}&#xA;            echo -e &#34;fatto.&#34;&#xA;        done&#xA;    else&#xA;        echo &#34;È necessario inizializzare il server con &#39;wginit.sh init&#39;.&#34;&#xA;        echo &#34;L&#39;operazione richiesta non sarà completata&#34;&#xA;    fi&#xA;}&#xA;&#xA;Avvia il server wireguard con la nuova configurazione&#xA;deploy() {&#xA;    if isinit; then&#xA;        echo -n &#34;Inserire la password di Amministratore: &#34;; read -s PASSWORD&#xA;        sudo -k&#xA;        if echo $PASSWORD|sudo -S echo &#34;got a root&#34;   /dev/null; then&#xA;   &#xA;            # Stoppo il servizio wireguard&#xA;            echo -ne &#34;\nStop wireguard... &#34;&#xA;            sudo systemctl stop wg-quick@${WGINTERFACE}&#xA;            echo &#34;fatto.&#34;&#xA;            &#xA;            # Aggiorno la configurazione&#xA;            echo -n &#34;Copia della nuova configurazione... &#34;&#xA;            sudo cp ${WORKDIR}/conf.d/serverwg.conf /etc/wireguard/${WGINTERFACE}&#xA;            echo &#34;fatto.&#34;&#xA;            &#xA;            # Riavvio il servizio wireguard&#xA;            echo -n &#34;Riavvio wireguard... &#34;&#xA;            sudo systemctl start wg-quick@${WGINTERFACE}&#xA;            echo &#34;fatto.&#34;&#xA;            &#xA;            # Revoco i privilegi di amministrazione&#xA;            sudo -k&#xA;        else&#xA;            echo &#34;Sono necessarie le credenziali di amministrazione per eseguire questo comando.&#34;&#xA;            exit 1&#xA;        fi&#xA;    else&#xA;        echo &#34;È necessario inizializzare il server con &#39;wginit.sh init&#39;.&#34;&#xA;        echo &#34;L&#39;operazione richiesta non sarà completata&#34;&#xA;    fi&#xA;}&#xA;&#xA;Crea il qr-code della configurazione del client nella cartella corrente.&#xA;share() {&#xA;    if isinit; then&#xA;        if [[ $# -lt 1 ]]; then&#xA;            echo -e &#34;Devi inserire almeno un nome.&#34;&#xA;            exit 1&#xA;        else&#xA;            for CLIENTNAME in &#34;$@&#34;; do&#xA;                echo -n &#34;Creazione qr-code per il client \&#34;${CLIENTNAME}\&#34;... &#34;&#xA;                qrencode -r ${WORKDIR}/conf.d/client${CLIENTNAME}.conf -o qrcodeclient${CLIENTNAME}.jpg&#xA;                echo &#34;fatto.&#34;&#xA;            done&#xA;        fi&#xA;    else&#xA;        echo &#34;È necessario inizializzare il server con &#39;wginit.sh init&#39;.&#34;&#xA;        echo &#34;L&#39;operazione richiesta non sarà completata&#34;&#xA;    fi&#xA;}&#xA;&#xA;help() {&#xA;&#xA;[[ $1 != &#34;&#34; &amp;&amp; $1 != &#34;help&#34; ]] &amp;&amp; echo -e &#34;Comando inesistente.&#34;&#xA;&#xA;    cat&lt;&lt;EOF&#xA;Usa come: ./wgman.sh [command] ARG&#xA;dove:&#xA;    [command]&#xA;        init                     : Inizializza la configurazione del server.&#xA;        addclient lista nomi   : Aggiunge i client indicati in lista nomi.&#xA;        removeclient lista nomi: Rimuove i client indicati in lista nomi.&#xA;        rebuild                  : Ricostruisce il file di configurazione&#xA;                                   del server partendo dalle configurazioni&#xA;                                   di tutti i client registrati.&#xA;        deploy                   : Riavvia il server wireguard con l&#39;ultima&#xA;                                   configurazione disponibile.&#xA;        share lista nomi       : Genera i qr-code relativi ai client indicati in lista nomi.&#xA;        help                     : Stampa questa pagina di help.&#xA;&#xA;ESEMPI:&#xA;    INiZIALIZZA IL SERVER WIREGUARD&#xA;    wgman.sh init&#xA;&#xA;    AGGIUNGE I CLIENT &#39;macbookpro&#39;, &#39;mobile&#39;&#xA;    wgman.sh addclient macbookpro mobile&#xA;&#xA;    RIMUOVE I CLIENT &#39;iphoneluca&#39;, &#39;workstation&#39;&#xA;    wgman.sh removeclient iphoneluca workstation&#xA;&#xA;    RICOSTRUISCE LA CONFIGURAZIONE DEL SERVER WIREGUARD&#xA;    wgman.sh rebuild&#xA;    &#xA;    ATTIVA LA NUOVA CONFIGURAZIONE&#xA;    wgman.sh deploy&#xA;&#xA;    GENERA I QRCODE PER &#39;pcufficio&#39;, &#39;laptop&#39;&#xA;    wgman.sh share pcufficio laptop&#xA;EOF&#xA;}&#xA;&#xA;main() {&#xA;    case $1 in&#xA;        init         ) init ;;&#xA;        addclient    ) shift; addclient &#34;$@&#34; ;;&#xA;        removeclient ) shift; removeclient &#34;$@&#34; ;;&#xA;        rebuild      ) rebuild ;;&#xA;        deploy       ) deploy ;;&#xA;        share        ) shift; share &#34;$@&#34; ;;&#xA;        ) help ;;&#xA;    esac&#xA;}&#xA;&#xA;check_dependency&#xA;case $? in&#xA;    &#34;0&#34; ) main $* ;;&#xA;    &#34;1&#34; ) echo -e &#34;UFW non presente. Installare UFW.&#34;; exit 1 ;;&#xA;    &#34;2&#34; ) echo -e &#34;wireguard-tools non presenti. È necessario installarli.&#34;; exit 1 ;;&#xA;esac&#xA;&#xA;#bash #wireguard #psk #chiavi #certificati #crittografia&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/586f75268-5004eb/XBn3L6jB84Ka/b6zYDZWzIcLbax1taLgBnIQu8hoy7ZeZVlXBkGf0.png" alt="vpn"></p>

<p><a href="https://noblogo.org/aytin/vpn-con-wireguard-semplice-e-veloce" rel="nofollow">Cos&#39;è wireguard e come si configura</a>, lo sappiamo ma mi serviva qualcosa che mi permettesse di fare provisioning e deprovisioning dei certificati in maniera più semplice di quanto già si faccia con i tool disponibili nella userland, wg e wg-quick.</p>

<p>E questo è il motivo principale per cui è nato questo script.

Prende come riferimento una configurazione road warrior, <a href="https://noblogo.org/aytin/vpn-con-wireguard-semplice-e-veloce#primo-scenario" rel="nofollow">il primo scenario di una topologia point-to-site</a>, quella più comune.</p>

<h2 id="alcune-considerazioni">Alcune considerazioni</h2>
<ol><li><p>Lo script definisce una workdir dove deposita tutte le configurazioni e i certificati.
Le precondizioni sono legate alla presenza dei tool userland <strong>wg-tools</strong> (ovviamente) e di <strong>ufw</strong>. Vengono comunque verificate nello script.</p></li>

<li><p>Altra semplificazione è data dal fatto di allocare una /24 come rete wireguard. 254 host per una rete domestica sono più che sufficienti.</p></li>

<li><p>L&#39;allocazione degli ip viene fatta con un progressivo memorizzato nel file &#39;ip_renew&#39;. Gli ip dei certificati revocati vengono mantenuti in un file, &#39;ip_release&#39;.
Quando si crea un nuovo certificato, si controlla prima che ci sia un ip da recuperare in ip_release. Se la lista è vuota si ricorre al progressivo.</p></li>

<li><p>La creazione della configurazione lato server passa da due file di configurazione: una configurazione <strong>globale</strong> ottenuta tracciando l&#39;evoluzione iniziale in termini di aggiunta o rimozione dei client peer e destinata al rilascio in esecuzione. L&#39;altra contenente <strong>la sola configurazione del server</strong> e usata unicamente per la rigenerazione della configurazione globale a partire dai peer esistenti.</p></li>

<li><p>L&#39;operazione di <strong>init</strong> è propedeutica per <strong>addclient</strong>, <strong>removeclient</strong>, <strong>rebuild</strong>, <strong>deploy</strong>, <strong>share</strong>.</p></li></ol>

<p>Le operazioni a disposizione sono:</p>
<ul><li><strong>init:</strong> inizializza la configurazione di un server wireguard</li>
<li><strong>addclient:</strong> crea il certificato lato client e aggiunge il relativo peer sulla configurazione del server</li>
<li><strong>removeclient:</strong> cancella il certificato lato client e rimuove il relativo peer sulla configurazione del server</li>
<li><strong>rebuild:</strong> rigenera la configurazione del server usando i certificati client esistenti</li>
<li><strong>deploy:</strong> finalizza la configurazione riavviando il servizio con le nuove impostazioni</li>
<li><strong>share:</strong> crea i qr-code per i certificati client da utilizzare nelle configurazioni</li></ul>

<p>Per tutto il resto, i commenti nel codice sono abbastanza esplicativi.</p>

<h2 id="lo-script">Lo script</h2>

<pre><code class="language-bash">#!/bin/bash

# Questo è il file di configurazione globale, i dati sono fittizi.
# Può essere mantenuto nello script o nella home dell&#39;utente 
# (es. $HOME/.config/wg_man.conf) e importato 
# con &#39;source&#39; all&#39;inizio.
WG_INTERFACE=wg0
PHYSICAL_INTERFACE=eth0
NETWORK=&#34;192.168.15.0&#34;
SUBNET_MASK=&#34;24&#34;
SERVER_IP_ADDRESS=&#34;192.168.15.1&#34;
DNS=&#34;1.1.1.1&#34;
LISTEN_PORT=&#34;51820&#34;
ENDPOINT=wireguard.nodns.net:51820&#34;
WORKDIR=&#34;$HOME/wireguard&#34;



check_dependency() {
    if test -e /usr/sbin/ufw; then
        if test -e /usr/bin/wg; then
            return 0
        else
            return 2
        fi
    else
        return 1
    fi
}



is_init() {
    test -e ${WORKDIR}/conf.d/server_wg.conf &amp;&amp; return 0 || return 1
}



# Genera la chiave privata
gen_priv_key() {
    wg genkey | tee ${WORKDIR}/keys/$1_privkey
}



# Genera la pre-shared key
gen_client_psk() {
    # Evita il warning sui permessi del file che devono essere 600
    umask 077
    wg genpsk | tee ${WORKDIR}/psk/$1_psk
}



# Rilascio di un nuovo indirizzo ip. Questa funziona viene invocata da
# addclient().
#
# I primi 3 ottetti li ottengo dalla variabile globale NETWORK.
# L&#39;ultimo ottetto, relativo all&#39;host, lo ricavo dalla lista degli ip
# riutilizzabili (&#34;ip_release&#34;).
#
# Se non è vuota, prelevo il primo e lo rimuovo dalla lista. Se è vuota,
# prelevo l&#39;ultimo ottetto da &#34;ip_renew&#34; e lo incremento per il successivo
# assegnamento.
ip_renew() {
    # Selezioni i primi 3 ottetti del network
    SUB_IP=$(echo ${NETWORK}|awk -F &#34;.&#34; &#39;{print $1&#34;.&#34;$2&#34;.&#34;$3}&#39;)

    if [[ ! -e ${WORKDIR}/conf.d/ip_release || ! -s ${WORKDIR}/conf.d/ip_release ]]; then
        # Genero il nuovo ip (Incremento di 1 l&#39;ultimo ottetto)
        IP=$(cat ${WORKDIR}/conf.d/ip_renew)
        echo $((++IP)) &gt; ${WORKDIR}/conf.d/ip_renew

        # Restituisco i 3 ottetti + il quarto
        #echo -n ${SUB_IP};cat ${WORKDIR}/conf.d/ip_renew
    else
        IP=$(head -n 1 ${WORKDIR}/conf.d/ip_release)
        sed -i &#34;1d&#34; ${WORKDIR}/conf.d/ip_release
    fi
    echo -n ${SUB_IP}&#34;.&#34;${IP}
}



# Riallocazione di un indirizzo ip. Questa funzione viene invocata da
# removeclient().
# Aggiungo l&#39;ultimo ottetto alla lista degli ip riallocabili.
# @par 1: ultimo ottetto.
ip_release() {
    echo $1|cut -d&#34;.&#34; -f 4 &gt;&gt; ${WORKDIR}/conf.d/ip_release
}



# Aggiunge il nuovo peer al file di configurazione del server
# @par 1: CLIENT_PUBLIC_KEY
# @par 2: CLIENT_PSK
# @par 3: CLIENT_IP_ADDRESS
# @par 4: CLIENT_NAME
add_peer_to_server() {
    cat &gt;&gt; ${WORKDIR}/conf.d/server_wg.conf &lt;&lt; EOF
# $4
[Peer]
PublicKey = $1
PresharedKey = $2
AllowedIPs = $3/32
PersistentKeepalive = 25

EOF
}



# Inizializza la configurazione del server wireguard.
#
# Questa operazione può essere fatta una sola volta a meno che non si
# cancelli tutta la workdir.
#
# Verranno creati due file  di configurazione: server_wg.conf e 
# server_wg_raw.conf
#
# Il primo conterrà la configurazione completa del server e dei peer,
# verrà aggiornato ad ogni modifica dei client (aggiunta o rimozione) e
# verrà usato per il deploy della configurazione.
#
# Il secondo conterrà la configurazione del solo server e verrà usato
# solo per rigenerare il primo file di configurazione.
init() {
    # Controllo che wireguard sia almeno abilitato
    echo -n &#34;Inserire la password di Amministratore: &#34;; read -s PASSWORD
    sudo -k
    if echo $PASSWORD|sudo -S echo &#34;got a root&#34; &gt; /dev/null; then
        if ! sudo systemctl is-enabled --quiet wg-quick@${WG_INTERFACE}; then
            echo -en &#34;\nAttivazione servizio wireguard... &#34;
            #sudo systemctl enable --quiet wg-quick@${WG_INTERFACE}
            echo &#34;fatto.&#34;
        fi
        sudo -k 
        
        #Verifico che queste cartelle esistano. Se lo sono, non faccio nulla, se no le creo.
        echo -n &#34;Creazione workdir... &#34;
        [[ ! -e ${WORKDIR}/conf.d || ! -e ${WORKDIR}/psk  || ! -e ${WORKDIR}/keys ]] \
            &amp;&amp; { mkdir -p ${WORKDIR}/{conf.d,keys,psk}; } \
            || { echo &#34;inizializzazione già effettuata.&#34;; exit; }
        echo &#34;fatto.&#34;
        
        # Genero la chiave privata per il server
        echo -n &#34;Creazione chiave private del server...&#34;
        SERVER_PRIV_KEY=$(gen_priv_key &#34;server_wg&#34;)
        echo &#34;fatto.&#34;

        # Genero il file di configurazione
        echo -n &#34;Inizializzazione del server... &#34;
        cat &gt; ${WORKDIR}/conf.d/server_wg.conf &lt;&lt; EOF
[Interface]
Address = ${SERVER_IP_ADDRESS}/${SUBNET_MASK}
# SaveConfig = true

PreUp = ufw route allow in on ${WG_INTERFACE} out on ${PHYSICAL_INTERFACE} log from ${NETWORK}/${SUBNET_MASK} to 0.0.0.0/0
PostDown = ufw route delete allow in on ${WG_INTERFACE} out on ${PHYSICAL_INTERFACE} log from ${NETWORK}/${SUBNET_MASK} to 0.0.0.0/0

# IP masquerading
PreUp = iptables -t nat -A POSTROUTING -o ${PHYSICAL_INTERFACE} -s ${NETWORK}/${SUBNET_MASK} -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o ${PHYSICAL_INTERFACE} -s ${NETWORK}/${SUBNET_MASK} -j MASQUERADE

# IP filtering
PreUp = ufw allow in on ${PHYSICAL_INTERFACE} log to 0.0.0.0/0 app Wireguard
PostDown = ufw delete allow in on ${PHYSICAL_INTERFACE} log to 0.0.0.0/0 app Wireguard

ListenPort = ${LISTEN_PORT}
PrivateKey = ${SERVER_PRIV_KEY}

EOF
        echo &#34;fatto.&#34;
        cp ${WORKDIR}/conf.d/server_wg.conf ${WORKDIR}/conf.d/server_wg_raw.conf
        # Inizializza l&#39;erogatore di ip
        echo 1 &gt; ${WORKDIR}/conf.d/ip_renew
    else
        echo &#34;Sono necessarie le credenziali di amministrazione per eseguire questo comando.&#34;
        exit 1
    fi
}



# Genera un certificato per il client composto da:
# * chiave privata del client
# * chiave pre-condivisa
# * client ip
# * chiave pubblica del server
# * nome simbolico del client
#
# Dopo la creazione e il salvataggio in &lt;WORKDIR&gt;/conf.d, verrà aggiunto
# il relativo peer nella configurazione del server (server_wg.conf).
# @par_1 @par_2 @par_3...: lista di nomi relativi ai certificati da creare.
add_client() {
    if is_init; then
        # Se non c&#39;è alcun input, esco.
        if [[ $# -lt 1 ]]; then
            echo -e &#34;Devi inserire almeno un nome.&#34;
            exit 1
        else
            # Per ogni nome presente in input, creo una configurazione 
            # client e l&#39;aggiungo alla configurazione del server.
            for CLIENT_NAME in &#34;$@&#34;; do
                echo -n &#34;Creazione certificato per il client \&#34;${CLIENT_NAME}\&#34;... &#34;
                
                # Controllo se la configurazione esista già discriminando
                # in base al nome del file.
                if [[ -e ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf ]]; then
                    echo &#34;già esistente.&#34;
                else
                    # Creo la configurazione del client
                    CLIENT_PRIV_KEY=$(gen_priv_key ${CLIENT_NAME})
                    CLIENT_PUBLIC_KEY=$(echo ${CLIENT_PRIV_KEY} | wg pubkey)
                    CLIENT_PSK=$(gen_client_psk ${CLIENT_NAME})
                    CLIENT_IP_ADDRESS=$(ip_renew)
                    SERVER_PUBLIC_KEY=$(grep PrivateKey ${WORKDIR}/conf.d/server_wg.conf | cut -d &#34; &#34; -f 3 | tr -d &#34; &#34; | wg pubkey)
                    CLIENT_NAME_UPPER=$(echo ${CLIENT_NAME} | tr &#39;[:lower:]&#39; &#39;[:upper:]&#39;)
                    cat &gt; ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf &lt;&lt; EOF
    # ${CLIENT_NAME_UPPER}
    [Interface]
    Address = ${CLIENT_IP_ADDRESS}/${SUBNET_MASK}
    DNS = ${DNS}
    PrivateKey = ${CLIENT_PRIV_KEY}

    [Peer]
    PublicKey = ${SERVER_PUBLIC_KEY}
    PresharedKey = ${CLIENT_PSK}
    AllowedIPs = 0.0.0.0/0
    Endpoint = ${ENDPOINT}
    PersistentKeepalive = 25
EOF
                    echo &#34;fatto.&#34;
                    echo -n &#34;Aggiunta peer \&#34;${CLIENT_NAME}\&#34; al file di configurazione del server... &#34;
                    
                    # Aggiungo il peer alla configurazione del server.
                    add_peer_to_server ${CLIENT_PUBLIC_KEY} ${CLIENT_PSK} ${CLIENT_IP_ADDRESS} ${CLIENT_NAME_UPPER}
                    echo -e &#34;fatto.\n&#34;                
                fi
            done
        fi
    else
        echo &#34;È necessario inizializzare il server con &#39;wg_init.sh init&#39;.&#34;
        echo &#34;L&#39;operazione richiesta non sarà completata&#34;
    fi
}



# Rimuove file di configurazioni, chiavi e pre-shared key realtive a file
# dati in input.
# Rimuove inoltre il peer dal file di configurazione server_wg.conf.
# @par_1 @par_2 @par_3...: lista di nomi relativi ai certificati da rimuovere.
remove_client() {
    if is_init; then
        if [[ $# -lt 1 ]]; then
            echo -e &#34;Devi inserire almeno un nome.&#34;
            exit 1
        else
            for CLIENT_NAME in &#34;$@&#34;; do
                echo -n &#34;Rimozione client \&#34;${CLIENT_NAME}\&#34;... &#34;
                if [[ ! -e ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf ]]; then
                    echo &#34;non esistente.&#34;
                else
                    # Estraggo l&#39;ultimo ottetto dell&#39;ip del client.
                    IP=$(grep &#34;Address&#34; ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;|cut -d &#34;/&#34; -f 1)
                    
                    # Lo inserisco nella lista degli ip riallocabili.
                    ip_release ${IP}
                    
                    # Cancello file di configurazione, chiave e psk del client.
                    rm ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf ${WORKDIR}/keys/${CLIENT_NAME}_privkey ${WORKDIR}/psk/${CLIENT_NAME}_psk
                    echo &#34;terminata con successo.&#34;
                    echo -n &#34;Rimozione peer \&#34;${CLIENT_NAME}\&#34; dal file di configurazione del server... &#34;
                    
                    # Rimuovo il peer dalla configurazione del server.
                    CLIENT_NAME_UPPER=$(echo ${CLIENT_NAME} | tr &#39;[:lower:]&#39; &#39;[:upper:]&#39;)
                    sed -i &#34;/# ${CLIENT_NAME_UPPER}/,+6d&#34; ${WORKDIR}/conf.d/server_wg.conf
                    echo -e &#34;terminata con successo.\n&#34;   
                fi
            done
        fi
    else
        echo &#34;È necessario inizializzare il server con &#39;wg_init.sh init&#39;.&#34;
        echo &#34;L&#39;operazione richiesta non sarà completata&#34;
    fi
}



rebuild() {
    if is_init; then
        # Rigenero il file di configurazione del server da server_wg_raw.conf.
        echo -n &#34;Ripristino del file di configurazione del server... &#34;
        cat ${WORKDIR}/conf.d/server_wg_raw.conf &gt; ${WORKDIR}/conf.d/server_wg.conf
        echo &#34;fatto.&#34;
        
        # Per ogni file di configurazione client, aggiungo il relativo peer
        # nel file di configurazione server_wg.conf.
        for FILE_CONF in ${WORKDIR}/conf.d/client_*.conf; do
            CLIENT_PUBLIC_KEY=$(grep &#34;PrivateKey&#34; ${FILE_CONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34; | wg pubkey)
            CLIENT_PSK=$(grep &#34;PresharedKey&#34; ${FILE_CONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;)
            CLIENT_IP_ADDRESS=$(grep &#34;Address&#34; ${FILE_CONF}|cut -d &#34; &#34; -f 3|tr -d &#34; &#34;|cut -d &#34;/&#34; -f 1)
            CLIENT_NAME_UPPER=$(grep &#34;#&#34; ${FILE_CONF} | cut -d &#34; &#34; -f 2)
            echo -n &#34;Aggiunta peer \&#34;$(echo ${CLIENT_NAME_UPPER} | tr &#39;[:upper:]&#39; &#39;[:lower:]&#39;)\&#34;... &#34;
            add_peer_to_server ${CLIENT_PUBLIC_KEY} ${CLIENT_PSK} ${CLIENT_IP_ADDRESS} ${CLIENT_NAME_UPPER}
            echo -e &#34;fatto.&#34;
        done
    else
        echo &#34;È necessario inizializzare il server con &#39;wg_init.sh init&#39;.&#34;
        echo &#34;L&#39;operazione richiesta non sarà completata&#34;
    fi
}



# Avvia il server wireguard con la nuova configurazione
deploy() {
    if is_init; then
        echo -n &#34;Inserire la password di Amministratore: &#34;; read -s PASSWORD
        sudo -k
        if echo $PASSWORD|sudo -S echo &#34;got a root&#34; &gt; /dev/null; then
   
            # Stoppo il servizio wireguard
            echo -ne &#34;\nStop wireguard... &#34;
            sudo systemctl stop wg-quick@${WG_INTERFACE}
            echo &#34;fatto.&#34;
            
            # Aggiorno la configurazione
            echo -n &#34;Copia della nuova configurazione... &#34;
            sudo cp ${WORKDIR}/conf.d/server_wg.conf /etc/wireguard/${WG_INTERFACE}
            echo &#34;fatto.&#34;
            
            # Riavvio il servizio wireguard
            echo -n &#34;Riavvio wireguard... &#34;
            sudo systemctl start wg-quick@${WG_INTERFACE}
            echo &#34;fatto.&#34;
            
            # Revoco i privilegi di amministrazione
            sudo -k
        else
            echo &#34;Sono necessarie le credenziali di amministrazione per eseguire questo comando.&#34;
            exit 1
        fi
    else
        echo &#34;È necessario inizializzare il server con &#39;wg_init.sh init&#39;.&#34;
        echo &#34;L&#39;operazione richiesta non sarà completata&#34;
    fi
}



# Crea il qr-code della configurazione del client nella cartella corrente.
share() {
    if is_init; then
        if [[ $# -lt 1 ]]; then
            echo -e &#34;Devi inserire almeno un nome.&#34;
            exit 1
        else
            for CLIENT_NAME in &#34;$@&#34;; do
                echo -n &#34;Creazione qr-code per il client \&#34;${CLIENT_NAME}\&#34;... &#34;
                qrencode -r ${WORKDIR}/conf.d/client_${CLIENT_NAME}.conf -o qrcode_client_${CLIENT_NAME}.jpg
                echo &#34;fatto.&#34;
            done
        fi
    else
        echo &#34;È necessario inizializzare il server con &#39;wg_init.sh init&#39;.&#34;
        echo &#34;L&#39;operazione richiesta non sarà completata&#34;
    fi
}



help() {

[[ $1 != &#34;&#34; &amp;&amp; $1 != &#34;help&#34; ]] &amp;&amp; echo -e &#34;Comando inesistente.&#34;

    cat&lt;&lt;EOF
Usa come: ./wg_man.sh [command] ARG
dove:
    [command]
        init                     : Inizializza la configurazione del server.
        addclient &lt;lista nomi&gt;   : Aggiunge i client indicati in &lt;lista nomi&gt;.
        removeclient &lt;lista nomi&gt;: Rimuove i client indicati in &lt;lista nomi&gt;.
        rebuild                  : Ricostruisce il file di configurazione
                                   del server partendo dalle configurazioni
                                   di tutti i client registrati.
        deploy                   : Riavvia il server wireguard con l&#39;ultima
                                   configurazione disponibile.
        share &lt;lista nomi&gt;       : Genera i qr-code relativi ai client indicati in &lt;lista nomi&gt;.
        help                     : Stampa questa pagina di help.

ESEMPI:
    INiZIALIZZA IL SERVER WIREGUARD
    wg_man.sh init

    AGGIUNGE I CLIENT &#39;macbook_pro&#39;, &#39;mobile&#39;
    wg_man.sh addclient macbook_pro mobile

    RIMUOVE I CLIENT &#39;iphone_luca&#39;, &#39;workstation&#39;
    wg_man.sh removeclient iphone_luca workstation

    RICOSTRUISCE LA CONFIGURAZIONE DEL SERVER WIREGUARD
    wg_man.sh rebuild
    
    ATTIVA LA NUOVA CONFIGURAZIONE
    wg_man.sh deploy

    GENERA I QRCODE PER &#39;pc_ufficio&#39;, &#39;laptop&#39;
    wg_man.sh share pc_ufficio laptop
EOF
}



main() {
    case $1 in
        init         ) init ;;
        addclient    ) shift; add_client &#34;$@&#34; ;;
        removeclient ) shift; remove_client &#34;$@&#34; ;;
        rebuild      ) rebuild ;;
        deploy       ) deploy ;;
        share        ) shift; share &#34;$@&#34; ;;
        *            ) help ;;
    esac
}



check_dependency
case $? in
    &#34;0&#34; ) main $* ;;
    &#34;1&#34; ) echo -e &#34;UFW non presente. Installare UFW.&#34;; exit 1 ;;
    &#34;2&#34; ) echo -e &#34;wireguard-tools non presenti. È necessario installarli.&#34;; exit 1 ;;
esac
</code></pre>

<p><a href="/aytin/tag:bash" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">bash</span></a> <a href="/aytin/tag:wireguard" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">wireguard</span></a> <a href="/aytin/tag:psk" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">psk</span></a> <a href="/aytin/tag:chiavi" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">chiavi</span></a> <a href="/aytin/tag:certificati" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">certificati</span></a> <a href="/aytin/tag:crittografia" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">crittografia</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/script-per-la-gestione-della-configurazione-di-una-vpn-wireguard</guid>
      <pubDate>Sun, 22 Sep 2024 13:27:09 +0000</pubDate>
    </item>
    <item>
      <title>VPN con Wireguard: semplice e veloce</title>
      <link>https://noblogo.org/aytin/vpn-con-wireguard-semplice-e-veloce</link>
      <description>&lt;![CDATA[vpn&#xA;smalliFonte:  Photo by Stefan Coders on a href=&#34;https://www.pexels.com/it-it/foto/uomo-persone-donna-apple-5243610/&#34;Pexels.com/a/i/small&#xA;&#xA;a id=&#34;perche-wireguard&#34;Perché wireguard?/a&#xA;&#xA;È più semplice di OpenVPN.&#xA;Fa parte del kernel dalla versione 5.6 in poi (ci sono anche versioni in userspaces). Vanno installati solo i software di gestione del tunnel&#xA;Si basa su uno strato di crittografia all&#39;avanguardia per quel che riguarda efficienza e robustezza&#xA;Il suo codice, estremamente compatto, viene revisionato con molta più facilità.&#xA;Non si basa su un modello client-server ma P2P&#xA;Il traffico è UDP piuttosto che TCP (ci sono modi per fare un wrapping TCP delle connessioni UDP)&#xA;&#xA;!--more--&#xA;&#xA;a href=&#34;#perche-wireguard&#34;Perché wireguard?/a&#xA;a href=&#34;#crittografia-di-wireguard&#34;Crittografia di Wireguard/a&#xA;a href=&#34;#un-po-di-teoria&#34;Un po&#39; di teoria/a&#xA;a href=&#34;#installazione&#34;Installazione/a&#xA;   a href=&#34;#generazione-chiavi&#34;Generazione chiavi/a&#xA;a href=&#34;#attivazione-nodo&#34;Attivazione del nodo/a&#xA;   a href=&#34;#pc-laptop&#34;PC/Laptop/a&#xA;   a href=&#34;#mobile&#34;Mobile/a&#xA;a href=&#34;#debug&#34;Debug/a&#xA;a href=&#34;#topologie&#34;Topologie/a&#xA;a href=&#34;#point-to-site&#34;Point-To-Site/a&#xA;   a href=&#34;#primo-scenario&#34;Primo scenario/a&#xA;      a href=&#34;#pts-configurazione-wireguard-endpoint-a&#34;Configurazione wireguard Endpoint A/a&#xA;      a href=&#34;#pts-configurazione-wireguard-host-b&#34;Configurazione wireguard Host B/a&#xA;      a href=&#34;#pts-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;      a href=&#34;#pts-test&#34;Test/a&#xA;      a href=&#34;#pts-tips&#34;Tips/a&#xA;   a href=&#34;#secondo-scenario&#34;Secondo scenario/a&#xA;      a href=&#34;#stp-configurazione-wireguard-endpoint-a&#34;Configurazione wireguard Endpoint A/a&#xA;      a href=&#34;#stp-configurazione-wireguard-host-b&#34;Configurazione wireguard Host B/a&#xA;      a href=&#34;#stp-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;      a href=&#34;#stp-test&#34;Test/a&#xA;      a href=&#34;#stp-tips&#34;Tips/a&#xA;   a href=&#34;#terzo-scenario&#34;Terzo scenario/a&#xA;      a href=&#34;#gtw-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;      a href=&#34;#gtw-configurazione-gateway-host-sito-b&#34;Configurazione gateway Sito B/a&#xA;      a href=&#34;#gtw-test&#34;Test/a&#xA;      a href=&#34;#gtw-tips&#34;Tips/a&#xA;   a href=&#34;#differenze-3-approcci&#34;Differenze fra i 3 approcci/a&#xA;&#xA;a id=&#34;crittografia-di-wireguard&#34;Crittografia di Wireguard/a&#xA;&#xA;Le primitive crittografiche di Wireguard si basano su:&#xA;&#xA;Curve25519, per autenticazione e key exchange (ECDH)&#xA;ChaCha20 e Poly1305, per la cifratura simmetrica con autenticazione (AEAD)&#xA;BLAKE2, come hash crittografico&#xA;SipHash-2-4, come funzione di hash crittografico con chiave (tipo HMAC)&#xA;HKDF, come funzione di derivazione della chiave basata su HMAC&#xA;Noise Framework, è un protocollo crittografico. Stabilisce il modo con cui tutte queste operazioni crittografiche vengono fatte lavorare.&#xA;&#xA;a id=&#34;un-po-di-teoria&#34;Un po&#39; di teoria/a&#xA;&#xA;Wireguard implementa una vpn L3 solo tunneling, incapsulando pacchetti IP all&#39;interno di pacchetti UDP per il trasporto. Ciò implica che funzioni come dhcp, essendo L2, non possono trovare spazio all&#39;interno di wireguard, ergo l&#39;indirizzamento (ip, subnet, dns) deve essere fatto staticamente.&#xA;&#xA;Avendo un&#39;anima P2P, ogni nodo (peer) wireguard è sia client che server. Ciò permette di realizzare topologie anche piuttosto complesse con uno sforzo relativamente ridotto.&#xA;&#xA;Un peer wireguard è composto da due tipi di sezioni:&#xA;&#xA;una sezione &#34;interface&#34;, relativa al peer stesso, contenente:&#xA;  il proprio IP, nello spazio di indirizzamento privato usato dalla vpn.&#xA;  una porta, su cui il peer può essere in ascolto per accettare richieste da altri nodi wireguard&#xA;  la parte privata della chiave asimmetrica con cui decifra e autentica&#xA;una o più sezioni &#34;peer&#34;, relative ai nodi a cui può connettersi, contenenti:&#xA;  la parte pubblica della chiave asimmetrica del peer, con cui cifra e verifica&#xA;  AllowedIPs, che descrive l&#39;ip o le reti da ruotare nel tunnel, a cui è consentito il traffico in entrata e a cui è diretto il traffico in uscita&#xA;  l&#39;endpoint del peer, necessario solo se altri peer devono avviare connessioni verso di lui&#xA;&#xA;I nodi si autenticano a vicenda scambiandosi e convalidando le chiavi pubbliche. Ogni chiave pubblica è associata all&#39;IP di un peer.&#xA;&#xA;Quando un peer deve inviare dei pacchetti, AllowedIPs si comporta come una tabella di instradamento. Il peer esamina l&#39;IP di destinazione di quel pacchetto e lo cerca negli AllowedIPs dei suoi peer per capire a chi inviarlo. Se lo trova, ruota il pacchetto nel tunnel, altrimenti no.&#xA;&#xA;Quando si ricevono pacchetti, AllowedIPs si comporta come una lista di controllo degli accessi. Il peer esamina l&#39;IP di origine e se rientra nell&#39;AllowedIPs di uno dei suoi peer, accetterà il pacchetto altrimenti lo scarterà.&#xA;&#xA;Per esperienza personale, il 99% degli errori di configurazione su wireguard viene fatto proprio sul campo AllowedIPs perché non se ne comprende bene il funzionamento.&#xA;&#xA;Uno degli errori più comuni è quello di definire dei peer in cui gli ip contenuti nei campi AllowedIPs si sovrappongono. In base al funzionamento di wireguard infatti, non posso avere chiavi pubbliche diverse per uno stesso ip perché il peer, pur essendo in grado di ricevere pacchetti, non riuscirebbe a inviarli, non sapendo come ruotarli dovendo scegliere fra più peer.&#xA;a id=&#34;installazione&#34;Installazione/a&#xA;&#xA;Come già detto, wireguard è presente di base nel kernel linux. Bisogna installare solo gli strumenti di interfacciamento per la configurazione su ogni host.&#xA;&#xA;Per sistemi debian-based:&#xA;apt install wireguard wireguard-tools&#xA;a id=&#34;generazione-chiavi&#34;Generazione chiavi/a&#xA;Per semplicità, suppongo di generare tutte le chiavi che mi occorrono, del server (host B) e del client (Endpoint A) in questo caso. Oltre alle chiavi, userò anche una pre-shared key per il client. Non è obbligatorio ma mi costa zero e aumenta la resistenza post-quantistica.&#xA;&#xA;server&#xA;wg genkey   serverwg.key&#xA;wg pubkey  serverwg.key  serverwg.pub&#xA;&#xA;client&#xA;wg genkey   endpoint-awg.key&#xA;wg pubkey  endpoint-awg.key  endpoint-awg.pub&#xA;&#xA;Creazione psk&#xA;wg genpsk   endpoint-a.psk&#xA;a id=&#34;attivazione-nodo&#34;Attivazione del nodo/a&#xA;&#xA;Una volta che la configurazione del nodo è pronta, va attivato il servizio se ci troviamo su un pc. Altrimenti bisognerà importare la configurazione sul device.&#xA;a id=&#34;pc-laptop&#34;PC/Laptop/a&#xA;&#xA;Sia esso un client o un server, una volta configurato il peer, salva il file file sotto /etc/wireguard/ col nome dell&#39;interfaccia virtuale che hai scelto, nel mio caso, wg0.conf&#xA;&#xA;Attivazione/Disattivazione vpn on-demand:&#xA;wg-quick up wg0 #attiva la vpn&#xA;wg-quick down wg0 #disattiva la vpn&#xA;Attivazione/Disattivazione vpn come servizio:&#xA;systemctl enable wg-quick@wg0&#xA;systemctl start/stop wg-quick@wg0.service&#xA;a id=&#34;mobile&#34;Mobile/a&#xA;&#xA;Se il provisioning delle configurazioni si fa attraverso un pc, per portare facilmente la configurazione su un device mobile, si può generare un qrcode del file (supponiamo sia mobile.conf) e importarlo.&#xA;Installazione qrencode (debian-based)&#xA;apt install qrencode&#xA;&#xA;Crea il qr-code e dallo in pasto a al client&#xA;qrencode -t ansiutf8 &lt; mobile.conf&#xA;a id=&#34;debug&#34;Debug/a&#xA;&#xA;Wireguard è un modulo del kernel e quindi la sua attività viene raccolta dai log del kernel (/var/log/kern.log o /var/log/messages).&#xA;&#xA;Bisogna verificare che sul kernel si possa abilitare il dynamicdebugcontrol, controllando se è presente:&#xA;ls /sys/kernel/debug/dynamicdebug&#xA;Se lo è, si carica il modulo, si setta il dynamic debug e si potrà esaminare log del kernel ad es. con journalctl -fk&#xA;modprobe wireguard&#xA;echo module wireguard +p | sudo tee /sys/kernel/debug/dynamicdebug/control&#xA;Potresti dover installare resolvconf sul server.&#xA;&#xA;Quando wireguard fa salire l&#39;interfaccia, la registra su systemd-resolve attraverso resolvconf e se non è installato potrebbe verificarsi un malfunzionamento.&#xA;a id=&#34;topologie&#34;Topologie/a&#xA;&#xA;Le principali topologie che possono essere realizzate con wireguard sono:&#xA;&#xA;point-to-point&#xA;point-to-site&#xA;site-to-site&#xA;hub-and-spoke (a stella)&#xA;&#xA;Il canale sicuro fra i nodi wireguard viene creato attraverso le primitive crittografiche di cui sopra, ogni peer viene identificato da una chiave asimmetrica.&#xA;&#xA;Non è necessario approfondire la parte di crittografia per capire come configurare wireguard. Ci fidiamo che faccia un buon lavoro.&#xA;&#xA;Ciò su cui invece vale la pena soffermarsi, è la parte di instradamento, essenziale per l&#39;implementazione delle topologie di cui sopra.&#xA;&#xA;Io mi soffermerò sulla topologia più comune, point-to-site, che permette di unire un endpoint che esegue wireguard, con un altro endpoint situato all&#39;interno di una LAN in cui c&#39;è un host wireguard.&#xA;&#xA;easy-point-to-site&#xA;&#xA;Tanto per fissare le idee indicherò:&#xA;&#xA;col termine peer, uno dei punti logici di una vpn wireguard&#xA;col termine endpoint, uno dei punti di arrivo della tratta interessata dal tunnel vpn&#xA;col termine host wireguard, l&#39;host che esegue wireguard.&#xA;&#xA;Osservazioni banali:&#xA;In una topologia point-to-point, host wireguard ed endpoint coincidono su entrambi gli estremi della tratta.&#xA;In una topologia point-to-site, host wireguard ed endpoint coincidono solo sul &#34;point&#34; (l&#39;altro endpoint è dietro ad un host wireguard).&#xA;In una topologia site-to-site, gli endpoint sono sempre dietro gli host wireguard.&#xA;a id=&#34;point-to-site&#34;Point-To-Site/a&#xA;&#xA;Avrò un Sito A che comprende il solo endpoint dove non ho la possibilità di gestire routing e filtering e un Sito B dove, al contrario, potrò impostare le mie policy di instradamento e filtraggio e dove sarà presente l&#39;host wireguard (indicato come Host B, di solito) che fungerà da server.&#xA;&#xA;La configurazione di un peer si divide in 3 tronconi:&#xA;&#xA;il listener&#xA;l&#39;instradamento dei pacchetti fra gli host wireguard e gli endpoint&#xA;gli altri peers della VPN Wireguard&#xA;&#xA;Gli scenari che andremo a considerare riguarderanno la direzione delle comunicazioni e le strategie adottate per realizzarle:&#xA;&#xA;da Endpoint A a Endpoint B (punto-sito)&#xA;da Endpoint B a Endpoint A (sito-punto)&#xA;bidirezionale (punto-sito-punto)&#xA;&#xA;Prendendo uno scenario reale come riferimento, suppongo che la parte &#34;point&#34; sia dietro un NAT che nasconde l&#39;ip privato dell&#39;endpoint e permette solo connessioni già stabilite.&#xA;Nella parte &#34;site&#34;, la lan è protetta da un firewall-router-nat che espone il solo ip pubblico.&#xA;&#xA;Nella configurazione di filtering/routing sul firewall (ufw nel mio caso) di Host B, ci sarà da tenere conto delle politiche di inoltro. Per semplificarci la vita si potrebbe abilitare qualunque inoltro di default ma sarebbe un po&#39; pericoloso quindi, a meno di casi particolari, anche gli inoltri saranno filtrati.&#xA;a id=&#34;primo-scenario&#34;Primo scenario/a&#xA;&#xA;Nel primo scenario, considererò il caso punto-sito, in cui un endpoint (con wireguard) si collega, nella LAN attraverso un host wireguard, all&#39;endpoint che eroga un servizio.&#xA;&#xA;point-to-site&#xA;smallPoint-To-Site/small&#xA;&#xA;Obiettivo:&#xA;L&#39;endpoint del sito B (192.168.1.3) ha un servizio web https sulla porta 443, che non è raggiungibile dall&#39;esterno.&#xA;Possiamo usare wireguard per permettere all&#39;Endpoint A di raggiungere il servizio sugli endpoint del sito B, per mezzo dell&#39;host wireguard B.&#xA;Affinché l&#39;host B possa inoltrare i pacchetti dall&#39;Endpoint A all&#39;Endpoint B si ricorre al SNAT (MASQUERADING).&#xA;&#xA;point-to-site-masquerading&#xA;smallPoint-To-Site: Masquerading/small&#xA;&#xA;a id=&#34;pts-configurazione-wireguard-endpoint-a&#34;Configurazione wireguard Endpoint A/a&#xA;&#xA;[Interface]&#xA;Address = 10.0.0.2/32&#xA;SaveConfig = true&#xA;PrivateKey = Contenuto di endpoint-awg.key&#xA;&#xA;[Peer]&#xA;PublicKey = Contenuto di serverwg.pub&#xA;PresharedKey = Contenuto di endpoint-a.psk&#xA;Endpoint = 200.76.182.23:51820&#xA;AllowedIPs = 192.168.1.0/24&#xA;Dettagli:&#xA;&#xA;Interface.Address: IP dell&#39;Endpoint A nella rete virtuale definita da wireguard&#xA;Interface.SaveConfig: se è true, qualunque modifica fatta al file di configurazione prima dello spegnimento dell&#39;interfaccia verrà ignorato.&#xA;Interface.PrivateKey: la chiave privata dell&#39;Endpoint A&#xA;Peer.PublicKey: La chiave pubblica dell&#39;host B wireguard&#xA;Peer.PresharedKey: La preshared key dell&#39;Endpoint A&#xA;Peer.Endpoint: L&#39;ip esposto dell&#39;host B wireguard. Potrebbe trovarsi dietro un firewall/nat ma tanto sappiamo che sul sito B ho libertà d&#39;azione&#xA;Peer.AllowedIPs: Sono le reti che voglio ruotare nel tunnel. Possono essere singoli ip o subnet separati da &#34; , &#34;.&#xA;0.0.0.0/0 equivale a ruotare tutto il traffico del peer nella VPN wireguard. Nel caso in esame, ruoto nel tunnel solo la lan del sito B. Il resto del traffico è al di fuori della VPN wireguard (split tunnel)&#xA;&#xA;a id=&#34;pts-configurazione-wireguard-host-b&#34;Configurazione wireguard Host B/a&#xA;&#xA;[Interface]&#xA;Address = 10.0.0.1/24&#xA;SaveConfig = true&#xA;ListenPort = 51820&#xA;PrivateKey = Contenuto di serverwg.key&#xA;&#xA;endpoint A&#xA;[Peer]&#xA;PublicKey = Contenuto di endpoint-awg.pub&#xA;PresharedKey = Contenuto di endpoint-a.psk&#xA;AllowedIPs = 10.0.0.2/32&#xA;Dettagli:&#xA;&#xA;Interface.Address: ip dell&#39;host B nella rete virtuale definita da wireguard&#xA;Interface.SaveConfig: se è true, qualunque modifica fatta al file di configurazione prima dello spegnimento dell&#39;interfaccia verrà ignorato.&#xA;Interface.PrivateKey: la chiave privata dell&#39;host B&#xA;Peer.PublicKey: La chiave pubblica dell&#39;Endpoint A&#xA;Peer.PresharedKey: La preshared key dell&#39;Endpoint A&#xA;Peer.AllowedIPs: Dovendo contattare il singolo endpoint, AllowedIPs definito nel peer è l&#39;ip del peer stesso all&#39;interno della rete virtuale definita da wireguard.&#xA;&#xA;Non poteva essere altrimenti. In una topologia point-to-site,&#xA;&#xA;da point verso site, AllowedIPs della sezione [Peer] del point indirizza una o più subnet.&#xA;da site verso point, AllowedIPs della sezione [Peer] nell&#39;host wireguard indirizza puntualmente l&#39;Endpoint A.&#xA;&#xA;Inoltre, sempre in una topologia point-to-site, è sempre il point ad iniziare la connessione per cui:&#xA;&#xA;nel point:&#xA;  si deve specificare l&#39;Endpoint (\fqdn\or\ip:port\) nella sezione [Peer] relativa al server wireguard.&#xA;  non importa specificare la ListenPort nella sezione Interface che può essere scelta casualmente, perché l&#39;Endpoint A non verrà mai contattato direttamente&#xA;nel site:&#xA;  non importa specificare l&#39;Endpoint (\fqdn\orip:port\) nella sezione [Peer] relativa all&#39;Endpoint A, perché non sarà mai in attesa di una connessione&#xA;  si deve specificare la ListenPort nella sezione [Interface] perché le connessioni sono sempre iniziate dagli endpoint verso di lui&#xA;&#xA;a id=&#34;pts-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;&#xA;Il resto della configurazione non riguarda più wireguard direttamente ma riguarda l&#39;insieme di  policy di routing e filtering da fare sull&#39;host B per permettere ai pacchetti dell&#39;Endpoint A di essere inoltrati all&#39;Endpoint B attraverso l&#39;host B.&#xA;&#xA;Affinchè i pacchetti possano viaggiare dall&#39;Endpoint A all&#39;Endpoint B:&#xA;&#xA;i pacchetti arriveranno all&#39;host B sull&#39;interfaccia virtuale della VPN (wg0)&#xA;poi verranno inoltrati dall&#39;interfaccia virtuale della vpn (wg0) all&#39;interfaccia reale di host B (eth0),&#xA;prima di essere inviati a Endpoint B, una regola di post-routing riscriverà i pacchetti cambiandone l&#39;ip sorgente in modo che risultino inviati da host B piuttosto che da Endpoint A, così da permettere ad Endpoint B di rispondere.&#xA;&#xA;Quindi:&#xA;&#xA;va configurato un inoltro (eventualmente filtrato) dall&#39;interfaccia virtuale wireguard (wg0) a quella reale dell&#39;host B (eth0)&#xA;deve essere configurato il SNAT affinché l&#39;Endpoint B possa rispondere all&#39;Endpoint A&#xA;&#xA;abilita il forward&#xA;sysctl -w net.ipv4.ipforward=1&#xA;inoltra tutto il traffico in arrivo da wg0 verso il solo Endpoint B&#xA;ufw route allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443;&#xA;masquerading&#xA;iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE&#xA;N.B. potrei ancora raffinare queste regole ricorrendo alla tabella Mangle per marcare i pacchetti ai quali applicare il masquerading.&#xA;&#xA;Questi comandi possono far parte della configurazione. Nella sezione [Interface] si possono usare i costrutti PreUp, PreDown, PostUp e PostDown per rendere dinamici alcuni passi di configurazione prima/dopo l&#39;apertura/chiusura del tunnel.&#xA;E così, la configurazione del server diventa:&#xA;&#xA;[Interface]&#xA;Address = 10.0.0.1/24&#xA;SaveConfig = true&#xA;ListenPort = 51820&#xA;PrivateKey = Contenuto di serverwg.key&#xA;&#xA;IP forwarding&#xA;PreUp = sysctl -w net.ipv4.ipforward=1&#xA;PreUp = ufw route allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443&#xA;PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443&#xA;&#xA;IP masquerading&#xA;PreUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE&#xA;PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE&#xA;&#xA;IP filtering&#xA;PreUp = ufw allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;&#xA;PostDown = ufw delete allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;&#xA;&#xA;endpoint A&#xA;[Peer]&#xA;PublicKey = Contenuto di endpoint.awg.pub&#xA;PresharedKey = Contenuto di endpoint-a.psk&#xA;AllowedIPs = 10.0.0.2/32&#xA;a id=&#34;pts-test&#34;Test/a&#xA;&#xA;Da Endpoint A (192.168.10.10) possiamo raggiungere il servizio come se fossimo nella lan del sito B, quindi:&#xA;curl https://192.168.1.3&#xA;risponderà al browsing.&#xA;a id=&#34;pts-tips&#34;Tips/a&#xA;&#xA;La combinazione AllowedIPs / routing è la chiave per gestire qualunque instradamento.&#xA;Nell&#39;esempio visto finora abbiamo fatto in modo che:&#xA;&#xA;l&#39;Endpoint A ruotasse nella VPN wireguard solo la subnet relativa al sito B, 192.168.1.0/24, facendo split tunnel per il resto.&#xA;l&#39;host B avesse delle regole di inoltro per l&#39;Endpoint B per i soli pacchetti destinati al servizio che eroga, https. Qualuque altro host del sito B non può essere raggiunto.&#xA;&#xA;In questo modello, qualunque altro endpoint abilitato alla VPN wireguard potrebbe accedere al servizio dell&#39;Endpoint B.&#xA;Vale la pena dare un&#39;occhiata ad un altro paio di combinazioni che si trovano agli opposti del nostro esempio.&#xA;In un caso, ruoteremo tutto il traffico verso la vpn, in un altro consentiremo solo a determinati peer, non a tutti, di fruire di determinati servizi.&#xA;&#xA;1. Inoltro di tutto il traffico nella vpn&#xA;In questo modo, l&#39;Endpoint A lavora come se facesse parte della lan del sito B. È una modalità totalmente anonimizzante. Da usare solo con  dispositivi trusted perché un eventuale traffico malevolo verrebbe ruotato nel tunnel e risulterebbe proveniente dal sito B&#xA;&#xA;Su Endpoint A:&#xA;...&#xA;AllowedIPs = 0.0.0.0/0&#xA;...&#xA;Su host B:&#xA;...&#xA;ufw route allow in on wg0 out on eth0;`&#xA;...&#xA;2. Indirizzamento puntuale su servizi specifici&#xA;È il caso in cui alcuni peer debbano raggiungere solo determinati servizi e non altri. Supponiamo di avere altri due endpoint, Endpoint Asub1/sub e Endpoint Asub2/sub.&#xA;&#xA;Su Endpoint Asub1/sub e Asub2/sub (in realtà AllowedIPs potrebbe essere puntuale):&#xA;...&#xA;AllowedIPs = 192.168.1.0/24&#xA;...&#xA;...&#xA;PreUp = ufw route allow in on wg0 out on eth0 proto tcp from 10.0.0.3 to 192.168.1.4 port 3306&#xA;PreUp = ufw route allow in on wg0 out on eth0 proto tcp from 10.0.0.4 to 192.168.1.5 port 22&#xA;PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp from 10.0.0.3 to 192.168.1.4 port 3306&#xA;PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp from 10.0.0.4 to 192.168.1.5 port 22&#xA;...&#xA;a id=&#34;secondo-scenario&#34;Secondo scenario/a&#xA;&#xA;Nel secondo scenario, ribalterò il punto di vista e prenderò in esame il caso in cui sia un host del sito B a contattare un endpoint esterno con wireguard (sito-punto).&#xA;Non il classico scenario road-warrior in cui un endpoint deve raggiungere la rete aziendale o domestica, ma il suo opposto.&#xA;&#xA;site-to-point&#xA;smallSite-To-Point/small&#xA;&#xA;Obiettivo:&#xA;L&#39;host del sito A (192.168.10.10) ha un servizio web https sulla porta 1443, che non è raggiungibile dall&#39;esterno ma vogliamo che lo sia dal sito B.&#xA;Con wireguard, possiamo usare l&#39;interfaccia virtuale per esporre il servizio su 10.0.0.2, verso gli endpoint del sito B, per mezzo dell&#39;host wireguard B.&#xA;Affinché l&#39;host B possa inoltrare i pacchetti dall&#39;Endpoint B all&#39;Endpoint A si ricorre al DNAT (PORT FORWARDING).&#xA;&#xA;point-to-site-port-forwarding&#xA;smallSite-To-Point: Port-Forwarding/small&#xA;&#xA;La configurazione di wireguard su host B rimane sostanzialmente identica rispetto a prima.&#xA;A cambiare sarà soprattutto la parte di filtering e routing.&#xA;a id=&#34;stp-configurazione-wireguard-endpoint-a&#34;Configurazione wireguard Endpoint A/a&#xA;&#xA;[Interface]&#xA;Address = 10.0.0.2/32&#xA;SaveConfig = true&#xA;PrivateKey = Contenuto di endpoint-awg.key&#xA;&#xA;[Peer]&#xA;PublicKey = Contenuto di serverwg.pub&#xA;PresharedKey = Contenuto di endpoint-a.psk&#xA;Endpoint = 200.76.182.23:51820&#xA;AllowedIPs = 192.168.1.0/24&#xA;PersistentKeepalive = 25&#xA;Su Endpoint A c&#39;è una piccola modifica.&#xA;&#xA;Dettagli:&#xA;&#xA;PersistentKeepalive: Il NAT davanti all&#39;Endpoint A potrebbe troncare la connessione dopo un po&#39; visto che non è lui ad avviarla. Dal momento che è Endpoint A a dare servizio, si ricorre al keepalive per mantenere la connessione persistente.&#xA;&#xA;a id=&#34;stp-configurazione-wireguard-host-b&#34;Configurazione wireguard Host B/a&#xA;&#xA;[Interface]&#xA;Address = 10.0.0.1/24&#xA;SaveConfig = true&#xA;ListenPort = 51820&#xA;PrivateKey = Contenuto di serverwg.key&#xA;&#xA;endpoint A&#xA;[Peer]&#xA;PublicKey = Contenuto di endpoint-awg.pub&#xA;PresharedKey = Contenuto di endpoint-a.psk&#xA;AllowedIPs = 10.0.0.2/32&#xA;La configurazione di Host B rimane sostanzialmente invariata.&#xA;a id=&#34;stp-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;&#xA;Affinchè i pacchetti possano viaggiare dall&#39;Endpoint B all&#39;Endpoint A:&#xA;&#xA;i pacchetti arriveranno sull&#39;interfaccia reale di host B (eth0),&#xA;una regola di pre-routing riscriverà i pacchetti cambiandone l&#39;ip di destinazione con quello virtuale dell&#39;Endpoint A&#xA;poi verranno inoltrati dall&#39;interfaccia reale di host B (eth0) all&#39;interfaccia virtuale della VPN (wg0) che li recapiterà ad Endpoint A&#xA;&#xA;Quindi&#xA;&#xA;va configurato un inoltro (eventualmente filtrato) dall&#39;interfaccia reale dell&#39;host B (eth0) a quella virtuale wireguard (wg0)&#xA;deve essere configurato il DNAT affinché l&#39;Endpoint B possa contattare l&#39;Endpoint A.&#xA;&#xA;...&#xA;IP forwarding&#xA;abilita il forward&#xA;PreUp = sysctl -w net.ipv4.ipforward=1&#xA;inoltra tutto il traffico in arrivo da eth0 verso l&#39;Endpoint A&#xA;PreUp = ufw route allow in on eth0 out on wg0 proto tcp to 10.0.0.2 port 443&#xA;PostDown = ufw route delete allow in on eth0 out on wg0 proto tcp to 10.0.0.2 port 443&#xA;&#xA;IP port forwarding&#xA;inoltro della porta 1443 dall&#39;interfaccia lan verso la porta 443 dell&#39;Endpoint A&#xA;PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.2:1443&#xA;PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.2:1443&#xA;&#xA;IP filtering&#xA;PreUp = ufw allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;&#xA;PostDown = ufw delete allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;&#xA;...&#xA;a id=&#34;stp-test&#34;Test/a&#xA;&#xA;Da Endpoint B (192.168.1.3) possiamo raggiungere il servizio sull&#39;interfaccia virtuale dell&#39;Endpoint A passando dalla porta dell&#39;host B, quindi:&#xA;curl https://192.168.1.2&#xA;risponderà al browsing.&#xA;a id=&#34;stp-tips&#34;Tips/a&#xA;&#xA;In questa rappresentazione, ogni host del sito B viene indirizzato solo verso la vpn wireguard.&#xA;L&#39;host B inoltra:&#xA;&#xA;la porta 443 di ogni host del sito B verso l&#39;Endpoint A&#xA;tutto il traffico della lan verso la vpn wireguard.&#xA;&#xA;Se volessimo che solo determinati endpoint del sito B potessero inoltrare il loro traffico, si dovrebbero rendere le regole di inoltro più puntuali.&#xA;Supponiamo che Endpoint A (10.0.0.2) esponga un servzio ihttpd/i sulla porta 10080 e vogliamo che solo gli host 192.168.1.9-192.168.1.14 del sito B lo possano raggiungere sulla canonica porta 80.&#xA;&#xA;Port Forwarding di un solo endpoint&#xA;ufw route allow from 192.168.1.4 to 10.0.0.2 port 10080 proto tcp&#xA;iptables -t nat -A PREROUTING -s 192.168.1.4 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:10080&#xA;Port Forwarding di una subnet&#xA;ufw route allow from 192.168.1.8/29 to 10.0.0.2 port 10080 proto tcp&#xA;iptables -t nat -A PREROUTING -s 192.168.1.9-192.168.1.14 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:10080&#xA;a id=&#34;terzo-scenario&#34;Terzo scenario/a&#xA;&#xA;Il terzo scenario può essere considerato un&#39;unione dei primi due.&#xA;&#xA;point-to-site-to-point&#xA;smallPoint-To-Site-To-Point/small&#xA;&#xA;Obiettivo:&#xA;L&#39;host del sito A (192.168.10.10) espone un servizio di remote desktop (porta 3389), l&#39;endpoint del sito B (192.168.1.3) espone un servizio web https sulla porta 443. Vogliamo che l&#39;Endpoint A raggiunga il servizio web e che l&#39;Endpoint B acceda al desktop remoto dell&#39;Endpoint A.&#xA;&#xA;point-to-site-gateway&#xA;smallPoint-To-Site: Gateway/small&#xA;&#xA;Se viene configurato il routing sul gateway per indirizzare wireguard, il traffico potrà essere bidirezionale. Non ci sarà bisogno di manipolare i pacchetti perché:&#xA;&#xA;Da Endpoint A a Endpoint B, i pacchetti inoltrati da host B avranno come sorgente l&#39;ip della rete wireguard di Endpoint A.&#xA;Attraverso il gateway, Endpoint B potrà rispondere/contattare direttamente l&#39;indirizzo sorgente wireguard di Endpoint A.&#xA;&#xA;La configurazione di wireguard su Endpoint A e Endpoint B è assimilabile allo scenario 2 con l&#39;impostazione del PersistentKeepAlive_ su Endpoint A&#xA;&#xA;a id=&#34;gtw-configurazione-routing-filtering-host-b&#34;Configurazione routing/filtering Host B/a&#xA;&#xA;Al solito va configurato l&#39;inoltro su Host B da Endpoint A a B e viceversa&#xA;...&#xA;PreUp = ufw route allow in on wg0 out on eth0 to 192.168.1.3 port 443 proto tcp&#xA;PostDown = ufw route delete allow in on wg0 out on eth0 to 192.168.1.3 port 443 proto tcp&#xA;PreUp = ufw route allow in on eth0 out on wg0 from 192.168.1.3 port 3389 proto tcp&#xA;PostDown = ufw route delete allow in on eth0 out on wg0 from 192.168.1.3 port 3389 proto tcp&#xA;...&#xA;a id=&#34;gtw-configurazione-gateway-host-sito-b&#34;Configurazione gateway host del Sito B/a&#xA;&#xA;A parte attivare il solito inoltro su host B, bisognerà avere la possibilità di configurare il routing anche sul nostro router (192.168.1.1), in maniera che Endpoint B, che presumbilmente ha proprio 192.168.1.1 come gateway di default, indirizzando Endpoint A, venga rediretto verso Host B. Ad es.&#xA;ip route add 10.0.0.2/32 via 192.168.1.2 dev eth0&#xA;In alternativa, se non si ha la possibilità/voglia di configurare il router, bisognerà configurare Endpoint B con la rotta statica indicata prima.&#xA;a id=&#34;gtw-test&#34;Test/a&#xA;&#xA;Da Endpoint A (192.168.10.10) possiamo raggiungere il servizio come se fossimo nella lan del sito B, quindi:&#xA;curl https://192.168.1.3&#xA;&#xA;Da Endpoint B (192.168.1.3) raggiungiamo il desktop remoto dell&#39;Endpoint A attraverso la sua interfaccia virtuale (10.0.0.2)&#xA;rdesktop 10.0.0.2&#xA;a id=&#34;gtw-tips&#34;Tips/a&#xA;&#xA;Si potrebbe pensare di aggregare le potenziali rotte statiche considerando l&#39;intera subnet  wireguard per avere un&#39;unica rotta statica su tutti gli host del sito B configurando sul nostro router (oppure su tutti gli host del sito B):&#xA;ip route add 10.0.0.0/24 via 192.168.1.2 dev eth0&#xA;In questo modo, ogni host del sito B può indirizzare vicendevolmente il suo traffico verso endpoint esterni purché le regole wireguard lo consentano (iAllowedIPs/i)&#xA;a id=&#34;differenze-3-approcci&#34;Differenze fra i 3 approcci/a&#xA;&#xA;Primo scenario: l&#39;Endpoint A contatta l&#39;Endpoint B sul suo indirizzo reale ma l&#39;Endpoint B non ha idea di chi siano gli endpoint, lato &#34;punto&#34;, che lo contattano (per effetto del masquerading, le connessioni agli Endpoint B partono da host B).&#xA;&#xA;Secondo scenario: l&#39;Endpoint B non può contattare direttamente gli endpoint lato &#34;punto&#34; ma contatterà l&#39;host B e sarà il DNAT a veicolare i pacchetti agli endpoint lato &#34;punto&#34;.&#xA;&#xA;Terzo scenario: potendo configurare il router (o gli host del sito B), è l&#39;approccio più semplice e garantisce bidirezionalità senza manipolazione dei pacchetti.&#xA;&#xA;small Riferimenti:&#xA;&#xA;https://www.wireguard.com/&#xA;/small&#xA;&#xA;#vpn #openvpn #wireguard #CryptokeyRouting&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/42a8ecf32-5a8865/ppStGSe7U66H/y0DHDOsjleOm5BwuCTL4fqaibuW7yYDX643arMfx.jpg" alt="vpn">
<small><i>Fonte:  Photo by Stefan Coders on <a href="https://www.pexels.com/it-it/foto/uomo-persone-donna-apple-5243610/" rel="nofollow">Pexels.com</a></i></small></p>

<h2 id="a-id-perche-wireguard-perché-wireguard-a"><a id="perche-wireguard">Perché wireguard?</a></h2>
<ul><li>È più semplice di OpenVPN.</li>
<li>Fa parte del kernel dalla versione 5.6 in poi (ci sono anche versioni in userspaces). Vanno installati solo i software di gestione del tunnel</li>
<li>Si basa su uno strato di crittografia all&#39;avanguardia per quel che riguarda efficienza e robustezza</li>
<li>Il suo codice, estremamente compatto, viene revisionato con molta più facilità.</li>
<li>Non si basa su un modello client-server ma P2P</li>
<li>Il traffico è UDP piuttosto che TCP (ci sono modi per fare un wrapping TCP delle connessioni UDP)</li></ul>


<ol><li><a href="#perche-wireguard" rel="nofollow">Perché wireguard?</a></li>
<li><a href="#crittografia-di-wireguard" rel="nofollow">Crittografia di Wireguard</a></li>
<li><a href="#un-po-di-teoria" rel="nofollow">Un po&#39; di teoria</a></li>
<li><a href="#installazione" rel="nofollow">Installazione</a>
<ol><li><a href="#generazione-chiavi" rel="nofollow">Generazione chiavi</a></li></ol></li>
<li><a href="#attivazione-nodo" rel="nofollow">Attivazione del nodo</a>
<ol><li><a href="#pc-laptop" rel="nofollow">PC/Laptop</a></li>
<li><a href="#mobile" rel="nofollow">Mobile</a></li></ol></li>
<li><a href="#debug" rel="nofollow">Debug</a></li>
<li><a href="#topologie" rel="nofollow">Topologie</a></li>
<li><a href="#point-to-site" rel="nofollow">Point-To-Site</a>
<ol><li><a href="#primo-scenario" rel="nofollow">Primo scenario</a>
<ol><li><a href="#pts-configurazione-wireguard-endpoint-a" rel="nofollow">Configurazione wireguard Endpoint A</a></li>
<li><a href="#pts-configurazione-wireguard-host-b" rel="nofollow">Configurazione wireguard Host B</a></li>
<li><a href="#pts-configurazione-routing-filtering-host-b" rel="nofollow">Configurazione routing/filtering Host B</a></li>
<li><a href="#pts-test" rel="nofollow">Test</a></li>
<li><a href="#pts-tips" rel="nofollow">Tips</a></li></ol></li>
<li><a href="#secondo-scenario" rel="nofollow">Secondo scenario</a>
<ol><li><a href="#stp-configurazione-wireguard-endpoint-a" rel="nofollow">Configurazione wireguard Endpoint A</a></li>
<li><a href="#stp-configurazione-wireguard-host-b" rel="nofollow">Configurazione wireguard Host B</a></li>
<li><a href="#stp-configurazione-routing-filtering-host-b" rel="nofollow">Configurazione routing/filtering Host B</a></li>
<li><a href="#stp-test" rel="nofollow">Test</a></li>
<li><a href="#stp-tips" rel="nofollow">Tips</a></li></ol></li>
<li><a href="#terzo-scenario" rel="nofollow">Terzo scenario</a>
<ol><li><a href="#gtw-configurazione-routing-filtering-host-b" rel="nofollow">Configurazione routing/filtering Host B</a></li>
<li><a href="#gtw-configurazione-gateway-host-sito-b" rel="nofollow">Configurazione gateway Sito B</a></li>
<li><a href="#gtw-test" rel="nofollow">Test</a></li>
<li><a href="#gtw-tips" rel="nofollow">Tips</a></li></ol></li>
<li><a href="#differenze-3-approcci" rel="nofollow">Differenze fra i 3 approcci</a></li></ol></li></ol>

<h2 id="a-id-crittografia-di-wireguard-crittografia-di-wireguard-a"><a id="crittografia-di-wireguard">Crittografia di Wireguard</a></h2>

<p>Le primitive crittografiche di Wireguard si basano su:</p>
<ul><li><strong>Curve25519</strong>, per autenticazione e key exchange (ECDH)</li>
<li><strong>ChaCha20</strong> e <strong>Poly1305</strong>, per la cifratura simmetrica con autenticazione (AEAD)</li>
<li><strong>BLAKE2</strong>, come hash crittografico</li>
<li><strong>SipHash-2-4</strong>, come funzione di hash crittografico con chiave (tipo HMAC)</li>
<li><strong>HKDF</strong>, come funzione di derivazione della chiave basata su HMAC</li>
<li><strong>Noise Framework</strong>, è un protocollo crittografico. Stabilisce il modo con cui tutte queste operazioni crittografiche vengono fatte lavorare.</li></ul>

<h2 id="a-id-un-po-di-teoria-un-po-di-teoria-a"><a id="un-po-di-teoria">Un po&#39; di teoria</a></h2>

<p>Wireguard implementa una vpn L3 solo tunneling, incapsulando pacchetti IP all&#39;interno di pacchetti UDP per il trasporto. Ciò implica che funzioni come dhcp, essendo L2, non possono trovare spazio all&#39;interno di wireguard, ergo l&#39;indirizzamento (ip, subnet, dns) deve essere fatto staticamente.</p>

<p>Avendo un&#39;anima P2P, ogni nodo (peer) wireguard è sia client che server. Ciò permette di realizzare topologie anche piuttosto complesse con uno sforzo relativamente ridotto.</p>

<p>Un peer wireguard è composto da due tipi di sezioni:</p>
<ul><li>una sezione “interface”, relativa al peer stesso, contenente:
<ul><li>il proprio IP, nello spazio di indirizzamento privato usato dalla vpn.</li>
<li>una porta, su cui il peer può essere in ascolto per accettare richieste da altri nodi wireguard</li>
<li>la parte privata della chiave asimmetrica con cui decifra e autentica</li></ul></li>
<li>una o più sezioni “peer”, relative ai nodi a cui può connettersi, contenenti:
<ul><li>la parte pubblica della chiave asimmetrica del peer, con cui cifra e verifica</li>
<li>AllowedIPs, che descrive l&#39;ip o le reti da ruotare nel tunnel, a cui è consentito il traffico in entrata e a cui è diretto il traffico in uscita</li>
<li>l&#39;endpoint del peer, necessario solo se altri peer devono avviare connessioni verso di lui</li></ul></li></ul>

<p>I nodi si autenticano a vicenda scambiandosi e convalidando le chiavi pubbliche. Ogni chiave pubblica è associata all&#39;IP di un peer.</p>

<p>Quando un peer deve inviare dei pacchetti, <strong>AllowedIPs</strong> si comporta come una <strong>tabella di instradamento</strong>. Il peer esamina l&#39;<strong>IP di destinazione</strong> di quel pacchetto e lo cerca negli <strong>AllowedIPs</strong> dei suoi peer per capire a chi inviarlo. Se lo trova, ruota il pacchetto nel tunnel, altrimenti no.</p>

<p>Quando si ricevono pacchetti, <strong>AllowedIPs</strong> si comporta come una <strong>lista di controllo degli accessi</strong>. Il peer esamina l&#39;<strong>IP di origine</strong> e se rientra nell&#39;<strong>AllowedIPs</strong> di uno dei suoi peer, accetterà il pacchetto altrimenti lo scarterà.</p>

<p>Per esperienza personale, il 99% degli errori di configurazione su wireguard viene fatto proprio sul campo <strong>AllowedIPs</strong> perché non se ne comprende bene il funzionamento.</p>

<p>Uno degli errori più comuni è quello di definire dei peer in cui gli ip contenuti nei campi AllowedIPs si sovrappongono. In base al funzionamento di wireguard infatti, non posso avere chiavi pubbliche diverse per uno stesso ip perché il peer, pur essendo in grado di ricevere pacchetti, non riuscirebbe a inviarli, non sapendo come ruotarli dovendo scegliere fra più peer.</p>

<h2 id="a-id-installazione-installazione-a"><a id="installazione">Installazione</a></h2>

<p>Come già detto, wireguard è presente di base nel kernel linux. Bisogna installare solo gli strumenti di interfacciamento per la configurazione su ogni host.</p>

<p>Per sistemi debian-based:</p>

<pre><code class="language-bash">apt install wireguard wireguard-tools
</code></pre>

<h2 id="a-id-generazione-chiavi-generazione-chiavi-a"><a id="generazione-chiavi">Generazione chiavi</a></h2>

<p>Per semplicità, suppongo di generare tutte le chiavi che mi occorrono, del server (host B) e del client (Endpoint A) in questo caso. Oltre alle chiavi, userò anche una pre-shared key per il client. Non è obbligatorio ma mi costa zero e aumenta la resistenza post-quantistica.</p>

<pre><code class="language-bash">#server
wg genkey &gt; server_wg.key
wg pubkey &lt; server_wg.key &gt; server_wg.pub

#client
wg genkey &gt; endpoint-a_wg.key
wg pubkey &lt; endpoint-a_wg.key &gt; endpoint-a_wg.pub

# Creazione psk
wg genpsk &gt; endpoint-a.psk
</code></pre>

<h2 id="a-id-attivazione-nodo-attivazione-del-nodo-a"><a id="attivazione-nodo">Attivazione del nodo</a></h2>

<p>Una volta che la configurazione del nodo è pronta, va attivato il servizio se ci troviamo su un pc. Altrimenti bisognerà importare la configurazione sul device.</p>

<h3 id="a-id-pc-laptop-pc-laptop-a"><a id="pc-laptop">PC/Laptop</a></h3>

<p>Sia esso un client o un server, una volta configurato il peer, salva il file file sotto <strong>/etc/wireguard/</strong> col nome dell&#39;interfaccia virtuale che hai scelto, nel mio caso, <strong>wg0.conf</strong></p>

<p><strong>Attivazione/Disattivazione vpn on-demand</strong>:</p>

<pre><code class="language-bash">wg-quick up wg0 #attiva la vpn
wg-quick down wg0 #disattiva la vpn
</code></pre>

<p><strong>Attivazione/Disattivazione vpn come servizio</strong>:</p>

<pre><code class="language-bash">systemctl enable wg-quick@wg0
systemctl start/stop wg-quick@wg0.service
</code></pre>

<h3 id="a-id-mobile-mobile-a"><a id="mobile">Mobile</a></h3>

<p>Se il provisioning delle configurazioni si fa attraverso un pc, per portare facilmente la configurazione su un device mobile, si può generare un qrcode del file (supponiamo sia <em>mobile.conf</em>) e importarlo.</p>

<pre><code class="language-bash"># Installazione qrencode (debian-based)
apt install qrencode

#Crea il qr-code e dallo in pasto a al client
qrencode -t ansiutf8 &lt; mobile.conf
</code></pre>

<h2 id="a-id-debug-debug-a"><a id="debug">Debug</a></h2>

<p>Wireguard è un modulo del kernel e quindi la sua attività viene raccolta dai log del kernel (<strong>/var/log/kern.log</strong> o <strong>/var/log/messages</strong>).</p>

<p>Bisogna verificare che sul kernel si possa abilitare il <code>dynamic_debug_control</code>, controllando se è presente:</p>

<pre><code class="language-bash">ls /sys/kernel/debug/dynamic_debug
</code></pre>

<p>Se lo è, si carica il modulo, si setta il dynamic debug e si potrà esaminare log del kernel ad es. con <code>journalctl -fk</code></p>

<pre><code class="language-bash">modprobe wireguard
echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control
</code></pre>

<p>Potresti dover installare <strong>resolvconf</strong> sul server.</p>

<p>Quando wireguard fa salire l&#39;interfaccia, la registra su <strong>systemd-resolve</strong> attraverso <strong>resolvconf</strong> e se non è installato potrebbe verificarsi un malfunzionamento.</p>

<h2 id="a-id-topologie-topologie-a"><a id="topologie">Topologie</a></h2>

<p>Le principali topologie che possono essere realizzate con wireguard sono:</p>
<ul><li>point-to-point</li>
<li>point-to-site</li>
<li>site-to-site</li>
<li>hub-and-spoke (a stella)</li></ul>

<p>Il canale sicuro fra i nodi wireguard viene creato attraverso le primitive crittografiche di cui sopra, ogni peer viene identificato da una chiave asimmetrica.</p>

<p>Non è necessario approfondire la parte di crittografia per capire come configurare wireguard. Ci fidiamo che faccia un buon lavoro.</p>

<p>Ciò su cui invece vale la pena soffermarsi, è la parte di instradamento, essenziale per l&#39;implementazione delle topologie di cui sopra.</p>

<p>Io mi soffermerò sulla topologia più comune, point-to-site, che permette di unire un endpoint che esegue wireguard, con un altro endpoint situato all&#39;interno di una LAN in cui c&#39;è un host wireguard.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/9e2db7367-e375b7/4wYB1RIZRwIY/ZlVqqUt6vE98pxToDuixqc0cKJdZeeorUu2pqGL7.png" alt="easy-point-to-site"></p>

<p>Tanto per fissare le idee indicherò:</p>
<ul><li>col termine <strong>peer</strong>, uno dei punti logici di una vpn wireguard</li>
<li>col termine <strong>endpoint</strong>, uno dei punti di arrivo della tratta interessata dal tunnel vpn</li>
<li>col termine <strong>host wireguard</strong>, l&#39;host che esegue wireguard.</li></ul>

<p><strong>Osservazioni banali:</strong>
– In una topologia point-to-point, <strong>host wireguard</strong> ed <strong>endpoint</strong> coincidono su entrambi gli estremi della tratta.
– In una topologia point-to-site, <strong>host wireguard</strong> ed <strong>endpoint</strong> coincidono solo sul “point” (l&#39;altro endpoint è dietro ad un host wireguard).
– In una topologia site-to-site, gli endpoint sono sempre dietro gli host wireguard.</p>

<h2 id="a-id-point-to-site-point-to-site-a"><a id="point-to-site">Point-To-Site</a></h2>

<p>Avrò un <strong>Sito A</strong> che comprende il solo endpoint dove non ho la possibilità di gestire routing e filtering e un <strong>Sito B</strong> dove, al contrario, potrò impostare le mie policy di instradamento e filtraggio e dove sarà presente l&#39;host wireguard (indicato come Host B, di solito) che fungerà da server.</p>

<p>La configurazione di un peer si divide in 3 tronconi:</p>
<ul><li>il listener</li>
<li>l&#39;instradamento dei pacchetti fra gli host wireguard e gli endpoint</li>
<li>gli altri peers della VPN Wireguard</li></ul>

<p>Gli scenari che andremo a considerare riguarderanno la direzione delle comunicazioni e le strategie adottate per realizzarle:</p>
<ul><li>da Endpoint A a Endpoint B (punto-sito)</li>
<li>da Endpoint B a Endpoint A (sito-punto)</li>
<li>bidirezionale (punto-sito-punto)</li></ul>

<p>Prendendo uno scenario reale come riferimento, suppongo che la parte “point” sia dietro un NAT che nasconde l&#39;ip privato dell&#39;endpoint e permette solo connessioni già stabilite.
Nella parte “site”, la lan è protetta da un firewall-router-nat che espone il solo ip pubblico.</p>

<p>Nella configurazione di filtering/routing sul firewall (ufw nel mio caso) di Host B, ci sarà da tenere conto delle politiche di inoltro. Per semplificarci la vita si potrebbe abilitare qualunque inoltro di default ma sarebbe un po&#39; pericoloso quindi, a meno di casi particolari, anche gli inoltri saranno filtrati.</p>

<h3 id="a-id-primo-scenario-primo-scenario-a"><a id="primo-scenario">Primo scenario</a></h3>

<p>Nel primo scenario, considererò il caso <strong>punto-sito</strong>, in cui un endpoint (con wireguard) si collega, nella LAN attraverso un <strong>host wireguard</strong>, all&#39;endpoint che eroga un servizio.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/9e2db7367-e375b7/S1wOox3eybrz/wSkUqX0YwaqHqt4DEoCakacEVmzqOuITr1x0NS88.png" alt="point-to-site">
<em><small>Point-To-Site</small></em></p>

<p><strong>Obiettivo</strong>:
L&#39;endpoint del sito B (<strong>192.168.1.3</strong>) ha un servizio web https sulla porta 443, che non è raggiungibile dall&#39;esterno.
Possiamo usare wireguard per permettere all&#39;Endpoint A di raggiungere il servizio sugli endpoint del sito B, per mezzo dell&#39;host wireguard B.
Affinché l&#39;host B possa inoltrare i pacchetti dall&#39;Endpoint A all&#39;Endpoint B si ricorre al <strong>SNAT (MASQUERADING)</strong>.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/c537ce87c-f5971d/6qCphDfGjYeW/7XkgfWnP54UKaFMio7kaHRvThXhmfkzW9Lbnkm4M.png" alt="point-to-site-masquerading">
<em><small>Point-To-Site: Masquerading</small></em></p>

<h4 id="a-id-pts-configurazione-wireguard-endpoint-a-configurazione-wireguard-endpoint-a-a"><a id="pts-configurazione-wireguard-endpoint-a">Configurazione wireguard Endpoint A</a></h4>

<pre><code class="language-bash">[Interface]
Address = 10.0.0.2/32
SaveConfig = true
PrivateKey = &lt;Contenuto di endpoint-a_wg.key&gt;

[Peer]
PublicKey = &lt;Contenuto di server_wg.pub&gt;
PresharedKey = &lt;Contenuto di endpoint-a.psk&gt;
Endpoint = 200.76.182.23:51820
AllowedIPs = 192.168.1.0/24
</code></pre>

<p><strong>Dettagli:</strong></p>
<ul><li><strong>Interface.Address</strong>: IP dell&#39;Endpoint A nella rete virtuale definita da wireguard</li>
<li><strong>Interface.SaveConfig</strong>: se è true, qualunque modifica fatta al file di configurazione prima dello spegnimento dell&#39;interfaccia verrà ignorato.</li>
<li><strong>Interface.PrivateKey</strong>: la chiave privata dell&#39;Endpoint A</li>
<li><strong>Peer.PublicKey</strong>: La chiave pubblica dell&#39;host B wireguard</li>
<li><strong>Peer.PresharedKey</strong>: La preshared key dell&#39;Endpoint A</li>
<li><strong>Peer.Endpoint</strong>: L&#39;ip esposto dell&#39;host B wireguard. Potrebbe trovarsi dietro un firewall/nat ma tanto sappiamo che sul sito B ho libertà d&#39;azione</li>
<li><strong>Peer.AllowedIPs</strong>: Sono le reti che voglio ruotare nel tunnel. Possono essere singoli ip o subnet separati da “ , “.
0.0.0.0/0 equivale a ruotare tutto il traffico del peer nella VPN wireguard. Nel caso in esame, ruoto nel tunnel solo la lan del sito B. Il resto del traffico è al di fuori della VPN wireguard (<strong>split tunnel</strong>)</li></ul>

<h4 id="a-id-pts-configurazione-wireguard-host-b-configurazione-wireguard-host-b-a"><a id="pts-configurazione-wireguard-host-b">Configurazione wireguard Host B</a></h4>

<pre><code class="language-bash">[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = &lt;Contenuto di server_wg.key&gt;

# endpoint A
[Peer]
PublicKey = &lt;Contenuto di endpoint-a_wg.pub&gt;
PresharedKey = &lt;Contenuto di endpoint-a.psk&gt;
AllowedIPs = 10.0.0.2/32
</code></pre>

<p><strong>Dettagli:</strong></p>
<ul><li><strong>Interface.Address</strong>: ip dell&#39;host B nella rete virtuale definita da wireguard</li>
<li><strong>Interface.SaveConfig</strong>: se è true, qualunque modifica fatta al file di configurazione prima dello spegnimento dell&#39;interfaccia verrà ignorato.</li>
<li><strong>Interface.PrivateKey</strong>: la chiave privata dell&#39;host B</li>
<li><strong>Peer.PublicKey</strong>: La chiave pubblica dell&#39;Endpoint A</li>
<li><strong>Peer.PresharedKey</strong>: La preshared key dell&#39;Endpoint A</li>
<li><strong>Peer.AllowedIPs</strong>: Dovendo contattare il singolo endpoint, AllowedIPs definito nel peer è l&#39;ip del peer stesso all&#39;interno della rete virtuale definita da wireguard.</li></ul>

<p>Non poteva essere altrimenti. In una topologia point-to-site,</p>
<ul><li>da point verso site, <em>AllowedIPs</em> della sezione [Peer] del point <strong>indirizza una o più subnet</strong>.</li>
<li>da site verso point, <em>AllowedIPs</em> della sezione [Peer] nell&#39;host wireguard <strong>indirizza puntualmente l&#39;Endpoint A</strong>.</li></ul>

<p>Inoltre, sempre in una topologia point-to-site, è sempre il point ad iniziare la connessione per cui:</p>
<ul><li>nel point:
<ul><li><strong>si deve specificare l&#39;Endpoint</strong> (&lt;fqdn_or_ip:port&gt;) nella sezione [Peer] relativa al server wireguard.</li>
<li><strong>non importa specificare la ListenPort</strong> nella sezione Interface che può essere scelta casualmente, perché l&#39;Endpoint A non verrà mai contattato direttamente</li></ul></li>
<li>nel site:
<ul><li><strong>non importa specificare l&#39;Endpoint</strong> (&lt;fqdn_or_ip:port&gt;) nella sezione [Peer] relativa all&#39;Endpoint A, perché non sarà mai in attesa di una connessione</li>
<li><strong>si deve specificare la ListenPort</strong> nella sezione [Interface] perché le connessioni sono sempre iniziate dagli endpoint verso di lui</li></ul></li></ul>

<h4 id="a-id-pts-configurazione-routing-filtering-host-b-configurazione-routing-filtering-host-b-a"><a id="pts-configurazione-routing-filtering-host-b">Configurazione routing/filtering Host B</a></h4>

<p>Il resto della configurazione non riguarda più wireguard direttamente ma riguarda l&#39;insieme di  policy di routing e filtering da fare sull&#39;host B per permettere ai pacchetti dell&#39;Endpoint A di essere inoltrati all&#39;Endpoint B attraverso l&#39;host B.</p>

<p>Affinchè i pacchetti possano viaggiare dall&#39;Endpoint A all&#39;Endpoint B:</p>
<ul><li>i pacchetti arriveranno all&#39;host B sull&#39;interfaccia virtuale della VPN (wg0)</li>
<li>poi verranno inoltrati dall&#39;interfaccia virtuale della vpn (wg0) all&#39;interfaccia reale di host B (eth0),</li>
<li>prima di essere inviati a Endpoint B, una regola di post-routing riscriverà i pacchetti cambiandone l&#39;ip sorgente in modo che risultino inviati da host B piuttosto che da Endpoint A, così da permettere ad Endpoint B di rispondere.</li></ul>

<p>Quindi:</p>
<ul><li>va configurato un inoltro (eventualmente filtrato) dall&#39;interfaccia virtuale wireguard (wg0) a quella reale dell&#39;host B (eth0)</li>
<li>deve essere configurato il SNAT affinché l&#39;Endpoint B possa <strong>rispondere</strong> all&#39;Endpoint A</li></ul>

<pre><code class="language-bash"># abilita il forward
sysctl -w net.ipv4.ip_forward=1
# inoltra tutto il traffico in arrivo da wg0 verso il solo Endpoint B
ufw route allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443;
# masquerading
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
</code></pre>

<p><strong>N.B.</strong> potrei ancora raffinare queste regole ricorrendo alla tabella <strong>Mangle</strong> per marcare i pacchetti ai quali applicare il masquerading.</p>

<p>Questi comandi possono far parte della configurazione. Nella sezione [Interface] si possono usare i costrutti <strong>PreUp</strong>, <strong>PreDown</strong>, <strong>PostUp</strong> e <strong>PostDown</strong> per rendere dinamici alcuni passi di configurazione prima/dopo l&#39;apertura/chiusura del tunnel.
E così, la configurazione del server diventa:</p>

<pre><code class="language-bash">[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = &lt;Contenuto di server_wg.key&gt;

# IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
PreUp = ufw route allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443
PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp to 192.168.1.3 port 443

# IP masquerading
PreUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# IP filtering
PreUp = ufw allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;
PostDown = ufw delete allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;

# endpoint A
[Peer]
PublicKey = &lt;Contenuto di endpoint.a_wg.pub&gt;
PresharedKey = &lt;Contenuto di endpoint-a.psk&gt;
AllowedIPs = 10.0.0.2/32
</code></pre>

<h4 id="a-id-pts-test-test-a"><a id="pts-test">Test</a></h4>

<p>Da Endpoint A (192.168.10.10) possiamo raggiungere il servizio come se fossimo nella lan del sito B, quindi:</p>

<pre><code class="language-bash">curl https://192.168.1.3
</code></pre>

<p>risponderà al browsing.</p>

<h4 id="a-id-pts-tips-tips-a"><a id="pts-tips">Tips</a></h4>

<p>La combinazione <em>AllowedIPs / routing</em> è la chiave per gestire qualunque instradamento.
Nell&#39;esempio visto finora abbiamo fatto in modo che:</p>
<ul><li>l&#39;Endpoint A ruotasse nella VPN wireguard solo la subnet relativa al sito B, 192.168.1.0/24, facendo split tunnel per il resto.</li>
<li>l&#39;host B avesse delle regole di inoltro per l&#39;Endpoint B per i soli pacchetti destinati al servizio che eroga, https. Qualuque altro host del sito B non può essere raggiunto.</li></ul>

<p>In questo modello, qualunque altro endpoint abilitato alla VPN wireguard potrebbe accedere al servizio dell&#39;Endpoint B.
Vale la pena dare un&#39;occhiata ad un altro paio di combinazioni che si trovano agli opposti del nostro esempio.
In un caso, ruoteremo tutto il traffico verso la vpn, in un altro consentiremo solo a determinati peer, non a tutti, di fruire di determinati servizi.</p>

<p><strong>1. Inoltro di tutto il traffico nella vpn</strong>
In questo modo, l&#39;Endpoint A lavora come se facesse parte della lan del sito B. È una modalità totalmente anonimizzante. Da usare solo con  dispositivi trusted perché un eventuale traffico malevolo verrebbe ruotato nel tunnel e risulterebbe proveniente dal sito B</p>

<p>Su Endpoint A:</p>

<pre><code class="language-bash">...
AllowedIPs = 0.0.0.0/0
...
</code></pre>

<p>Su host B:</p>

<pre><code class="language-bash">...
ufw route allow in on wg0 out on eth0;`
...
</code></pre>

<p><strong>2. Indirizzamento puntuale su servizi specifici</strong>
È il caso in cui alcuni peer debbano raggiungere <strong>solo</strong> determinati servizi e non altri. Supponiamo di avere altri due endpoint, Endpoint A<sub>1</sub> e Endpoint A<sub>2</sub>.</p>

<p>Su Endpoint A<sub>1</sub> e A<sub>2</sub> (in realtà AllowedIPs potrebbe essere puntuale):</p>

<pre><code class="language-bash">...
AllowedIPs = 192.168.1.0/24
...
</code></pre>

<pre><code class="language-bash">...
PreUp = ufw route allow in on wg0 out on eth0 proto tcp from 10.0.0.3 to 192.168.1.4 port 3306
PreUp = ufw route allow in on wg0 out on eth0 proto tcp from 10.0.0.4 to 192.168.1.5 port 22
PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp from 10.0.0.3 to 192.168.1.4 port 3306
PostDown = ufw route delete allow in on wg0 out on eth0 proto tcp from 10.0.0.4 to 192.168.1.5 port 22
...
</code></pre>

<h3 id="a-id-secondo-scenario-secondo-scenario-a"><a id="secondo-scenario">Secondo scenario</a></h3>

<p>Nel secondo scenario, ribalterò il punto di vista e prenderò in esame il caso in cui sia un host del sito B a contattare un endpoint esterno con wireguard (sito-punto).
Non il classico scenario road-warrior in cui un endpoint deve raggiungere la rete aziendale o domestica, ma il suo opposto.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/9e2db7367-e375b7/1eWNsrbMjsVI/FByQcZ9tq4Ekl2LRtujHv64MNvKe6rTsgYrF6An9.png" alt="site-to-point">
<em><small>Site-To-Point</small></em></p>

<p><strong>Obiettivo</strong>:
L&#39;host del sito A (192.168.10.10) ha un servizio web https sulla porta 1443, che non è raggiungibile dall&#39;esterno ma vogliamo che lo sia dal sito B.
Con wireguard, possiamo usare l&#39;interfaccia virtuale per esporre il servizio su 10.0.0.2, verso gli endpoint del sito B, per mezzo dell&#39;host wireguard B.
Affinché l&#39;host B possa inoltrare i pacchetti dall&#39;Endpoint B all&#39;Endpoint A si ricorre al <strong>DNAT (PORT FORWARDING)</strong>.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/c537ce87c-f5971d/hN8OLKexz4gJ/nu9txh6VlDxnkMctuOGqgfJJrtI9csJLwpSoKYju.png" alt="point-to-site-port-forwarding">
<em><small>Site-To-Point: Port-Forwarding</small></em></p>

<p>La configurazione di wireguard su host B rimane sostanzialmente identica rispetto a prima.
A cambiare sarà soprattutto la parte di filtering e routing.</p>

<h4 id="a-id-stp-configurazione-wireguard-endpoint-a-configurazione-wireguard-endpoint-a-a"><a id="stp-configurazione-wireguard-endpoint-a">Configurazione wireguard Endpoint A</a></h4>

<pre><code class="language-bash">[Interface]
Address = 10.0.0.2/32
SaveConfig = true
PrivateKey = &lt;Contenuto di endpoint-a_wg.key&gt;

[Peer]
PublicKey = &lt;Contenuto di server_wg.pub&gt;
PresharedKey = &lt;Contenuto di endpoint-a.psk&gt;
Endpoint = 200.76.182.23:51820
AllowedIPs = 192.168.1.0/24
PersistentKeepalive = 25
</code></pre>

<p>Su Endpoint A c&#39;è una piccola modifica.</p>

<p><strong>Dettagli:</strong></p>
<ul><li><strong>PersistentKeepalive</strong>: Il NAT davanti all&#39;Endpoint A potrebbe troncare la connessione dopo un po&#39; visto che non è lui ad avviarla. Dal momento che è Endpoint A a dare servizio, si ricorre al keepalive per mantenere la connessione persistente.</li></ul>

<h4 id="a-id-stp-configurazione-wireguard-host-b-configurazione-wireguard-host-b-a"><a id="stp-configurazione-wireguard-host-b">Configurazione wireguard Host B</a></h4>

<pre><code class="language-bash">[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = &lt;Contenuto di server_wg.key&gt;

# endpoint A
[Peer]
PublicKey = &lt;Contenuto di endpoint-a_wg.pub&gt;
PresharedKey = &lt;Contenuto di endpoint-a.psk&gt;
AllowedIPs = 10.0.0.2/32
</code></pre>

<p>La configurazione di Host B rimane sostanzialmente invariata.</p>

<h4 id="a-id-stp-configurazione-routing-filtering-host-b-configurazione-routing-filtering-host-b-a"><a id="stp-configurazione-routing-filtering-host-b">Configurazione routing/filtering Host B</a></h4>

<p>Affinchè i pacchetti possano viaggiare dall&#39;Endpoint B all&#39;Endpoint A:</p>
<ul><li>i pacchetti arriveranno sull&#39;interfaccia reale di host B (eth0),</li>
<li>una regola di pre-routing riscriverà i pacchetti cambiandone l&#39;ip di destinazione con quello virtuale dell&#39;Endpoint A</li>
<li>poi verranno inoltrati dall&#39;interfaccia reale di host B (eth0) all&#39;interfaccia virtuale della VPN (wg0) che li recapiterà ad Endpoint A</li></ul>

<p>Quindi</p>
<ul><li>va configurato un inoltro (eventualmente filtrato) dall&#39;interfaccia reale dell&#39;host B (eth0) a quella virtuale wireguard (wg0)</li>
<li>deve essere configurato il DNAT affinché l&#39;Endpoint B possa <strong>contattare</strong> l&#39;Endpoint A.</li></ul>

<pre><code class="language-bash">...
# IP forwarding
# abilita il forward
PreUp = sysctl -w net.ipv4.ip_forward=1
# inoltra tutto il traffico in arrivo da eth0 verso l&#39;Endpoint A
PreUp = ufw route allow in on eth0 out on wg0 proto tcp to 10.0.0.2 port 443
PostDown = ufw route delete allow in on eth0 out on wg0 proto tcp to 10.0.0.2 port 443

# IP port forwarding
# inoltro della porta 1443 dall&#39;interfaccia lan verso la porta 443 dell&#39;Endpoint A
PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.2:1443
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.2:1443

# IP filtering
PreUp = ufw allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;
PostDown = ufw delete allow in on eth0 proto udp from 0.0.0.0/0 to 192.168.1.2 port 51820;
...
</code></pre>

<h4 id="a-id-stp-test-test-a"><a id="stp-test">Test</a></h4>

<p>Da Endpoint B (192.168.1.3) possiamo raggiungere il servizio sull&#39;interfaccia virtuale dell&#39;Endpoint A passando dalla porta dell&#39;host B, quindi:</p>

<pre><code class="language-bash">curl https://192.168.1.2
</code></pre>

<p>risponderà al browsing.</p>

<h4 id="a-id-stp-tips-tips-a"><a id="stp-tips">Tips</a></h4>

<p>In questa rappresentazione, ogni host del sito B viene indirizzato solo verso la vpn wireguard.
L&#39;host B inoltra:</p>
<ul><li>la porta 443 di ogni host del sito B verso l&#39;Endpoint A</li>
<li>tutto il traffico della lan verso la vpn wireguard.</li></ul>

<p>Se volessimo che solo determinati endpoint del sito B potessero inoltrare il loro traffico, si dovrebbero rendere le regole di inoltro più puntuali.
Supponiamo che Endpoint A (<strong>10.0.0.2</strong>) esponga un servzio <i>httpd</i> sulla porta <strong>10080</strong> e vogliamo che solo gli host <strong>192.168.1.9-192.168.1.14</strong> del sito B lo possano raggiungere sulla canonica porta <strong>80</strong>.</p>

<p><strong>Port Forwarding di un solo endpoint</strong></p>

<pre><code class="language-bash">ufw route allow from 192.168.1.4 to 10.0.0.2 port 10080 proto tcp
iptables -t nat -A PREROUTING -s 192.168.1.4 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:10080
</code></pre>

<p><strong>Port Forwarding di una subnet</strong></p>

<pre><code class="language-bash">ufw route allow from 192.168.1.8/29 to 10.0.0.2 port 10080 proto tcp
iptables -t nat -A PREROUTING -s 192.168.1.9-192.168.1.14 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:10080
</code></pre>

<h3 id="a-id-terzo-scenario-terzo-scenario-a"><a id="terzo-scenario">Terzo scenario</a></h3>

<p>Il terzo scenario può essere considerato un&#39;unione dei primi due.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/9e2db7367-e375b7/Tr8CQXQYASs1/uMnrW3IOWLPfQa2GH9HLDFSRarSgmIrs0RqOQvVH.png" alt="point-to-site-to-point">
<em><small>Point-To-Site-To-Point</small></em></p>

<p><strong>Obiettivo</strong>:
L&#39;host del sito A (<strong>192.168.10.10</strong>) espone un servizio di remote desktop (porta 3389), l&#39;endpoint del sito B (<strong>192.168.1.3</strong>) espone un servizio web https sulla porta 443. Vogliamo che l&#39;Endpoint A raggiunga il servizio web e che l&#39;Endpoint B acceda al desktop remoto dell&#39;Endpoint A.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/c537ce87c-f5971d/LRMwMdT8xPWR/SMZh2fF9ityxKdDatlJvoz9i0s1qHArvLGusPMhL.png" alt="point-to-site-gateway">
<em><small>Point-To-Site: Gateway</small></em></p>

<p>Se viene configurato il routing sul <strong>gateway</strong> per indirizzare wireguard, il traffico potrà essere bidirezionale. Non ci sarà bisogno di manipolare i pacchetti perché:</p>
<ol><li>Da Endpoint A a Endpoint B, i pacchetti inoltrati da host B avranno come sorgente l&#39;ip della rete wireguard di Endpoint A.</li>
<li>Attraverso il gateway, Endpoint B potrà rispondere/contattare direttamente l&#39;indirizzo sorgente wireguard di Endpoint A.</li></ol>

<p>La configurazione di wireguard su Endpoint A e Endpoint B è assimilabile allo scenario 2 con l&#39;impostazione del <em>PersistentKeepAlive</em> su Endpoint A</p>

<h4 id="a-id-gtw-configurazione-routing-filtering-host-b-configurazione-routing-filtering-host-b-a"><a id="gtw-configurazione-routing-filtering-host-b">Configurazione routing/filtering Host B</a></h4>

<p>Al solito va configurato l&#39;inoltro su Host B da Endpoint A a B e viceversa</p>

<pre><code class="language-bash">...
PreUp = ufw route allow in on wg0 out on eth0 to 192.168.1.3 port 443 proto tcp
PostDown = ufw route delete allow in on wg0 out on eth0 to 192.168.1.3 port 443 proto tcp
PreUp = ufw route allow in on eth0 out on wg0 from 192.168.1.3 port 3389 proto tcp
PostDown = ufw route delete allow in on eth0 out on wg0 from 192.168.1.3 port 3389 proto tcp
...
</code></pre>

<h4 id="a-id-gtw-configurazione-gateway-host-sito-b-configurazione-gateway-host-del-sito-b-a"><a id="gtw-configurazione-gateway-host-sito-b">Configurazione gateway host del Sito B</a></h4>

<p>A parte attivare il solito inoltro su host B, bisognerà avere la possibilità di configurare il routing anche sul nostro router (<strong>192.168.1.1</strong>), in maniera che Endpoint B, che presumbilmente ha proprio <strong>192.168.1.1</strong> come gateway di default, indirizzando Endpoint A, venga rediretto verso Host B. Ad es.</p>

<pre><code class="language-bash">ip route add 10.0.0.2/32 via 192.168.1.2 dev eth0
</code></pre>

<p>In alternativa, se non si ha la possibilità/voglia di configurare il router, bisognerà configurare Endpoint B con la rotta statica indicata prima.</p>

<h4 id="a-id-gtw-test-test-a"><a id="gtw-test">Test</a></h4>

<p>Da Endpoint A (<strong>192.168.10.10</strong>) possiamo raggiungere il servizio come se fossimo nella lan del sito B, quindi:</p>

<pre><code class="language-bash">curl https://192.168.1.3
</code></pre>

<p>Da Endpoint B (<strong>192.168.1.3</strong>) raggiungiamo il desktop remoto dell&#39;Endpoint A attraverso la sua interfaccia virtuale (<strong>10.0.0.2</strong>)</p>

<pre><code class="language-bash">rdesktop 10.0.0.2
</code></pre>

<h4 id="a-id-gtw-tips-tips-a"><a id="gtw-tips">Tips</a></h4>

<p>Si potrebbe pensare di aggregare le potenziali rotte statiche considerando l&#39;intera subnet  wireguard per avere un&#39;unica rotta statica su tutti gli host del sito B configurando sul nostro router (oppure su <strong>tutti</strong> gli host del sito B):</p>

<pre><code class="language-bash">ip route add 10.0.0.0/24 via 192.168.1.2 dev eth0
</code></pre>

<p>In questo modo, ogni host del sito B può indirizzare vicendevolmente il suo traffico verso endpoint esterni purché le regole wireguard lo consentano (<i>AllowedIPs</i>)</p>

<h3 id="a-id-differenze-3-approcci-differenze-fra-i-3-approcci-a"><a id="differenze-3-approcci">Differenze fra i 3 approcci</a></h3>

<p><strong>Primo scenario</strong>: l&#39;Endpoint A contatta l&#39;Endpoint B sul suo indirizzo reale ma l&#39;Endpoint B non ha idea di chi siano gli endpoint, lato “punto”, che lo contattano (per effetto del masquerading, le connessioni agli Endpoint B partono da host B).</p>

<p><strong>Secondo scenario</strong>: l&#39;Endpoint B non può contattare direttamente gli endpoint lato “punto” ma contatterà l&#39;host B e sarà il DNAT a veicolare i pacchetti agli endpoint lato “punto”.</p>

<p><strong>Terzo scenario</strong>: potendo configurare il router (o gli host del sito B), è l&#39;approccio più semplice e garantisce bidirezionalità senza manipolazione dei pacchetti.</p>

<p><small> <strong>Riferimenti</strong>:</p>
<ul><li><a href="https://www.wireguard.com/" rel="nofollow">https://www.wireguard.com/</a>
</small></li></ul>

<p><a href="/aytin/tag:vpn" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">vpn</span></a> <a href="/aytin/tag:openvpn" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openvpn</span></a> <a href="/aytin/tag:wireguard" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">wireguard</span></a> <a href="/aytin/tag:CryptokeyRouting" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">CryptokeyRouting</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/vpn-con-wireguard-semplice-e-veloce</guid>
      <pubDate>Thu, 16 Mar 2023 15:02:34 +0000</pubDate>
    </item>
  </channel>
</rss>