Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: DuckDNS e a Evolução dos Clientes para Atualização Dinâmica de DNS: Uma Análise do Cliente em Harbour como Alternativa ao Java

_Créditos das imagens: [JozefJarosciak](https://github.com/JozefJarosciak/DuckDNSClient/blob/master/DuckDNSClient/src/logo.png) **DuckDNS e a Evolução dos Clientes para Atualização Dinâmica de DNS: Uma Análise do Cliente em Harbour como Alternativa ao Java** --- ### **Introdução ao DuckDNS: Simplificando o DNS Dinâmico** O DuckDNS é um serviço gratuito de DNS dinâmico que permite associar subdomínios (como `meudominio.duckdns.org`) a um IP dinâmico, ideal para usuários que desejam acessar dispositivos domésticos (como servidores, câmeras IP ou NAS) remotamente, mesmo sem um IP fixo. Sua simplicidade e integração com tecnologias como Let's Encrypt para certificados SSL o tornam popular em projetos de automação e hospedagem pessoal. --- ### **O Cliente Java Tradicional: Características e Limitações** O cliente Java desenvolvido por JozefJarosciak (disponível [aqui](https://raw.githubusercontent.com/JozefJarosciak/DuckDNSClient/refs/heads/master/DuckDNSClient/src/duckdns...

BlackTDN :: Solução com HAProxy para Redirecionamento "Inteligente?": Caso de Sucesso e Desafios



_Créditos das imagens: Copilot_

## Solução com HAProxy para Redirecionamento "Inteligente?": Caso de Sucesso e Desafios

Na era da conectividade global, pequenas empresas enfrentam desafios únicos ao fornecer acesso remoto seguro para suas aplicações internas. Este artigo descreve como uma consultoria solucionou o problema de redirecionamento de tráfego para servidores TOTVS Application Server usando **HAProxy** e Lua. Também abordamos possíveis melhorias e limitações dessa abordagem.

---

### **Cenário e Desafios**

1. **IP Dinâmico no Servidor Central**  
   O servidor da consultoria utiliza um endereço dinâmico acessível via serviços como **No-IP** ou **DuckDNS**.

2. **Desenvolvedores com IPs Dinâmicos**  
   Os desenvolvedores acessam o servidor de locais variados, dificultando a configuração estática de firewalls ou ACLs.

3. **Porta Única para Acesso (1234)**  
   Por motivos de segurança, apenas a porta 1234 está aberta para comunicação com os servidores internos.

---

### **Solução Implementada**

Para gerenciar essas complexidades, a consultoria configurou um **HAProxy para Windows** compilado com suporte a Lua (disponível no [repositório do GitHub](https://github.com/naldodj/naldodj-haproxy-windows)). Com ele, foi possível:

1. **Verificar Origem do IP**  
   ACLs foram usadas para identificar ranges de IPs e redirecionar as conexões de maneira inteligente.

2. **Log Detalhado das Conexões**  
   Um servidor hb_syslog ([disponível aqui](https://github.com/naldodj/naldodj-hb_syslog)) registrou as conexões para auditoria.

3. **Redirecionamento por ACLs e Payloads**  
   Dependendo da origem e do conteúdo inicial da conexão, os desenvolvedores eram direcionados para o backend correto.

---

### **Configuração do HAProxy**

A configuração envolveu:

#### **Trecho Principal**
```haproxy
frontend tcp_frontend_protheus
    mode tcp
    bind *:1234

    # Chamada ao script Lua
    tcp-request content lua.log_transaction_tcp

    # ACLs para identificar IPs e redirecionar
    acl is_range1 src 191.199.192.0/18
    acl is_range2 src 170.244.192.0/18
    use_backend tcp_backend_protheus_1235 if is_range1
    use_backend tcp_backend_protheus_1236 if is_range2

    # Default para IPs desconhecidos
    default_backend tcp_backend_protheus_1236
```

#### **Script em Lua**
O script gerou logs detalhados para conexões TCP:
```lua
-- Records the "log_transaction" action to capture detailed transaction information.
local function safe_execute(func, description)
    local success, result = pcall(func)
    if not success then
        core.Alert("safe_execute :: Error while processing: " .. description .. " - " .. result)
        return nil
    end
    return result
end

-- Log para transações HTTP
core.register_action("log_transaction_http", { "http-req" }, function(txn)
    core.Info("=== log_transaction_http :: New HTTP connection ===")

    -- Informações gerais
    core.Info("log_transaction_http :: Source: " .. safe_execute(function() return txn.f:src() .. ":" .. txn.f:src_port() end, "Source Info") or "Unavailable")
    core.Info("log_transaction_http :: Destination: " .. safe_execute(function() return txn.f:dst() .. ":" .. txn.f:dst_port() end, "Destination Info") or "Unavailable")

    -- Identificação do frontend e backend
    core.Info("log_transaction_http :: Frontend: " .. (safe_execute(function() return txn.f:fe_name() end, "Frontend Name") or "Unidentified"))
    core.Info("log_transaction_http :: Backend: " .. (safe_execute(function() return txn.f:be_name() end, "Backend Name") or "Unidentified"))

    -- Informações HTTP específicas
    core.Info("log_transaction_http :: HTTP Method: " .. (safe_execute(function() return txn.f:method() end, "HTTP Method") or "Unavailable"))
    core.Info("log_transaction_http :: HTTP Path: " .. (safe_execute(function() return txn.f:path() end, "HTTP Path") or "Unavailable"))

    -- Cabeçalhos HTTP
    local headers = safe_execute(function() return txn.http:req_get_headers() end, "HTTP Headers")
    if headers and type(headers) == "table" then
        core.Info("log_transaction_http :: HTTP Headers Request:")
        for hdr, value in pairs(headers) do
            if type(value) == "table" then
                core.Info("log_transaction_http ::   " .. hdr .. ": " .. table.concat(value, ", "))
            else
                core.Info("log_transaction_http ::   " .. hdr .. ": " .. tostring(value))
            end
        end
    else
        core.Info("log_transaction_http :: HTTP Headers Request: Unavailable")
    end

    -- Informações sobre tempos
    core.Info("log_transaction_http :: Time since acceptance on the frontend: " .. (safe_execute(function() return txn.f:time_frontend_accept() end, "Frontend Accept Time") or "Unavailable") .. " ms")
    core.Info("log_transaction_http :: Time to connect to the backend: " .. (safe_execute(function() return txn.f:time_backend_connect() end, "Backend Connect Time") or "Unavailable") .. " ms")

    core.Info("=== log_transaction_http :: End of HTTP Connection ===")
end)

-- Log para transações TCP
core.register_action("log_transaction_tcp", { "tcp-req" }, function(txn)
    core.Info("=== log_transaction_tcp :: New TCP connection ===")

    -- Informações da origem
    core.Info("log_transaction_tcp :: Source IP: " .. (safe_execute(function() return txn.f:src() end, "Source IP") or "Unavailable"))
    core.Info("log_transaction_tcp :: Port of Origin: " .. (safe_execute(function() return txn.f:src_port() end, "Source Port") or "Unavailable"))

    -- Informações do destino
    core.Info("log_transaction_tcp :: Destination IP: " .. (safe_execute(function() return txn.f:dst() end, "Destination IP") or "Unavailable"))
    core.Info("log_transaction_tcp :: Destination Port: " .. (safe_execute(function() return txn.f:dst_port() end, "Destination Port") or "Unavailable"))

    -- Identificação do Frontend e Backend
    core.Info("log_transaction_tcp :: Frontend: " .. (safe_execute(function() return txn.f:fe_name() end, "Frontend Name") or "Unidentified"))
    core.Info("log_transaction_tcp :: Backend: " .. (safe_execute(function() return txn.f:be_name() end, "Backend Name") or "Unidentified"))

    -- Estados da conexão
    core.Info("log_transaction_tcp :: Connection Status: " .. (safe_execute(function() return txn.f:state() end, "Connection State") or "Unidentified"))

    -- Informações sobre tempo
    core.Info("log_transaction_tcp :: Time since acceptance on the frontend: " .. (safe_execute(function() return txn.f:time_frontend_accept() end, "Frontend Accept Time") or "Unavailable") .. " ms")
    core.Info("log_transaction_tcp :: Time to connect to the backend: " .. (safe_execute(function() return txn.f:time_backend_connect() end, "Backend Connect Time") or "Unavailable") .. " ms")
    core.Info("log_transaction_tcp :: Backend response time: " .. (safe_execute(function() return txn.f:time_backend_response() end, "Backend Response Time") or "Unavailable") .. " ms")

    -- Tamanho da requisição e resposta
    core.Info("log_transaction_tcp :: Requisition Size: " .. (safe_execute(function() return txn.f:req_len() end, "Request Size") or "Unavailable") .. " bytes")
    core.Info("log_transaction_tcp :: Response Size: " .. (safe_execute(function() return txn.f:res_len() end, "Response Size") or "Unavailable") .. " bytes")

    -- Logs de erro
    core.Info("log_transaction_tcp :: Error Code: " .. (safe_execute(function() return txn.f:err_code() end, "Error Code") or "None"))
    core.Info("log_transaction_tcp :: Error State: " .. (safe_execute(function() return txn.f:err_state() end, "Error State") or "None"))

    core.Info("=== log_transaction_tcp :: End of TCP Connection ===")
end)
```

---

#### Exemplo de Registro no Syslog:
```plaintext
2024-12-06 11:31:37 -- hb_syslog start -- 
2024-12-06 11:31:38 INFO: <134>/ Dec  6 11:31:38 haproxy[506]: Connect from ::1:49307 to ::1:8404 (stats/HTTP)
2024-12-06 11:31:39 INFO: <134>/ Dec  6 11:31:39 haproxy[506]: === log_transaction_tcp :: New TCP connection ===
2024-12-06 11:31:39 INFO: <134>/ Dec  6 11:31:39 haproxy[506]: log_transaction_tcp :: Source IP: 191.199.206.183
2024-12-06 11:31:39 INFO: <134>/ Dec  6 11:31:39 haproxy[506]: log_transaction_tcp :: Port of Origin: 55230
2024-12-06 11:31:39 INFO: <134>/ Dec  6 11:31:39 haproxy[506]: log_transaction_tcp :: Destination IP: 192.168.15.3
2024-12-06 11:31:39 INFO: <134>/ Dec  6 11:31:39 haproxy[506]: log_transaction_tcp :: Destination Port: 1234
```
---

## Benefícios e Problemas Potenciais
### Benefícios:
1. **Redirecionamento Dinâmico**: O sistema atende a diferentes ranges de IP ou IPs específicos, assegurando o acesso ao backend correto.
2. **Centralização de Logs**: Logs detalhados permitem auditoria e solução de problemas.
3. **Custo Zero**: Tanto o HAProxy quanto os scripts personalizados são gratuitos.

### Problemas Potenciais:
1. **Manutenção de Scripts**: Alterações nos ranges de IP ou regras exigem atualizações frequentes na configuração.
2. **Overhead de Processamento**: A execução de scripts Lua em conexões de alta frequência pode impactar o desempenho.
3. **Dependência de IPs Públicos**: O uso de IPs dinâmicos pode causar falhas temporárias, mesmo com serviços como No-IP ou DuckDNS.

---

### **Resultados**

- **Melhoria no Controle de Acesso**  
  Os desenvolvedores acessavam os servidores corretos sem intervenção manual.

- **Auditoria Simplificada**  
  Os logs detalhados registraram tentativas de acesso, ajudando na identificação de comportamentos anômalos.

---

### **Limitações e Possíveis Melhorias**

1. **Dependência de IP Dinâmico**  
   Embora serviços como **No-IP** resolvam parte do problema, IPs dinâmicos ainda podem introduzir atrasos devido à atualização do DNS.

2. **Configuração Complexa**  
   Manter ACLs atualizadas manualmente pode se tornar trabalhoso, especialmente com equipes remotas em expansão.

3. **Segurança Adicional**  
   Implementar autenticação baseada em certificados ou VPN poderia elevar a segurança significativamente.

---

## Soluções Alternativas
Se sua empresa busca uma solução ainda mais simples e gratuita, aqui estão algumas sugestões:
1. **VPN Dinâmica com WireGuard**: Configurar um túnel seguro com WireGuard oferece acesso seguro sem depender de regras IP no proxy.
2. **NGINX com Resolução Dinâmica**: Utilizar NGINX com upstreams dinâmicos para redirecionar conexões com base em domínios em vez de IPs.
3. **Proxy Reverso com ZeroTier**: Criar uma rede virtual que elimina a necessidade de lidar diretamente com IPs dinâmicos.

Recomendamos o uso do **WireGuard**, uma VPN leve e gratuita que pode integrar desenvolvedores em um túnel seguro. Com o WireGuard:

- O redirecionamento de tráfego torna-se transparente.
- A comunicação é criptografada ponta a ponta.
- A configuração e o gerenciamento de IPs dinâmicos são minimizados.

---

### **Conclusão**

A solução com HAProxy atendeu às necessidades imediatas da consultoria, oferecendo redirecionamento inteligente e log detalhado. No entanto, a adoção de soluções como **WireGuard** pode simplificar e fortalecer ainda mais o acesso remoto. Ferramentas gratuitas e de código aberto continuam sendo aliadas poderosas para pequenas empresas.

---

### **Links Importantes**
- [HAProxy para Windows com Lua](https://github.com/naldodj/naldodj-haproxy-windows)  
- [Syslog em Harbour](https://github.com/naldodj/naldodj-hb_syslog)  

---

### **Hashtags**

#HAProxy #LuaProgramming #SegurançaDigital #TOTVS #ConsultoriaTecnológica #IPDinâmico #LogsTCP #Redirecionamento #WireGuard #DevOps

---


Comentários

Postagens mais visitadas