<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: João Pedro </title>
    <description>The latest articles on DEV Community by João Pedro  (@joaoprd).</description>
    <link>https://dev.to/joaoprd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1063957%2F008438a3-ed67-47e1-9e4d-05df51502bf6.jpg</url>
      <title>DEV Community: João Pedro </title>
      <link>https://dev.to/joaoprd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaoprd"/>
    <language>en</language>
    <item>
      <title>Guia Warcraft III de Etiqueta para Pull Requests</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Fri, 16 Jan 2026 15:09:09 +0000</pubDate>
      <link>https://dev.to/joaoprd/guia-warcraft-iii-de-etiqueta-para-pull-requests-b29</link>
      <guid>https://dev.to/joaoprd/guia-warcraft-iii-de-etiqueta-para-pull-requests-b29</guid>
      <description>&lt;p&gt;Se os orcs e humanos fossem desenvolvedores, o Code Review seria assim:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avisos e Erros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Can't build there": Quando a build quebra ou o código está no lugar errado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Work complete": PR aprovado e mergeado.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;No Meio do Caos (A vida de Dev):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"What?": Vendo aquele código legado sem sentido.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Me busy!" / "Leave me alone!": Quando pedem review no meio do foco.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"No time for play!": Subindo correção de bug em produção.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Me not that kind of Orc!": Quando sugerem uma gambiarra técnica.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Aceitando Desafios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Ready to work!": Abrindo um novo PR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Something need doing?": Caçando PRs na fila para revisar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"I can do that!" / "Be happy to!": Aplicando as sugestões do revisor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Work, work!": Codando a próxima task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Okie dokie!": O último comentário antes do Approve.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>programming</category>
      <category>github</category>
    </item>
    <item>
      <title>Basic Server Hardening for Ubuntu/Debian: SSH Access and Firewall</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Mon, 04 Aug 2025 22:54:01 +0000</pubDate>
      <link>https://dev.to/joaoprd/basic-server-hardening-for-ubuntudebian-ssh-access-and-firewall-g2e</link>
      <guid>https://dev.to/joaoprd/basic-server-hardening-for-ubuntudebian-ssh-access-and-firewall-g2e</guid>
      <description>&lt;p&gt;Contrary to what many tutorials suggest, simply changing the SSH port or installing Fail2Ban is not enough. This documentation shows the exact steps to harden the security of an Ubuntu/Debian server by configuring key-based authentication, disabling insecure defaults, and reducing the attack surface.&lt;/p&gt;

&lt;p&gt;Author: joaoprd | &lt;a href="mailto:joaopedrord2001@gmail.com"&gt;joaopedrord2001@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Secure Administrator User
&lt;/h2&gt;

&lt;p&gt;Create a user with sudo privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adduser whiterose
usermod -aG sudo whiterose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user whiterose will be the only one authorized to connect via SSH after hardening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Public Key and Manually Configure SSH Login
&lt;/h2&gt;

&lt;p&gt;Public key authentication avoids the use of passwords and is essential for a secure server. This step will be done manually, without using ssh-copy-id.&lt;/p&gt;

&lt;h3&gt;
  
  
  On the Client
&lt;/h3&gt;

&lt;p&gt;Generate the RSA key pair (if it doesn’t already exist):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -C "whiterose@server"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default path (~/.ssh/id_rsa) and, if desired, set a passphrase for the private key.&lt;/p&gt;

&lt;p&gt;The generated keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private: ~/.ssh/id_rsa → must never leave the client
Public: ~/.ssh/id_rsa.pub → will be copied to the server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Display the contents of the public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the displayed content (starts with ssh-rsa).&lt;/p&gt;

&lt;h3&gt;
  
  
  On the Server
&lt;/h3&gt;

&lt;p&gt;Create the .ssh directory for the user whiterose (if it doesn’t exist):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /home/whiterose/.ssh
sudo chown whiterose:whiterose /home/whiterose/.ssh
sudo chmod 700 /home/whiterose/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create (or edit) the authorized_keys file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /home/whiterose/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the public key copied from the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set the correct permissions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown whiterose:whiterose /home/whiterose/.ssh/authorized_keys
sudo chmod 600 /home/whiterose/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From now on, the user whiterose will be able to connect via SSH using the private key corresponding to the uploaded public key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disable root login and password authentication in SSH
&lt;/h2&gt;

&lt;p&gt;On the Ubuntu/Debian server, edit the SSH configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify or add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PermitRootLogin no
PasswordAuthentication no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the SSH service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;code&gt;!!! Only do this after confirming that public key access is working for the user whiterose !!!&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable Firewall (UFW)
&lt;/h2&gt;

&lt;p&gt;Install and activate UFW:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw --force enable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All unauthorized services will be blocked. Only SSH (port 22) will be accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix Permissions of Sensitive Files
&lt;/h2&gt;

&lt;p&gt;Adjust permissions of the /etc/shadow file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 640 /etc/shadow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that only root and the shadow group have read access to password contents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and Configure Fail2Ban (Protection Against Brute Force Attacks)
&lt;/h2&gt;

&lt;p&gt;Fail2Ban monitors authentication logs and automatically blocks IPs that attempt malicious access to the server. Even with key-based authentication, it is important to protect the server against scanners and brute force attempts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Configuration
&lt;/h3&gt;

&lt;p&gt;Fail2Ban comes with default settings, but it’s recommended to create a local configuration file for customization (to avoid conflicts during updates):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recommended Adjustments (in jail.local)
&lt;/h3&gt;

&lt;p&gt;In the [DEFAULT] section, modify existing fields or add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[DEFAULT]
ignoreip = (IPs that will never be banned)
bantime = 1h
maxretry = 3
findtime = 10m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Restart Fail2Ban
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo tail -f /var/log/fail2ban.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these steps, you ensure a basic and effective protection for your Ubuntu/Debian server. Using SSH keys, disabling root login, enabling the firewall, and configuring Fail2Ban helps prevent common attacks and makes your system more secure.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>debian</category>
      <category>security</category>
      <category>network</category>
    </item>
    <item>
      <title>Hardening Básico de Servidor Ubuntu/Debian: Acesso SSH e Firewall</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Mon, 04 Aug 2025 22:40:30 +0000</pubDate>
      <link>https://dev.to/joaoprd/hardening-basico-de-servidor-ubuntudebian-acesso-ssh-e-firewall-5lm</link>
      <guid>https://dev.to/joaoprd/hardening-basico-de-servidor-ubuntudebian-acesso-ssh-e-firewall-5lm</guid>
      <description>&lt;p&gt;Ao contrário do que muitos tutoriais sugerem, alterar apenas a porta SSH ou instalar Fail2Ban não é suficiente. Esta documentação mostra os passos exatos para endurecer a segurança de um servidor Ubuntu / Debian configurando autenticação por chave, desabilitando padrões inseguros e reduzindo a superfície de ataque.&lt;/p&gt;

&lt;p&gt;Autor: joaoprd | &lt;a href="mailto:joaopedrord2001@gmail.com"&gt;joaopedrord2001@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criar usuário administrador seguro
&lt;/h2&gt;

&lt;p&gt;Criar um usuário com privilégios sudo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adduser whiterose
usermod -aG sudo whiterose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O usuário whiterose será o único autorizado a conectar via SSH após o hardening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerar chave pública e configurar login SSH manualmente
&lt;/h2&gt;

&lt;p&gt;A autenticação por chave pública evita o uso de senhas e é essencial para um servidor seguro. Essa etapa será feita manualmente, sem o uso do ssh-copy-id.&lt;/p&gt;

&lt;h3&gt;
  
  
  No cliente
&lt;/h3&gt;

&lt;p&gt;Gerar o par de chaves RSA (caso ainda não exista):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -C "whiterose@servidor"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pressione &lt;code&gt;Enter&lt;/code&gt; para aceitar o caminho padrão (~/.ssh/id_rsa) e, se desejar, defina uma senha para a chave privada.&lt;/p&gt;

&lt;p&gt;As chaves geradas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Privada: ~/.ssh/id_rsa → nunca deve sair do cliente
Pública: ~/.ssh/id_rsa.pub → será copiada para o servidor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exibir o conteúdo da chave pública:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copie o conteúdo exibido (começa com ssh-rsa).&lt;/p&gt;

&lt;h3&gt;
  
  
  No servidor
&lt;/h3&gt;

&lt;p&gt;Criar o diretório .ssh para o usuário whiterose (caso não exista):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /home/whiterose/.ssh
sudo chown whiterose:whiterose /home/whiterose/.ssh
sudo chmod 700 /home/whiterose/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criar (ou editar) o arquivo authorized_keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /home/whiterose/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cole a chave pública copiada do cliente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ajustar permissões
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown whiterose:whiterose /home/whiterose/.ssh/authorized_keys
sudo chmod 600 /home/whiterose/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir de agora, o usuário whiterose poderá se conectar via SSH utilizando a chave privada correspondente à pública inserida.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desativar login root e autenticação por senha no SSH
&lt;/h2&gt;

&lt;p&gt;No servidor Ubuntu / Debian deve-se editar o arquivo de configuração do SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modificar ou adicionar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PermitRootLogin no
PasswordAuthentication no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reiniciar o serviço SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;code&gt;!!!  Faça isso somente após confirmar que o acesso com chave pública está funcionando para o usuário whiterose !!!&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Ativar firewall (UFW)
&lt;/h2&gt;

&lt;p&gt;Instalar e ativar o UFW:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw --force enable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todos os serviços não autorizados serão bloqueados. Apenas SSH (porta 22) estará acessível.&lt;/p&gt;

&lt;h2&gt;
  
  
  Corrigir permissões de arquivos sensíveis
&lt;/h2&gt;

&lt;p&gt;Ajustar permissões do arquivo /etc/shadow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 640 /etc/shadow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Garante que apenas root e o grupo shadow tenham acesso de leitura ao conteúdo das senhas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalar e Configurar Fail2Ban (Proteção contra Brute Force)
&lt;/h2&gt;

&lt;p&gt;O Fail2Ban monitora logs de autenticação e bloqueia automaticamente IPs que tentam acessar o servidor de forma maliciosa. Mesmo com autenticação por chaves, é importante protegê-lo contra scanners e tentativas de força bruta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalação
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuração Básica
&lt;/h3&gt;

&lt;p&gt;O Fail2Ban já vem com configurações padrão, mas é recomendável criar um arquivo local para personalização (evitando conflitos em atualizações):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ajustes Recomendados (em jail.local)
&lt;/h3&gt;

&lt;p&gt;Na seção [DEFAULT], modifique os campos se já existirem ou adicione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[DEFAULT]
ignoreip = (IPs que nunca serão banidos)
bantime = 1h
maxretry = 3
findtime = 10m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reinicie o Fail2Ban
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verificar os logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo tail -f /var/log/fail2ban.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Seguindo estes passos, você garante uma proteção básica e eficiente para seu servidor Ubuntu/Debian. Usar chave SSH, desativar o login root, ativar o firewall e configurar o Fail2Ban ajuda a evitar ataques comuns e deixa seu sistema mais seguro.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>debian</category>
      <category>security</category>
      <category>network</category>
    </item>
    <item>
      <title>GLPI - Closing Ticket with API</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Tue, 13 Aug 2024 20:53:25 +0000</pubDate>
      <link>https://dev.to/joaoprd/glpi-closing-ticket-with-api-4mpk</link>
      <guid>https://dev.to/joaoprd/glpi-closing-ticket-with-api-4mpk</guid>
      <description>&lt;p&gt;Unlike what is described in the official GLPI documentation, the system does not work as expected and does not correctly respond to the provided parameters. The documentation found at &lt;code&gt;"https://YOUR_GLPI_DOMAIN.COM/apirest.php"&lt;/code&gt; states that some parameters should be passed in the request body, but this doesn't always work. The only method that seems to work is passing the parameters directly in the URL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Autor&lt;/strong&gt;: joaoprd | &lt;a href="mailto:joaopedrord2001@gmail.com"&gt;joaopedrord2001@gmail.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Starting a Session
&lt;/h2&gt;

&lt;p&gt;To initiate any call, we need the session_token and app-token. To generate the session_token, we make a request to &lt;code&gt;"https://YOUR_GLPI_DOMAIN.COM/apirest.php/initSession"&lt;/code&gt; with the app-token and user_token parameters, which are available in the user account we are working with.&lt;/p&gt;

&lt;p&gt;The following request generates the session_token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/initSession?app-token={YOUR-APP-TOKEN}&amp;amp;user_token={YOUR-USER-TOKEN}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ticket Search
&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;session_token&lt;/code&gt; in hand, we can perform searches for tickets. However, according to the GLPI documentation, it appears that the endpoint does not function as per the provided examples, as it does not allow sending a payload to this endpoint, resulting in the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"ERROR_JSON_PAYLOAD_FORBIDDEN"&lt;/span&gt;,
    &lt;span class="s2"&gt;"GET Request should not have json payload (http body); view documentation in your browser at /#ERROR_JSON_PAYLOAD_FORBIDDEN"&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To circumvent this limitation, we will pass the parameters directly in the URL of the request, using the link &lt;code&gt;"https://YOUR_GLPI_DOMAIN.COM/apirest.php/search/Ticket"&lt;/code&gt;. You must include the &lt;code&gt;app-token&lt;/code&gt; and &lt;code&gt;session-token&lt;/code&gt; to connect, and then add the desired filters to locate the necessary information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--globoff&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/search/Ticket
?app-token={YOUR-APP-TOKEN}
&amp;amp;session_token={YOUR-SESSION-TOKEN}
&amp;amp;criteria[0][field]=1
&amp;amp;criteria[0][searchtype]=contains
&amp;amp;criteria[0][value]=Verifica%C3%A7%C3%A3o%20diaria
&amp;amp;criteria[1][link]=AND
&amp;amp;criteria[1][field]=12
&amp;amp;criteria[1][searchtype]=equals
&amp;amp;criteria[1][value]=2
&amp;amp;glpilist_limit=1000'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Criteria" refers to the filtering criteria, where fields are specific filters to be applied to find something. For example, "criteria[0][field]=1" is designated for the title, where we pass "criteria[0][searchtype]=contains" indicating that it contains "criteria[0][value]=Verifica%C3%A7%C3%A3o%20diaria", which, in this case, is 'Verificação diária' that was encoded. This is where the ticket title should be placed. Another filter is applied below in "criteria[1][link]=AND", where an AND is performed, indicating a new search following the previous one.&lt;/p&gt;

&lt;p&gt;To analyze all filtering options, you can make a request to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/listSearchOptions/Ticket?app-token={YOUR-APP-TOKEN}&amp;amp;session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some example responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"common"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Características"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Título"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"itemlink"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.name"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"21"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Descrição"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.content"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.id"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Task
&lt;/h2&gt;

&lt;p&gt;With the previous request, we performed the search for tickets, which will be returned in JSON format. With this information, we can handle the necessary tasks. In this specific documentation, we will close the ticket. However, before completely closing the ticket, we need to create a task linked to the ticket that must be completed.&lt;/p&gt;

&lt;p&gt;Some GLPI systems require specific methods for closing tickets. In the system I am working with, it is necessary to create a task and a solution before closing the ticket.&lt;/p&gt;

&lt;p&gt;Below is the request that creates the task in the ticket (remember that the ticket I am passing was generated in the previous search in "Ticket Search"). In my automation code, I implemented a loop to process all returned tickets, but that will not be covered in this documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/TicketTask?session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'app_token: {YOUR-APP-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: user_token {YOUR-USER-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "input": {
        "tickets_id": 2408020023, 
        "taskcategories_id": 0, 
        "content": "Verificação diária - Tarefa realizada.",
        "actiontime": 60, 
        "state": 3 
    }
}
'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should note that in all cases, we pass the app_token in the header, and the Authorization, which contains the user_token for API authentication.&lt;/p&gt;

&lt;p&gt;Key points to consider are the parameters passed in the request body:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;content: The content that will be added to the task.&lt;/li&gt;
&lt;li&gt;actiontime: The time spent on the task.&lt;/li&gt;
&lt;li&gt;state: The status the ticket will have after the task is created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing the Ticket
&lt;/h2&gt;

&lt;p&gt;With the task added to the ticket, it is only necessary to close the ticket, which follows the same process used to add the task.&lt;/p&gt;

&lt;p&gt;The following request is used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; PUT &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/Ticket/2408020023?session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'app_token: {YOUR-APP-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: user_token {YOUR-USER-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
  "input": {
    "status": 6, 
    "solution": "&amp;lt;p&amp;gt;Chamado finallizado&amp;lt;/p&amp;gt;",  
    "content": "&amp;lt;p&amp;gt;Chamado finallizado&amp;lt;/p&amp;gt;",
    "solutiontypes_id": 3, 
    "solutiontemplates_id": 5  
  }
}'&lt;/span&gt;
&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;status: 6&lt;/code&gt; indicates the ticket is closed. For this, it is necessary to pass the &lt;code&gt;solution&lt;/code&gt; and &lt;code&gt;content&lt;/code&gt; as the texts for the solution. An important point in this request is the &lt;code&gt;solutiontemplates_id&lt;/code&gt;, which must be created by the GLPI system administrator, with this ID serving as a reference for a standard solution.&lt;/p&gt;

</description>
      <category>glpi</category>
      <category>backend</category>
      <category>backenddevelopment</category>
      <category>api</category>
    </item>
    <item>
      <title>GLPI - Fechar ticket com API</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Tue, 13 Aug 2024 20:29:28 +0000</pubDate>
      <link>https://dev.to/joaoprd/glpi-fechar-ticket-com-api-4a9l</link>
      <guid>https://dev.to/joaoprd/glpi-fechar-ticket-com-api-4a9l</guid>
      <description>&lt;p&gt;Diferente do que está descrito na documentação oficial do GLPI, o sistema não funciona como deveria e não responde corretamente aos parâmetros fornecidos. A documentação encontrada em &lt;code&gt;"https://DOMINIO_GLPI.COM/apirest.php"&lt;/code&gt; informa que alguns parâmetros devem ser passados no corpo da requisição, mas isso nem sempre funciona. O único jeito que parece funcionar é passando os parâmetros diretamente na URL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Autor&lt;/strong&gt;: joaoprd | &lt;a href="mailto:joaopedrord2001@gmail.com"&gt;joaopedrord2001@gmail.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Iniciando sessão
&lt;/h2&gt;

&lt;p&gt;Para iniciar qualquer chamada, precisamos do session_token e do app-token. Para gerar o session_token, fazemos uma requisição para &lt;code&gt;"https://DOMINIO_GLPI//apirest.php/initSession"&lt;/code&gt; com os parâmetros app-token e user_token, que estão disponíveis na conta do usuário com a qual estamos trabalhando.&lt;/p&gt;

&lt;p&gt;A requisição abaixo gera o session_token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/initSession?app-token={YOUR-APP-TOKEN}&amp;amp;user_token={YOUR-USER-TOKEN}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pesquisa de tickets
&lt;/h2&gt;

&lt;p&gt;Com o &lt;code&gt;session_token&lt;/code&gt; em mãos, podemos realizar pesquisas sobre os chamados. No entanto, de acordo com a documentação do GLPI, parece que o endpoint não funciona conforme os exemplos fornecidos, pois não é permitido enviar PAYLOAD para esse endpoint, resultando no seguinte erro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"ERROR_JSON_PAYLOAD_FORBIDDEN"&lt;/span&gt;,
    &lt;span class="s2"&gt;"GET Request should not have json payload (http body); view documentation in your browser at /#ERROR_JSON_PAYLOAD_FORBIDDEN"&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para contornar essa limitação, vamos passar os parâmetros diretamente na URL da requisição, utilizando o link &lt;code&gt;"https://DOMINIO_GLPI.COM/apirest.php/search/Ticket"&lt;/code&gt;. É necessário incluir o &lt;code&gt;app-token&lt;/code&gt; e o &lt;code&gt;session-token&lt;/code&gt; para se conectar, e em seguida, adicionar os filtros desejados para localizar as informações necessárias.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--globoff&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/search/Ticket
?app-token={YOUR-APP-TOKEN}
&amp;amp;session_token={YOUR-SESSION-TOKEN}
&amp;amp;criteria[0][field]=1
&amp;amp;criteria[0][searchtype]=contains
&amp;amp;criteria[0][value]=Verifica%C3%A7%C3%A3o%20diaria
&amp;amp;criteria[1][link]=AND
&amp;amp;criteria[1][field]=12
&amp;amp;criteria[1][searchtype]=equals
&amp;amp;criteria[1][value]=2
&amp;amp;glpilist_limit=1000'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Criteria" é a chamada de filtro, os fields são determidos filtros a serem colocados para encontrar algo. Por exemplo, "criteria[0][field]=1" é designado para o título onde passamos "criteria[0][searchtype]=contains" informando que contém "criteria[0][value]=Verifica%C3%A7%C3%A3o%20diaria", no caso seria 'Verificação diária' que foi encodado, mas ali seria o local a colocar o título do chamado. É feito outra filtragem abaixo em criteria[1][link]=AND, onde se é feito o AND informando uma nova pesquisa seguindo a anterior.&lt;/p&gt;

&lt;p&gt;Para analisar todas as filtragens pode-se fazer a requisição para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/listSearchOptions/Ticket?app-token={YOUR-APP-TOKEN}&amp;amp;session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alguns retornos para exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"common"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Características"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Título"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"itemlink"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.name"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"21"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Descrição"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.content"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"glpi_tickets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datatype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nosearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nodisplay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"available_searchtypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"notcontains"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ticket.id"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Criação de tarefa
&lt;/h2&gt;

&lt;p&gt;Com a requisição anterior, realizamos a busca dos chamados, que retornarão em formato JSON. Com essas informações, podemos realizar as tratativas necessárias. No caso específico desta documentação, vamos fechar o chamado. No entanto, antes de fechar o chamado completamente, precisamos criar uma tarefa vinculada ao ticket que deve ser concluída.&lt;/p&gt;

&lt;p&gt;Alguns sistemas GLPI requerem o fechamento de chamados de formas específicas. No sistema em que estou trabalhando, é necessário criar uma tarefa e uma solução antes de fechar o chamado.&lt;/p&gt;

&lt;p&gt;Abaixo está a requisição que cria a tarefa no ticket (lembre-se de que o ticket que estou passando foi gerado na busca anterior em "Pesquisa de tickets"). Em meu código de automação, foi implementado um loop para processar todos os tickets retornados, mas isso não será abordado nesta documentação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/TicketTask?session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'app_token: {YOUR-APP-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: user_token {YOUR-USER-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "input": {
        "tickets_id": 2408020023, 
        "taskcategories_id": 0, 
        "content": "Verificação diária - Tarefa realizada.",
        "actiontime": 60, 
        "state": 3 
    }
}
'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Devemos observar que, em todos os casos, passamos o &lt;code&gt;app_token&lt;/code&gt; no header, e o &lt;code&gt;Authorization&lt;/code&gt;, que contém o &lt;code&gt;user_token&lt;/code&gt; para autenticação da API.&lt;/p&gt;

&lt;p&gt;Pontos importantes a serem considerados são os parâmetros passados no corpo da requisição:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;content: O conteúdo que será inserido na tarefa.&lt;/li&gt;
&lt;li&gt;actiontime: O tempo gasto na tarefa.&lt;/li&gt;
&lt;li&gt;state: O estado que o chamado terá após a criação da tarefa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fechamento do chamado
&lt;/h2&gt;

&lt;p&gt;Com a tarefa adicionada ao chamado, é necessário apenas realizar o fechamento do chamado, que segue o mesmo processo utilizado para adicionar a tarefa.&lt;/p&gt;

&lt;p&gt;Utiliza-se a seguinte requisição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; PUT &lt;span class="s1"&gt;'https://DOMINIO_GLPI.COM/apirest.php/Ticket/2408020023?session_token={YOUR-SESSION-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'app_token: {YOUR-APP-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: user_token {YOUR-USER-TOKEN}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
  "input": {
    "status": 6, 
    "solution": "&amp;lt;p&amp;gt;Chamado finallizado&amp;lt;/p&amp;gt;",  
    "content": "&amp;lt;p&amp;gt;Chamado finallizado&amp;lt;/p&amp;gt;",
    "solutiontypes_id": 3, 
    "solutiontemplates_id": 5  
  }
}'&lt;/span&gt;
&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;status: 6&lt;/code&gt; indica o fechamento do chamado. Para isso, é necessário passar o &lt;code&gt;solution&lt;/code&gt; e o &lt;code&gt;content&lt;/code&gt; como os textos do corpo para a solução. Um ponto importante nessa requisição é o &lt;code&gt;solutiontemplates_id&lt;/code&gt;, que deve ser criado pelo administrador do sistema GLPI, sendo esse ID um referencial para uma solução padrão.&lt;/p&gt;

</description>
      <category>glpi</category>
      <category>api</category>
      <category>backend</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Signing VirtualBox Kernel Modules</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Tue, 29 Aug 2023 16:58:42 +0000</pubDate>
      <link>https://dev.to/joaoprd/signing-virtualbox-kernel-modules-52bf</link>
      <guid>https://dev.to/joaoprd/signing-virtualbox-kernel-modules-52bf</guid>
      <description>&lt;p&gt;When facing issues with module signing and errors in the 'vboxdrv, vboxnetflt, vboxnetadp, vboxpci' modules, these were the steps I followed to enable VirtualBox on my Fedora 38 machine without disabling UEFI Secure Boot. &lt;/p&gt;

&lt;p&gt;And this method creates a layer of protection between VirtualBox and the kernel.&lt;/p&gt;

&lt;h4&gt;Installing the package &lt;code&gt;mokutil&lt;/code&gt;:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo dnf update&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo dnf install mokutil&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mokutil&lt;/code&gt; will be used to sign your own modules for use with UEFI Secure Boot and to add certificates to the kernel's trusted certificate keyring.&lt;/p&gt;

&lt;h4&gt;Creating folder for module signing and RSA key:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo su&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mkdir /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VirtualBox/"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;chmod 700 MOK.priv&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Creating the password for MOK (this password will be needed for the reboot):&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo mokutil --import MOK.der&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Restart the system and follow the MOK processes:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select 'Enroll MOK&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka9tjhyigbrkravojsj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka9tjhyigbrkravojsj2.png" alt="Image description" width="646" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select Continue&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa3rmqc2ll3o9wzk9gk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa3rmqc2ll3o9wzk9gk5.png" alt="Image description" width="643" height="458"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select 'Yes' to add the keys&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhrbv2izh6xovspmxam2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhrbv2izh6xovspmxam2.png" alt="Image description" width="645" height="458"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the password created with mokutil"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23rpc6ed3mgjz1aa6y6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23rpc6ed3mgjz1aa6y6j.png" alt="Image description" width="647" height="459"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proceed to reboot&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cjfw4dgs88eenxdommy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cjfw4dgs88eenxdommy.png" alt="Image description" width="642" height="457"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Creating the script to perform the signatures:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;cd /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;vi sign-virtual-box&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following inside 'sign-virtual-box':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

for modfile in $(dirname $(modinfo -n vboxdrv))/*.ko; do
  echo "Signing $modfile"
  /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 \
                                /root/signed-modules/MOK.priv \
                                /root/signed-modules/MOK.der "$modfile"
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check for any errors in the script using the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;find /usr/src -name sign-file&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Add permissions to the script and execute it:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;chmod 700 sign-virtual-box&lt;/code&gt;&lt;br&gt;
&lt;code&gt;./sign-virtual-box &lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Run VirtualBox:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;modprobe vboxdrv&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Final conclusions:&lt;/h4&gt;

&lt;p&gt;If the process doesn't work, an option is to disable Secure Boot, but for various reasons, it's not a recommended practice.&lt;/p&gt;

&lt;p&gt;Another option is to check the quality of the VMs you're trying to run. In some cases, they might be corrupted, or even the ISO you're trying to install from.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>learning</category>
      <category>tutorial</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Assinando módulos VirtualBox Kernel</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Tue, 29 Aug 2023 14:29:43 +0000</pubDate>
      <link>https://dev.to/joaoprd/assinando-modulos-virtualbox-kernel-3eg4</link>
      <guid>https://dev.to/joaoprd/assinando-modulos-virtualbox-kernel-3eg4</guid>
      <description>&lt;p&gt;Ao enfrentar os problemas de assinatura e erros nos módulos "vboxdrv, vboxnetflt, vboxnetadp, vboxpci". Essas foram as etapas que segui para ativar o VirtualBox em minha máquina Fedora 38 sem desativar o UEFI Secure Boot.&lt;/p&gt;

&lt;h4&gt;Instalar o pacote &lt;code&gt;mokutil&lt;/code&gt;:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo dnf update&lt;/code&gt;&lt;br&gt;
&lt;code&gt;sudo dnf install mokutil&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mokutil&lt;/code&gt; será usado para assinar seus próprios módulos para usar com a Inicialização Segura UEFI, e adicionar certificados ao chaveiro de certificados confiáveis do kernel.&lt;/p&gt;

&lt;h4&gt;Criar pasta para assinatura de módulos e chave RSA:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo su&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mkdir /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VirtualBox/"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;chmod 700 MOK.priv&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Criar a senha para o MOK (será necessário esta senha para a reinicialização):&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;sudo mokutil --import MOK.der&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Reinicie o equipamento e siga os processos do MOK:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Seleciona Enroll MOK&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhav7ymqaaa2ksyxfb9pi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhav7ymqaaa2ksyxfb9pi.png" alt="Image description" width="646" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione Continue&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl59cc44tdt5at6l5k6vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl59cc44tdt5at6l5k6vw.png" alt="Image description" width="643" height="458"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione Yes para adicionar as chaves&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyyomhmx6ehl7cjenqfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyyomhmx6ehl7cjenqfh.png" alt="Image description" width="645" height="458"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coloque a senha&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e6cwtikmrpkqu9ugbuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e6cwtikmrpkqu9ugbuu.png" alt="Image description" width="647" height="459"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continue para o Reboot&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas5plx6lof4ukggc2k0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas5plx6lof4ukggc2k0a.png" alt="Image description" width="642" height="457"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Criar o script para fazer as assinaturas:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;cd /root/signed-modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;vi sign-virtual-box&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Adicione dentro de sign-virtual-box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

for modfile in $(dirname $(modinfo -n vboxdrv))/*.ko; do
  echo "Signing $modfile"
  /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 \
                                /root/signed-modules/MOK.priv \
                                /root/signed-modules/MOK.der "$modfile"
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifique se há algum erro no script com o comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;find /usr/src -name sign-file&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Adicione as permissões ao script e o execute:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;chmod 700 sign-virtual-box&lt;/code&gt;&lt;br&gt;
&lt;code&gt;./sign-virtual-box &lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Execute o VirtualBox:&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;modprobe vboxdrv&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;Conclusões finais:&lt;/h4&gt;

&lt;p&gt;Caso o processo não funcione, uma opção é desligar o Secure Boot, porém por diversos motivos não é uma prática recomendada. &lt;/p&gt;

&lt;p&gt;Outra opção é verificar a qualidade das VM's que está tentando rodar. Em alguns casos ela pode estar corrompida ou até mesmo a ISO na qual tenta instalar.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>virtualmachine</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>The Duality of Bitcoin: Privacy versus Transparency</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Fri, 14 Jul 2023 12:34:45 +0000</pubDate>
      <link>https://dev.to/joaoprd/the-duality-of-bitcoin-privacy-versus-transparency-28ld</link>
      <guid>https://dev.to/joaoprd/the-duality-of-bitcoin-privacy-versus-transparency-28ld</guid>
      <description>&lt;p&gt;Bitcoin is one of the most well-known and widely used cryptocurrencies in the world. The decentralized and pseudonymous nature of Bitcoin makes transactions difficult to trace, but there are still ways in which they can be tracked. There are several techniques that investigators can use to trace Bitcoin transactions and identify criminals who use the cryptocurrency for illegal activities.&lt;/p&gt;



&lt;h2&gt;Public addresses&lt;/h2&gt;

&lt;p&gt;Every transaction in Bitcoin is recorded on a public address in the blockchain, making it visible to anyone. This allows transactions to be traced and investigated if associated with a person or company. Investigators can track the origin and destination of the funds by monitoring the public addresses used in illegal transactions.&lt;/p&gt;

&lt;p&gt;Transactions are permanently recorded on a ledger called the blockchain, which is public and can be accessed by anyone through a blockchain explorer, such as Blockchain.info. This means that all transactions ever made in Bitcoin can be viewed.&lt;/p&gt;



&lt;h2&gt;Blockchain analysis&lt;/h2&gt;

&lt;p&gt;Blockchain analysis is a technique that allows tracking Bitcoin transactions and identifying the Bitcoin addresses involved in a transaction. While the identity of the Bitcoin address owner is not known, blockchain analysis can be used to track the activity of a specific address and, in some cases, link that address to a person or entity.&lt;/p&gt;

&lt;p&gt;One way to track a Bitcoin address is by analyzing the blockchain to identify all the addresses that have sent or received Bitcoin from that specific address. If a person uses a Bitcoin address to transact on an exchange or trading platform, for example, it is possible to link that address to a user account on the exchange.&lt;/p&gt;

&lt;p&gt;Furthermore, blockchain analysis can also be utilized to track transaction patterns that may indicate illegal or suspicious activities, such as money laundering, drug trafficking, or terrorist financing.&lt;/p&gt;



&lt;h2&gt;User identification&lt;/h2&gt;

&lt;p&gt;While Bitcoin users are generally pseudonymous, it is still possible to identify individuals through transactions involving other fiat currencies, personal information, or connections to IP addresses. For example, if a person uses the same IP address to make a Bitcoin transaction and to connect to a social media account, it is possible to identify that person based on information from the social media account.&lt;/p&gt;



&lt;h2&gt;Cryptocurrency exchanges&lt;/h2&gt;

&lt;p&gt;Cryptocurrency exchanges are required to comply with anti-money laundering regulations, which may include collecting personal information from users and verifying their identity before allowing transactions. Investigators can use the information collected by cryptocurrency exchanges to trace transactions and identify users involved in illegal activities.&lt;/p&gt;

&lt;p&gt;One real example of how Bitcoin was traced and a criminal was arrested is the case of Silk Road. Silk Road was an online marketplace on the dark web that facilitated the sale of illegal products, including drugs, weapons, and counterfeit documents, in exchange for Bitcoin. The creator of Silk Road, Ross Ulbricht, also known as "Dread Pirate Roberts," was arrested in 2013 and sentenced to life imprisonment in 2015 on various charges, including conspiracy to commit money laundering, drug trafficking, and conspiracy to hack computers.&lt;/p&gt;

&lt;p&gt;Ulbricht's arrest was made possible through a coordinated investigation among multiple government agencies, including the FBI, DEA, and IRS. The agencies traced Bitcoin transactions on Silk Road and were able to identify some addresses belonging to Dread Pirate Roberts. They then conducted blockchain analysis to track the flow of Bitcoin between these addresses and other addresses associated with illegal activities on Silk Road. This allowed them to identify several suspicious transactions and eventually trace back to the Bitcoin address Ulbricht used to pay for the Silk Road server.&lt;/p&gt;

&lt;p&gt;Through the analysis of the IP address associated with that transaction and other information collected from online forums, investigators were able to identify Ross Ulbricht as the owner of the address. He was arrested in 2013 and subsequently convicted for his illegal activities on Silk Road.&lt;/p&gt;

&lt;p&gt;The Silk Road case illustrates how Bitcoin can be traced and how government agencies can work together to identify and apprehend criminals who use the cryptocurrency for illegal activities. While the pseudonymous and decentralized nature of Bitcoin may make transactions more difficult to trace, there are still various techniques and tools available to investigators and government agencies who aim to identify and apprehend criminals using cryptocurrency for illicit purposes.&lt;/p&gt;



&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Bitcoin is a fascinating technology that offers many benefits and opportunities for people around the world. However, like any technology, there are also risks and challenges associated with its use. The ability of Bitcoin to be traced and monitored by government agencies can be seen both as an advantage and a disadvantage. On one hand, it can help prevent illegal and criminal activities, but on the other hand, it can be viewed as an invasion of privacy and a threat to financial freedom.&lt;/p&gt;

&lt;p&gt;It is important for Bitcoin users to understand the implications and risks involved in its use and take steps to protect their privacy and financial security.&lt;/p&gt;

</description>
      <category>security</category>
      <category>bitcoin</category>
      <category>devops</category>
    </item>
    <item>
      <title>Join a Linux machine to the Active Directory</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Fri, 14 Jul 2023 12:14:25 +0000</pubDate>
      <link>https://dev.to/joaoprd/join-a-linux-machine-to-the-active-directory-2bjd</link>
      <guid>https://dev.to/joaoprd/join-a-linux-machine-to-the-active-directory-2bjd</guid>
      <description>&lt;p&gt;Step-by-step guide to configure a Linux machine in an Active Directory domain:&lt;/p&gt;

&lt;h2&gt;Preparations and package installation&lt;/h2&gt;

&lt;p&gt;Start by updating the packages already present on the machine, and then proceed to install only what we actually need.&lt;/p&gt;

&lt;p&gt;Update the dependencies using the command:&lt;/p&gt;

&lt;p&gt;Debian&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo apt update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RHEL&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo yum update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And proceed with the installation of the packages:&lt;/p&gt;

&lt;p&gt;Debian&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo apt install -y realmd libnss-sss sssd sssd-tools adcli samba-common-bin oddjob oddjob-   mkhomedir packagekit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RHEL&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo dnf install realmd sssd oddjob oddjob-mkhomedir adcli samba-common-tools -y&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Configuring the realm&lt;/h2&gt;

&lt;p&gt;In short, Realm helps us discover and manage the domains we have on the machine.&lt;/p&gt;

&lt;p&gt;To start, we first need to discover the domain we are looking for.&lt;/p&gt;

&lt;p&gt;Use the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm discover DOMAIN-NAME&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will have a response similar to this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9i457beq0pyavlv4n3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9i457beq0pyavlv4n3r.png" alt="Image description" width="739" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have discovered the domain, we will need to log in to it with a user. Use the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo realm join -U USUARIO DOMINIO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If no errors have occurred so far, we can verify if we are indeed connected by using the following command to check the user's permissions and groups.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;id USUARIO@DOMINIO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Another method to verify if everything is going correctly is the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This way, we can verify if we are already connected to the desired domain.&lt;/p&gt;

&lt;h2&gt;Pam-configs (ubuntu)&lt;/h2&gt;

&lt;p&gt;The pam-configs configuration was only necessary on Ubuntu to ensure that the user's folder is created upon logging into the system.&lt;/p&gt;

&lt;p&gt;You just need to execute the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pam-auth-update --enable mkhomedir&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Configuring SSSD&lt;/h2&gt;

&lt;p&gt;We need to access the file &lt;code&gt;/etc/sssd/sssd.conf&lt;/code&gt; to make the modifications. In this file, we will change the &lt;code&gt;use_fully_qualified_names&lt;/code&gt; option from &lt;code&gt;False&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;. With this option enabled, users will be in the format user@domain instead of just user.&lt;/p&gt;

&lt;p&gt;In our case, we will change it to True since we have only one AD. However, please note that this change should only be made if you are certain that no other domain will be added to the AD forest.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;fallback_homedir = /home/%u@%d&lt;/code&gt;, we will modify it to &lt;code&gt;fallback_homedir = /home/%u&lt;/code&gt;. By removing the "@%d" part, the user's folder will be created with only the username.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;access_provider = ad&lt;/code&gt; option, change it to &lt;code&gt;access_provider = simple&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let's add an option that is not present in our file, which is &lt;code&gt;simple_allow_groups&lt;/code&gt;. In this option, we will add the groups we have in AD and want to grant access to the Linux machine.&lt;/p&gt;

&lt;p&gt;In our case, we have two groups: linuxuser and linuxadmin. To add them, we should include &lt;code&gt;simple_allow_groups = linuxuser, linuxadmin&lt;/code&gt; in the file.&lt;/p&gt;

&lt;p&gt;As a result, the file will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc1u45kakvjkvdln3gyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc1u45kakvjkvdln3gyn.png" alt="Image description" width="523" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: in the places where it says 'Domain.local', you should use the domain you are integrating with the system. And in 'simple_allow_users = groups, linuxuser, linuxadmin', it is an option that will be added automatically in the next item.&lt;/p&gt;

&lt;p&gt;Thus, concluding the SSSD configuration process, we will allow access for users who are in the groups we added in simple_allow_groups. Use the following commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit [group]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit linuxuser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit linuxadmin&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;SUDOERS&lt;/h2&gt;

&lt;p&gt;With the processes performed in the above steps, we will be able to access the machine using the AD user. However, the user won't have root access to the system. To solve this, we need to add the groups to the /etc/sudoers file. The result will be as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagt7h6amrr4ykwkujxt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagt7h6amrr4ykwkujxt8.png" alt="Image description" width="642" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We added the %linuxuser group to allow all users in the linuxuser group to access the machine and obtain root access.&lt;/p&gt;




&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;By following these steps, Active Directory users will be able to authenticate on the Linux machine and have the appropriate privileges. Always ensure to follow best security practices when performing these configurations.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Atrelar máquina Linux ao Active Directory</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Sun, 18 Jun 2023 16:22:40 +0000</pubDate>
      <link>https://dev.to/joaoprd/atrelar-maquina-linux-ao-active-directory-jnc</link>
      <guid>https://dev.to/joaoprd/atrelar-maquina-linux-ao-active-directory-jnc</guid>
      <description>&lt;p&gt;Passo a passo de como configurar uma máquina Linux em um domínio do Active Directory.&lt;/p&gt;

&lt;h2&gt;Preparações e instalação de pacotes&lt;/h2&gt;

&lt;p&gt;Comece atualizando os pacotes que já possuímos na máquina e, logo após, instale o que realmente precisamos. &lt;/p&gt;

&lt;p&gt;Atualize as dependências com o comando:&lt;/p&gt;

&lt;p&gt;Debian&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo apt update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RHEL&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo yum update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E prossiga com a instalação dos pacotes:&lt;/p&gt;

&lt;p&gt;Debian&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo apt install -y realmd libnss-sss sssd sssd-tools adcli samba-common-bin oddjob oddjob-   mkhomedir packagekit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RHEL&lt;br&gt;&lt;br&gt;
&lt;code&gt;sudo dnf install realmd sssd oddjob oddjob-mkhomedir adcli samba-common-tools -y&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Configurando o realm&lt;/h2&gt;

&lt;p&gt;De forma resumida, o Realm nos ajuda a descobrir e controlar os domínios que possuímos na máquina.&lt;/p&gt;

&lt;p&gt;Para começar, precisamos primeiro descobrir o domínio que estamos procurando. &lt;/p&gt;

&lt;p&gt;Utilize o seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm discover NOME-DO-DOMINIO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Teremos uma resposta semelhante a esta:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9i457beq0pyavlv4n3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9i457beq0pyavlv4n3r.png" alt="Image description" width="739" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que descobrimos o domínio, precisaremos fazer login nele com um usuário. Utilize o seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo realm join -U USUARIO DOMINIO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Se até o momento não ocorreram erros, podemos verificar se realmente estamos conectados, utilizando o comando abaixo para verificar as permissões e grupos do usuário.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;id USUARIO@DOMINIO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Outro método para verificar se está tudo ocorrendo corretamente é o seguinte:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma, verificamos se já estamos conectados ao domínio desejado.&lt;/p&gt;

&lt;h2&gt;Pam-configs (ubuntu)&lt;/h2&gt;

&lt;p&gt;A configuração no pam-configs foi necessária apenas no Ubuntu para que a pasta do usuário seja criada no momento em que ele entra no sistema.&lt;/p&gt;

&lt;p&gt;Apenas é necessário executar o comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pam-auth-update --enable mkhomedir&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Configurando SSSD&lt;/h2&gt;

&lt;p&gt;Devemos acessar o arquivo &lt;code&gt;/etc/sssd/sssd.conf&lt;/code&gt; para realizar as modificações. Nele, vamos alterar a opção &lt;code&gt;use_fully_qualified_names&lt;/code&gt; de &lt;code&gt;False&lt;/code&gt; para &lt;code&gt;True&lt;/code&gt;. Com essa opção ativada, os usuários estarão no formato user@domain, em vez de apenas user.&lt;/p&gt;

&lt;p&gt;No nosso caso, vamos alterar para True, pois possuímos apenas um AD. No entanto, observe que essa alteração deve ser feita somente se você tiver certeza de que nenhum outro domínio será adicionado à floresta do AD.&lt;/p&gt;

&lt;p&gt;Em &lt;code&gt;fallback_homedir = /home/%u@%d&lt;/code&gt;, vamos modificar para &lt;code&gt;fallback_homedir = /home/%u&lt;/code&gt;. Removendo o "@%d", a pasta do usuário será criada apenas com o nome do usuário.&lt;/p&gt;

&lt;p&gt;Na opção &lt;code&gt;access_provider = ad&lt;/code&gt;, muda-se para &lt;code&gt;access_provider = simple&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora vamos adicionar uma opção que não está presente em nosso arquivo, que é o &lt;code&gt;simple_allow_groups&lt;/code&gt;. Nessa opção, vamos adicionar os grupos que temos no AD e desejamos que tenham acesso à máquina Linux.&lt;/p&gt;

&lt;p&gt;No nosso caso, temos dois grupos: linuxuser e linuxadmin. Para adicioná-los, devemos incluir &lt;code&gt;simple_allow_groups = linuxuser, linuxadmin&lt;/code&gt; no arquivo.&lt;/p&gt;

&lt;p&gt;Como resultado, o arquivo ficará da seguinte maneira:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc1u45kakvjkvdln3gyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc1u45kakvjkvdln3gyn.png" alt="Image description" width="523" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observação: nos lugares onde está escrito "Domain.local", deve ser o domínio que você está integrando ao sistema. E em "simple_allow_users = groups, linuxuser, linuxadmin" é uma opção adicionada automaticamente no próximo item.&lt;/p&gt;

&lt;p&gt;Assim, finalizando o processo de configuração do SSSD, vamos permitir o acesso dos usuários que estão nos grupos que adicionamos em simple_allow_groups. Utilize os seguintes comandos:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit [group]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit linuxuser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;realm permit linuxadmin&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;SUDOERS&lt;/h2&gt;

&lt;p&gt;Com os processos realizados nos itens acima, já conseguiremos acessar a máquina utilizando o usuário do AD. No entanto, ele não terá acesso root no sistema. Para resolver isso, devemos adicionar os grupos dentro do arquivo /etc/sudoers. O resultado será o seguinte:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagt7h6amrr4ykwkujxt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagt7h6amrr4ykwkujxt8.png" alt="Image description" width="642" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicionamos o grupo %linuxuser para permitir que todos os usuários do grupo linuxuser possam acessar a máquina e obter acesso root.&lt;/p&gt;




&lt;h2&gt;Conclusão&lt;/h2&gt;

&lt;p&gt;Ao seguir essas etapas, os usuários do Active Directory poderão autenticar-se na máquina Linux e ter os privilégios adequados. Certifique-se sempre de seguir as melhores práticas de segurança ao realizar essas configurações.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Dualidade do Bitcoin: Privacidade versus Transparência</title>
      <dc:creator>João Pedro </dc:creator>
      <pubDate>Wed, 12 Apr 2023 18:36:22 +0000</pubDate>
      <link>https://dev.to/joaoprd/a-dualidade-do-bitcoin-privacidade-versus-transparencia-hfc</link>
      <guid>https://dev.to/joaoprd/a-dualidade-do-bitcoin-privacidade-versus-transparencia-hfc</guid>
      <description>&lt;p&gt;Bitcoin é uma das criptomoedas mais conhecidas e amplamente utilizadas no mundo.
A natureza descentralizada e pseudônima do Bitcoin torna as transações difíceis de rastrear,
mas ainda assim existem maneiras pelas quais elas podem ser rastreadas. Existem várias
técnicas que os investigadores podem usar para rastrear as transações de Bitcoin e identificar
criminosos que usam a criptomoeda para atividades ilegais.&lt;/p&gt;



&lt;h2&gt;Endereços públicos&lt;/h2&gt;

&lt;p&gt;Cada transação em Bitcoin é gravada em um endereço público na blockchain,
tornando-a visível para qualquer um. Isso permite que as transações sejam rastreadas e
investigadas, se associadas a uma pessoa ou empresa. Investigadores podem rastrear a origem
e o destino do dinheiro monitorando os endereços públicos usados em transações ilegais&lt;/p&gt;

&lt;p&gt;As transações são permanentemente registradas em um livro-razão chamado
"Blockchain", que é público e pode ser acessado por qualquer pessoa por meio de um
explorador de blockchain, como o Blockchain.info. Isso significa que todas as transações já
realizadas em Bitcoin podem ser visualizadas.&lt;/p&gt;



&lt;h2&gt;Análise de cadeia de blocos&lt;/h2&gt;

&lt;p&gt;A análise de cadeia de blocos é uma técnica que permite rastrear as transações do
Bitcoin e identificar os endereços de Bitcoin envolvidos em uma transação. Embora a
identidade do proprietário do endereço de Bitcoin não seja conhecida, a análise da cadeia de
blocos pode ser usada para rastrear a atividade de um endereço específico e, em alguns casos,
vincular esse endereço a uma pessoa ou entidade.&lt;/p&gt;

&lt;p&gt;Uma maneira de rastrear um endereço de Bitcoin é analisando a cadeia de blocos para
identificar todos os endereços que enviaram ou receberam Bitcoin desse endereço específico.
Se uma pessoa usar um endereço de Bitcoin para realizar transações em uma exchange ou
plataforma de negociação, por exemplo, é possível vincular esse endereço a uma conta de
usuário na exchange.&lt;/p&gt;

&lt;p&gt;Além disso, a análise da cadeia de blocos também pode ser usada para rastrear
padrões de transação que possam ser indicativos de atividades ilegais ou suspeitas, como
lavagem de dinheiro, tráfico de drogas ou financiamento terrorista.&lt;/p&gt;



&lt;h2&gt;Identificação de usuários&lt;/h2&gt;

&lt;p&gt;Embora os usuários de Bitcoin sejam geralmente pseudônimos, ainda é possível
identificar indivíduos por meio de transações que envolvem outras moedas fiduciárias,
informações pessoais ou conexões com endereços de IP. Por exemplo, se uma pessoa usa o
mesmo endereço de IP para fazer uma transação de Bitcoin e para se conectar a uma conta de
mídia social, é possível identificar essa pessoa com base em informações da conta de mídia
social.&lt;/p&gt;



&lt;h2&gt;Intercâmbios de criptomoedas&lt;/h2&gt;

&lt;p&gt;Os intercâmbios de criptomoedas são obrigados a seguir as regulamentações contra
lavagem de dinheiro, o que pode incluir a coleta de informações pessoais dos usuários e a
verificação de identidade antes de permitir transações. Os investigadores podem usar as
informações coletadas pelos intercâmbios de criptomoedas para rastrear transações e
identificar os usuários envolvidos em atividades ilegais.&lt;/p&gt;

&lt;p&gt;Um exemplo real de como o Bitcoin foi rastreado e um criminoso foi preso é o caso da
Silk Road. A Silk Road foi um mercado online na dark web que facilitou a venda de produtos
ilegais, incluindo drogas, armas e documentos falsificados, em troca de Bitcoin. O criador da
Silk Road, Ross Ulbricht, também conhecido como "Dread Pirate Roberts", foi preso em 2013 e
condenado a prisão perpétua em 2015 por uma série de acusações, incluindo conspiração para
lavagem de dinheiro, tráfico de drogas e conspiração para hackear computadores.&lt;/p&gt;

&lt;p&gt;A prisão de Ulbricht foi possível graças a uma investigação coordenada entre várias
agências governamentais, incluindo o FBI, a DEA e o IRS. As agências rastrearam as transações
de Bitcoin na Silk Road e conseguiram identificar alguns endereços que pertenciam ao Dread
Pirate Roberts. Eles então realizaram uma análise da cadeia de blocos para rastrear o fluxo de
Bitcoin entre esses endereços e outros endereços associados a atividades ilegais na Silk Road.
Isso permitiu que eles identificassem várias transações suspeitas e, eventualmente, chegaram
ao endereço de Bitcoin que Ulbricht usou para pagar o servidor da Silk Road.&lt;/p&gt;

&lt;p&gt;Através da análise do endereço IP associado a essa transação e outras informações
coletadas em fóruns online, os investigadores conseguiram identificar Ross Ulbricht como o
proprietário do endereço. Ele foi preso em 2013 e posteriormente condenado por suas
atividades ilegais na Silk Road.&lt;/p&gt;

&lt;p&gt;O caso da Silk Road ilustra como o Bitcoin pode ser rastreado e como as agências
governamentais podem trabalhar juntas para identificar e prender criminosos que usam a
criptomoeda para atividades ilegais. Embora a natureza pseudônima e descentralizada do
Bitcoin possa tornar as transações mais difíceis de rastrear, ainda existem várias técnicas e
ferramentas disponíveis para investigadores e agências governamentais que desejam
identificar e prender criminosos que usam a criptomoeda para atividades ilegais.&lt;/p&gt;



&lt;h2&gt;Conclusão&lt;/h2&gt;

&lt;p&gt;O Bitcoin é uma tecnologia fascinante que oferece muitos benefícios e oportunidades
para as pessoas em todo o mundo. No entanto, como com qualquer tecnologia, há também
riscos e desafios associados ao seu uso. A capacidade do Bitcoin de ser rastreado e monitorado
pelas agências governamentais pode ser vista tanto como uma vantagem quanto como uma
desvantagem. Por um lado, isso pode ajudar a prevenir atividades ilegais e criminosas, mas, por
outro lado, pode ser visto como uma invasão de privacidade e uma ameaça à liberdade
financeira.&lt;/p&gt;

&lt;p&gt;É importante que os usuários de Bitcoin entendam as implicações e riscos envolvidos
em seu uso e tomem medidas para proteger sua privacidade e segurança financeira.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>bitcoin</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
