<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://blog.leonardoamaral.com.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.leonardoamaral.com.br/" rel="alternate" type="text/html" hreflang="pt-BR" /><updated>2024-10-09T17:44:35-03:00</updated><id>https://blog.leonardoamaral.com.br/feed.xml</id><title type="html">Um Sysadmin Cansado</title><subtitle>Um blog cansado de um Sysadmin cansado &lt;b style=&quot;color: #f45;&quot;&gt;&amp;lt;3&lt;/b&gt; by &lt;b&gt;&lt;a href=&quot;https://blog.leonardoamaral.com.br&quot;&gt;https://blog.leonardoamaral.com.br/&lt;/a&gt;&lt;/b&gt;</subtitle><author><name>Leonardo Amaral</name></author><entry><title type="html">Volume in the sky with Docker - Apertem os cintos, o contêiner subiu!</title><link href="https://blog.leonardoamaral.com.br/Volume-in-the-sky-with-Docker-Apertem-os-cintos,-o-conteiner-subiu!/" rel="alternate" type="text/html" title="Volume in the sky with Docker - Apertem os cintos, o contêiner subiu!" /><published>2023-03-25T23:00:00-03:00</published><updated>2023-03-25T23:00:00-03:00</updated><id>https://blog.leonardoamaral.com.br/Volume-in-the-sky-with-Docker---Apertem-os-cintos,-o-conteiner-subiu!</id><content type="html" xml:base="https://blog.leonardoamaral.com.br/Volume-in-the-sky-with-Docker-Apertem-os-cintos,-o-conteiner-subiu!/"><![CDATA[<h2 id="introdução">Introdução</h2>

<p><a href="https://www.docker.com/company/" target="_blank">O</a> <a href="https://www.docker.com/blog/inside-look-docker-captains-program/" target="_blank">mundo</a> <a href="https://news.itsfoss.com/docker-dropping-free-team-orgs/" target="_blank">ama</a> <a href="https://www.docker.com/blog/we-apologize-we-did-a-terrible-job-announcing-the-end-of-docker-free-teams/" target="_blank">Docker</a>, não é mesmo? Existe por ai uma tonelada de alternativas a ele, inclusive <a href="https://podman.io/" target="_blank">meu queridinho</a>. Eu devo alguns postes sobre o Podman e o ambiente de contêineres que não seja ambiente dev e também não seja um cluster Kubernetes inteiro e hoje eu venho fazer um pouco de justiça neste ponto.</p>

<p>Muitas aplicações não precisam ser convertidas em microsserviços e não precisam da distribuição que um ambiente distribuído tem. Ainda não precisando, podem se beneficiar de algumas comodidades dos contêineres, como consistência de ambiente e configuração, facilidade de operação e facilidade de recovery caso algo exploda em um ambiente de produção.</p>

<p>Hoje apresento mais um motivo pra colocar nesta lista: A possibilidade de gerenciar automaticamente volumes remotos dentro dos contêineres usando <a href="https://hub.docker.com/r/rclone/docker-volume-rclone" target="_blank">docker-volume-rclone</a>.</p>

<h2 id="rclone">Rclone</h2>

<p>O <a href="https://rclone.org/#about:~:text=Rclone%20is%20a%20command%2Dline%20program%20to%20manage%20files%20on%20cloud%20storage." target="_blank">Rclone é um programa de linha de comando para gerenciar arquivos em armazenamento em nuvem</a>. Esta auto descrição pode levantar suspeitas sobre a necessidade deste poste, principalmente quando o leitor descobrir que ele é capaz de <a href="https://rclone.org/commands/rclone_mount/" target="_blank">montar volumes</a> mas não se enganem, ainda será mais prático manter a <a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes" target="_blank">sintaxe habitual de volumes do Docker Compose</a>. Aconselho a todos os aventureiros nuvenáuticos que se apoderem dessa ferramenta - até mesmo como substituição para <a href="https://rclone.org/commands/rclone_sync/" target="_blank">rsync</a>/<a href="https://rclone.org/sftp/" target="_blank">sftp</a>/<a href="https://rclone.org/ftp/" target="_blank">ftp</a>/<a href="https://rclone.org/commands/rclone_mount/" target="_blank">mount</a>.<a href="https://rclone.org/smb/" target="_blank">cifs</a> e tantas outras ferramentas que temos por ai.</p>

<p>Aos que ainda não se convenceram do poder do Rclone, há duas ferramentas do Rclone - <a href="https://rclone.org/hasher/" target="_blank">hasher</a> e <a href="https://rclone.org/compress/" target="_blank">compress</a> - que podem ser aninhadas em qualquer outro endpoint (E aninhadas entre si também - como faremos adiante), adicionando algum poder a protocolos mais restritos, como o <a href="https://rclone.org/ftp/" target="_blank">ftp</a>.</p>

<h2 id="docker-plugin">Docker plugin</h2>

<p>O Docker tem uma plataforma de <a href="https://docs.docker.com/engine/extend/" target="_blank">plugins</a> bem mais interessante que os <a href="https://github.com/containers/common/blob/main/docs/containers.conf.5.md#:~:text=A%20table%20of%20all%20the%20enabled%20volume%20plugins%20on%20the%20system.%20Volume%20plugins%20can%20be%20used%20as%20the%20backend%20for%20Podman%20named%20volumes.%20Individual%20plugins%20are%20specified%20below%2C%20as%20a%20map%20of%20the%20plugin%20name%20(what%20the%20plugin%20will%20be%20called)%20to%20its%20path%20(filepath%20of%20the%20plugin%27s%20unix%20socket)." target="_blank">plugins do podman</a> em termos de facilidade de deploy de novas expansões. Não avaliei se o podman é capaz de rodar a mesma estrutura da <a href="https://docs.docker.com/engine/extend/plugin_api/" target="_blank">plugin API do Docker</a> - deixando a sugestão ao leitor a possibilidade de buscar esta possibilidade - e quem sabe a publicar também. Esta plataforma de plugins será utilizada para <strong>mapear em volumes Docker qualquer serviço suportado pelo Rclone</strong>.</p>

<h2 id="bora-passar-raiva-booooooooraa">Bora passar raiva? Booooooooraa!</h2>

<h3 id="pré-requisitos">Pré-requisitos</h3>

<p>Para o procedimento, o pacote fuse se faz necessário. Nas duas bases mais comuns, o processo de instalação costuma ser o mesmo:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">apt install fuse</code></li>
  <li><code class="language-plaintext highlighter-rouge">yum install fuse</code></li>
  <li><code class="language-plaintext highlighter-rouge">dnf install fuse</code></li>
</ul>

<p>Também é necessária a criação de duas pastas para armazenar o cache e a configuração <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> <span class="nt">-p</span> /var/lib/docker-plugins/rclone/config
<span class="nb">sudo mkdir</span> <span class="nt">-p</span> /var/lib/docker-plugins/rclone/cache
</code></pre></div></div>

<h3 id="instalação-do-plugin">Instalação do plugin</h3>

<p>Atendidos os <a href="#pré-requisitos">pré-requisitos</a>, hora de instalar o plugin!</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker plugin <span class="nb">install </span>rclone/docker-volume-rclone:amd64 <span class="se">\</span>
<span class="nv">args</span><span class="o">=</span><span class="s2">"-v"</span> <span class="nt">--alias</span> rclone <span class="nt">--grant-all-permissions</span>
</code></pre></div></div>

<p>E ver se tudo está instalado como deveria:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker plugin list
</code></pre></div></div>

<p>É esperado um resultado como o seguinte:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ docker plugin list
ID             NAME            DESCRIPTION                       ENABLED
c0ef4f512e4f   rclone:latest   Rclone volume plugin for Docker   true
</code></pre></div></div>

<h2 id="voa-passarinho-voa">Voa passarinho, voa</h2>

<p>Vou deixar propositalmente <a href="https://rclone.org/docker/" target="_blank">os dois passos que já estão documentados pela equipe do Rclone</a> de fora deste texto. O cenário mais simples que cria manualmente o volume pode ser compreendido partindo da leitura deste texto - mesmo sem conhecimento da língua inglesa. O cenário envolvendo <em>docker-compose</em> está ilustrado, mas devo trazer uma visão um pouco mais prática de como chegar a um ponto de uso útil da ferramenta - ilustrando um backup simples de <em>MySQL</em> como exemplo.</p>

<h3 id="configurando-os-serviços">Configurando os serviços</h3>

<p>A pasta onde o Rclone instala seu arquivo de config é a <code class="language-plaintext highlighter-rouge">/var/lib/docker-plugins/rclone/config/</code> e a configuração do Rclone é gerada pelo comando <a href="https://rclone.org/commands/rclone_config/"><code class="language-plaintext highlighter-rouge">rclone config</code></a>. Juntando as duas coisas com um contêiner pra configurar o Rclone (Afinal, pra que motivo iremos instalar via gerenciador de pacotes?), fica da seguinte forma:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Contêiner para configurar o Rclone</span>

docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">--name</span> rclone_config <span class="nt">-v</span> /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone config
</code></pre></div></div>

<p>Nesta altura do campeonato, já fica posto que é possível usar variações do comando acima para fazer qualquer operação fora dos contêineres envolvendo os serviços configurados para os volumes do Docker, como por exemplo:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Vamos listar os arquivos do serviço brasil_bagunca:</span>
<span class="c"># E não podemos esquecer do dois-pontos no final!</span>

docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">--name</span> rclone_config <span class="nt">-v</span> /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone <span class="nb">ls </span>brasilbagunca:
</code></pre></div></div>

<p>E assim deverá ser criada toda as configurações para que o Rclone possa operar e vou deixar um exemplo que demonstra um dos poderes interessantes do Rclone:</p>

<figure class="highlight"><pre><code class="language-init" data-lang="init"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre>[brasilbagunca]
type = ftp
host = senhoresselva.com.br
user = cristiano
pass = seu_lixo
explicit_tls = true

[brasilbagunca_compress]
type = compress
remote = brasilbagunca:

[brasilbagunca_compress_hash]
type = hasher
remote = brasilbagunca_compress:
</pre></td></tr></tbody></table></code></pre></figure>

<p>Criamos um perfil de acesso chamado <em>brasilbagunça</em> que se conecta em um FTP. Como não tem como fazer hash e compressão no FTP, criamos um novo perfil de acesso chamado <em>brasilbagunca_compress</em> que comprime os arquivos em gzip e envia para o remote <em>brasilbagunca</em>.</p>

<p><strong>AVISO: O Rclone diz <a href="https://rclone.org/compress/#:~:text=The%20file%20names%20should%20not%20be%20changed%20by%20anything%20other%20than%20the%20rclone%20compression%20backend.">explicitamente</a> que é possível acessar os arquivos e que modificá-los é perigoso! Não altere os arquivos gerados no destino! No lugar disso, veja acima o exemplo que usamos com <em>rclone ls</em>.</strong></p>

<p>E como FTP também não suporta hash remoto, adotamos o componente <em>hasher</em> em cima do componente <em>compress</em>. O <em>hasher</em> gera arquivos .json para cada arquivo enviado com o hash local e verifica este hash em funções como <code class="language-plaintext highlighter-rouge">copy</code>, <code class="language-plaintext highlighter-rouge">sync</code> e etc.</p>

<p>No final das contas, com uma configuração destas, é possível enviar dados para o FTP com um hash e compressão dos arquivos, o que facilita bastante a vida ao utilizar sistemas legados. Como a configuração é aninhada, usaremos a configuração que contempla os três sistemas, como no exemplo abaixo:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Vamos listar os arquivos do serviço brasil_bagunca após a compressão e o hashing:</span>
<span class="c"># E novamente não podemos esquecer do dois-pontos no final!</span>

docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">--name</span> rclone_config <span class="nt">-v</span> /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone <span class="nb">ls </span>brasilbagunca_compress_hash:
</code></pre></div></div>

<h3 id="forjando-um-docker-composeyml">Forjando um <em>docker-compose.yml</em></h3>

<p>E chega a hora de juntar isso em uma configuração útil. Para manter os serviços o mais modular possível, utilizei o agendador <a href="https://github.com/mcuadros/ofelia">Ofelia</a> - um sistema construído em Go que permite utilizar labels do Docker para parametrizar o agendador. O contêiner <a href="https://hub.docker.com/_/mariadb">MariaDB</a> é padrão e só tem a mais uma pasta de backup que será mapeada para o volume criado com o driver <em>rclone</em>. As rotinas e configurações do <em>job-exec</em> podem ser consultadas <a href="https://github.com/mcuadros/ofelia/blob/master/docs/jobs.md">aqui</a>. Para os entendidos de <em>cron</em> e <em>mysql</em>, os comandos serão intuitivos e não explicados neste artigo para não desviar do tema do artigo.</p>

<figure class="highlight"><pre><code class="language-yaml" data-lang="yaml"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre><span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">3.8'</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">fora_do_brasil</span>

<span class="na">services</span><span class="pi">:</span>
  <span class="na">ofelia</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">mcuadros/ofelia:latest</span>
    <span class="na">command</span><span class="pi">:</span> <span class="s">daemon --docker</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">/var/run/docker.sock:/var/run/docker.sock:ro</span>

  <span class="na">mariadb</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">mariadb:latest</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
    <span class="na">labels</span><span class="pi">:</span>
      <span class="na">ofelia.enabled</span><span class="pi">:</span> <span class="no">true</span>
      <span class="na">ofelia.job-exec.mysql-optimize-fora_do_brasil.schedule</span><span class="pi">:</span> <span class="s2">"</span><span class="s">@daily"</span>
      <span class="na">ofelia.job-exec.mysql-optimize-fora_do_brasil.command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">mysqlcheck</span><span class="nv"> </span><span class="s">-uroot</span><span class="nv"> </span><span class="s">-ppiano_caindo</span><span class="nv"> </span><span class="s">-o</span><span class="nv"> </span><span class="s">--all-databases"</span>
      <span class="na">ofelia.job-exec.mysql-backup-fora_do_brasil.schedule</span><span class="pi">:</span> <span class="s2">"</span><span class="s">@daily"</span>
      <span class="na">ofelia.job-exec.mysql-backup-fora_do_brasil.command</span><span class="pi">:</span> <span class="s1">'</span><span class="s">bash</span><span class="nv"> </span><span class="s">-c</span><span class="nv"> </span><span class="s">"mysqldump</span><span class="nv"> </span><span class="s">-uroot</span><span class="nv"> </span><span class="s">-ppiano_caindo</span><span class="nv"> </span><span class="s">--all-databases</span><span class="nv"> </span><span class="s">&gt;&gt;</span><span class="nv"> </span><span class="s">/backup/$(date</span><span class="nv"> </span><span class="s">+%Y%m%d-%H%M%S).sql"'</span>
      <span class="na">ofelia.job-exec.mysql-clean-fora_do_brasil.schedule</span><span class="pi">:</span> <span class="s2">"</span><span class="s">@daily"</span>
      <span class="na">ofelia.job-exec.mysql-clean-fora_do_brasil.command</span><span class="pi">:</span> <span class="s1">'</span><span class="s">bash</span><span class="nv"> </span><span class="s">-c</span><span class="nv"> </span><span class="s">"find</span><span class="nv"> </span><span class="s">/backup</span><span class="nv"> </span><span class="s">-type</span><span class="nv"> </span><span class="s">f</span><span class="nv"> </span><span class="s">-mtime</span><span class="nv"> </span><span class="s">+7</span><span class="nv"> </span><span class="s">-print0</span><span class="nv"> </span><span class="s">|</span><span class="nv"> </span><span class="s">xargs</span><span class="nv"> </span><span class="s">-r0</span><span class="nv"> </span><span class="s">rm</span><span class="nv"> </span><span class="s">-v</span><span class="nv"> </span><span class="s">--"'</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">MYSQL_ROOT_PASSWORD=piano_caindo</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">backup:/backup</span>

<span class="na">volumes</span><span class="pi">:</span>
  <span class="na">backup</span><span class="pi">:</span>
    <span class="na">driver</span><span class="pi">:</span> <span class="s">rclone</span>
    <span class="na">driver_opts</span><span class="pi">:</span>
      <span class="na">remote</span><span class="pi">:</span> <span class="s1">'</span><span class="s">brasilbagunca_compress_hash:vejam/voces/percebem/a/loucura/'</span>
      <span class="na">allow_other</span><span class="pi">:</span> <span class="s1">'</span><span class="s">true'</span>
      <span class="na">vfs_cache_mode</span><span class="pi">:</span> <span class="s">full</span>
      <span class="na">poll_interval</span><span class="pi">:</span> <span class="s">0</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Pode chamar atenção do leitor mais cuidadoso a opção <em>allow_other</em> que é mandatória: Esta opção permite que mais de um volume no mesmo remote seja lançado. Caso esta opção não seja utilizada, somente um volume será montado para cada remote.</p>

<p>A opção <em>vfs_cache_mode</em> está explicada <a href="https://rclone.org/commands/rclone_mount/#vfs-file-caching">neste link</a> e resumidamente se comporta da seguinte forma: É preciso escolher um modo de cache para qualquer operação que não seja sequencial e que contemple as limitações que cada uma das opções de cache oferece (<em>off</em>, <em>minimal</em>, <em>writes</em> e <em>full</em>). O uso da opção <em>full</em> considerando que é um cenário de backup é adequada, porém cada cenário poderá exigir uma configuração diferente.</p>

<p>A opção <em>poll_interval</em> determina o tempo que o Rclone irá atualizar a lista local com a lista remota. No caso deixei em 0 porque é fundamentalmente um sistema de somente escrita, então não vejo razão para carregar o remoto com polling. Entretanto - conforme sinalizado em outros casos - a situação pode demandar mudanças.</p>

<p>Recomendo a leitura da página de informações sobre o <a href="https://rclone.org/commands/rclone_mount">rclone mount</a> pois as opções desta página se aplicam para a montagem dos volumes também.</p>

<h2 id="conclusão">Conclusão</h2>

<p>Este artigo visa mostrar o poder dos plugins do Docker e também indicar o poderoso <em>Rclone</em>. Os dois juntos podem ser uma excelente ferramenta para quem está convertendo estruturas on premisse legadas para contêineres em qualquer formato - sem necessariamente mudar os paradigmas da solução existente.</p>

<p>Caso tenha dúvidas, sugestões ou alguma observação, dá um toque nos comentários abaixo ou nas redes sociais no menu acima!</p>

<p>E nunca se esqueça, se for <a href="https://metalgear.fandom.com/wiki/Fulton_surface-to-air_recovery_system">fultonar</a> um contêiner, segure-se bem e aproveite a viagem!</p>

<p><img src="/assets/images/mgs_fulton.jpg" alt="Metal Gear Auto Extração via Fulton" /></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>O comando <code class="language-plaintext highlighter-rouge">sudo</code> será indicativo - salvo por outra necessidade - de que há necessidade de execução como root. Poderia indicar usando <code class="language-plaintext highlighter-rouge">#</code> e <code class="language-plaintext highlighter-rouge">$</code>, porém acredito que esta forma é mais verbosa e compreensível. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Leonardo Amaral</name></author><category term="docker" /><category term="container" /><category term="contêiner" /><category term="rclone" /><category term="nuvem" /><summary type="html"><![CDATA[Com a possibilidade do uso de plugins de volume no Docker, o contêiner aprende a voar pras nuvens com o rclone]]></summary></entry><entry><title type="html">eToken SafeNet no Linux (Fedora/Debian)</title><link href="https://blog.leonardoamaral.com.br/SafeNet-eToken-no-Linux/" rel="alternate" type="text/html" title="eToken SafeNet no Linux (Fedora/Debian)" /><published>2021-09-16T11:00:00-03:00</published><updated>2021-09-16T11:00:00-03:00</updated><id>https://blog.leonardoamaral.com.br/SafeNet-eToken-no-Linux</id><content type="html" xml:base="https://blog.leonardoamaral.com.br/SafeNet-eToken-no-Linux/"><![CDATA[<h2 id="introdução">Introdução</h2>

<p>A briga dos usuários de ceritificados digitais da ICP-Brasil no Linux é eterna e sem perspectiva de fim: A falta de suporte oficial das Autoridades Certificadoras e do próprio governo em seus sistemas são razões para a ínfima adoção de Software Livre nas empresas.</p>

<p>A <a href="https://github.com/ZenithTecnologia/">Zenith Tecnologia</a> é fortemente baseada em Software Livre e por isso precisa dos sistemas do Governo em estado operacional com Linux. Até o momento tem sido possível seguir sem uso de Softwares Proprietários para o dia a dia da empresa e esta postagem no <a href="https://blog.leonardoamaral.com.br/">blog</a> busca documentar mais um passo relativo ao uso de sistemas governamentais com Linux: O funcionamento dos SmartCards.</p>

<h2 id="a-escolha-da-autoridade-certificadora">A escolha da Autoridade Certificadora</h2>

<p>Há muitos anos uso a <a href="https://www.certisign.com.br/">Certisign</a> para emissão de meus certificados <a href="https://www.gov.br/pt-br/servicos/obter-certificacao-digital">eCPF e eCNPJ</a>. A razão para a escolha deles é a organização enquanto empresa para a emissão e validação dos certificados. É fácil marcar a entrevista, nunca tive problemas com os ceritifcados tampouco com os hardwares Criptográficos. No entanto, cada nova compra de SmartCard torna-se uma dor de cabeça e não foi diferente desta vez.</p>

<p>A Certisign usa soluções da Gemalto (Atualmente comprada pela <a href="https://www.thalesgroup.com/en">Thales</a>) e normalmente estes SmartCards não funcionam de primeira no Linux. Fui informado ao emitir meu certificado que a tecnologia dos SmartCards havia sido atualizada e fui munido de Notebook para a validação presencial.</p>

<p>Em tempos de pandemia de <a href="https://www.nature.com/articles/s41591-020-0820-9">SARS-CoV-2</a> - <a href="https://www1.folha.uol.com.br/poder/2021/03/relembre-o-que-bolsonaro-ja-disse-sobre-a-pandemia-de-gripezinha-e-pais-de-maricas-a-frescura-e-mimimi.shtml">dispar da ignorância</a> - se faz importante ressaltar que é possível a <a href="https://www.in.gov.br/en/web/dou/-/instrucao-normativa-iti-n-5-de-22-de-fevereiro-de-2021-304617035">emissão de certificados validados por Video Conferência</a>. A razão que precisei comparecer ao prédio da Associação Comercial se deu somente devida a necessidade da retirada dos novos cartões presencialmente.</p>

<h2 id="o-novo-cartão">O novo cartão</h2>

<p>O novo cartão me foi descrito como <em>“Cartão com o chip redondo”</em> - <a href="https://www.blogs.unicamp.br/dimensional/2009/04/29/044/">descrição relativamente adequada</a>:</p>

<p><img src="/assets/images/certisign_cartao_frente.jpg" alt="eCPF e cCNPJ Certisign Frente" /></p>

<p>Para quem tiver curiosidade, a parte traseira com a numeração de modelo/lote do cartão (Não é S/N, por isso envio a imagem)</p>

<p><img src="/assets/images/certisign_cartao_costas.jpg" alt="eCPF/eCNPJ Costas" /></p>

<p>A identificação via pcsc_scan é:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[root@manaira ~]# pcsc_scan 
Using reader plug'n play mechanism
Scanning present readers...
0: Gemalto PC Twin Reader 00 00
 
Thu Sep 16 12:19:32 2021
 Reader 0: Gemalto PC Twin Reader 00 00
  Event number: 11
  Card state: Card inserted, Shared Mode, 
  ATR: 3B 7F 96 00 00 80 31 80 65 B0 84 56 51 10 12 0F FE 82 90 00

ATR: 3B 7F 96 00 00 80 31 80 65 B0 84 56 51 10 12 0F FE 82 90 00
+ TS = 3B --&gt; Direct Convention
+ T0 = 7F, Y(1): 0111, K: 15 (historical bytes)
  TA(1) = 96 --&gt; Fi=512, Di=32, 16 cycles/ETU
    250000 bits/s at 4 MHz, fMax for Fi = 5 MHz =&gt; 312500 bits/s
  TB(1) = 00 --&gt; VPP is not electrically connected
  TC(1) = 00 --&gt; Extra guard time: 0
+ Historical bytes: 80 31 80 65 B0 84 56 51 10 12 0F FE 82 90 00
  Category indicator byte: 80 (compact TLV data object)
    Tag: 3, len: 1 (card service data byte)
      Card service data byte: 80
        - Application selection: by full DF name
        - EF.DIR and EF.ATR access services: by GET RECORD(s) command
        - Card with MF
    Tag: 6, len: 5 (pre-issuing data)
      Data: B0 84 56 51 10
    Tag: 1, len: 2 (country code, ISO 3166-1)
      Country code: 0F FE
    Tag: 8, len: 2 (status indicator)
      SW: 9000

Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B 7F 96 00 00 80 31 80 65 B0 84 56 51 10 12 0F FE 82 90 00
3B 7F .. 00 00 80 31 80 65 B0 .. .. .. .. 12 0F FE 82 90 00
	IDPrime MD 8840, 3840, 3810, 840 and 830 Cards T=0
</code></pre></div></div>

<p>E justamente esta identificação me permitiu achar os modulos corretos.</p>

<h2 id="os-modulos-pkcs11-do-cartão">Os modulos PKCS11 do cartão</h2>

<p>Até aqui, nada demais, a versão mais atual do Safenet Authentication Client é a <a href="https://data-protection-updates.gemalto.com/2021/07/05/safenet-authentication-client-sac-10-8-for-linux-release-announcement/">10.8</a> com um changelog interessante:</p>

<ul>
  <li>Rebranding to Thales</li>
  <li>Support for latest version for Ubuntu (v20.04), Red Hat (v8.3), Fedora (v34) and Cent OS (v8.3)</li>
  <li>Support for SafeNet IDPrime 930/3930 and SafeNet IDPrime 3940 FIDO</li>
  <li>Support for GTK3</li>
</ul>

<p>Sobre o primeiro ítem do changelog, <a href="https://www.thalesgroup.com/en/group/journalist/press-release/thales-completes-acquisition-gemalto-become-global-leader-digital">who cares</a>? Suportar versões novas de Ubuntu/RHEL/Fedora e CentOS é interessante. O IDPrime novo não faz sentido nesse caso e o Suporte a GTK3 seria muito desejado. <a href="https://gemalto.service-now.com/csm?sys_kb_id=23404c661b4d7c90e2af520f6e4bcbc9&amp;id=kb_article_view&amp;sysparm_rank=1&amp;sysparm_tsqueryId=4f71c86a1b4d7c90e2af520f6e4bcb8e&amp;sysparm_article=KB0024526">Mas o mundo não é flores</a>.</p>

<p>Nos resta a versão 10.7 disponível no link da <a href="https://www.globalsign.com/">GlobalSign</a>: <a href="https://support.globalsign.com/ssl/ssl-certificates-installation/safenet-drivers">https://support.globalsign.com/ssl/ssl-certificates-installation/safenet-drivers</a>.</p>

<h2 id="parte-genérica-da-instalação-pacotes">Parte genérica da instalação: Pacotes</h2>

<p>Não abordarei aqui os procedimentos de descompressão de arquivos pós-descarga. A parte que poucos sabem aqui é como instalar adequadamente pacotes .deb e .rpm (nas versões modernas) e seguem as linhas de exemplo para Fedora e Debian-based:</p>

<h3 id="fedora">Fedora</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dnf install /home/leonardo/Downloads/Linux\ RPM\ x64/SafenetAuthenticationClient-10.7.77-1.x86_64.rpm
</code></pre></div></div>

<h3 id="debian-based">Debian-based</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install /home/leonardo/Downloads/2021_CertisignSmartCard/safenetauthenticationclient_10.7.77_amd64.deb
</code></pre></div></div>

<p>Esta instalação dá acesso imediato ao Safenet Authentication Client Tools:</p>

<p><img src="https://user-images.githubusercontent.com/201189/133641434-36df1825-c089-41ca-9e24-a8c3bca1243b.png" alt="SACTools" /></p>

<h2 id="parte-não-genérica-da-instalação-configurações">Parte não genérica da instalação: Configurações</h2>

<h3 id="debian">Debian</h3>

<p>No Debian, por usar em uma máquina com <a href="https://gist.githubusercontent.com/leleobhz/e6d849e50da63cf5d86ff1b64c985a5d/raw/c69bcdfa08a69c05f7c8d5cc31b2c0a7e9fc7157/gistfile0.txt">muitas restrições computacionais</a>, utilizei o certificado via Firefox, bastando adicionar um novo plugin PKCS11 apontado para <code class="language-plaintext highlighter-rouge">/usr/lib/pkcs11/libIDPrimePKCS11.so</code></p>

<p><img src="https://user-images.githubusercontent.com/201189/133644220-0d659f27-b53c-4d3b-8405-c1b518b502c3.png" alt="Firefox PKCS11" /></p>

<h3 id="fedora-1">Fedora</h3>

<p>No Fedora com Chrome - <a href="https://gist.githubusercontent.com/leleobhz/2070efd61a54136272647055567a13f4/raw/70a69af508d1afadaba62127d3ef2455386957a0/gistfile0.txt">numa máquina mais modesta ainda</a> - a coisa fica diferente por causa do <a href="https://p11-glue.github.io/p11-glue/p11-kit.html">p11-kit</a></p>

<p>Em geral as pessoas tem medo do diferente, então é comum ouvir reclamações de que ficou mais difícil fazer as coisas. No caso do p11-kit esse caso não se aplica - ao menos não em relação ao <a href="https://linuxkamarada.com/en/2019/09/26/setting-up-smart-card-authentication-on-google-chrome-chromium/">caos que é adicionar módulos PKCS11 no Google Chrome</a>.</p>

<p>Bastam dois passos: A criação dos seguintes arquivos (Como root):</p>

<p><code class="language-plaintext highlighter-rouge">/etc/pkcs11/modules/eToken.module</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module: libeToken.so
managed: true
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">/etc/pkcs11/modules/IDPrime.module</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module: libIDPrimePKCS11.so
managed: true
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>E a criação dos links simbólicos corretos:
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ln -s /usr/lib64/libIDPrimePKCS11.so /usr/lib64/pkcs11/
ln -s /usr/lib64/libeToken.so /usr/lib64/pkcs11/
</code></pre></div></div>

<p>E aqui talvez fique explicado o update da versão 10.8 ter citado suporte explicito para distribuições Linux novas: Acredito que estes arquivos já sejam corretamente posicionados. No Fedora, a configuração do p11-kit é suficiente para todos os navegadores (E acredito que até para a autenticação PAM):</p>

<p><img src="https://user-images.githubusercontent.com/201189/133646329-2b32fcc7-9c2c-430c-9dd7-6648359e9546.png" alt="Firefox com p11-kit" /></p>

<p><img src="https://user-images.githubusercontent.com/201189/133646831-ec05af8c-7194-4f25-b088-3c924e815d10.png" alt="Chrome com p11-kit" /></p>

<h3 id="outras-distribuições-">Outras distribuições (?)</h3>

<p>Acredito que qualquer distribuição que utilize o p11-kit terá o mesmo procedimento adotado no Fedora - Seja nos pacotes RPM ou nos pacotes DEB<sup id="a1"><a href="#f1">1</a></sup>.</p>

<h2 id="considerações-finais">Considerações finais</h2>

<p>Pela primeira vez o procedimento foi mais fácil de executar, embora com alguns procedimentos manuais. Não é irrelevante notar que a versão 10.8 resolveria os problemas de acessibilidade em todas as distribuições modernas baseadas em RPM/DEB. Esta observação deveria ser suficiente para cobrar das Autoridades Ceritificadoras que disponibilzem os módulos atualizados de seus sistemas também.</p>

<p>Uma questão que pode ser relevante para escritórios que compartilhem cartões é a presença de um stack de <a href="https://p11-glue.github.io/p11-glue/p11-kit/manual/remoting.html">“cardshare” no p11-kit</a>. Pode ser um recurso muito interessante quando mais de uma pessoa precisa ler o SmartCard sem precisar apelar para métodos de transporte bastante arcaicos quanto o <a href="https://vidadeprogramador.com.br/2017/01/30/comunicacao-dpl-dpc/">CPC/CPL</a>.</p>

<p><b id="f1">1</b> É preciso notar que na versão deb no lugar da libeToken.so, é instalada na pasta pkcs11 o arquivo <code class="language-plaintext highlighter-rouge">libeTPkcs11.so</code>. Usualmente a guia de qual arquivo deve ser criado o link simbólico é usar os arquivos contidos em /usr/lib/pkcs11. <a href="#a1">↩</a></p>]]></content><author><name>Leonardo Amaral</name></author><category term="linux" /><category term="segurança" /><category term="token" /><category term="certisign" /><summary type="html"><![CDATA[Mais um capítulo da eterna briga entre usuários de Linux e usuários do ICP-Brasil com suas ACs que não gostam de suportar Linux.]]></summary></entry><entry><title type="html">Comentários (incompletos) sobre o Post mortem do TSE no Primeiro turno das Eleições 2020</title><link href="https://blog.leonardoamaral.com.br/Coment%C3%A1rios-sobre-o-Post-mortem-do-TSE/" rel="alternate" type="text/html" title="Comentários (incompletos) sobre o Post mortem do TSE no Primeiro turno das Eleições 2020" /><published>2020-11-18T11:00:00-03:00</published><updated>2020-11-18T11:00:00-03:00</updated><id>https://blog.leonardoamaral.com.br/Coment%C3%A1rios-sobre-o-Post-mortem-do-TSE</id><content type="html" xml:base="https://blog.leonardoamaral.com.br/Coment%C3%A1rios-sobre-o-Post-mortem-do-TSE/"><![CDATA[<p>O TSE em <a href="https://www.tse.jus.br/imprensa/noticias-tse/2020/Novembro/tse-divulga-nota-tecnica-sobre-o-atraso-da-totalizacao-dos-votos-no-primeiro-turno">nota à imprensa</a> divulgou uma nota técnica sobre o incidente do atraso no primeiro turno das eleições de 2020. Abaixo deixo uma cópia do documento no momento em que lí e minha perspectiva sobre o assunto, trecho-a-trecho. Lembrando que estas são <strong>impressões pessoais</strong> e sujeitas ao que se conhece <strong>no escopo do documento citado</strong> - salvo quando fato histórico citado no meio do texto.</p>

<p><a href="https://github.com/leleobhz/leleobhz.github.io/files/5560645/TSE-nota-tecnica-eleicoes-2020.pdf">TSE-nota-tecnica-eleicoes-2020.pdf</a></p>

<p>1) O sistema da Oracle não é a única partícula nesta equação, segundo o próprio item “<em>[n]a arquitetura descentralizada, o fato de existir um banco de dados e um servidor de aplicações local em um computador em cada TRE aumenta o leque de potenciais ataques ao ambiente, que podem ser mitigados com a localização física destas máquinas no ambiente do TSE.</em>”</p>

<p>2) Até as declarações que o Barroso levantou na noite da eleição não tinha como relacionar corretamente qual era o sistema danificado na equação. O fato do TSE ter licitado uma solução da Oracle não garante que seja a única aplicação usada na solução e também foi isso que quis dizer <a href="https://www.facebook.com/vidadba/posts/3510817589005902?comment_id=3510859325668395">em algumas discussões</a> quando disse que alguns comentários ignoraram a complexidade de ambiente (Talvez tivesse tido muito sarcasmo? Talvez. Disgurpa, a internet das pessoas físicas é assim).</p>

<p>3) Ainda falando do momento pré-post mortem, quando se culpa <strong>Um processador</strong> por atraso - ainda mais considerando que a solução de banco de nabos (risos) tinha caráter de cloud - não deveria afetar da maneira que afetou a apuração. Lembrando que em eleições passadas, usualmente o resultado ficava disponível por volta de 4h depois do pleito e esse tempo aumentou pra algo próximo do dobro (Já que os resultados foram somados em quase totalidade somente perto da meia noite - quase 7h depois do término do pleito). Um processador queimado dobraria mesmo o tempo de apuração? E daqui já parte a suspeita de que a informação dada até o momento era INCORRETA OU IMPRECISA. E por isso bati na tecla de que <strong>não dava pra falar nada até soltarem um post mortem</strong>. Este ponto sobre especulação pré-post mortem também gerou <a href="https://www.facebook.com/vidadba/posts/3510817589005902?comment_id=3510859325668395">discussões acaloradas pela Internet</a>.</p>

<p>4) “<em>De acordo com o Contrato TSE nº 22/2020, os serviços foram contratados diretamente, por inexigibilidade de licitação, com base no art. 25, inciso I, da Lei nº 8.666/93(lei das licitações), que prevê que é inexigível a licitação quando houver inviabilidade de competição, tendo em vista a existência de fornecedor exclusivo.</em>” <br /><br />Neste sentido minha opinião é ressonante com a perspectiva do <a href="https://twitter.com/samadeu/status/1328791205132505089">Sergio Amadeu da Silveira</a>.</p>

<p>5) “<em>No caso do TSE, a contratação em prestação de serviço “Cloud at Customer” é composta de dois supercomputadores (um principal e um redundante),e a Oracle fornece todos os softwares de banco de dados e presta serviços de suporte e atualização dos produtos.</em>“<br /><br />Aqui temos um problema, pois realmente o Banco de Nabos da Oracle só pode ser vendido por ela, <strong>mas uma solução Cloud, não</strong>. Existem mais de um fornecedor de infraestrutura para Cloud disponíveis no Brasil. E ainda que falemos somente em banco de dados, existem também mais de uma empresa que provê banco de dados que suportam a magnitude dos dados que o TSE tem (<a href="https://www.ibm.com/br-pt/cloud/databases">IBM</a> está na lista, por exemplo). Então este princípio da inexigibilidade foi adotado incorretamente. Sem fanboysismo por Oracle x IBM x SAP e outros players, a lei é essa e não foi adequadamente observada.</p>

<p>6) “<em>O contrato assinado em março de 2020 previa o prazo de 70 dias para a entrega dos equipamentos ao TSE, que deveriam, portanto, ter chegado no início de junho de 2020. Emr azão da pandemia da Covid-19, porém, a Oracle –assim como as demais empresas de  tecnologia  do  mundo -foi  afetada  pela  ausência  de  peças  eletrônicas  e indisponibilidade de dispositivos. Por isso, a entrega do equipamento se deu com cerca de um mês de atraso, em 17 de julho de 2020.</em>“<br />+<br />“<em>Cinco testes de totalização foram planejados para as Eleições 2020 pela equipe técnica do tribunal. Porém, em razão do atraso na entrega provocado pela pandemia e do cronograma de testes, apenas os dois últimos foram feitos com o equipamento Oracle.</em>“<br /><br />Até aqui, tudo certo, porém não era o caso então de pedir o atraso das Eleições? Quem acatou que somente dois testes eram suficientes acatou o risco de alterar a especificação inicial do projeto. Se fosse bobagem observar este ponto, não haveria impacto no dia da Eleição.</p>

<p>7) “<em>Por meio do contrato, a Oracle disponibiliza ao TSE um servidor principal “Exadata X8 Full Rack”, com oito nós (núcleos) de processamento, e um “Exadata X8 Half Rack”, com quatro nós de processamento.</em>“<br />+<br />“<em>Durante a totalização dos votos no dia 15/11,observou-se o desligamento de um dos oito nós de processamento do servidor principal.</em>“<br /><br />Há um problema de ordem lógica aqui. A falha foi em um dos processadores, mas pelo tempo que a eleição levou para ser calculada, não foi somente um processador que foi <strong>DESCONECTADO</strong>, mesmo que somente um deles tenha sido danificado. Ai temos o seguinte: Na função de um pleito eleitoral do tamanho que é, <strong>quem diabos coloca redundância assimétrica nessa joça?</strong> O que a TI do TSE tem na cabeça? O resultado é ruido que deu. A TI do TSE ignorou inclusive que uma falha nesses sistemas tem uma implicação POLITICA grave (E tá ai os comentários de todos os partidos políticos e da pressão política sobre o pleito - que já não era pouca). Dado o nível dos profissionais que esperava-se ter nesta solução acho sim os chamar de retardados algo no mínimo justo - embora pouco pólido.</p>

<p>8) “<em>Posteriormente, porém, constatou-seque a falha no nó não teve relação direta e imediata com a demora da totalização, tendo em vista que, com o desligamento de um dos nós,o equipamento foi capaz de redistribuir de forma automática a carga para os demais nós de processamento sem impacto no desempenho e disponibilidade.No entanto, ao supor inicialmente que essa falha poderia ter originado a demora na totalização, a equipe da Secretaria de Tecnologia da Informação (STI) do TSE dedicou os seus esforços à verificação desse problema e ao restabelecimento do funcionamento do nó, atrasando a identificação da causa direta do problema a ser solucionado para maior celeridade na contabilização. Por isso, a STI entende que, de forma indireta, o episódio contribuiu para o atraso na divulgação dos resultados.</em>“<br /><br />Se um nó meio rack com 4 processadores era suficiente e não causaria atraso (Hipótese levantada ao dizer que o desligamento e redistribuição de carga não causou impacto no desempenho e na disponibilidade), porque então compraram o nó principal com 8 cores? Então ou a compra foi além do que devia (Se realmente eles estão certos nessa afirmação) ou foi aquém do que devia (No caso dessa afirmação ser um truque de palavras - que é meu credo nesse sentido).<br /><br /><strong>Nos dois casos, MÁ ESPECIFICAÇÃO de solução.</strong><br /><br />Ainda sobre o fato dos técnicos debruçados no problema terem atrasado a identificação do problema, então o cluster tinha que ser operado manualmente? Esperava mais numa solução desse porte (Veja que novamente, a critica e a acidez dela é dimensionada para o tamanho do que se esperava, não para as pessoas físicas envolvidas no processo).</p>

<p>9) “<em>O TSE informa que, nesta terça-feira (17/11), a equipe da Oracle identificou problema na memória do nó que falhou no domingo e realizou a devida troca do nó defeituoso, de modo que o equipamento se encontra plenamente funcional.</em>“<br /><br />Speechless. Além do sistema não ter convergência automática (E soma-se a sabotagem da fase de testes conforme apontei no item 6, depender de convergência manual e de ter um cluster assimétrico - ainda não conseguiram identificar a tempo e hora se o problema era CPU ou Memória? Ademais, 3 dias para substituição de peças? Ninguém colocou spare in loco para esse cluster não?</p>

<p>10) “<em>No domingo, após o restabelecimento do nó com o suporte da equipe da Oracle, que,inclusive, tinha representantes presente no TSE, verificou-se que a lentidão prosseguia. Ao realizar os esforços de apurar a causa do incidente, a Tecnologia da Informação identificou que a lentidão foi ocasionada por recurso de inteligência artificial existente em um otimizador do banco de dados Oracle,que garante o processamento veloz.</em>“<br /><br />Sabe o item 6? Teriam pego isso lá e o próprio documento admite isso:<br /><br />“<em>Porém, isso poderia ter sido evitado com a realização de testes para calibrar o otimizador. Novos planos de execução foram gerados ao longo da totalização, mas se mostraram ineficientes diante do crescimento do volume de dados.</em>”</p>

<p>11) “<em>Equipes técnicas do TSE e da Oracle entendem que a falha no plano de execução no primeiro turno não se repetirá no segundo turno, em 29 de novembro, tendo em vista que o otimizador já está calibrado para processar um volume maior de informações de forma célere.No entanto, até o dia 29 de novembro, toda a equipe está focada na definição de providências para evitar incidente semelhante na apuração e totalização dos resultados do segundo turno.</em>“<br /><br />O TSE e a Oracle vão completar os 3 testes + a validação do que houve no primeiro turno até o dia 29?</p>

<h2 id="minha-conclusão">Minha conclusão:</h2>

<ul>
  <li>TSE precisa aprender a fazer post-mortem. Estes são post-mortem decentes:<br /><br />
    <ul>
      <li><a href="https://blog.cloudflare.com/tag/postmortem/">https://blog.cloudflare.com/tag/postmortem/</a></li>
      <li><a href="https://github.blog/2018-10-30-oct21-post-incident-analysis/">https://github.blog/2018-10-30-oct21-post-incident-analysis/</a></li>
      <li><a href="https://github.blog/2020-03-26-february-service-disruptions-post-incident-analysis/">https://github.blog/2020-03-26-february-service-disruptions-post-incident-analysis/</a></li>
      <li><a href="https://about.gitlab.com/blog/2017/02/10/postmortem-of-database-outage-of-january-31/">https://about.gitlab.com/blog/2017/02/10/postmortem-of-database-outage-of-january-31/</a></li>
    </ul>
  </li>
  <li>
    <p>Meu entendimento é que se o TSE contrata o suporte da Oracle, era obrigação da Oracle fazer esta reconstrução do post-mortem. Este relatório da forma que veio mostra a má vontade política e técnica em fazer um relatório de incidentes.</p>
  </li>
  <li>
    <p>As incongruências do documento apontam uma total desorientação sobre o que aconteceu até o dia de hoje.</p>
  </li>
  <li>O TSE na minha leitura descumpriu a lei das licitações.</li>
</ul>]]></content><author><name>Leonardo Amaral</name></author><category term="politica" /><category term="análise" /><summary type="html"><![CDATA[Uma pequena análise sobre o post mortem do TSE sobre atraso na apuração das eleições 2020 no Brasil]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://user-images.githubusercontent.com/201189/99551333-7932b200-299a-11eb-9580-10584a89b2bc.jpeg" /><media:content medium="image" url="https://user-images.githubusercontent.com/201189/99551333-7932b200-299a-11eb-9580-10584a89b2bc.jpeg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Olá Mundo</title><link href="https://blog.leonardoamaral.com.br/ola-mundo/" rel="alternate" type="text/html" title="Olá Mundo" /><published>2020-11-11T12:00:00-03:00</published><updated>2020-11-11T12:00:00-03:00</updated><id>https://blog.leonardoamaral.com.br/ola-mundo</id><content type="html" xml:base="https://blog.leonardoamaral.com.br/ola-mundo/"><![CDATA[<p>Poste curtinho, simples (E cansado como deve ser) pra anunciar este espaço para compartilhar algumas falcatruas técnicas que são feitas no dia a dia tanto <a href="https://twitter.com/pqatsi"><em>deste quem vos fala</em></a> quanto <a href="https://zenithtecnologia.com.br/"><em>de sua empresa também</em></a>.</p>

<p><img src="/assets/images/por_hoje_e_so_pessoal.jpg" width="100%" /></p>]]></content><author><name>Leonardo Amaral</name></author><summary type="html"><![CDATA[Poste curtinho, simples (E cansado como deve ser) pra anunciar este espaço para compartilhar algumas falcatruas técnicas que são feitas no dia a dia tanto deste quem vos fala quanto de sua empresa também.]]></summary></entry></feed>