<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>NGINX &amp;mdash; Verolinux</title>
    <link>https://verolinux.com/tag:NGINX</link>
    <description>Esperimenti di software libero</description>
    <pubDate>Wed, 12 Aug 2026 21:08:45 +0200</pubDate>
    <item>
      <title>NGINX request-time name resolution</title>
      <link>https://verolinux.com/nginx-request-time-name-resolution</link>
      <description>&lt;![CDATA[Qualche giorno fa, mi pare fosse il primo di agosto, mi sono accorto che questo sito web era down, insieme a tutte le altre applicazioni web installate sullo stesso server. Ho pensato che fosse andato offline l&#39;intero VPS, invece era UP e perfettamente raggiungibile via ssh.&#xA;&#xA;Una volta collegatomi alla shell, mi sono reso conto che il problema era dovuto al server web, #NGINX, fermo più o meno dalle 6.30 del mattino:&#xA;!--more--&#xA;$ systemctl status nginx&#xA;× nginx.service - nginx - high performance web server&#xA;     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)&#xA;     Active: failed (Result: exit-code) since Sat 2026-08-01 06:32:54 CEST; 3h 30min ago&#xA;   Duration: 4d 17min 4.105s&#xA;       Docs: https://nginx.org/en/docs/&#xA;    Process: 276634 ExecStart=/usr/sbin/nginx -c ${CONFFILE} (code=exited, status=1/FAILURE)&#xA;        CPU: 10ms&#xA;&#xA;ago 01 06:32:54 vps-1 nginx[276634]: nginx: [emerg] host not found in upstream &#34;ap.ghost.org&#34; in /etc/nginx/sites-enabled/verolinux.com.conf:22&#xA;&#xA;Il problema&#xA;&#xA;Cos&#39;era successo alle 6? Un attacco hacker aveva compromesso il mio sistema e tutti i miei dati si erano volatilizzati? No!&#xA;&#xA;La causa scatenante è stato l&#39;aggiornamento automatico di alcuni pacchetti di sistema, in particolare libssl, avvenuto pochi secondi prima:&#xA;&#xA;Start-Date: 2026-08-01  06:32:51&#xA;Commandline: /usr/bin/unattended-upgrade&#xA;Upgrade: libssl3t64:amd64 (3.0.13-0ubuntu3.11, 3.0.13-0ubuntu3.12), openssl:amd64 (3.0.13-0ubuntu3.11, 3.0.13-0ubuntu3.12)&#xA;End-Date: 2026-08-01  06:32:53&#xA;&#xA;Infatti, NGINX dipende direttamente da questo pacchetto e, quando viene aggiornato, c&#39;è un sistema che si accorge della presenza della nuova versione e che fa ripartire il servizio:&#xA;&#xA;$ apt-cache show nginx&#xA;Package: nginx&#xA;Version: 1.31.3-1~noble&#xA;Architecture: amd64&#xA;Maintainer: NGINX Packaging nginx-packaging@f5.com&#xA;Installed-Size: 3851&#xA;Depends: libc6 (  = 2.34), libcrypt1 (  = 1:4.1.0), libpcre2-8-0 (  = 10.22), libssl3t64 (  = 3.0.0), zlib1g (  = 1:1.1.4), lsb-base (  = 3.0-6)&#xA;&#xA;Il restart di NGINX è una cosa assolutamente normale, ma allora perché è fallito?&#xA;&#xA;All&#39;epoca dei fatti il mio sito girava su #Ghost, che usa delle API per l&#39;implementazione del protocollo ActivityPub. Per farlo, utilizza l&#39;endpoint ap.ghost.org e il mio server, per qualche strano motivo, in quel preciso istante non è riuscito a risolverlo su un indirizzo IP.&#xA;&#xA;  nginx, di default, risolve i nomi a dominio configurati in un upstream o in una proxypass al momento dell&#39;avvio (o del reload). Se la risoluzione fallisce in quel preciso istante, nginx va in errore emerg e non si avvia. Questo comportamento è intenzionale e progettato per garantire che tutte le dipendenze siano raggiungibili, ma può diventare un problema quando la risoluzione DNS di un dominio esterno è temporaneamente instabile.&#xA;&#xA;La soluzione&#xA;&#xA;Per evitare che un blip DNS di un dominio esterno blocchi l&#39;intero server web, si può modificare la configurazione di nginx in modo che risolva il dominio ap.ghost.org al momento della richiesta (request-time) invece che all&#39;avvio.&#xA;&#xA;Per farlo, è sufficiente specificare i resolver all&#39;interno della configurazione del virtual host del sito e sostituire l&#39;hostname con una variabile da utilizzare nelle direttive proxypass, come nell&#39;esempio seguente:&#xA;&#xA;resolver 127.0.0.53 1.1.1.1 valid=300s; # &lt;-- definizione del resolver e del TTL&#xA;set $apupstream ap.ghost.org;  # &lt;-- definizione della variabile&#xA;&#xA;location ~ /.ghost/activitypub/* {&#xA;    proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;    proxysetheader X-Forwarded-Proto $scheme;&#xA;    proxysetheader X-Real-IP $remoteaddr;&#xA;    proxysetheader Host $httphost;&#xA;    addheader X-Content-Type-Options $headercontenttypeoptions;&#xA;    proxysslservername on;&#xA;    proxypass https://$apupstream;  # &lt;-- direttiva proxypass&#xA;}&#xA;&#xA;location ~ /.well-known/(webfinger|nodeinfo) {&#xA;    proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;    proxysetheader X-Forwarded-Proto $scheme;&#xA;    proxysetheader X-Real-IP $remoteaddr;&#xA;    proxysetheader Host $httphost;&#xA;    addheader X-Content-Type-Options $headercontenttypeoptions;&#xA;    proxysslservername on;&#xA;    proxypass https://$apupstream;  # &lt;-- direttiva proxy_pass&#xA;}&#xA;&#xA;Con questa configurazione, anche se un hostname non è risolvibile al momento dell&#39;avvio/riavvio di NGINX, il server web parte ugualmente perché la risoluzione vera e propria viene eseguita solo nel momento in cui arriva una richiesta da un client. Come resolver viene indicato quello locale (127.0.0.53) e uno remoto. Il TTL impostato a 300 secondi fa in modo che la risoluzione venga tenuta in cache per 5 minuti dopo una singola richiesta, in modo da non rallentare la risposta in caso di richieste multiple in un dato intervallo di tempo.&#xA;&#xA;Qualora la risoluzione al tempo della richiesta, per qualsiasi motivo, dovesse fallire, NGINX continuerà ad utilizzare il valore della cache.]]&gt;</description>
      <content:encoded><![CDATA[<p>Qualche giorno fa, mi pare fosse il primo di agosto, mi sono accorto che questo sito web era down, insieme a tutte le altre applicazioni web installate sullo stesso server. Ho pensato che fosse andato <em>offline</em> l&#39;intero VPS, invece era UP e perfettamente raggiungibile via ssh.</p>

<p>Una volta collegatomi alla shell, mi sono reso conto che il problema era dovuto al server web, <a href="https://verolinux.com/tag:NGINX" class="hashtag"><span>#</span><span class="p-category">NGINX</span></a>, fermo più o meno dalle 6.30 del mattino:
</p>

<pre><code class="language-shell">$ systemctl status nginx
× nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Sat 2026-08-01 06:32:54 CEST; 3h 30min ago
   Duration: 4d 17min 4.105s
       Docs: https://nginx.org/en/docs/
    Process: 276634 ExecStart=/usr/sbin/nginx -c ${CONFFILE} (code=exited, status=1/FAILURE)
        CPU: 10ms

ago 01 06:32:54 vps-1 nginx[276634]: nginx: [emerg] host not found in upstream &#34;ap.ghost.org&#34; in /etc/nginx/sites-enabled/verolinux.com.conf:22
</code></pre>

<h2 id="il-problema">Il problema</h2>

<p>Cos&#39;era successo alle 6? Un attacco hacker aveva compromesso il mio sistema e tutti i miei dati si erano volatilizzati? No!</p>

<p>La causa scatenante è stato l&#39;aggiornamento automatico di alcuni pacchetti di sistema, in particolare libssl, avvenuto pochi secondi prima:</p>

<pre><code>Start-Date: 2026-08-01  06:32:51
Commandline: /usr/bin/unattended-upgrade
Upgrade: libssl3t64:amd64 (3.0.13-0ubuntu3.11, 3.0.13-0ubuntu3.12), openssl:amd64 (3.0.13-0ubuntu3.11, 3.0.13-0ubuntu3.12)
End-Date: 2026-08-01  06:32:53
</code></pre>

<p>Infatti, NGINX dipende direttamente da questo pacchetto e, quando viene aggiornato, c&#39;è un sistema che si accorge della presenza della nuova versione e che fa ripartire il servizio:</p>

<pre><code class="language-shell">$ apt-cache show nginx
Package: nginx
Version: 1.31.3-1~noble
Architecture: amd64
Maintainer: NGINX Packaging &lt;nginx-packaging@f5.com&gt;
Installed-Size: 3851
Depends: libc6 (&gt;= 2.34), libcrypt1 (&gt;= 1:4.1.0), libpcre2-8-0 (&gt;= 10.22), libssl3t64 (&gt;= 3.0.0), zlib1g (&gt;= 1:1.1.4), lsb-base (&gt;= 3.0-6)
</code></pre>

<p>Il restart di NGINX è una cosa assolutamente normale, ma allora perché è fallito?</p>

<p>All&#39;epoca dei fatti il mio sito girava su <a href="https://verolinux.com/tag:Ghost" class="hashtag"><span>#</span><span class="p-category">Ghost</span></a>, che usa delle API per l&#39;implementazione del protocollo ActivityPub. Per farlo, utilizza l&#39;endpoint <code>ap.ghost.org</code> e il mio server, per qualche strano motivo, in quel preciso istante non è riuscito a risolverlo su un indirizzo IP.</p>

<blockquote><p>nginx, di default, risolve i nomi a dominio configurati in un <code>upstream</code> o in una <code>proxy_pass</code> al momento dell&#39;avvio (o del reload). Se la risoluzione fallisce in quel preciso istante, nginx va in errore <code>emerg</code> e non si avvia. Questo comportamento è intenzionale e progettato per garantire che tutte le dipendenze siano raggiungibili, ma può diventare un problema quando la risoluzione DNS di un dominio esterno è temporaneamente instabile.</p></blockquote>

<h2 id="la-soluzione">La soluzione</h2>

<p>Per evitare che un <em>blip</em> DNS di un dominio esterno blocchi l&#39;intero server web, si può modificare la configurazione di nginx in modo che risolva il dominio ap.ghost.org al momento della richiesta (request-time) invece che all&#39;avvio.</p>

<p>Per farlo, è sufficiente specificare i resolver all&#39;interno della configurazione del virtual host del sito e sostituire l&#39;hostname con una variabile da utilizzare nelle direttive <code>proxy_pass</code>, come nell&#39;esempio seguente:</p>

<pre><code class="language-nginx">resolver 127.0.0.53 1.1.1.1 valid=300s; # &lt;-- definizione del resolver e del TTL
set $ap_upstream ap.ghost.org;  # &lt;-- definizione della variabile

location ~ /.ghost/activitypub/* {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    add_header X-Content-Type-Options $header_content_type_options;
    proxy_ssl_server_name on;
    proxy_pass https://$ap_upstream;  # &lt;-- direttiva proxy_pass
}

location ~ /.well-known/(webfinger|nodeinfo) {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    add_header X-Content-Type-Options $header_content_type_options;
    proxy_ssl_server_name on;
    proxy_pass https://$ap_upstream;  # &lt;-- direttiva proxy_pass
}
</code></pre>

<p>Con questa configurazione, anche se un hostname non è risolvibile al momento dell&#39;avvio/riavvio di NGINX, il server web parte ugualmente perché la risoluzione vera e propria viene eseguita solo nel momento in cui arriva una richiesta da un client. Come resolver viene indicato quello locale (127.0.0.53) e uno remoto. Il TTL impostato a 300 secondi fa in modo che la risoluzione venga tenuta in cache per 5 minuti dopo una singola richiesta, in modo da non rallentare la risposta in caso di richieste multiple in un dato intervallo di tempo.</p>

<p>Qualora la risoluzione al tempo della richiesta, per qualsiasi motivo, dovesse fallire, NGINX continuerà ad utilizzare il valore della cache.</p>
]]></content:encoded>
      <guid>https://verolinux.com/nginx-request-time-name-resolution</guid>
      <pubDate>Wed, 12 Aug 2026 08:13:41 +0200</pubDate>
    </item>
  </channel>
</rss>