curl

curl

  • E Joomla 6.0.3 instalado

    joomla broken 2 2026 02 23 16 29

    Depois do erro do upgrade pro Joomla 6.0.3 descrito em deu ruim com o Joomla 6.0.2, eu meio que deixei pra lá esperando algo como sair o 6.0.4 que talvez resolvesse isso.  Mas hoje eu decidi abrir um bug report.

    Botei o site em mode debug e rodei o upgrade.  Peguei o erro e fui pro site registrar o bug.

    A primeira tarefa foi ver se já existia bug aberto.  E encontrei um:

    https://issues.joomla.org/tracker/joomla-cms/31330

    No bug é comentado que falta suporte ao curl.

    Então conectei no servidor e instaleio php8.4-curl.  Rodei o upgrade e... falhou.

    Claro!  PHP exige reiniciar o servidor web, que é Apache.

    Reiniciei e... pimba!  Estamos na versão 6.0.3.

  • Melhorando o serviço de DNS automático da bolha

    ps5 mimir relocation later

    Eu já tinha descrito em atualizando mapas de DNS no estilo do DynDNS como fazia o sistema de DNS dinâmico que uso pra manter o nome bolha.linux-br.org atualizado, entre alguns outros, com o link residencial que tenho em casa.

    Funcionava mas não era aquela maravilha.  Atualizava a cada 5 minutos e pegava a mudança de IP pelos logs do Apache.

    Até aí, sem grandes problemas.

    Mas daí o Guto, da instância bolha.us, disse que estava tendo problemas de conexão com a bolha.linux-br.org.

    Minha suspeita foi DNS.  Então dei uma olhada nos logs.

    starting: 20251228T18:45:01
    finished: 20251228T18:45:01
    starting: 20251228T18:50:01
    finished: 20251228T18:50:01
    starting: 20251228T18:55:01
    updating IPv4 for raspberry3: old=83.233.219.150 new=51.75.236.128
    updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122854 new_serial=2025122855
    restarting named.service
    finished: 20251228T18:55:01
    starting: 20251228T19:00:01
    updating IPv4 for raspberry3: old=51.75.236.128 new=83.233.219.150
    updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122855 new_serial=2025122856
    restarting named.service
    finished: 20251228T19:00:01
    starting: 20251228T19:05:01
    finished: 20251228T19:05:01
    starting: 20251228T19:10:01
    finished: 20251228T19:10:01
    starting: 20251228T19:15:01
    finished: 20251228T19:15:01
    starting: 20251228T19:20:01
    updating IPv4 for raspberry3: old=83.233.219.150 new=51.68.247.213
    updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122856 new_serial=2025122857
    restarting named.service
    finished: 20251228T19:20:01
    starting: 20251228T19:25:01
    updating IPv4 for raspberry3: old=51.68.247.213 new=83.233.219.150
    updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122857 new_serial=2025122858
    restarting named.service
    finished: 20251228T19:25:01
    starting: 20251228T19:30:01
    finished: 20251228T19:30:01

    O código mostra que IPv4 mudou várias vezes no mesmo dia.

    Então entrei em contato com o provedor e perguntei se não era possível deixar o lease do DHCP mais longo.  A resposta foi que um desses IPs nem era deles.

    Um bug na lógica.

    Então resolvi escrever algo em Go pra tomar o lugar desse sistema pereba de atualização de DNS.  Fiz o dns-monitor.

    Agora o dns-monitor funciona ouvido numa API REST, que recebe JSON, atualiza no banco de dados, faz o update dos mapas de DNS e reinicia o serviço de DNS via systemd.

    E vejo logs assim:

    
    Feb 24 18:15:02 dns-monitor[1139847]: [2026-02-24T18:15:02] (INFO): [RESP] remote_addr=127.0.0.1:59286, real_ip=2a00:1598:23af:4900:5fe7:c566:dbbd:7b35 status_code=200 hostname=www.bolha message=unchanged
    Feb 24 18:15:02 dns-monitor[1139847]: [2026-02-24T18:15:02] (INFO): [REQ] remote_addr=127.0.0.1:59312 real_ip=2a00:1598:23af:4900:5fe7:c566:dbbd:7b35 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:17:27 dns-monitor[1139847]: [2026-02-24T18:17:27] (INFO): [REQ] remote_addr=127.0.0.1:52066 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:17:28 dns-monitor[1139847]: [2026-02-24T18:17:28] (INFO): [REQ] remote_addr=127.0.0.1:52074 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:47990 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:47990, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48006 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): Updating DNS maps: hostname=www.bolha ip_version=6 ip_address=2a00:1598:23af:4900:3e52:82ff:fe62:ff11
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022400
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022400
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48006, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=www.bolha message=IPv6_updated
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48010 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48034 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48020 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48034, real_ip=83.233.219.150 status_code=200 hostname=www.bolha message=unchanged
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): Updating DNS maps: hostname=bolha ip_version=6 ip_address=2a00:1598:23af:4900:3e52:82ff:fe62:ff11
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022401
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022401
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48036 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022402
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022402
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48020, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=bolha message=IPv6_updated
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
    Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
    Feb 24 18:22:28 dns-monitor[1139847]: [2026-02-24T18:22:28] (INFO): [REQ] remote_addr=127.0.0.1:48738 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:22:28 dns-monitor[1139847]: [2026-02-24T18:22:28] (INFO): [REQ] remote_addr=127.0.0.1:48740 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52456 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52456, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52468 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52476 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52476, real_ip=83.233.219.150 status_code=200 hostname=www.bolha message=unchanged
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52482 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52484 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52484, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=www.bolha message=unchanged
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52498 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52498, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=bolha message=unchanged
    Feb 24 18:27:28 dns-monitor[1139847]: [2026-02-24T18:27:28] (INFO): [REQ] remote_addr=127.0.0.1:46772 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:27:29 dns-monitor[1139847]: [2026-02-24T18:27:29] (INFO): [REQ] remote_addr=127.0.0.1:46774 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
    Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37288 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37294 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
    Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [RESP] remote_addr=127.0.0.1:37294, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
    Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37302 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
     

    Ficou mais fácil acompanhar as mudanças e o sistema ficou mais estável.

    No servidor eu fiz um reverse proxy no Apache pra chegar no serviço dns-monitor.

    Do lado do cliente, eu uso curl, como é possível ver pelos logs com user_agent.  Envio algo como isso abaixo mas na crontab a cada 5 minutos:

    ❯ curl -6 -o /dev/null -s "https://api.linux-br.org/api/register" -d '{"hostname": "bolha", "token": "abcdefgh123456"}'
    ❯ curl -4 -o /dev/null -s "https://api.linux-br.org/api/register" -d '{"hostname": "bolha", "token": "abcdefgh123456"}'
    

    O sistema está longe de estar perfeito.  Roda vários updates no mapa seguidamente se o endereço mudar tanto no IPv4 quanto no IPv6, que aconteceu quando mudei o servidor fisicamente do quarto pra sala.  Mas está funcionando e com menos erros que antes.

    Quem quiser olhar o código, já esta no Codeberg:

    https://codeberg.org/helioloureiro/dns_monitor

    Não tem muita descrição, mas está lá e está funcionando em produção.

    Nota: depois de tudo isso, o Guto falou que o problema era do lado da bolha.us.  Ao menos serviu pra eu sair da inércia e escrever um pouco de Go, o que foi bem divertido.

    Nota 2: nenhum código de AI foi usando durante o desenvolvimento desse programa.

  • pycurl no MacOS

    Tive de trabalhar nessa semana com um caso que me exigiu usar o pycurl no Python.  O problema foi que escrevi um script que rodava baixando artefatos de build no Jenkins usando o módulo requests, e o mesmo não funcionava mais no Gitlab.

    Depois de gastar um pouco de tempo no request, e usando o curl do exemplo do site do Gitlab, eu acabei desistindo e indo pra usar o pycurl no script.  De cara descobri que não tinha pycurl instalado.  E no MacOS não foi tão simples como poderia ter sido.  A receita de bolo pra instalar o pycurl foi a seguinte sequência:

    helio@MacOS> arch -arm64 brew install openssl curl
    helio@MacOS> export PATH=/opt/homebrew/opt/curl/bin:$PATH
    helio@MacOS> export LDFLAGS="-L/opt/homebrew/opt/curl/lib":$LDFLAGS
    helio@MacOS> export CPPFLAGS="-I/opt/homebrew/opt/curl/include":$CPPFLAGS
    helio@MacOS> arch -arm64 pip install --no-cache-dir --compile --ignore-installed --install-option="--with-openssl" --install-option="--openssl-dir=/opt/homebrew/Cellar/openssl@3/3.0.7" pycurl

    Quando algo funciona em curl é fácil escrever o código em python.  Basta rodar com o parâmetro --libcurl foo.c que ele joga o código em funcionou dentro do arquivo.c no formato pra linguagem C, mas é bem próximo do uso em python.

       hnd = curl_easy_init();
      curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
      curl_easy_setopt(hnd, CURLOPT_URL, "https://gitlab.[redacted]/api/v4/projects/[redacted]/jobs/[redacted]/artifacts");
      curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
      curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1);
      curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.86.0");
      curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L);
      curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
      curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
      curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
      curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
    

    Em python:

                 url = "https://gitlab.[redacted]/api/v4/projects/[redacted]/jobs/[redacted]/artifacts"
                 buffer = BytesIO()
                c = pycurl.Curl()
                c.setopt(c.URL, url)
                c.setopt(c.BUFFERSIZE, 102400)
                c.setopt(c.NOPROGRESS, 1)
                if GITLAB_PRIVATE_TOKEN:
                    c.setopt(c.HTTPHEADER, [ "PRIVATE-TOKEN:" + GITLAB_PRIVATE_TOKEN ])
                else:
                    c.setopt(c.HTTPHEADER, [ USERNAME + ":" + PASSWORD])
                c.setopt(c.USERAGENT, "curl/7.84.0")
                c.setopt(c.FOLLOWLOCATION, 1)
                c.setopt(c.HTTP_VERSION, c.CURL_HTTP_VERSION_2TLS)
                c.setopt(c.TCP_KEEPALIVE, 1)
                c.setopt(c.WRITEDATA, buffer)
                c.perform()
                c.close()

    E assim o código saiu funcionando.

script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js">