<?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[Distinct Research]]></title><description><![CDATA[Distinct Research]]></description><link>https://d1stinct.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1735665745778/10bfcd21-2574-4e97-86f7-9c8e4c230582.jpeg</url><title>Distinct Research</title><link>https://d1stinct.com</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 09:57:14 GMT</lastBuildDate><atom:link href="https://d1stinct.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Practicas seguras en Docker]]></title><description><![CDATA[La idea es ver algunas de las practicas frecuentes (y no tan frecuentes) para poder configurar aplicaciones en contenedores, la mayoria de estas ideas aplican a kubernetes tambien pero con diferente sintaxis!
Dockerfile
Tenemos nuestro dockerfile de ...]]></description><link>https://d1stinct.com/practicas-seguras-en-docker</link><guid isPermaLink="true">https://d1stinct.com/practicas-seguras-en-docker</guid><category><![CDATA[Docker]]></category><category><![CDATA[Security]]></category><category><![CDATA[networking]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[jd]]></dc:creator><pubDate>Mon, 16 Jun 2025 03:15:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750043584459/31f5ed02-6d2c-4a03-951a-eb2db40745e1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>La idea es ver algunas de las practicas frecuentes (y no tan frecuentes) para poder configurar aplicaciones en contenedores, la mayoria de estas ideas aplican a kubernetes tambien pero con diferente sintaxis!</p>
<h2 id="heading-dockerfile">Dockerfile</h2>
<p>Tenemos nuestro dockerfile de ejemplo, el mismo es multistage para optimizar recursos, utiliza un usuario y grupo creado para no utilizar root una vez se ejecute.</p>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> rust:slim-bookworm AS build

<span class="hljs-keyword">RUN</span><span class="bash"> USER=root cargo new --bin sample_app</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /tmp/app</span>

<span class="hljs-keyword">RUN</span><span class="bash"> apt-get update &amp;&amp; apt-get install -y \
    build-essential \
    <span class="hljs-comment">## Add additional dependencies here</span></span>
    &amp;&amp; rm -rf /var/lib/apt/lists/*

<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>
<span class="hljs-keyword">RUN</span><span class="bash"> cargo build --release --bin sample_app</span>

<span class="hljs-keyword">FROM</span> rust:slim-bookworm AS runtime

<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>
<span class="hljs-keyword">COPY</span><span class="bash"> --from=build /tmp/app/target/release/sample_app/app/sample_app</span>

<span class="hljs-keyword">RUN</span><span class="bash"> groupadd user \
&amp;&amp; useradd -m -g user user \
&amp;&amp; chown -R user:user /app</span>

<span class="hljs-keyword">USER</span> <span class="hljs-keyword">user</span>
<span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [<span class="hljs-string">"/app/sample_app"</span>]</span>
</code></pre>
<h3 id="heading-buildtime">Buildtime</h3>
<p>De aca mismo a nivel build utilizamos root para generar nuestro binario pero jamas deberiamos utilizar ese usuario en runtime, ahora despues de instalar las dependencias necesarias tambien podriamos eliminar recursos del sistema base (runtime) que no vamos a utilizar y vienen incluidos en la imagen base que utilicemos, si nuestro entorno lo permite podemos optar por <a target="_blank" href="https://github.com/GoogleContainerTools/distroless">https://github.com/GoogleContainerTools/distroless</a></p>
<h3 id="heading-runtime">Runtime</h3>
<p>A nivel runtime optamos por crear un grupo y usuario el cual despues vamos a gestionar sus permisos a nivel apparmor, tambien podriamos hacerlo a nivel imagen en caso que gesitone archivos u demas.</p>
<h2 id="heading-compose">Compose</h2>
<p>En el caso de nuestro compose</p>
<pre><code class="lang-yml"><span class="hljs-attr">services:</span>
  <span class="hljs-attr">sample_app:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">&lt;your_image&gt;</span>
    <span class="hljs-attr">security_opt:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">apparmor:./non-root-apparmor.profile</span>
      <span class="hljs-bullet">-</span> <span class="hljs-literal">no</span><span class="hljs-string">-new-privileges:true</span>
    <span class="hljs-attr">cap_drop:</span> [<span class="hljs-string">"ALL"</span>]
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">sample_app</span>

<span class="hljs-attr">networks:</span>
  <span class="hljs-attr">sample_app:</span>
    <span class="hljs-attr">driver:</span> <span class="hljs-string">bridge</span>
</code></pre>
<h3 id="heading-networks">Networks</h3>
<p>Podemos crear una red para este servicio, el cual haria que no tenga acceso a otras redes de otros contenedores en la misma situacion, el caso de usar el modo bridge es por si necesitamos comunicar un contenedor con otro den tro del mismo stack (docker-compose.yml)</p>
<h3 id="heading-no-new-privileges">No-new-privileges</h3>
<p>Esto evita que el usuario pueda escalar mas privilegios del que se le asigno al momento de crear la imagen https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs</p>
<h3 id="heading-capdrop">Cap_drop</h3>
<p>Las capabilities son tema de linux propio, pero que podemos aplicar a los contenedores, tanto cap_drop como cap_add permiten agregar como quitar funcionabilidades a los procesos del sistema (en este caso del contenedor), inicialmente siempre se tienen que dropear todas para que este tenga los privilegios minimos y solo agregar lo necesario ej <code>cap_add: ["CHOWN"]</code> https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-3-limit-capabilities-grant-only-specific-capabilities-needed-by-a-container</p>
<h2 id="heading-apparmor">AppArmor</h2>
<p>Mismo que las capabilities, vamos a gestionar de forma granular segmentar los permisos del sistema operativo, esto es un concepto propio de linux el cual aplica a los sistemas de docker, en el apparmor que cree estamos dando permisos de exec solamente al binario que yo puse dentro de la carpeta /app que es donde corre nuestra aplicacion.</p>
<pre><code class="lang-yml"><span class="hljs-string">include</span> <span class="hljs-string">&lt;abstractions/base&gt;</span>

<span class="hljs-string">/app</span> {
    <span class="hljs-comment"># Denegamos escalada de privilegios</span>
    <span class="hljs-string">deny</span> <span class="hljs-string">capability</span> <span class="hljs-string">sys_admin</span>,
    <span class="hljs-comment"># Le damos exec al binario que creamos</span>
    <span class="hljs-string">/app/sample_app</span> <span class="hljs-string">ix</span>,
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Tenemos muchas formas de aislar recursos en docker, las mismas pueden variar por app por eso es importante hacer nuestro Thread Modeling para entender la superficie de ataque para entender cual puede ser nuestra prioridad en que recursos querer cuidar.</p>
<p>El repositorio utilizado para la demostracion es el siguiente <a target="_blank" href="https://github.com/jd-apprentice/mks">https://github.com/jd-apprentice/mks</a></p>
]]></content:encoded></item></channel></rss>