helio.loureiro.eng.br
  • Home
  • Unix
  • Linux
  • Blog
  • Python
  • Programação
  • Tudo
  • Suécia
  1. You are here:  
  2. Home
  3. Programação e desenvolvimento
  4. Perl
  5. Acessos de robôs nos logs web

Os artigos mais lidos de 2025

  • Configurando o grafana alloy pra monitorar VMs
  • Configurando traefik com ssh
  • Configurando o teclado Keychron C3 no Linux
  • Parâmetros de compilação pra Go!
  • Script pra verificar e atualizar os certificados dos domínios com letsencrypt

Home

DNS4EU, um sistema de DNS da Europa

Details
Written by: Helio Loureiro
Category: Blog
Published: June 09, 2025
Hits: 907
  • dns
  • europa

A Europa tem tentado manter sistemas independentes dos EUA. Não é algo de agora, mas sempre foi um dos pensamentos vigentes por aqui. Quem não lembra do projeto Galileu, pra subistutir o GPS dos americanos caso esse fosse desligado?

E isso tem sido mais acirrado ultimamente com os temas de soberania de dados. Sem falar no Trump. Esse sozinho é um caso à parte.

E uma das iniciativas da Europa é esses sistema de DNS independente de empresas americanas. Eu já adotei aqui em casa.

https://www.joindns4.eu/for-public

Seu browser é seguro?

Details
Written by: Helio Loureiro
Category: Blog
Published: May 29, 2025
Hits: 970

A EFF, Eletronic Frontier Foundation, lançou uma iniciativa bem legal. Você pode acessar e testar se seu browser mantém seus dados seguros no sentido de privacidade.

Eu testei no meus Firefox, tanto dos computadores (laptops e desktop) tanto quanto no meu telefone. Todos passaram maravilhosamente seguros quanto a minha privacidade.

E você? Já testou seus browser?

https://coveryourtracks.eff.org

Mais uma tentativa com python3.13 e python3.13t

Details
Written by: Helio Loureiro
Category: Python
Published: May 29, 2025
Hits: 932
  • python3.13
  • performance

Resolvi aproveitar que meu desktop está menos sobrecarregado e rodar os testes novamente pra comparar com os do artigo anterior, revisitando o artigo de shell lento com python3.13.

  
❯ time python3.13 20M-touch.py; time python3.13t 20M-touch.py 

________________________________________________________
Executed in  396.13 secs    fish           external
   usr time  231.65 secs  479.00 micros  231.65 secs
   sys time  158.26 secs  803.00 micros  158.26 secs


________________________________________________________
Executed in   22.31 mins    fish           external
   usr time  495.80 secs    0.00 millis  495.80 secs
   sys time  820.21 secs    1.22 millis  820.20 secs    
  

De 621 pra 396s já foi um ganho significativo de desempenho. Mas abaixo dos 374s do primeiro artigo, shell é lento?

O python3.13t, quer permite desabilitar o GIL, continua lento. Eu esqueci de desabilitar o GIL e não deveria fazer diferença. Mas fez. 22 minutos. Melhor que os 31 minutos do artigo anterior.

E com GIL desabilitado?

  
❯ time env PYTHON_GIL=0 python3.13t 20M-touch.py

________________________________________________________
Executed in   22.63 mins    fish           external
   usr time  506.53 secs  381.00 micros  506.53 secs
   sys time  822.23 secs  825.00 micros  822.23 secs    
  

Não mudou muita coisa. O jeito é aceitar que é isso e seguir em frente. Segura o choro que dói menos.

Revisitando o artigo de shell lento com python3.13

Details
Written by: Helio Loureiro
Category: Python
Published: May 12, 2025
Hits: 906
  • python3.13
  • performance

Quando escrevi o artigo Shell é lento? python teve uma performance miserável. Pra não chamar de outra coisa.

Resolvi então dar uma revisitada no teste e rodando o python3.13. A cada versão de python dizem que a performance é melhorada. Nada melhor que tirar a prova. E além disso a versão 3.13 permite desabilitar o GIL, o Global Interpreter Locker. Não se se faz alguma diferença num teste desses, mas vamos tentar.

Eu mantive o mesmo programa que rodei da outra vez:

  
#! /usr/bin/env python3

for i in range(20000000):
    with open("arq-python3", "w") as fd:
        None   
  

E o resultado:

  
helio@goosfraba❯ time python3.13 20M-touch.py

________________________________________________________
Executed in  621.80 secs    fish           external
   usr time  384.60 secs  998.00 micros  384.60 secs
   sys time  229.78 secs    0.00 micros  229.78 secs
  

Demorou mais que o teste anterior. Se antes foi miserável, essa aqui... Mas antes de botar a culpa no Python, vamos rodar a versão em Go e olhar se os tempos mudaram. O código de Go também continua o mesmo:

  
package main

import (
        "log"
        "os"
)

func main() {
        for i := 0; i < 20000000; i++ {
                fd, err := os.Create("arq-go")
                fd.Close()
                if err != nil {
                        log.Fatal(err)
                }
        }
}
  

E depois daquela compilada básica:

  
helio@goosfraba❯ go build -o 20M-touch 20M-touch.go
helio@goosfraba❯ time ./20M-touch

________________________________________________________
Executed in  295.12 secs    fish           external
   usr time   88.50 secs    0.20 millis   88.50 secs
   sys time  199.48 secs    1.03 millis  199.47 secs
  

Realmente baixou o Exu-tranca-sistema no HDD. Da época em que fiz o primeiro teste pra cá a mudança foi a adição de um disco extra de 12 TB. E afetou bastante a performance. De 148s pra 295s com o binário em Go. Nesse caso é melhor rodar o este com cada linguagem pra ver as diferenças no sistema novo e ter um equilíbrio maior entre os resultados.

  
helio@goosfraba❯ time perl 20M-touch.pl

________________________________________________________
Executed in  260.95 secs    fish           external
   usr time   61.45 secs    1.31 millis   61.45 secs
   sys time  195.20 secs    0.04 millis  195.20 secs  

helio@goosfraba❯ time bash 20M-touch.sh 

________________________________________________________
Executed in  443.89 secs    fish           external
   usr time  213.20 secs    1.26 millis  213.20 secs
   sys time  227.43 secs    0.04 millis  227.43 secs
  

E pra melhorar o escope de testes, adicionei ainda a versão em C++:

  
#include <iostream>
#include <fstream>
using namespace std;

int main() {
  for (int i=0;i<20000000;i++) {
    ofstream MyFile("arq-cpp");
    MyFile.close();
  }
}    
  

O resultado:

  
helio@goosfraba❯ time ./20M-touch-cpp 

________________________________________________________
Executed in  205.39 secs    fish           external
   usr time   39.56 secs  359.00 micros   39.56 secs
   sys time  163.64 secs  911.00 micros  163.64 secs
  

O resultados foram então (do mais rápido pro mais lento):

  • c++: 205.39s
  • perl: 260.95s
  • go: 295.12s
  • bash: 443.89s
  • python: 621.80s
  • Enquanto C++ manteve a performance esperada, perl deu um show. Eu pessoalmente achei que Go! ficou devendo, ainda mais se comparado com C++. Mas python... python fracassou miseravelmente. E de novo.

    E fui tentar rodar com o GIL desabilitado e...

      
    helio@goosfraba❯ time env PYTHON_GIL=0 python3.13 20M-touch.py
    Fatal Python error: config_read_gil: Disabling the GIL is not supported by this build
    Python runtime state: preinitialized
    
    
    ________________________________________________________
    Executed in    4.91 millis    fish           external
       usr time    2.03 millis    1.09 millis    0.95 millis
       sys time    2.85 millis    0.02 millis    2.83 millis
      
    

    Vou precisar compilar um python3.13 com a configuração que permite desabilitar o GIL...

    Update: compilei um pacote do AUR.

      
    ==> Creating package "python313-freethreaded"...
      -> Generating .PKGINFO file...
      -> Generating .BUILDINFO file...
      -> Generating .MTREE file...
      -> Compressing package...
    ==> Leaving fakeroot environment.
    ==> Finished making: python313-freethreaded 3.13.3-1 (Mon 12 May 2025 06:04:15 PM CEST)
    ==> Cleaning up...
      
    

    E vamos aos resultados:

      
    helio@goosfraba❯ time env PYTHON_GIL=0 python3.13t 20M-touch.py
    
    ________________________________________________________
    Executed in   31.58 mins    fish           external
       usr time   14.01 mins    0.00 millis   14.01 mins
       sys time   17.25 mins    1.96 millis   17.25 mins
      
    

    Python continua parecendo que bateu uma feijuca antes de rodar os testes. Não que remover o GIL fosse mudar muita coisa uma vez que o teste é sequencial. Mas podia ter melhorado um pouco.

    Enquanto isso também descobri o porquê dos testes estarem mais lentos: tem algum treco do yay compilando. Sei lá eu o que é uma vez que estou conectado remotamente.

    O ano do Linux no desktop está acontecendo!

    Details
    Written by: Helio Loureiro
    Category: Linux
    Published: May 05, 2025
    Hits: 924
    • migração
    • youtube
    • pewdiepie
    • influencer

    Sempre tenho renovado meus votos sobre o ano do Linux no desktop. E parece que dessa vez deu certo mesmo.

    Sem nenhuma ligação com comunidades Linux ou software livre, o influenciador digital "PewDiePie", com milhões de seguidores, simplemente resolveu migrar e enaltecer o uso do Linux. E não pense que foi pouca coisa. O cara já meteu uma variante do archlinux com hyperland.

    Simplesmente maravilhoso. Confira:

    Se ainda existisse FISL, era certeza que o PewDiePie era o próximo keynote. Quem sabe não seja no FOSDEM?

    Novo canal da Bárbara Tostes

    Details
    Written by: Helio Loureiro
    Category: Blog
    Published: April 28, 2025
    Hits: 910

    A querida Bárbara Tostes lançou esse vídeo anunciando seu novo canal e o trabalho que irá fazer por lá. Então aqui está minha contribuição em sua divulgação.

    E boa sorte para ela.

    Gerando senhas com openssl

    Details
    Written by: Helio Loureiro
    Category: Scripts
    Published: April 24, 2025
    Hits: 917

    Só um comando que uso bastante e provavelmente tem gente que nem sabe que existe.

    OpenSSL tem várias funcionalidades, entre elas gerar senhas. O comando que uso é o seguinte:

      
    ❯ openssl rand -base64 32 | cut -c 1-43
      
    

    O resultado é algo como isso aqui (que a cada comando resulta em algo aleatório):

      
    ❯ openssl rand -base64 32 | cut -c 1-43
    EHjsiO2IIuaBzGmugiVDZgfmj83v/LqZ/nevZ5itzV0    
      
    

    Configurando traefik com ssh

    Details
    Written by: Helio Loureiro
    Category: SRE - Site Reliability Engineer
    Published: April 24, 2025
    Hits: 1426
    • docker
    • letsencrypt
    • traefik
    • ssh
    • certbot
    • gitea

    Esse parece ser um tópico um tanto quanto... distópico? Talvez nem tanto. Mas todas as referências sobre o assunto na Internet estão incompletos e geralmente são pra versões mais antigas do traefik. Traefik é um roteador de conexões que funciona tanto como programa chamado por systemd (ou outro sistema de init se for um BSD), ou por container com algo como docker-compose, ou ainda diretamente em kubernetes. E não só funciona como proxy-reverse: pode também atuar como um servidor http pra suas conexões. E não somente tcp como udp. E escrito em Go!

    Eu precisei colocar um servidor ssh atrás de um traefik. E deu um certo trabalho. Pra testar e mostrar aqui também, usei docker-compose pro serviço. Isso facilitou a configuração. Pra backend com ssh, subi uma instância do gitea com o ssh na porta 2222. Usei também certificados letsencrypt nas portas https do serviço.

    Como um plus, ainda adicionei um allowlist pra acessar o serviço somente de certos IPs.

    Vamos pra configuração então. Primeiramente do traefik. Pra subir, eu configurei pra ouvir nas portas 80 (http), 443 (https), 8080 (traefik dashboard) e 2222 (ssh). O conteúdo de traefik/docker-compose.yml:

      
    services:
      traefik:
        image: "traefik:v3.3"
        container_name: "traefik"
        restart: unless-stopped
        environment:
          - TZ=Europe/Stockholm
        ports:
          - "80:80"
          - "443:443"
          - "8080:8080"
          - "2222:2222"
        volumes:
          - "./letsencrypt:/letsencrypt"
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
          - "./traefik.yml:/traefik.yml:ro"
        networks:
          - traefik
    
    networks:
      traefik:
        name: traefik    
      
    

    Junto com essa configuração de container, ainda inclui a configuração do serviço em traefik/traefik.yml:

      
    api:
      dashboard: true
      insecure: true
      debug: true
    entryPoints:
      web:
        address: ":80"
        http:
          redirections:
            entryPoint:
              to: websecure
              scheme: https
      websecure:
        address: ":443"
      ssh:
        address: ":2222"
    serversTransport:
      insecureSkipVerify: true
    providers:
      docker:
        endpoint: "unix:///var/run/docker.sock"
        exposedByDefault: false
        network: traefik
    certificatesResolvers:
      letsencrypt:
        acme:
          email: This email address is being protected from spambots. You need JavaScript enabled to view it.
          storage: /letsencrypt/acme.json
          httpChallenge:
            # used during the challenge
            entryPoint: web
    
    log:
      level: WARN
      
    

    Aqui é possível ver que defino novamente os entrypoints pra 80, 443 e 2222. E no 80 (http) eu redireciono pro 443 (https). E certificado do letsencrypt.

    Tudo pronto no lado do traefik. Agora é o ponto de subir o serviço e preparar algumas coisas pra testar.

      
    # docker compose -p traefik -f traefik/docker-compose.yml up -d
    [+] Running 1/1
     ✔ Container traefik  Started                                0.4s
      
    

    Dentro do diretório traefik será criado um diretório letsencrypt e dentro dele terá o arquivo acme.json com seus certificados.

    Primeiramente vamos subir um container de teste pra ver se tudo funciona. O próprio projeto traefik fornece um container chamado whoami pra isso. O conteúdo de whois/docker-compose.yml:

      
    services:
      whoami:
        container_name: simple-service
        image: traefik/whoami
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.whoami.rule=Host(`whoami.tests.loureiro.eng.br`)"
            - "traefik.http.routers.whoami.entrypoints=websecure"
            - "traefik.http.routers.whoami.tls=true"
            - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
            - "traefik.http.services.whoami.loadbalancer.server.port=80"
        networks:
            - traefik
    networks:
      traefik:
        name: traefik    
      
    

    E habilitando o serviço com docker-compose:

      
    # docker compose -p whoami -f whoami/docker-compose.yml up -d
    WARN[0000] a network with name traefik exists but was not created for project "whoami".
    Set `external: true` to use an existing network 
    [+] Running 1/1
     ✔ Container simple-service  Started                                              0.3s 
      
    

    E um simples teste do serviço:

      
    ❯ curl -I http://whoami.tests.loureiro.eng.br
    HTTP/1.1 308 Permanent Redirect
    Location: https://whoami.tests.loureiro.eng.br/
    Date: Thu, 24 Apr 2025 12:43:55 GMT
    Content-Length: 18
    
    ❯ curl  https://whoami.tests.loureiro.eng.br
    Hostname: 0da540e1039c
    IP: 127.0.0.1
    IP: ::1
    IP: 172.18.0.3
    RemoteAddr: 172.18.0.2:52686
    GET / HTTP/1.1
    Host: whoami.tests.loureiro.eng.br
    User-Agent: curl/8.5.0
    Accept: */*
    Accept-Encoding: gzip
    X-Forwarded-For: 1.2.3.4
    X-Forwarded-Host: whoami.tests.loureiro.eng.br
    X-Forwarded-Port: 443
    X-Forwarded-Proto: https
    X-Forwarded-Server: 4cacedb0129a
    X-Real-Ip: 1.2.3.4
      
    

    O primeiro curl pro endpoint na porta 80 (http) recebe um redirect pra https. Perfeito! O segundo, os dados do container de forma transparente.

    O serviço funciona! Mas pra http e https. Falta ssh na porta 2222, que está nessa porta pra não atrapalhar o uso do ssh normal do sistema.

    Pra isso eu configurei um gitea, como descrevi no início do artigo. Seu docker-compose.yml é o seguinte:

      
        services:
      server:
        image: gitea/gitea:1.23-rootless #latest-rootless
        container_name: gitea
        environment:
         - GITEA__database__DB_TYPE=postgres
         - GITEA__database__HOST=db:5432
         - GITEA__database__NAME=gitea
         - GITEA__database__USER=gitea
         - GITEA__database__PASSWD=A4COU5a6JF5ZvWoSufi0L1aomSkzqww7s1wv039qy6o=
         - LOCAL_ROOT_URL=https://gitea.tests.loureiro.eng.br
         - GITEA__openid__ENABLE_OPENID_SIGNIN=false
         - GITEA__openid__ENABLE_OPENID_SIGNUP=false
         - GITEA__service__DISABLE_REGISTRATION=true
         - GITEA__service__SHOW_REGISTRATION_BUTTON=false
         - GITEA__server__SSH_DOMAIN=gitea.tests.loureiro.eng.br
         - GITEA__server__START_SSH_SERVER=true
         - GITEA__server__DISABLE_SSH=false    
        restart: always
        volumes:
          - gitea-data:/var/lib/gitea
          - gitea-config:/etc/gitea
          - /etc/timezone:/etc/timezone:ro
          - /etc/localtime:/etc/localtime:ro
        #ports:
        #  - "127.0.0.1:3000:3000"
        #  - "127.0.0.1:2222:2222"
        depends_on:
          - db
        networks:
          - traefik
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.giteaweb.rule=Host(`gitea.tests.loureiro.eng.br`)"
          - "traefik.http.routers.giteaweb.entrypoints=websecure"
          - "traefik.http.routers.giteaweb.tls=true"
          - "traefik.http.routers.giteaweb.tls.certresolver=letsencrypt"
          - "traefik.http.services.giteaweb.loadbalancer.server.port=3000"
          - "traefik.http.middlewares.giteaweb-ipwhitelist.ipallowlist.sourcerange=1.2.3.4, 4.5.6.7"
          - "traefik.http.routers.giteaweb.middlewares=giteaweb-ipwhitelist"
          - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
          - "traefik.tcp.routers.gitea-ssh.entrypoints=ssh"
          - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc"
          - "traefik.tcp.services.gitea-ssh-svc.loadbalancer.server.port=2222"
          - "traefik.tcp.middlewares.giteassh-ipwhitelist.ipallowlist.sourcerange=1.2.3.4, 4.5.6.7"
          - "traefik.tcp.routers.gitea-ssh.middlewares=giteassh-ipwhitelist"
    
      db:
        image: postgres:17
        restart: always
        container_name: gitea_db
        environment:
          - POSTGRES_DB=gitea
          - POSTGRES_USER=gitea
          - POSTGRES_PASSWORD=A4COU5a6JF5ZvWoSufi0L1aomSkzqww7s1wv039qy6o=
    
        networks:
          - traefik
        volumes:
          - gitea-db:/var/lib/postgresql/data
    
    networks:
      traefik:
        name: traefik
    
    volumes:
      gitea-data:
      gitea-config:
      gitea-db:
      
    

    Pode ser visto que existe uma regra pra parte web, que roda na porta 3000 do container, e pra parte de ssh, que fica na porta 22222. Eu deixei comentado a parte que exporta as portas pra mostrar claramente que isso não é necessário. Aliás não funciona se especificar as portas.

    E finalmente rodando o serviço:

      
    # docker compose -p gitea -f gitea/docker-compose.yml up -d
    WARN[0000] a network with name traefik exists but was not created for project "gitea".
    Set `external: true` to use an existing network 
    [+] Running 2/2
     ✔ Container gitea_db  Started                   0.3s 
     ✔ Container gitea     Started                   1.0s     
      
    

    E vamos ao testes.

      
    ❯ curl -s  https://gitea.tests.loureiro.eng.br | head -n 10
    <!DOCTYPE html>
    <html lang="en-US" data-theme="gitea-auto">
    <head>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>Gitea: Git with a cup of tea</title>
            <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR2l0ZWE6IEdpdCB3aXRoIGEgY3VwIG9mIHRlYSIsInNob3J0X25hbWUiOiJHaXRlYTogR2l0IHdpdGggYSBjdXAgb2YgdGVhIiwic3RhcnRfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImljb25zIjpbeyJzcmMiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9hc3NldHMvaW1nL2xvZ28uc3ZnIiwidHlwZSI6ImltYWdlL3N2Zyt4bWwiLCJzaXplcyI6IjUxMng1MTIifV19">
            <meta name="author" content="Gitea - Git with a cup of tea">
            <meta name="description" content="Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go">
            <meta name="keywords" content="go,git,self-hosted,gitea">
            <meta name="referrer" content="no-referrer">
    ❯ telnet gitea.tests.loureiro.eng.br 2222
    Trying 1.2.3.4...
    Connected to gitea.tests.loureiro.eng.br.
    Escape character is '^]'.
    SSH-2.0-Go
    
    ^]
    telnet> q
    Connection closed.    
      
    

    E pronto! Temos o serviço funcionando e roteado pelo traefik. E podendo fazer ACL de ip do serviço sem precisar do firewall pra isso.

    Boa diversão!

    Nota: eu coloquei um básico da configuração do gitea pra exemplo. E não funciona se copiar e colar. Pra ter um serviço rodando, terá de adicionar mais algumas partes em environment.

    Script pra verificar e atualizar os certificados dos domínios com letsencrypt

    Details
    Written by: Helio Loureiro
    Category: Shell Scripts
    Published: April 19, 2025
    Hits: 1241

    Continuando os trabalhos do artigo Ferramenta pra verificar quantidades de dias válidos de um certificado do letsencrypt, fiz uma pequena entrada na crontab pra chamar um script que fiz em fish.

      
    # tail -1 /etc/crontab 
    0  1  */5 * * root /root/bin/check-domain-expiration-dates.fish >> /tmp/certificate_renew.log 2>&1
      
    

    E o respectivo script:

      
    #! /usr/bin/env fish
    set EXPIRATION_DAYS 10
    
    for info in (letsencrypt-cert-days)
      set domain (echo $info | cut -d"=" -f1)
      set days (echo $info | cut -d"=" -f2)
      if [ $days -lt $EXPIRATION_DAYS ]
        echo "Renewing domain: $domain"
        certbot renew -d $domain
      end
    end    
      
    

    Então eu rodo no crontab a cada 5 dias pra detectar se algum certificado está expirando. E então chamo o `certbot` pra renovar se for o caso.

    Funciona? Não sei. Meus certificados estão válidos ainda por quase 50 dias. Daqui um mês eu atualizo se funcionou.

      
    # letsencrypt-cert-days --domain=helio.loureiro.eng.br
    helio.loureiro.eng.br=48    
      
    

    .oO(nota mental: trocar crontab por systemd-timer)

    Ferramenta pra verificar quantidades de dias válidos de um certificado do letsencrypt

    Details
    Written by: Helio Loureiro
    Category: Go
    Published: April 17, 2025
    Hits: 1114
    • certificados
    • letsencrypt
    • x509

    Já faz algum tempo que venho recebendo esses emails do letsencrypt avisando que as notificações de certificados expirados enviados por email serão suspensas. Até aí ok. Imagino que isso consuma um volume razoável de banda da organização, sem falar nos problemas de antispam por aí.

    O problema é que enquanto eles param esse serviço, ao mesmo tempo não fornecem uma ferramenta fácil pra olhar quando certificado irá expirar. Claro que é possível fazer isso usando o openssl:

      
    ❯ openssl x509 -dates -noout -in /etc/letsencrypt/live/helio.loureiro.eng.br/cert.pem 
    notBefore=Mar  8 17:32:15 2025 GMT
    notAfter=Jun  6 17:32:14 2025 GMT    
      
    

    O problema é que não é possível fazer uma automação disso pra rodar alguma crontab e renovar os certificados em caso de expiração.

    Então resolvi arregaçar as mangas e fazer alguma coisa em Go! pra resolver de vez esse problema.

      
    $ /home/helio/bin/letsencrypt-cert-days
    helio.loureiro.eng.br=50
    hl.eng.br=50
    linux-br.org=50
    loureiro.eng.br=50
    truta.org=50
      
    

    O código está no GitHub.

    https://github.com/helioloureiro/letsencrypt-cert-remaining-days

    Autenticação por reconhecimento biométrico (leitura de digital)

    Details
    Written by: Helio Loureiro
    Category: Linux
    Published: March 07, 2025
    Hits: 1137
    • KDE
    • biometria
    • thinkpad
    • leitura de digitais
    • autenticação
    • fingerd

    Outro dia eu estava mexendo no meu perfil no KDE quando percebi a possibilidade de registrar as digitais pra fazer autenticação. Algo possível nos laptops da linha ThinkPad.

    Configurei meus dois dedos indicadores e... nada. Simplesmente não funcionou.

    Deixei isso pra lá. Afinal não era algo que eu queria tanto assim. Mas ficou aquele desgosto de ter falhado. E hoje eu resolvi pesquisar um pouco mais.

    A dica pra resolver estava numa discussão do Linux Mint.

    https://forums.linuxmint.com/viewtopic.php?t=408129

    tl;dr: o daemon que cuida de tudo é o fingerd, que estava instalado. Mas faltava rodar o comando pam-auth-update e selecionar pra fazer a autenticação pelas digitais.

    Feito isso, a autenticação passou a funcionar tanto pra desbloquear a interface gráfica quanto pro uso do sudo.

    E basta um ctrl+c pra voltar pra usar a senha digitada pelo teclado.

    Colorindo os códigos do site com highlight.js

    Details
    Written by: Helio Loureiro
    Category: Joomla
    Published: February 26, 2025
    Hits: 1050
    • dracula
    • javascript
    • cores
    • temas escuros
    • joomla

    Um dia eu perguntei no grupo do Joomla no Telegram se tinha algum jeito de deixar os códigos publicados com cores, da mesma forma que vemos hoje em dia nos editores. A resposta foi "use o highlight.js".

    E assim o fiz.

    Não sei se configurei da melhor forma possível. Muito provavelmente não porque, cada vez que atualizo o tema, tenho de reconfigurar tudo. Mas a forma que uso é editar no tema principal o "index.php" e adicionar as seguintes linhas na parte de baixo:

      [...]
    <head>
        <jdoc:include type="metas" />
        <jdoc:include type="styles" />
        <link rel="stylesheet" href="/media/templates/site/cassiopeia/css/dracula.css">
        <jdoc:include type="scripts" />
    </head>
    [...]
    </body>    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script>hljs.highlightAll();</script>
    </html>
    

    O dracula.css foi uma adição mais recente. Eu queria que o código ficasse com uma aparência de tema escuro, que é a mesma do site. Tentei usar apontando remotamente, mas como não funcionava eu acabei fazendo na força bruta: copiei e salvei dentro do diretório de css do tema.

    Pra quem quiser fazer o mesmo em seu site:

    https://highlightjs.org/
    https://draculatheme.com/highlightjs

    Update: depois que escrevi o artigo, resolvi procurar se existe uma forma menos tosca de adicionar css e js. Não tem. Simples assim.

    Essa merece o selo "pai chora no banho".

    Imprimindo uma caixa em volta do texto em shell

    Details
    Written by: Helio Loureiro
    Category: Shell Scripts
    Published: February 26, 2025
    Hits: 965
    • bash
    • UI

    Nada muito glamoroso. Só um script usando utf-8 pra fazer uma caixinha bonitinha em volta do texto.

      #!/usr/bin/env bash
    
    sizeof() {
        local msg="$1"
        local size=$(echo $msg | wc -L)
        # one space at beginning and other at the end
        size=$((size+2))
        echo $size
    }
    
    printchar() {
        local char="$1"
        local nr="$2"
        while [ $nr -gt 0 ]
            do
            echo -ne "$char"
            nr=$((nr-1))
        done
    }
    
    
    printbox() {
        local msg="$1"
        local s=$(sizeof "$msg")
    
        echo -n "┌"
        printchar "─" $s
        echo "┐"
        echo -e "│ ${msg} │"
        echo -n "└"
        printchar "─" $s
        echo -e "┘\n"
    }
    
    message="$@"
    printbox "$message"
    

    O código também está publicado no GitHub.

    https://github.com/helioloureiro/homemadescripts/blob/master/printbox.sh
    • Configurando o grafana alloy pra monitorar VMs
    • Configurando o teclado Keychron C3 no Linux
    • Parâmetros de compilação pra Go!
    • Dirigindo de bunda quente
    • Totais de transporte durante 2024

    Page 3 of 37

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Estatísticas

    • Users 2
    • Articles 484
    • Articles View Hits 3511630

    Imagem aleatória