<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ideas y tecnología]]></title><description><![CDATA[Ideas y tecnología]]></description><link>https://community.acceleratek.com</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 16:01:04 GMT</lastBuildDate><atom:link href="https://community.acceleratek.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Creando una imagen de contenedor con soporte multiarquitectura]]></title><description><![CDATA[Por lo general, cuando se crea una imagen de contenedor, esta se construye con el objetivo de correrla en la misma plataforma de hardware en la cual es construído, sin embargo, es posible utilizar un emulador como QEMU para crear una imagen que pueda...]]></description><link>https://community.acceleratek.com/creando-una-imagen-de-contenedor-con-soporte-multiarquitectura</link><guid isPermaLink="true">https://community.acceleratek.com/creando-una-imagen-de-contenedor-con-soporte-multiarquitectura</guid><category><![CDATA[Docker]]></category><category><![CDATA[containers]]></category><category><![CDATA[container images]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[multiarch]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Thu, 23 Oct 2025 21:38:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761255443038/121e087e-edde-4ea1-a679-5870a6aa8b00.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Por lo general, cuando se crea una imagen de contenedor, esta se construye con el objetivo de correrla en la misma plataforma de hardware en la cual es construído, sin embargo, es posible utilizar un emulador como QEMU para crear una imagen que pueda correr en otros dispositivos con una arquitectura distinta. Un ejemplo de esto sería correr un un mismo contenedor en un computador con soporte para instrucciones x86 (Intel/AMD) o en un Raspberry Pi (Arm).</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>Para nuestro laboratorio, vamos a utilizar una computadora x86 corriendo Ubuntu. Adicionalmente, es necesario tener Docker instalado <a target="_blank" href="https://docs.docker.com/engine/install/ubuntu/">utilizando las instrucciones oficiales</a>.</p>
<p>Adicionalmente, es necesario contar con una cuenta en Docker hub (gratis)</p>
<h1 id="heading-procedimiento">Procedimiento</h1>
<ul>
<li><p>Instalar QEMU en el sistema operativo</p>
<pre><code class="lang-bash">  apt install -y qemu-user-static
</code></pre>
</li>
<li><p>Correr Binfmt en un contenedor</p>
<pre><code class="lang-bash">  docker run --privileged --rm tonistiigi/binfmt --install all
</code></pre>
</li>
<li><p>Configurar Buildkit</p>
<pre><code class="lang-bash">  docker buildx create --use --name mymultiarchbuilder \
    --driver docker-container

  docker buildx inspect --bootstrap
</code></pre>
</li>
<li><p>Iniciar sesión en Docker Hub</p>
<pre><code class="lang-bash">  docker login
</code></pre>
</li>
<li><p>Crear el contenedor. Por favor note que <strong>es necesario</strong> reemplazar “&lt;my username&gt;” en el script con su username del Docker Hub</p>
<pre><code class="lang-bash">  docker buildx build \
          -t &lt;my username&gt;/mymultiarch:latest \
          --platform linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x,linux/arm64 \
          --push \
          -f - . &lt;&lt;EOF
                  FROM alpine:latest
                  <span class="hljs-comment"># Install bash inside the image for all target platforms</span>
                  RUN apk add bash

                  <span class="hljs-comment"># Define the command that will run when the container starts</span>
                  CMD [<span class="hljs-string">"sh"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-string">"echo 'Hola desde Arch: <span class="hljs-subst">$(uname -m)</span>' &amp;&amp; /bin/bash"</span>]
  EOF
</code></pre>
</li>
<li><p>Inspeccionando la imagen</p>
<pre><code class="lang-bash">  docker buildx imagetools inspect &lt;my username&gt;/mymultiarch:latest
</code></pre>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761248796920/94261e66-239f-400f-abed-36c4fc93e0db.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-pruebas">Pruebas</h1>
<ul>
<li><p>Corra el contenedor en diferentes hardware en diferentes plataformas</p>
<pre><code class="lang-bash">  docker run --rm &lt;my username&gt;/mymultiarch:latest uname -m
</code></pre>
</li>
</ul>
<p>Dependiendo de la plataforma desde la que ejecute el comando se mostrará la arquitectura en la que está corriendo el contenedor</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761254942521/ffe39eeb-6ec1-4ad6-80f9-e1f48be79b51.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761254898995/5e8e5acd-fd3e-4f76-91cf-76eb76779512.png" alt class="image--center mx-auto" /></p>
<p>Adicionalmente, puede abrir la imagen en Docker Hub y ver todas las plataformas que son soportadas por el contenedor</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761248295728/df0253d5-8523-4c36-a059-0d402696222c.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusión</h1>
<p>Es posible lograr que su software corra en varias plataformas logrando un rendimiento nativo gracias a la tecnología de cross compiling que permite lograr una verdadera multiarquitectura en donde su software no corre siendo emulado sino utilizando las instrucciones nativas que ofrece el procesador. De la misma manera, este tipo de contenedores pueden ser utilizados en clusters de Kubernetes que ofrecen capacidades de hospedaje híbrido, en donde usted podría por ejemplo correr su software en hardware x86 a la par de estaciones de trabajo Apple con procesadores de la serie M (arm64) de una forma completamente transparente.</p>
]]></content:encoded></item><item><title><![CDATA[Memoria USB con capacidad multi-boot]]></title><description><![CDATA[Poder arrancar una computadora utilizando una memoria USB nos brinda varias ventajas, no solo por su conveniencia, sino por su alta versatilidad y compatibilidad en computadoras modernas.
Ventoy es una utilidad que nos permite no solo lograr este obj...]]></description><link>https://community.acceleratek.com/memoria-usb-con-capacidad-multi-boot</link><guid isPermaLink="true">https://community.acceleratek.com/memoria-usb-con-capacidad-multi-boot</guid><category><![CDATA[rescue images]]></category><category><![CDATA[usb drive]]></category><category><![CDATA[Ventoy]]></category><category><![CDATA[multiboot]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Thu, 16 Oct 2025 14:57:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760569311015/b89dbcaf-efef-4e22-86df-cf3379cf8ca7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Poder arrancar una computadora utilizando una memoria USB nos brinda varias ventajas, no solo por su conveniencia, sino por su alta versatilidad y compatibilidad en computadoras modernas.</p>
<p><a target="_blank" href="https://www.ventoy.net/en/index.html">Ventoy</a> es una utilidad que nos permite no solo lograr este objetivo, sino hacerlo para una variedad de sistemas operativos limitada únicamente por la capacidad de la memoria USB que se utilice.</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>Asegúrese de cumplir con los siguientes requisitos antes de crear su primer memoria USB multiboot:</p>
<ol>
<li><p>Poseer una memoria USB (conector tipo A o C) que esté limpia o que pueda ser formateada sin riesgo a perder información valiosa.</p>
</li>
<li><p><a target="_blank" href="https://www.ventoy.net/en/download.html">Bajar la utilidad de Ventoy para Windows</a> (archivo con la palabra “windows” en el nombre).</p>
</li>
<li><p>Bajar los archivos .iso para los sistemas operativos que desea poder arrancar con su memoria USB. Estos son algunos ejemplos que considero útiles no solo para nuevas instalaciones, sino para casos de emergencia también:</p>
<ul>
<li><p><a target="_blank" href="https://www.hirensbootcd.org/download/">Hiren’s BootCD:</a> Colección de herramientas para diagnosticar y reparar su computadora.</p>
</li>
<li><p><a target="_blank" href="https://www.system-rescue.org/Download/">SystemRescueCD:</a> Provee un <a target="_blank" href="https://www.system-rescue.org/System-tools/">ambiente de rescate y diagnóstico</a> exhaustivo en casos de emergencias.</p>
</li>
<li><p><a target="_blank" href="https://clonezilla.org/downloads.php">Clonezilla:</a> Para clonado de discos e imágenes.</p>
</li>
<li><p><a target="_blank" href="https://gparted.org/download.php">GParted Live:</a> Un poderoso editor de particiones.</p>
</li>
<li><p><a target="_blank" href="https://nano11-dev.github.io/">Nano11</a> y <a target="_blank" href="https://archive.org/details/tiny-11-NTDEV">Tiny11:</a> Versiones minimizadas y optimizadas de Windows.</p>
</li>
<li><p><a target="_blank" href="https://www.proxmox.com/en/downloads/proxmox-virtual-environment/iso">Proxmox:</a> Solución poderosa para la creación de ambientes virtualizados.</p>
</li>
<li><p><a target="_blank" href="https://ubuntu.com/download/server">Ubuntu Server:</a> Distribución popular de Linux para servidores basada en Debian.</p>
</li>
<li><p><a target="_blank" href="https://linuxmint.com/download.php">Linux Mint:</a> Distribución popular de Linux para computadoras de escritorio basada en Ubuntu (y a su vez Debian)</p>
</li>
</ul>
</li>
</ol>
<h1 id="heading-procedimiento">Procedimiento</h1>
<h2 id="heading-instalacion-de-ventoy">Instalación de Ventoy</h2>
<ul>
<li><p>El primer paso es conectar su memoria USB a su computadora</p>
</li>
<li><p>Lo siguiente es descomprimir el .zip de Ventoy y correr el archivo Ventoy2Disk.exe</p>
<p>  <img src="https://img.utdstc.com/screen/847/36c/84736c418274821cc388823df1c2abd8a5f781c0a337e5a8b7aed95a2c4fc854:600" alt="Download Ventoy 1.1.07 for Windows | Uptodown.com" /></p>
</li>
<li><p>Presione el botón “Install” y espere a que la instalación de Ventoy se complete.</p>
</li>
<li><p>Una vez completada la instalación, Windows mostrará una nueva unidad con el nombre “Ventoy”. Usted puede en este momento copiar los archivos .iso/.img/.wim/.vhd a esta nueva unidad.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760568017023/2ad6ef96-e621-4d91-bd9a-2aa7c45916ef.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h2 id="heading-probando-su-nueva-memoria-usb-multiboot">Probando su nueva memoria USB multiboot</h2>
<ul>
<li><p>En este punto, debe reiniciar su computadora y configurar el BIOS para que pueda arrancar utilizando el USB drive como primer dispositivo de arranque. Una explicación detallada de este proceso está fuera del dominio de este artículo.</p>
</li>
<li><p>Una vez que todo sea configurado apropiadamente, podrá ver el menú de arranque de Ventoy con las entradas correspondientes para las imágenes que haya copiado a memoria USB.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760568344099/ec974864-d4bd-4614-b33c-bc0e4b552793.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusión</h1>
<p>Ventoy nos permite crear memorias USB con la capacidad de arrancar diferentes sistemas operativos utilizando un solo dispositivo físico. Este tipo de herramienta es muy útil en casos de emergencia o simplemente para instalar/reinstalar un sistema operativo en una computadora.</p>
]]></content:encoded></item><item><title><![CDATA[Criptografía post-cuántica en .NET y Windows]]></title><description><![CDATA[Microsoft anunció el soporte de criptografía post cuántica para Windows recientemente. Este es un acontecimiento importante porque marca el inicio del soporte nativo en el sistema operativo en lugar de depender de herramientas de terceros.
Pre-requis...]]></description><link>https://community.acceleratek.com/criptografia-post-cuatica-en-net-y-windows</link><guid isPermaLink="true">https://community.acceleratek.com/criptografia-post-cuatica-en-net-y-windows</guid><category><![CDATA[#QuantumCryptography  #QuantumSecurity  #Blockchain  #PostQuantumCryptography  #Web3Security  #CryptoResilience  #QuantumComputing  #DecentralizedSecurity  #QuantumSafe  #Cybersecurity  #BlockchainSecurity  #ZeroTrust  #FutureTech  #Cryptography  #PQCrypto]]></category><category><![CDATA[PQC]]></category><category><![CDATA[.NET]]></category><category><![CDATA[Windows]]></category><category><![CDATA[Microsoft]]></category><category><![CDATA[ML-DSA]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Wed, 15 Oct 2025 00:40:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488950445/c604ba7d-8233-4d03-97e1-702331df0548.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microsoft <a target="_blank" href="https://techcommunity.microsoft.com/blog/microsoft-security-blog/post-quantum-cryptography-comes-to-windows-insiders-and-linux/4413803">anunció el soporte de criptografía post cuántica para Windows</a> recientemente. Este es un acontecimiento importante porque marca el inicio del soporte nativo en el sistema operativo en lugar de depender de herramientas de terceros.</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>El soporte para PQC (Post-Quantum Cryptography) se introdujo en el build 27852 y superiores, esto quiere decir que antes de esta versión, si usted intenta abrir un archivo que utilizan estos algoritmos, Windows simplemente va a tirar un error indicando que el certificado tiene un formato inválido.</p>
<p>En la actualidad, la única forma de tener acceso a esa versión de Windows es mediante el Canary Channel, el cual da acceso a las capacidades mas recientes y experimentales de Windows. Es considerado altamente técnico puesto que muchos de los errores que se pueden encontrar podrían no tener una solución adecuada por parte de Microsoft.</p>
<p><a target="_blank" href="https://www.ninjaone.com/blog/change-windows-insider-program-channels-in-windows-11/#:~:text=Canary%20channel:%20This%20previews%20highly,but%20still%20have%20low%20stability.">Existen varias maneras de habilitar el Canary Channel de Windows</a>, pero el mas sencillo es habilitarlo en el GUI de Windows Update, haciendo click en la pestaña de “Windows Insider Program”, y escogiendo el radio button de “Canary Channel”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488660962/49b1d21f-7ce8-403d-a91d-41b0cb389756.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488628764/e1f917b3-1a02-47b6-9e71-1832e7432f60.png" alt class="image--center mx-auto" /></p>
<p>El soporte formal para ML-KEM (Key Encapsulation), ML-DSA y SLH-DSA (Signature algorithms) se introdujo en .NET 10, por lo cual vamos a necesitar <a target="_blank" href="https://dotnet.microsoft.com/en-us/download/dotnet/10.0">bajar e instalar la versión más reciente de .NET 10</a>.</p>
<h1 id="heading-procedimiento">Procedimiento</h1>
<p>Vamos a enfocarnos en ML-DSA, y el objetivo principal va a ser cubrir las funcionalidades básicas que ofrece esta clase utilizando el lenguaje C#.</p>
<h2 id="heading-creando-un-certificado-self-signed">Creando un certificado self-signed</h2>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> System.Security.Cryptography;
<span class="hljs-keyword">using</span> System.Security.Cryptography.X509Certificates;

<span class="hljs-keyword">var</span> dsaAlgorithm = MLDsaAlgorithm.MLDsa65;
<span class="hljs-keyword">var</span> hashAlgorithm = HashAlgorithmName.SHA512;
<span class="hljs-keyword">var</span> subjectName = <span class="hljs-keyword">new</span> X500DistinguishedName(<span class="hljs-string">$"CN=ML-DSA-Certificate, O=ExampleOrg, C=US"</span>);

<span class="hljs-comment">// Generación de la llave</span>
MLDsa mldsaKey = MLDsa.GenerateKey(dsaAlgorithm);
CertificateRequest certRequest = <span class="hljs-keyword">new</span> CertificateRequest(
    subjectName,
    mldsaKey
);
certRequest.CertificateExtensions.Add(
    <span class="hljs-keyword">new</span> X509BasicConstraintsExtension(<span class="hljs-literal">true</span>, <span class="hljs-literal">false</span>, <span class="hljs-number">0</span>, <span class="hljs-literal">true</span>));
certRequest.CertificateExtensions.Add(
    <span class="hljs-keyword">new</span> X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.CrlSign, <span class="hljs-literal">true</span>));

DateTimeOffset notBefore = DateTimeOffset.Now.AddDays(<span class="hljs-number">-1</span>);
DateTimeOffset notAfter = DateTimeOffset.Now.AddYears(<span class="hljs-number">1</span>);

<span class="hljs-comment">// Creación del certificado</span>
X509Certificate2 certificate = certRequest.CreateSelfSigned(notBefore, notAfter);
</code></pre>
<h1 id="heading-firmando-con-el-certificado-y-validando-la-firma">Firmando con el certificado y validando la firma</h1>
<pre><code class="lang-csharp"><span class="hljs-comment">// ------------------------------------------------------------------</span>
<span class="hljs-comment">// Parte 1: Generando la firma</span>
<span class="hljs-comment">// ------------------------------------------------------------------</span>

<span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> originalData = <span class="hljs-string">"Mensaje que quiero firmar usando la llave ML-DSA"</span>;
<span class="hljs-keyword">byte</span>[] dataToSign = Encoding.UTF8.GetBytes(originalData);

<span class="hljs-comment">// Definir el hash algorithm del certificado (que es diferente al de la llave)</span>
HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;

<span class="hljs-keyword">byte</span>[] signatureContext = Encoding.UTF8.GetBytes(<span class="hljs-string">"Application-Usage-V1"</span>);


<span class="hljs-comment">// Accesar la llave privada del certificado</span>
MLDsa mldsaPrivateKey = certificate.GetMLDsaPrivateKey();

<span class="hljs-keyword">if</span> (mldsaPrivateKey == <span class="hljs-literal">null</span>)
{
    Console.WriteLine(<span class="hljs-string">"\nERROR: No se puede obtener la llave privada del certificado."</span>);
    <span class="hljs-keyword">return</span>;
}

<span class="hljs-keyword">byte</span>[] signature;
<span class="hljs-keyword">try</span>
{
    Console.WriteLine(<span class="hljs-string">"\n--- Firmando datos con la llave privada ---"</span>);

    <span class="hljs-comment">// Llamando al método que firma los datos</span>
    signature = mldsaPrivateKey.SignData(dataToSign, signatureContext);

    Console.WriteLine(<span class="hljs-string">$"Firma exitosa, utilizando (<span class="hljs-subst">{signature.Length}</span> bytes)."</span>);
    Console.WriteLine(<span class="hljs-string">$"Firma (Base64): <span class="hljs-subst">{Convert.ToBase64String(signature).Substring(<span class="hljs-number">0</span>, <span class="hljs-number">32</span>)}</span>..."</span>); <span class="hljs-comment">// Mostrar un fragmento de la firma</span>

}
<span class="hljs-keyword">catch</span> (CryptographicException ex)
{
    Console.WriteLine(<span class="hljs-string">$"\nERROR durante firma: <span class="hljs-subst">{ex.Message}</span>"</span>);
    <span class="hljs-keyword">return</span>;
}


<span class="hljs-comment">// ------------------------------------------------------------------</span>
<span class="hljs-comment">// Parte 2: Verificando la firma</span>
<span class="hljs-comment">// ------------------------------------------------------------------</span>

<span class="hljs-comment">// Cargar la llave pública</span>
MLDsa mldsaPublicKey = certificate.GetMLDsaPublicKey();
<span class="hljs-keyword">if</span> (mldsaPublicKey == <span class="hljs-literal">null</span>)
{
    Console.WriteLine(<span class="hljs-string">"\nERROR: No se puede obtener la llave pública del certificado."</span>);
    <span class="hljs-keyword">return</span>;
}

<span class="hljs-comment">// Verificación</span>
Console.WriteLine(<span class="hljs-string">"\n--- Validando la firma ---"</span>);
<span class="hljs-keyword">bool</span> isValid = mldsaPublicKey.VerifyData(
    dataToSign,
    signature,
    signatureContext
);

<span class="hljs-keyword">if</span> (isValid)
{
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine(<span class="hljs-string">"La firma digital es válida!"</span>);
}
<span class="hljs-keyword">else</span>
{
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine(<span class="hljs-string">"La firma digital es inválida!"</span>);
}
Console.ResetColor();

<span class="hljs-comment">// Clean up</span>
mldsaPrivateKey.Dispose();
mldsaPublicKey.Dispose();
</code></pre>
<h2 id="heading-exportando-el-certificado">Exportando el certificado</h2>
<pre><code class="lang-csharp"><span class="hljs-comment">// Salvar el certificado (incluyendo la llave privada) en un archivo PFX</span>
<span class="hljs-keyword">string</span> pfxFilePath = <span class="hljs-string">"mldsa_certificate.pfx"</span>;
<span class="hljs-keyword">string</span> pfxPassword = <span class="hljs-string">"MySecurePassword"</span>;

<span class="hljs-comment">// Exportar el certificado en un archivo</span>
<span class="hljs-keyword">byte</span>[] pfxBytes = certificate.Export(X509ContentType.Pfx, pfxPassword);
File.WriteAllBytes(pfxFilePath, pfxBytes);

Console.WriteLine(<span class="hljs-string">$"\nEl certificado se salvó en: <span class="hljs-subst">{Path.GetFullPath(pfxFilePath)}</span>"</span>);
Console.WriteLine(<span class="hljs-string">$"Contraseña: <span class="hljs-subst">{pfxPassword}</span>"</span>);
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488147663/69b5a5f4-4e7f-4558-af2e-ed8f3cb2850a.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488181077/26aedd22-95db-47bb-8e4d-f57118668adb.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760488206956/df06414e-e9ed-43f6-a58d-f245e0f3c089.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusión</h1>
<p>En este momento, el soporte para PQC por parte de Windows se encuentra apenas dando sus primeros pasos, sin embargo las bases han sido sentadas y es adecuado aprender sobre estas tecnologías dada la importancia que van a tomar en la segunda mitad de la década tecnológica de los 20s.</p>
]]></content:encoded></item><item><title><![CDATA[Creando un cluster de bases de datos tipo active-active usando PostgreSQL]]></title><description><![CDATA[Es común encontrar escenarios en los que las empresas necesitan tener la habilidad de leer y escribir datos de manera simultánea en puntos geográficamente dispersos. Muchas veces, esas necesidades pueden traspasar fronteras entre países e inclusive c...]]></description><link>https://community.acceleratek.com/creando-un-cluster-de-bases-de-datos-tipo-active-active-usando-postgresql</link><guid isPermaLink="true">https://community.acceleratek.com/creando-un-cluster-de-bases-de-datos-tipo-active-active-usando-postgresql</guid><category><![CDATA[multi geo]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[replication]]></category><category><![CDATA[Databases]]></category><category><![CDATA[scaling]]></category><category><![CDATA[active-active]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Tue, 07 Oct 2025 03:47:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759773146168/00283fc1-9236-4ef0-a9a3-a83b4d76a540.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Es común encontrar escenarios en los que las empresas necesitan tener la habilidad de leer y escribir datos de manera simultánea en puntos geográficamente dispersos. Muchas veces, esas necesidades pueden traspasar fronteras entre países e inclusive continentes, creando retos tecnológicos que no todos los productos pueden satisfacer de manera satisfactoria.</p>
<p>Esta ha sido una de las principales razones por las cuales los proveedores en la nube se han vuelto tan prominentes, porque tienen la capacidad de proveer este tipo de arquitectura sin que uno se tenga que preocupar por los detalles de implementación, aunque esto por lo general trae un alto costo.</p>
<p>Esta configuración se puede implementar usando infraestructura local (on-premise) o en la nube, lo cual provee una gran flexibilidad pero además, posibilita la reducción de costos al estar basada completamente en software libre.</p>
<p>Vamos a similar una red mesh con 5 instancias, vamos a instalar una instancia en 5 namespaces distintos dentro de un mismo cluster de Kubernetes, sin embargo, es importante entender que en un ambiente de producción, se pueden tener estas bases de datos instaladas en diferentes puntos físicos y que no necesariamente tienen que ser el mismo servidor.</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>Antes de comenzar con la instalación de Microsoft SQL Server 2022 en Kubernetes, es esencial contar con un clúster de Kubernetes funcional. Para ello, te recomendamos seguir los pasos detallados en nuestra: <a target="_blank" href="https://community.acceleratek.com/guia-para-crear-un-servidor-personal-de-kubernetes">Guía para crear un servidor personal de Kubernetes</a>. Esta guía te proporcionará las instrucciones necesarias para configurar tu entorno de Kubernetes de manera adecuada, asegurando que los siguientes pasos del tutorial se ejecuten sin inconvenientes.</p>
<h1 id="heading-procedimiento">Procedimiento</h1>
<p>Vamos a simular 5 nodos distintos utilizando 5 namespaces diferentes en kubernetes. Cada uno de estos nodos va a correr una instancia de PostgreSQL, y cada nodo va a replicar y recibir cambios del resto de los nodos en la red:</p>
<p><img src="https://media.springernature.com/lw685/springer-static/image/chp%3A10.1007%2F978-3-031-06764-8_15/MediaObjects/534053_1_En_15_Fig1_HTML.png" alt="figure 1" class="image--center mx-auto" /></p>
<ul>
<li><p>Script que crea 5 namespaces e instala postgresql en cada uno de ellos</p>
<pre><code class="lang-plaintext">  helm repo add bitnami https://charts.bitnami.com/bitnami
  helm repo update

  for i in {1..5}
  do
      echo "========= n$i ========="
      helm install pg$i bitnami/postgresql -n n$i --create-namespace \
          --set auth.postgresPassword=postgres \
          --set auth.replicationUsername=active_active \
          --set auth.replicationPassword=active \
          --set architecture=replication \
          --set auth.database=db01 \
          --set primary.service.type=LoadBalancer \
          --set primary.persistence.storageClass=longhorn \
          --set primary.persistence.size=1Gi \
          --set primary.configuration="wal_level=logical
          max_replication_slots=10
          max_wal_senders=10
          max_worker_processes=8
          max_logical_replication_workers=4
          max_sync_workers_per_subscription=2
          listen_addresses='*'"
  done
</code></pre>
</li>
<li><p>Crear una tabla y la publicación en cada nodo</p>
<pre><code class="lang-plaintext">  for u in {1..5}
  do
      echo "========= pg$u ========="
      kubectl exec -n n$u pg$u-postgresql-primary-0 -- bash -c "
          PGPASSWORD=postgres psql -U postgres -d db01 -c \"
              drop publication if exists pg$u;
              drop table if exists t1;
              create table t1(
                  id uuid default gen_random_uuid(),
                  comments text default 'pg$u-example',
                  t_stamp timestamptz default now(),
                  PRIMARY KEY (t_stamp,id)
              );
              grant all on all tables in schema public to active_active;
              create publication pg$u for table t1;
          \"
      "
  done
</code></pre>
</li>
<li><p>Creando la suscripción en todos los nodos</p>
<pre><code class="lang-plaintext">  for u in {1..5}
  do
      for v in {1..5}
      do
          if [ $u -ne $v ]
          then
              echo "========= pg$u -&gt; pg$v ========="
              kubectl exec -n n$u pg$u-postgresql-primary-0 -- bash -c "
                  PGPASSWORD=postgres psql -U postgres -d db01 -c \"
                  CREATE SUBSCRIPTION pg$v
                      CONNECTION 'host=pg$v-postgresql-primary-hl.n$v.svc.cluster.local port=5432 dbname=db01 user=active_active password=active'
                      PUBLICATION pg$v
                      WITH (origin=none, copy_data=false, slot_name=pg$u);
                  \"
              "
          fi
      done
  done
</code></pre>
</li>
</ul>
<h1 id="heading-pruebas">Pruebas</h1>
<p>Para verificar que la replicación está funcionando adecuadamente, vamos a crear una nueva fila en la tabla t1 dentro de cada una de las instancias. Luego, vamos a hacer un select en cada una de las 5 instancias y ambas deberíamos de poder ver todas las 5 filas en cada una de ellas.</p>
<ul>
<li><p>Creando una nueva fila en cada una de las 5 instancias. Esto demuestra que es posible escribir en cualquier instancia y que la información va a ser replicada al resto de los nodos:</p>
<pre><code class="lang-plaintext">  for u in {1..5}
  do
      echo "========= insert into pg$u ========="
      kubectl exec -n n$u pg$u-postgresql-primary-0 -- bash -c "
          PGPASSWORD=postgres psql -U postgres -d db01 -c \"
              INSERT INTO t1 (t_stamp) VALUES (default);
          \"
      "
  done
</code></pre>
</li>
<li><p>Ahora revisamos los resultados en t1 para cada una de las 5 instancias</p>
<pre><code class="lang-plaintext">  for u in {1..5}
  do
      echo "========= select pg$u ========="
      kubectl exec -n n$u pg$u-postgresql-primary-0 -- bash -c "
          PGPASSWORD=postgres psql -U postgres -d db01 -c \"
              SELECT * FROM t1;
          \"
      "
  done
</code></pre>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759806645442/d8af64fd-1a2a-423c-9d32-5b5c73605154.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-datos-adicionales">Datos adicionales</h1>
<p>La clave para que la replicación mesh funcione en postgreSQL es el parámetro <strong>origin=none</strong> dentro de la definición de la suscripción; este parámetro es el que evita que se ejecute una replicación infinita entre los nodos.</p>
<p>El parámetro <strong>origin</strong> controla el origen de los datos que van a ser replicados. Cuando una nueva entrada es creada <strong>localmente</strong>, <strong>el origin es none</strong>, pero <strong>cuando se replica la información</strong>, <strong>el origin es el nodo en el que se creó la información</strong>, por lo que cuando un suscriptor recibe la nueva fila, esta se guarda localmente, y al ver que el origin es diferente a none, no se replica a otros nodos.</p>
<p>Si usted quisiera entender mejor como se ve la información que está siendo replicada, puede revisar la tabla de suscripciones en uno de los nodos:</p>
<pre><code class="lang-plaintext">kubectl exec -n n1 pg1-postgresql-primary-0 -- bash -c "
    PGPASSWORD=postgres psql -U postgres -d db01 -c \"
        SELECT subname, subenabled, subconninfo, subslotname FROM pg_subscription;
    \"
"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759808347729/cfc91bf8-013c-408a-a094-fd863d90dbe7.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusión</h1>
<p>PostgreSQL provee mecanismos robustos para crear bases de datos que son capaces de replicar datos transaccionales a múltiples nodos de manera eficiente y confiable.</p>
<p>Este ejemplo puede ser extendido para poder crear esquemas tipo arbol de navidad, para por ejemplo agregar bases de datos que evitan que los reportes conectados a las bases de datos afecten el rendimiento total del sistema.</p>
]]></content:encoded></item><item><title><![CDATA[Creando un certificado digital utilizando un algoritmo de encriptación post-cuántica]]></title><description><![CDATA[Es posible crear un certificado digital que implemente algoritmos PQC (Post-Quantum Crypto). Vamos a demostrar como es posible generar un par de llaves ML-DSA y utilizarlas dentro de un certificado X.509, ya sea self-signed o firmado por un CA privad...]]></description><link>https://community.acceleratek.com/creando-un-certificado-digital-utilizando-un-algoritmo-de-encriptacion-post-cuantica</link><guid isPermaLink="true">https://community.acceleratek.com/creando-un-certificado-digital-utilizando-un-algoritmo-de-encriptacion-post-cuantica</guid><category><![CDATA[ML-DSA]]></category><category><![CDATA[Crystals-Dillithium]]></category><category><![CDATA[Post-Quantum Cryptography]]></category><category><![CDATA[pki]]></category><category><![CDATA[openssl]]></category><category><![CDATA[Certificates]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Fri, 03 Oct 2025 06:58:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759474708112/0de14f59-a57f-47fa-8654-6b2eb78d6731.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Es posible crear un certificado digital que implemente <a target="_blank" href="https://www.cloudflare.com/es-es/learning/ssl/quantum/what-is-post-quantum-cryptography/">algoritmos PQC (Post-Quantum Crypto)</a>. Vamos a demostrar como es posible generar un par de llaves ML-DSA y utilizarlas dentro de un certificado X.509, ya sea self-signed o firmado por un CA privado usando las herramientas CLI de OpenSSL.</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<ul>
<li><p>El soporte para ML-DSA fue introducido a partir de OpenSSL 3.5.</p>
</li>
<li><p>Existen algoritmos PQC para varios propósitos, pero en esta guía nos vamos a enfocar en algoritmos stateless y asimétricos para firmas digitales: ml-dsa-44, ml-dsa-65 y ml-dsa-87 (categorías de seguridad 128/192/256-bit).</p>
</li>
<li><p>Tome en cuenta que el soporte en la actualidad a nivel de industria para este tipo de certificados sigue siendo limitado. No se recomienda utilizar este tipo de certificados <strong>TODAVIA</strong> en producción a no ser que sepa <strong>MUY BIEN</strong> lo que está haciendo.</p>
</li>
<li><p>Esta vez vamos a utilizar Windows para nuestro tutorial, pero las instrucciones funcionan para cualquier sistema operativo en el que se pueda utilizar openssl 3.5+.</p>
</li>
</ul>
<h1 id="heading-utilizando-la-version-correcta-de-openssl">Utilizando la versión correcta de OpenSSL</h1>
<ul>
<li><p>Bajar la versión más reciente de OpenSSL en versión ZIP para <strong>Windows</strong> de <a target="_blank" href="https://kb.firedaemon.com/support/solutions/articles/4000121705-openssl-binary-distributions-for-microsoft-windows">aquí</a>:</p>
<pre><code class="lang-plaintext">  https://download.firedaemon.com/FireDaemon-OpenSSL/FireDaemon-OpenSSL-x64-3.6.0.exe
</code></pre>
</li>
<li><p>Ejecute el instalador y asegúrese de habilitar la opción de agregar al PATH:</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759471000168/4e535b7e-61e1-4488-b8ef-1f8849968c17.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Abra una sesión de DOS/command prompt y asegúrese de tener permisos de lectura/escritura en el directorio de trabajo que decida utilizar</p>
<p>  <img src="https://www.geog.leeds.ac.uk/courses/other/programming/info/software/command.jpg" alt="Command Prompt" class="image--center mx-auto" /></p>
</li>
</ul>
<h1 id="heading-creando-un-ca">Creando un CA</h1>
<p>Vamos a enfocarnos en un ejemplo básico que no incluya un <a target="_blank" href="https://es.wikipedia.org/wiki/Autoridad_de_registro">RA</a>, el cual es un componente clave cuando se construye una infrastuctura de PKI. Por lo pronto, comenzamos creando el <a target="_blank" href="https://es.wikipedia.org/wiki/Autoridad_de_certificaci%C3%B3n">CA</a>:</p>
<ul>
<li><p>Generar una llave privada ML-DSA (escoja ml-dsa-44 / -65 / -87)</p>
<pre><code class="lang-plaintext">  openssl genpkey -algorithm ml-dsa-87 -out ca-priv.pem
</code></pre>
</li>
<li><p>Generamos un CA temporal para pruebas utilizando un certificado self-signed con una validez de 10 años:</p>
<pre><code class="lang-plaintext">  openssl req -x509 -new -key ca-priv.pem -subj "/CN=Test CA" -days 3650 -nodes -keyout ca.key -out ca.crt
</code></pre>
</li>
</ul>
<h1 id="heading-creacion-del-certificado-firmado-por-el-ca">Creación del certificado firmado por el CA</h1>
<ul>
<li><p>Generar una llave privada ML-DSA (escoja ml-dsa-44 / -65 / -87)</p>
<pre><code class="lang-plaintext">  openssl genpkey -algorithm ml-dsa-65 -out mldsa65-priv.pem
</code></pre>
</li>
<li><p>Extraiga la llave pública</p>
<pre><code class="lang-plaintext">  openssl pkey -in mldsa65-priv.pem -pubout -out mldsa65-pub.pem
</code></pre>
</li>
<li><p>Crear un <a target="_blank" href="https://es.wikipedia.org/wiki/Certificate_Signing_Request">CSR</a></p>
<pre><code class="lang-plaintext">  openssl req -new -key mldsa65-priv.pem -subj "/CN=example.local" -out mldsa65.csr
</code></pre>
</li>
<li><p>Crear un certificado self-signed con una validez de 1 año:</p>
<pre><code class="lang-plaintext">  openssl req -x509 -new -key mldsa65-priv.pem -subj "/CN=example.local" -days 365 -out mldsa65-self.crt
</code></pre>
</li>
<li><p>Firmar el CSR con un CA cert+key</p>
<pre><code class="lang-plaintext">  openssl x509 -req -in mldsa65.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -out mldsa65-by-ca.crt
</code></pre>
</li>
</ul>
<h1 id="heading-verificacion">Verificación</h1>
<ul>
<li><p>Obtener una versión texto del certificado privado:</p>
<pre><code class="lang-plaintext">  openssl x509 -in mldsa65-by-ca.crt -text -noout
</code></pre>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759472808988/2aed15fa-d045-47c8-9a80-a60978de5e78.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Verificar el certificado firmado por el CA:</p>
<pre><code class="lang-plaintext">  openssl verify -CAfile ca.crt mldsa65-by-ca.crt
</code></pre>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759472698278/833b8430-edd2-489b-bb92-2ffeb61e4e61.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusión</h1>
<p>El Post-Quantum Cryptography (PQC) es el futuro, Microsoft <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/libraries">ya comenzó a soportar librerías de PQC en .NET 10</a>, Chrome Browser desde hace varios años <a target="_blank" href="https://thehackernews.com/2024/09/google-chrome-switches-to-ml-kem-for.html?m=1">empezó la adopción</a> de PQC, y existen muchos otros ejemplos más de los gigantes de la industria adoptando estas prácticas.</p>
<p>Este laboratorio permite tener acceso a los mismos algoritmos y tecnología criptográfica que los gigantes de la industria están empezando a adoptar alrededor del planeta.</p>
]]></content:encoded></item><item><title><![CDATA[Corriendo Microsoft SQL Server 2022 en Kubernetes]]></title><description><![CDATA[Correr Microsoft SQL Server 2022 en Kubernetes ofrece la flexibilidad de los contenedores junto con las fortalezas de una base de datos empresarial. En este artículo veremos cómo instalar SQL Server sobre un clúster de Kubernetes corriendo sobre Ubun...]]></description><link>https://community.acceleratek.com/corriendo-microsoft-sql-server-2022-en-kubernetes</link><guid isPermaLink="true">https://community.acceleratek.com/corriendo-microsoft-sql-server-2022-en-kubernetes</guid><category><![CDATA[SQL Server]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[Microsoft]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Thu, 02 Oct 2025 04:50:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759379005741/ca3a0f5b-6d29-4c00-9c29-260e3990e810.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Correr <strong>Microsoft SQL Server 2022</strong> en <strong>Kubernetes</strong> ofrece la flexibilidad de los contenedores junto con las fortalezas de una base de datos empresarial. En este artículo veremos cómo instalar SQL Server sobre un clúster de Kubernetes corriendo sobre <strong>Ubuntu 24.04</strong>.</p>
<h1 id="heading-limitaciones">Limitaciones</h1>
<p>Para este ejemplo, es importante destacar que no se va a contar con la integración a Active Directory (<a target="_blank" href="https://learn.microsoft.com/es-es/sql/linux/sql-server-linux-ad-auth-adutil-tutorial?view=sql-server-ver17">a pesar de que es posible hacerlo</a>) y tampoco estará disponible el servicio de Microsoft SQL Server Agent.</p>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>Antes de comenzar con la instalación de Microsoft SQL Server 2022 en Kubernetes, es esencial contar con un clúster de Kubernetes funcional. Para ello, te recomendamos seguir los pasos detallados en nuestra: <a target="_blank" href="https://community.acceleratek.com/guia-para-crear-un-servidor-personal-de-kubernetes">Guía para crear un servidor personal de Kubernetes</a>. Esta guía te proporcionará las instrucciones necesarias para configurar tu entorno de Kubernetes de manera adecuada, asegurando que los siguientes pasos del tutorial se ejecuten sin inconvenientes.</p>
<h1 id="heading-procedimiento">Procedimiento</h1>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: mssql
---
apiVersion: v1
kind: Secret
metadata:
  name: mssql-secret
  namespace: mssql
type: Opaque
stringData:
  SA_PASSWORD: "YourStrong!Passw0rd"   # ⚠️ Reemplazar con un password fuerte
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mssql-pvc
  namespace: mssql
spec:
  storageClassName: longhorn
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mssql
  namespace: mssql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mssql
  template:
    metadata:
      labels:
        app: mssql
    spec:
      securityContext:
        fsGroup: 10001
      containers:
      - name: mssql
        image: mcr.microsoft.com/mssql/server:2022-latest
        ports:
        - containerPort: 1433
        env:
        - name: ACCEPT_EULA
          value: "Y"
        - name: SA_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mssql-secret
              key: SA_PASSWORD
        volumeMounts:
        - name: mssql-data
          mountPath: /var/opt/mssql
      volumes:
      - name: mssql-data
        persistentVolumeClaim:
          claimName: mssql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mssql
  namespace: mssql
spec:
  type: LoadBalancer
  selector:
    app: mssql
  ports:
  - protocol: TCP
    port: 1433
    targetPort: 1433
EOF
</code></pre>
<h2 id="heading-probando-la-nueva-instancia-de-microsoft-sql-server-2022">Probando la nueva instancia de Microsoft SQL Server 2022</h2>
<p>Empiece por verificar el IP asignado por MetalLB a su instancia:</p>
<pre><code class="lang-plaintext">kubectl get svc mssql -n mssql -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
</code></pre>
<p>Utilice este IP en la ventana de conexión del SQL Server Management Studio 21 o superior:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759379539683/e302c74e-9031-4334-9508-e34c4321dc81.png" alt class="image--center mx-auto" /></p>
<p>Tome en cuenta que para este ejemplo, el password del usuario “sa” es: YourStrong!Passw0rd</p>
<h1 id="heading-conclusion">Conclusión</h1>
<p>En este artículo vimos cómo instalar <strong>Microsoft SQL Server 2022 en Kubernetes</strong>, cubriendo la creación del contenedor y el acceso al servicio. Al combinar la robustez de SQL Server con la escalabilidad de Kubernetes, es posible crear entornos de bases de datos modernos, flexibles y fácilmente gestionables.  </p>
<p>Es recomendable investigar sobre mejores prácticas de seguridad antes de intentar correr esta instancia en un ambiente de producción.</p>
]]></content:encoded></item><item><title><![CDATA[Guía para crear un servidor personal de Kubernetes]]></title><description><![CDATA[Un servidor personal de Kubernetes es una excelente herramienta de aprendizaje. Nos puede ayudar a entender como funciona esta tecnología, y así poder aplicarla en un ambiente laboral.
Nuestros objetivos para esta guía van a ser los siguientes:

Habi...]]></description><link>https://community.acceleratek.com/guia-para-crear-un-servidor-personal-de-kubernetes</link><guid isPermaLink="true">https://community.acceleratek.com/guia-para-crear-un-servidor-personal-de-kubernetes</guid><category><![CDATA[kubernetes dashboard]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[k3s]]></category><category><![CDATA[Helm]]></category><category><![CDATA[metallb]]></category><category><![CDATA[longhorn]]></category><category><![CDATA[Ubuntu 24.04]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Wed, 01 Oct 2025 21:16:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759351587676/bb55bb3a-08d3-4ca8-b02c-c23bf620a5db.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Un servidor personal de Kubernetes es una excelente herramienta de aprendizaje. Nos puede ayudar a entender como funciona esta tecnología, y así poder aplicarla en un ambiente laboral.</p>
<p>Nuestros objetivos para esta guía van a ser los siguientes:</p>
<ul>
<li><p>Habilitar una instancia de Kubernetes que utilice pocos recursos pero que no limite el aprendizaje sobre contenedores.</p>
</li>
<li><p>Lograr gestionar la instancia de Kubernetes utilizando una interfaz gráfica.</p>
</li>
<li><p>Poder publicar servicios que se puedan accesar externamente utilizando un número de IP.</p>
</li>
<li><p>Poder almacenar informacion permanentemente, a pesar de la naturaleza efímera de los contenedores.</p>
</li>
</ul>
<p>Entre los objetivos que fueron <em>excluídos</em> para esta guía se encuentran:</p>
<ul>
<li><p>Mejores prácticas de seguridad.</p>
</li>
<li><p>Arquitectura e implementación para un ambiente de producción.</p>
</li>
<li><p>Explicación detallada de los componentes de Kubernetes.</p>
</li>
<li><p>Como instalar el Sistema Operativo Ubuntu 24.04 LTS y operaciones básicas de Linux como elevar los privilegios del comando a ser ejecutado (por ejemplo, utilizando el comando su).</p>
</li>
<li><p>Configuración de la red.</p>
</li>
</ul>
<h1 id="heading-pre-requisitos">Pre-requisitos</h1>
<p>Es importante que el lector tenga todo esto listo antes de seguir los pasos descritos más adelante:</p>
<ul>
<li><p>Una subred <a target="_blank" href="https://en.wikipedia.org/wiki/Reserved_IP_addresses">dentro del rango de IPs reservados</a>, con al menos 16 IPs disponibles. Para esta guía, vamos a asumir que la red disponible se encuentra dentro del rango 10.0.0.0/24, pero los servicios que se van a publicar estarán en las IPs que van desde 10.0.0.70 a 10.0.0.99.</p>
</li>
<li><p>Una máquina física o virtual con al menos 16GB de memoria, 10GB de disco duro y 2 procesadores. Nos vamos a referir a este servidor con el nombre de “host”, y vamos a asumir que utiliza el IP 10.0.0.12 (efectivamente, el IP se encuentra fuera del rango de los IPs libres que vamos a necesitar, pero dentro de la misma subred 10.0.0.0/24).</p>
</li>
<li><p>El sistema operativo Ubuntu 24.04 LTS va a estar instalado en el host.</p>
</li>
</ul>
<h1 id="heading-instalando-kubernetes">Instalando Kubernetes</h1>
<p>Vamos a utilizar <a target="_blank" href="https://k3s.io/">K3S</a> para faciilar la instalación de Kubernetes, nos enfocaremos en correr todos los servicios en una sola computadora, lo cual está bien para un servidor personal, pero no para un ambiente de producción. Ejecute el siguiente comando para instalar Kubernetes en el host utilizando K3S:</p>
<pre><code class="lang-plaintext">curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=latest K3S_TOKEN=SECRET sh -s - --write-kubeconfig-mode 644 --disable traefik --disable servicelb
</code></pre>
<p>El servicio va a durar un par de minutos habilitándose, mientras tanto nos vamos a enfocar en acciones que nos van a hacer más fácil su gestionamiento. Estos comandos van a requerir de un re-inicio de sesión en Linux.</p>
<p>Edite el archivo <strong>~/.bashrc</strong>, y agregue la siguiente línea al final:</p>
<pre><code class="lang-plaintext">alias kubectl="k3s kubectl”
</code></pre>
<p>Adicionalmente, edite el archivo <strong>/etc/environment</strong> y agregue la siguiente linea al final del archivo:</p>
<pre><code class="lang-plaintext">KUBECONFIG="/etc/rancher/k3s/k3s.yaml"
</code></pre>
<p>En este punto los servicios de Kubernetes deben estar arriba, y puede verificar que todo está corriendo normalmente utilizando el siguiente comando:</p>
<pre><code class="lang-plaintext">kubectl version
</code></pre>
<p>Si todo funciona correctamente, el resultado debería verse así:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759347560867/2d387b5b-3ff2-4f77-bcc5-40b78ebca66b.png" alt class="image--center mx-auto" /></p>
<p>Adicionalmente, si necesita desinstalar K3S porque quisiera comenzar desde 0, puede utilizar:</p>
<pre><code class="lang-plaintext">/usr/local/bin/k3s-uninstall.sh
</code></pre>
<h1 id="heading-implementando-un-load-balancer-para-la-red">Implementando un load balancer para la red</h1>
<p>Un servicio de load balancer nos permite tener un IP que envía las solicitudes que este recibe a alguno de los nodos en nuestro cluster de Kubernetes. En nuestro caso solo tenemos un nodo/servidor, pero entender como funciona un load balancer es básico para poder implementar un cluster de múltiples nodos a futuro.</p>
<p>La implementación del load balancer la vamos a hacer utilizando <a target="_blank" href="https://metallb.io/">MetalLB</a>. El primer paso es de hecho instalar el servicio de MetalLB en el cluster de Kubernetes utilizando el siguiente comando:</p>
<pre><code class="lang-plaintext">kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
</code></pre>
<p>Luego, ocupamos indicarle a MetalLB cuales son los IPs que puede utilizar para asignar a los servicios que vamos a instalar en el cluster; como dijimos anteriormente, nuestros IPs van desde 10.0.0.70 a 10.0.0.90. <strong><em>Nota:</em></strong> <em>a Kubernetes le va a tomar un rato levantar todos los contenedores/servicios de MetalLB antes de que este comando funcione.</em></p>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 10.0.0.70-10.0.0.90
EOF
</code></pre>
<p>Finalmente, ocupamos que MetalLB anuncie los IPs a la red, esto se logra con el comando:</p>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF | k3s kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: external-pool
  namespace: metallb-system
spec:
  ipAddressPools:
  - default-pool
EOF
</code></pre>
<h2 id="heading-probando-el-load-balancer">Probando el load balancer</h2>
<p>Estamos listos para correr nuestro primer ejemplo “Hello World!”, para ello, vamos a publicar un servicio de nginx (webserver), que nos permita usar nuestro navegador para ver el mensaje “Hello World!”.</p>
<pre><code class="lang-plaintext">kubectl create namespace sandbox
kubectl create deploy nginx-test --image nginx --namespace sandbox
kubectl get pods --all-namespaces
kubectl expose deploy nginx-test --namespace sandbox --port 80 --type LoadBalancer
kubectl get svc --all-namespaces
</code></pre>
<p>Una vez que corran esos comandos y los servicios se encuentren arriba, va a poder ver la página navegando a: (Note el uso de <strong>http</strong> y no https)</p>
<pre><code class="lang-plaintext">http://10.0.0.70
</code></pre>
<p><img src="https://global.discourse-cdn.com/docker/original/3X/e/0/e0149e4f73a1196794233f4f0731374171986d07.png" alt="Local host only shows Nginx welcome page - Docker Hub - Docker Community  Forums" class="image--center mx-auto" /></p>
<h1 id="heading-gestionando-kubernetes-usando-un-dashboard">Gestionando Kubernetes usando un dashboard</h1>
<p>Kubernetes puede ser gestionado mediante la linea de comandos utilizando el comando kubectl, pero vamos a habilitar una interfaz gráfica para facilitar este proceso. Comenzamos instalando el servicio:</p>
<pre><code class="lang-plaintext">kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml 

kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec": {"ports": [{"port": 443,"targetPort": 8443,"name": "https"}],"type": "LoadBalancer"}}'

cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF

cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF
</code></pre>
<p>Una vez que todos los contenedores/servicios del Kubernetes dashboard estén corriendo, podrá ingresar al dashboard utilizando la dirección: (Note el uso de <strong>https</strong>)</p>
<pre><code class="lang-plaintext">https://10.0.0.71
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759350980387/e2a9cd16-4765-4e31-92d1-6f373a4388f0.png" alt class="image--center mx-auto" /></p>
<p>Para poder autenticarse en la pantalla de login, va a necesitar generar un token primero, mediante el comando:</p>
<pre><code class="lang-plaintext">kubectl -n kubernetes-dashboard create token admin-user
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759351734790/5f01153f-107c-4240-8d0e-69376404f90d.png" alt class="image--center mx-auto" /></p>
<p>Copie y pegue ese comando en la pantalla de login y podrá ingresar al dashboard. Este es un ejemplo de la vista de los pods para todos los namespaces:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759351858363/167d5d4a-dc9a-4d76-bc9e-70aa27c1a770.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-habilitando-almacenamiento-persistente">Habilitando almacenamiento persistente</h1>
<p>El almacenamiento persistente nos permite conservar información aún y cuando un contenedor se mate, reinicie o mueva. Por su naturaleza, los contenedores no conservan los cambios que se les hace, a no ser que la información se guarde dentro de un medio de almacenamiento persistente.</p>
<p>Volviendo a nuestro ejemplo, en este punto hemos habilitado una serie de servicios que no necesitan guardar información persistente, pero cuando se hace necesario hacerlo, vamos a tener que habilitar un servicio llamado persistent storage.</p>
<p>Esta vez, vamos a realizar la instalación utilizando Helm, que es un manejador de paquetes para Kubernetes (Helm es a Kubernetes lo que Aptitude/apt es a Ubuntu). Para ello, vamos a ejecutar:</p>
<pre><code class="lang-plaintext">curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
</code></pre>
<p>A continuación, vamos a instalar <a target="_blank" href="https://longhorn.io/">Longhorn</a>, que se caracteriza por proveer una arquitectura <a target="_blank" href="https://es.wikipedia.org/wiki/Infraestructura_hiperconvergente">hyper-converged</a>.</p>
<pre><code class="lang-plaintext">sudo apt install open-iscsi 

helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn --create-namespace --namespace longhorn-system
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
</code></pre>
<h2 id="heading-probando-el-almacenamiento-persistente">Probando el almacenamiento persistente</h2>
<p>Vamos a modificar nuestra instancia Hello World en nginx para que se puedan almacenar los archivos del sitio en el sistema de archivos del host. Para ello, empezamos creando un Persistent Volume Claim (PVC):</p>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  namespace: sandbox
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 1Gi
EOF
</code></pre>
<p>Luego ocupamos modificar la instancia existente de nginx para que haga uso del PVC:</p>
<pre><code class="lang-plaintext">kubectl patch deployment nginx-test -n sandbox --type='json' -p='[{"op": "add", "path": "/spec/template/spec/volumes", "value": [{"name": "nginx-storage", "persistentVolumeClaim": {"claimName": "nginx-pvc"}}]}, {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts", "value": [{"name": "nginx-storage", "mountPath": "/usr/share/nginx/html"}]}]'
</code></pre>
<p>Y finalmente modificamos el contenido del archivo para cambiar el mensaje que muestra el sitio:</p>
<pre><code class="lang-plaintext">kubectl exec $(kubectl get pods -n sandbox -l app=nginx-test -o jsonpath='{.items[0].metadata.name}') -n sandbox -- sh -c 'echo "&lt;h1&gt;Hello from my Longhorn volume!&lt;/h1&gt;" &gt; /usr/share/nginx/html/index.html'
</code></pre>
<p>En este punto, puede acceder el servicio nuevamente en http://10.0.0.70 y va a notar un nuevo mensaje. No solamente eso, puede matar el pod, y el nuevo pod va a contener el mismo mensaje gracias al almacenamiento persistente.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759351953909/e46b7d21-0aa8-4fc7-a7e8-9b44bb5c9d3b.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusión</h1>
<p>Logramos construir un cluster de Kubernetes con un load balancer, almacenamiento persistente, dashboard y un sitio de nginx que hace uso de todos esos recursos.</p>
<p>Los ejercicios en esta guía pueden ser utilizados en un futuro dentro de contenedores con múltiples nodos, los cuales son aptos para escenarios que van más allá del simple aprendizaje de la tecnología.</p>
]]></content:encoded></item><item><title><![CDATA[Copiando archivos entre computadoras eficientemente]]></title><description><![CDATA[Una necesidad común entre las compañías es la de copiar archivos entre diferentes computadoras. Por lo general se recurre al uso de los comandos que provee el sistema operativo unido a una tarea calendarizada para lograr el objetivo, pero existen muc...]]></description><link>https://community.acceleratek.com/copiando-archivos-entre-computadoras-eficientemente</link><guid isPermaLink="true">https://community.acceleratek.com/copiando-archivos-entre-computadoras-eficientemente</guid><category><![CDATA[file copy]]></category><category><![CDATA[p2p]]></category><category><![CDATA[syncthing]]></category><category><![CDATA[servers]]></category><dc:creator><![CDATA[Hector Bejarano]]></dc:creator><pubDate>Wed, 24 Sep 2025 03:00:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758609337635/de920957-ae04-477b-9612-95346a88b09c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Una necesidad común entre las compañías es la de copiar archivos entre diferentes computadoras. Por lo general se recurre al uso de los comandos que provee el sistema operativo unido a una tarea calendarizada para lograr el objetivo, pero existen muchas consideraciones que se deben de tomar en cuenta para resolver un problema que inicialmente parece trivial:</p>
<ul>
<li><p>Reanudar la copia cuando se cae la red o alguno de los servidores falla</p>
</li>
<li><p>Maximizar el ancho de banda para disminuir el tiempo de copia</p>
</li>
<li><p>Copiar únicamente archivos que han cambiado</p>
</li>
<li><p>Asegurarse de que la copia se haga de manera segura</p>
</li>
<li><p>Recibir notificaciones cuando han ocurrido problemas con el proceso de copia</p>
</li>
<li><p>Permitir copiar archivos entre diferentes plataformas y sistemas operativos</p>
</li>
<li><p>Permitir hacer múltiples copias simultáneas, inclusive a lugares físicamente distantes</p>
</li>
<li><p>Habilitar la copia de archivos a dispositivos tanto en la red empresarial como a servidores en la nube</p>
</li>
</ul>
<p>Pues bien, existe una manera de cumplir con los objetivos listados anteriormente y más, utilizando un programa gratuito llamado <a target="_blank" href="https://syncthing.net/">Syncthing</a>.</p>
<h2 id="heading-como-funciona-syncthing">¿Como funciona Syncthing?</h2>
<p>Desde el punto de vista tecnológico, Syncthing utiliza el protocolo de comunicación BitTorrent. Sin embargo, esto no significa que cualquiera en el Internet puede ver sus archivos a través de la red Torrent, por el contrario, Syncthing permite que estos archivos sean intercambiados de manera privada, pero manteniendo todas las ventajas tecnológicas que una red peer-to-peer como Torrent puede traer.</p>
<p>La instalación de Syncthing se puede hacer en diferentes dispositivos, desde máquinas físicas o virtuales corriendo Windows, Linux, Mac OS X, etc. hasta dispositivos especializados como un NAS, un teléfono celular y muchos más. Syncthing le permite escoger cuales archivos o folders van a ser compartidos utilizando configuraciones simples o complejas que usted mismo puede especificar en detalle.</p>
<p><img src="https://cdn.prod.website-files.com/64149f8bba6c132029e75004/67150f2a4163ae8c6300c888_64149f8bba6c131208e75132_1*QZdcVYvd6GCJG4U7Z_oLWg.png" alt="Why You Might Not Want a Mesh VPN | Netmaker" /></p>
<h2 id="heading-instalando-syncthing-en-windows">Instalando Syncthing en Windows</h2>
<p>Los siguientes pasos detallan una guía de instalación <em>básica</em> de Syncthing. Por favor note que este método no es recomendable para ser usado en un servidor de producción, este es simplemente un ejemplo de como poner a correr Syncthing de una forma rápida y simple.</p>
<ul>
<li><p>Baje el archivo instalador con la versión mas reciente de Syncthing: <a target="_blank" href="https://github.com/syncthing/syncthing/releases">https://github.com/syncthing/syncthing/releases</a><br />  Nota: El archivo de instalación para Windows tiene un nombre que comienza con “syncthing-windows-amd64“, seguido por la versión. La extensión del archivo es .zip</p>
</li>
<li><p>Copie el archivo .zip a todas las computadoras que van a formar parte de la copia de archivos privados.</p>
</li>
<li><p>Extraiga los archivos del .zip, y ejecute el archivo syncthing.exe en cada computadora</p>
</li>
<li><p>Se abrirá una pantalla de consola y adicionalmente se abrirá una nueva ventana en su Internet browser apuntando a la página de configuración de Syncthing en: <a target="_blank" href="http://127.0.0.1:8384/">http://127.0.0.1:8384/</a></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758612309250/fadf3ecb-aa92-46f8-a64f-d9b0f7b42cf0.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758612490926/2309e68f-7e44-4685-b616-1e37e1f77fb9.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-operando-syncthing">Operando Syncthing</h2>
<p>Una vez que el servicio está corriendo en los servidores que van a participar en la copia de archivos, es necesario ejecutar dos acciones adicionales: agregar los dispositivos a la red Syncthing y especificar lo que se quiere compartir.</p>
<h3 id="heading-agregar-el-dispositivo-a-la-red-syncthing">Agregar el dispositivo a la red Syncthing</h3>
<p>Desde la página principal de Syncthing:</p>
<ul>
<li><p>Obtenga la identificación de cada dispositivo, esta identificación única es creada por Syncthing y se puede ver haciendo click al hyperlink ubicado dentro de la sección “This Device”, al lado derecho de “Identification”</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758613086929/475bbaa6-e1eb-48ee-b13b-7915b89f3b56.png" alt class="image--center mx-auto" /></p>
<p>  El siguiente paso es agregar este primer dispositivo a los demás dispositivos en la red. Esto se logra haciendo click al botón “+ Add Remote Devices“ en los otros dispositivos de la red, e introduciendo el Device ID así como el Device Name. Finalmente haga click en el botón Save para salvar los datos:</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758613193066/fd4f9e59-b274-4d3c-848f-8faefad10fd6.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>De vuelta en el primer servidor, deberá confirmar que desea establecer la conexión":</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758613856503/6cd083f7-cde6-4c98-87a2-d092d2fec7a8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Una conexión correcta será confirmada por Syncthing en la sección de Remote Devices</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758614022711/9bb225d0-fdef-420d-8949-3a6b9f205796.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h3 id="heading-especificar-lo-que-se-quiere-compartir">Especificar lo que se quiere compartir</h3>
<p>De vuelta en la página principal:</p>
<ul>
<li><p>Haga click en el botón Add Folder e introduzca los datos solicitados en el formulario</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758613612174/fe6c1635-bed3-4ad5-a727-e8572868442f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Haga click en el tab Sharing, y especifique el servidor que va a tener acceso a este folder</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758614135889/f2f07090-c5b0-423b-b217-f561f4146e3e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Una vez completada esta configuración del folder, deberá aceptar el Sharing:</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758614255710/e660b2bf-18d5-470c-9ff7-9cf7187c60bf.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Finalmente Syncthing mostrará el folder con su estado actual en la pantalla principal:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758614310437/42008ec1-4cef-4448-a25b-af45cc284ddf.png" alt class="image--center mx-auto" /></p>
<p>A partir de este momento, Syncthing se va a encargar de mantener ambos folders sincronizados. Para conocer en detalle otras formas de configurar Syncthing, recomendamos referirse a la <a target="_blank" href="https://docs.syncthing.net/users/index.html">documentación oficial</a>.</p>
<h2 id="heading-ecosistema-y-futuro-de-syncthing">Ecosistema y futuro de Syncthing</h2>
<p>Los líderes técnicos dentro de las empresas conocen bien la importancia de entender no solo cómo funciona una tecnología, sino el ecosistema que la rodea y su visión a futuro.</p>
<p>En el caso de Syncthing, existe la posibilidad de obtener soporte tanto comercialmente, o bajo la sombrilla de código abierto. Es importante entender que una instalación exitosa de este tipo de soluciones requiere de una planeación técnica y de negocio, además es importante preparar planes de contingencia y un proceso de emergencias que describa las acciones a tomar si algo sale mal.</p>
<p>Syncthing tiene a disposición un <a target="_blank" href="https://roadmap.syncthing.net/">roadmap abierto</a>, el cual puede ser influenciado, para el desarrollo y futura dirección de las capacidades ofrecidas por la plataforma.</p>
<p>Debido a su amplia adopción en el mercado y robusto soporte por parte de la comunidad de código abierto, Syncthing no presenta riesgos en el corto o mediano plazo.</p>
<p><img src="https://www.sambent.com/content/images/2025/08/context-view.jpg" alt="Syncthing Eliminates File Sync Surveillance Through Mesh Architecture" /></p>
<h2 id="heading-conclusion">Conclusión</h2>
<p>Syncthing es una solución tecnológica madura, segura y gratuita para resolver el problema de copia de archivos entre computadoras. Puede ser utilizada en una alta diversidad de dispositivos y se adapta a un sinnúmero de casos de uso, los cuales son comunes en las empresas modernas.</p>
]]></content:encoded></item></channel></rss>