<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Firewall on inetshell</title><link>https://inet.sh/es/tags/firewall/</link><description>Recent content in Firewall on inetshell</description><generator>Hugo</generator><language>es</language><lastBuildDate>Mon, 05 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/es/tags/firewall/index.xml" rel="self" type="application/rss+xml"/><item><title>OPNsense: port-forward inalcanzable desde la misma subred WAN (reply-to)</title><link>https://inet.sh/es/posts/opnsense/reply-to-misma-subred-wan/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/es/posts/opnsense/reply-to-misma-subred-wan/</guid><description>Por qué un port-forward de OPNsense funciona desde internet pero da timeout desde una IP de la misma /24 que la WAN, y cómo lo arregla «Disable reply-to on WAN rules».</description><content:encoded><![CDATA[<h2 id="en-corto">En corto</h2>
<p><strong>Firewall → Settings → Advanced → Disable reply-to on WAN rules</strong> → marcar → <strong>Save</strong> → <strong>Apply</strong>.</p>
<p>Síntoma: un port-forward o una regla WAN responde desde cualquier IP de internet, pero desde un equipo que vive en <strong>la misma subred que la WAN del firewall</strong> todo da timeout (SSH, HTTPS, incluso <code>ping</code>), aunque la regla diga <code>from any</code>.</p>
<p>Con una sola WAN es seguro: el firewall deja de forzar el regreso por el gateway y vuelve a usar su tabla de rutas.</p>
<h2 id="el-escenario">El escenario</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">                203.0.113.0/24  (mismo segmento L2)
</span></span><span class="line"><span class="cl">   ┌────────────────────┬────────────────────┬────────────────────┐
</span></span><span class="line"><span class="cl">   │                    │                    │                    │
</span></span><span class="line"><span class="cl"> gateway             fw01 (OPNsense)      vecino               internet
</span></span><span class="line"><span class="cl"> 203.0.113.1         WAN 203.0.113.40     203.0.113.50         (vía gateway)
</span></span><span class="line"><span class="cl">                        │ rdr :22 → 192.168.1.10
</span></span><span class="line"><span class="cl">                        ▼
</span></span><span class="line"><span class="cl">                     servidor LAN
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>Desde internet: <code>ssh -p 22 203.0.113.40</code> entra al servidor de la LAN. Bien.</li>
<li>Desde <code>vecino</code> (203.0.113.50): timeout en todos los puertos.</li>
</ul>
<h2 id="qué-hace-reply-to">Qué hace <code>reply-to</code></h2>
<p>OPNsense genera las reglas de las interfaces tipo WAN (las que tienen gateway) con <code>reply-to</code> apuntando a ese gateway:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">pfctl -sr <span class="p">|</span> grep reply-to
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">pass in quick on vtnet0 reply-to (vtnet0 203.0.113.1) inet proto tcp from any to 192.168.1.10 port = ssh flags S/SA keep state
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>reply-to</code> es una opción de <strong>pf</strong>. Cuando un paquete entra y crea un estado, pf guarda en ese estado que <strong>todas las respuestas</strong> salgan por <code>vtnet0</code> hacia <code>203.0.113.1</code>. Esas respuestas no pasan por la tabla de rutas: pf decide el siguiente salto por su cuenta.</p>
<p>Existe por <strong>multi-WAN</strong>. Si tienes dos proveedores y un cliente entra por la WAN2, la respuesta tiene que salir por la WAN2. Si sale por la ruta por defecto (WAN1), lleva una IP de origen que el proveedor 1 no reconoce y se pierde. <code>reply-to</code> garantiza el regreso simétrico sin tener que pensar en rutas.</p>
<h2 id="por-qué-rompe-a-los-vecinos">Por qué rompe a los vecinos</h2>
<p>Para un cliente en internet, «responder al gateway» es justo lo que haría la tabla de rutas, así que no se nota nada.</p>
<p>Para el vecino es distinto. Su IP (203.0.113.50) está en una <strong>red conectada</strong> del firewall. Sin <code>reply-to</code>, el firewall resolvería su MAC por ARP y le respondería directo. Con <code>reply-to</code>, el SYN-ACK sale con la <strong>MAC del gateway</strong> como destino:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># en el OPNsense (shell csh: envuelve en sh -c)</span>
</span></span><span class="line"><span class="cl">sh -c <span class="s2">&#34;tcpdump -lnei vtnet0 host 203.0.113.50 and tcp port 22&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&lt;mac-vecino&gt; &gt; &lt;mac-fw01&gt;          203.0.113.50.49612 &gt; 203.0.113.40.22: Flags [S]    ← llega directo
</span></span><span class="line"><span class="cl">&lt;mac-fw01&gt;   &gt; 00:00:5e:00:01:&lt;vrid&gt; 203.0.113.40.22 &gt; 203.0.113.50.49612: Flags [S.]   ← sale al gateway
</span></span></code></pre></td></tr></table>
</div>
</div><p>(<code>00:00:5e:00:01:xx</code> es la MAC virtual de VRRP: el gateway era un par redundante.)</p>
<p>A partir de ahí depende del gateway. Para él, el paquete entra por la misma interfaz por la que tendría que salir, y si tiene un filtro con estado ve un SYN-ACK de una conexión cuyo SYN nunca vio. En el lab, el gateway simplemente no lo devolvía al segmento. En el vecino sólo se ven SYN reintentándose y ningún <code>[S.]</code>.</p>
<p>La huella en el firewall es un estado a medias:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">pfctl -ss <span class="p">|</span> grep 203.0.113.50
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">all tcp 192.168.1.10:22 (203.0.113.40:22) &lt;- 203.0.113.50:57792   SYN_SENT:ESTABLISHED
</span></span></code></pre></td></tr></table>
</div>
</div><p>El servidor ya respondió (<code>ESTABLISHED</code>) y el cliente sigue esperando (<code>SYN_SENT</code>): <strong>la respuesta se pierde de regreso</strong>, no a la ida. El filtro no está bloqueando nada.</p>
<h2 id="qué-cambia-el-fix">Qué cambia el fix</h2>
<p>Con <strong>Disable reply-to on WAN rules</strong> activado, OPNsense regenera las reglas sin <code>reply-to</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">pass in quick on vtnet0 inet proto tcp from any to 192.168.1.10 port = ssh flags S/SA keep state
</span></span></code></pre></td></tr></table>
</div>
</div><p>El estado ya no fija el siguiente salto, así que las respuestas pasan por la tabla de rutas normal:</p>
<table>
  <thead>
      <tr>
          <th>Destino de la respuesta</th>
          <th>Con <code>reply-to</code></th>
          <th>Sin <code>reply-to</code></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cliente en internet</td>
          <td>gateway</td>
          <td>gateway (ruta por defecto)</td>
      </tr>
      <tr>
          <td>Vecino en 203.0.113.0/24</td>
          <td>gateway ✗</td>
          <td>directo por ARP ✓</td>
      </tr>
      <tr>
          <td>Cliente que entró por otra WAN (multi-WAN)</td>
          <td>su gateway ✓</td>
          <td>ruta por defecto ✗</td>
      </tr>
  </tbody>
</table>
<p>La última fila es el costo. Con multi-WAN no lo desactives global. En vez de eso, quita el <code>reply-to</code> sólo en la regla del port-forward afectado: en la regla, <strong>Advanced → reply-to</strong>. Revisa las opciones que ofrece tu versión.</p>
<h2 id="verificar">Verificar</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># en el OPNsense</span>
</span></span><span class="line"><span class="cl">sh -c <span class="s2">&#34;pfctl -sr | grep -c reply-to; grep -n disablereplyto /conf/config.xml&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># esperado: 0  y  &lt;disablereplyto&gt;yes&lt;/disablereplyto&gt;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># desde el vecino</span>
</span></span><span class="line"><span class="cl">nc -z -w5 203.0.113.40 <span class="m">22</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> abierto
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="trampas">Trampas</h2>
<ul>
<li><strong>«Disable force gateway» no es esto.</strong> Está en la misma pantalla y tiene un nombre parecido, pero sólo afecta el tráfico que <strong>origina el propio firewall</strong> (DNS, NTP, actualizaciones). No toca las respuestas a tráfico entrante.</li>
<li><strong>Una ruta estática en el gateway no ayuda.</strong> El gateway ya tiene la subred como conectada; el problema es que no regresa el paquete al mismo segmento, no que no sepa llegar.</li>
<li><strong>Shell csh.</strong> Por SSH, OPNsense entra a <code>csh</code> y cosas como <code>2&gt;/dev/null</code> fallan con <code>Ambiguous output redirect</code>. Usa <code>sh -c &quot;...&quot;</code> o <code>ssh root@fw01 sh &lt;&lt;'EOF'</code>.</li>
<li><strong>Revisa todos los puertos, no uno.</strong> Si falla sólo un puerto es otro problema (regla, NAT, servicio). Si fallan todos, incluido <code>ping</code>, y sólo desde la misma subred, sospecha de <code>reply-to</code>.</li>
</ul>
<h2 id="ver-también">Ver también</h2>
<ul>
<li>Documentación de OPNsense, configuración del firewall: <a href="https://docs.opnsense.org/manual/firewall_settings.html">https://docs.opnsense.org/manual/firewall_settings.html</a></li>
<li><code>pf.conf(5)</code>, opciones <code>route-to</code> / <code>reply-to</code>: <a href="https://man.freebsd.org/cgi/man.cgi?query=pf.conf">https://man.freebsd.org/cgi/man.cgi?query=pf.conf</a></li>
</ul>
]]></content:encoded></item><item><title>Vault Agent Injector en GKE privado: el sidecar no aparece y el pod tarda 30 s (el control plane no llega al webhook en el 8080)</title><link>https://inet.sh/es/posts/kubernetes/vault-agent-injector-gke-private-cluster-sin-sidecar/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/es/posts/kubernetes/vault-agent-injector-gke-private-cluster-sin-sidecar/</guid><description>En un clúster GKE privado, los pods con vault.hashicorp.com/agent-inject arrancan sin los contenedores vault-agent-init y vault-agent, tardan medio minuto más en crearse y el injector no registra ninguna petición. El control plane solo puede abrir conexiones a los nodos en los puertos 443 y 10250; el injector escucha en el 8080 y el webhook falla en silencio porque failurePolicy es Ignore. Regla de firewall desde el rango del control plane, cómo validar en los logs del injector, y el mismo problema en cualquier otro webhook de admisión.</description><content:encoded><![CDATA[<h2 id="en-corto">En corto</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nv">CLUSTER</span><span class="o">=</span>my-cluster<span class="p">;</span> <span class="nv">REGION</span><span class="o">=</span>us-central1<span class="p">;</span> <span class="nv">NETWORK</span><span class="o">=</span>my-vpc
</span></span><span class="line"><span class="cl"><span class="nv">MASTER_CIDR</span><span class="o">=</span><span class="k">$(</span>gcloud container clusters describe <span class="nv">$CLUSTER</span> --region <span class="nv">$REGION</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --format<span class="o">=</span><span class="s1">&#39;value(privateClusterConfig.masterIpv4CidrBlock)&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">NODE_TAG</span><span class="o">=</span><span class="k">$(</span>gcloud compute firewall-rules list --filter<span class="o">=</span><span class="s2">&#34;name~^gke-</span><span class="nv">$CLUSTER</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --format<span class="o">=</span><span class="s1">&#39;value(targetTags.list())&#39;</span> <span class="p">|</span> head -1<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">gcloud compute firewall-rules create gke-<span class="nv">$CLUSTER</span>-master-to-vault-injector <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --network<span class="o">=</span><span class="nv">$NETWORK</span> --direction<span class="o">=</span>INGRESS --action<span class="o">=</span>ALLOW <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --source-ranges<span class="o">=</span><span class="nv">$MASTER_CIDR</span> --target-tags<span class="o">=</span><span class="nv">$NODE_TAG</span> --rules<span class="o">=</span>tcp:8080
</span></span></code></pre></td></tr></table>
</div>
</div><p>Borra un pod anotado y comprueba que el injector recibe la llamada:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">kubectl -n app delete pod -l <span class="nv">app</span><span class="o">=</span>api
</span></span><span class="line"><span class="cl">kubectl -n vault logs deploy/vault-agent-injector <span class="p">|</span> grep mutate
</span></span><span class="line"><span class="cl"><span class="c1"># [INFO]  handler: Request received: Method=POST URL=/mutate?timeout=30s</span>
</span></span><span class="line"><span class="cl">kubectl -n app get pod -l <span class="nv">app</span><span class="o">=</span>api -o <span class="nv">jsonpath</span><span class="o">=</span><span class="s1">&#39;{.items[0].spec.initContainers[*].name} {.items[0].spec.containers[*].name}{&#34;\n&#34;}&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># vault-agent-init api vault-agent</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="el-síntoma">El síntoma</h2>
<ul>
<li>El pod lleva <code>vault.hashicorp.com/agent-inject: &quot;true&quot;</code> y el resto de anotaciones, pero arranca <strong>solo con el contenedor de la aplicación</strong>: ni <code>vault-agent-init</code> ni <code>vault-agent</code>.</li>
<li>Crear el pod <strong>tarda unos 30 segundos más</strong> de lo normal.</li>
<li><code>kubectl get events</code> no dice nada del webhook. En los logs del injector no hay ni una línea de <code>Request received</code>.</li>
<li>En otros clústeres (zonales públicos, kind, k3s) el mismo chart y las mismas anotaciones funcionan.</li>
</ul>
<h2 id="por-qué">Por qué</h2>
<p>En un clúster <strong>privado</strong> de GKE el control plane vive en una VPC de Google y llega a tus nodos a través de la regla de firewall que GKE crea sola (<code>gke-&lt;cluster&gt;-&lt;hash&gt;-master</code>). Esa regla solo permite <strong>TCP 443 y 10250</strong> desde el rango del control plane hacia los nodos. Todo lo demás está cerrado.</p>
<p>Un webhook de admisión no pasa por el Service como lo haría un cliente normal: el API server resuelve el Service a sus endpoints y <strong>conecta directamente con la IP del pod en el <code>targetPort</code></strong>. El Service del injector (<code>vault-agent-injector-svc</code>) publica el 443, pero el pod escucha en el <strong>8080</strong> (<code>injector.port</code> del chart), así que la conexión real es al 8080 y el firewall la descarta.</p>
<p>Lo que pasa después lo explican dos valores por defecto del chart de Vault:</p>
<table>
  <thead>
      <tr>
          <th>Valor</th>
          <th>Por defecto</th>
          <th>Efecto</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>injector.webhook.timeoutSeconds</code></td>
          <td><code>30</code></td>
          <td>El API server espera 30 s la respuesta del webhook</td>
      </tr>
      <tr>
          <td><code>injector.webhook.failurePolicy</code></td>
          <td><code>Ignore</code></td>
          <td>Si el webhook no contesta, el pod se crea <strong>sin mutar</strong>, sin error</td>
      </tr>
  </tbody>
</table>
<p>De ahí los 30 segundos de retraso y el pod sin sidecar y sin ningún mensaje. Con <code>failurePolicy: Fail</code> habrías visto <code>failed calling webhook &quot;vault.hashicorp.com&quot;: … context deadline exceeded</code> en los eventos del ReplicaSet, que al menos apunta al sitio correcto.</p>
<h2 id="no-es-solo-vault">No es solo Vault</h2>
<p>Cualquier webhook de admisión, conversión de CRDs o API agregada que escuche en un puerto que no sea 443 o 10250 falla igual en GKE privado: el operador de OpenTelemetry (9443), Kyverno (9443), Gatekeeper (8443)… cert-manager escucha en el <strong>10250</strong> precisamente para no necesitar esta regla. La documentación de GKE lo lista como requisito de &ldquo;admission webhooks, aggregated API servers, webhook conversion&rdquo;: una regla por puerto, desde <code>masterIpv4CidrBlock</code> hacia los tags de los nodos.</p>
<p>Si el clúster está en Terraform, deja la regla junto al clúster para que no se pierda al recrearlo:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-hcl" data-lang="hcl"><span class="line"><span class="cl"><span class="k">resource</span> <span class="s2">&#34;google_compute_firewall&#34; &#34;master_to_vault_injector&#34;</span> {
</span></span><span class="line"><span class="cl"><span class="n">  name</span>          <span class="o">=</span> <span class="s2">&#34;gke-${google_container_cluster.main.name}-master-to-vault-injector&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">  network</span>       <span class="o">=</span> <span class="k">google_compute_network</span><span class="p">.</span><span class="k">main</span><span class="p">.</span><span class="k">name</span>
</span></span><span class="line"><span class="cl"><span class="n">  direction</span>     <span class="o">=</span> <span class="s2">&#34;INGRESS&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">  source_ranges</span> <span class="o">=</span> <span class="p">[</span><span class="k">google_container_cluster</span><span class="p">.</span><span class="k">main</span><span class="p">.</span><span class="k">private_cluster_config</span><span class="p">[</span><span class="m">0</span><span class="p">].</span><span class="k">master_ipv4_cidr_block</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">  target_tags</span>   <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;gke-${google_container_cluster.main.name}&#34;</span><span class="p">]</span><span class="c1">   # el tag que usan tus node pools
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">allow</span> {
</span></span><span class="line"><span class="cl"><span class="n">    protocol</span> <span class="o">=</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">    ports</span>    <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;8080&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  }
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="trampas">Trampas</h2>
<ul>
<li><strong>El tag equivocado</strong>: los nodos llevan <code>gke-&lt;cluster&gt;-&lt;hash&gt;-node</code>; cópialo de las reglas <code>gke-&lt;cluster&gt;-*</code> existentes en vez de escribirlo a mano. Con varios node pools, comprueba que todos tengan el tag.</li>
<li><strong>El rango del control plane cambia si recreas el clúster</strong>; una regla escrita a mano con el CIDR viejo deja de servir sin avisar.</li>
<li><strong><code>failurePolicy: Fail</code></strong> hace visible el fallo, pero mientras el webhook esté caído <strong>no se crea ningún pod</strong> en los namespaces que casen con el <code>namespaceSelector</code>; el chart excluye al propio injector, pero no a Vault si comparten namespace y etiquetas. Úsalo con <code>replicas: 2</code>.</li>
<li><strong>El injector sí recibe la petición y sigue sin sidecar</strong>: entonces ya no es red. Mira los logs de <code>vault-agent-init</code>: <code>permission denied</code> es el rol de Kubernetes auth (<code>bound_service_account_names</code>, <code>bound_service_account_namespaces</code>) o la política; <code>connection refused</code> es <code>vault.hashicorp.com/service</code> o la dirección de Vault.</li>
<li><strong>Un solo puerto por regla no escala</strong>: si acumulas webhooks, una regla con <code>--rules=tcp:8080,8443,9443</code> desde el control plane es más fácil de mantener que cinco.</li>
</ul>
<p>Referencias: <a href="https://github.com/hashicorp/vault-k8s/issues/46">vault-k8s #46</a>, <a href="https://github.com/hashicorp/vault-k8s/issues/32">vault-k8s #32</a> y <a href="https://docs.cloud.google.com/kubernetes-engine/docs/how-to/private-clusters">reglas de firewall en clústeres privados</a> en la documentación de GKE.</p>
<h2 id="ver-también">Ver también</h2>
<ul>
<li><a href="/es/posts/kubernetes/cert-manager-http01-308-ingressclassname/">cert-manager: el reto HTTP-01 devuelve 308</a> — otro componente que &ldquo;no hace nada&rdquo; hasta que miras el sitio correcto.</li>
<li><a href="/es/posts/gcp/github-actions-workload-identity-federation/">GitHub Actions → Google Cloud sin llaves</a> — para desplegar en ese GKE sin llaves JSON.</li>
</ul>
]]></content:encoded></item></channel></rss>