HOWTO - Sobrevivendo na Linha de Comandos

Started by ludarkstar99, November 05, 2024, 03:58:15 PM

Previous topic - Next topic
November 05, 2024, 03:58:15 PM Last Edit: December 12, 2024, 05:36:02 PM by ludarkstar99
======================================================
===         OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS        ===
======                        1 Temporada: EP I - O início (pfctl)                          ======
======================================================
Responsável: ludarkstar99
Data: 05/11/2024
Versão: 1.1
Contribuição: juliocbc
======================================================


DESCRIÇÃO
Muitas vezes quando estamos lidando com troubleshoot, precisamos ir além das ferramentas gráficas que o sistema fornece (WebGui) para encontrar a causa e também resolver determinados problemas. Neste singelo guia, compartilho as ferramentas que uso no dia-a-dia e que me ajudam a resolver determinados problemas ou mesmo investigá-los.


DESCRIÇÃO DOS COMANDOS

pfctl - utilitário para interagir com o filtro de pacotes, seja para listar regras, nat e também states (conexões abertas).
Falando sobre regras, não é possível criá-las como se usava no "iptables", no pfctl você precisa primeiro criar um arquivo com a lista completa de regras para serem carregadas na memória e então imputar este arquivo no pfctl. Isso serve tanto para regras de acesso quanto para regras de nat (aqui chamamos de rdr).

COMANDOS ÚTEIS DO PFCTL

# Exibir a documentação do pfctl
$ man pfctl

# exibir a lista de regras da memória
$ pfctl -sr

# exibir a lista de nat (rdr)
$ pfctl -sn

# exibir a lista de states (conexões abertas)
$ pfctl -vv -ss

# Limpar todas as conexões abertas
$ pfctl -F states

# Limpar as conexões iniciadas pelo host 192.168.1.2
$ pfctl -k 192.168.1.2

# Limpar as conexões destinadas ao host 8.8.8.8
$ pfctl -k 0.0.0.0/0 -k 8.8.8.8

# Testar se há algum erro no conjunto de regras automaticamente geradas
$ pfctl -n -f /tmp/rules.debug

# Recarregar novamente as regras na memória
$ pfctl -f /tmp/rules.debug

# Listar quais IPs estão em um alias (ex.: alias de auto-bloqueio do nginx para bots)
$ pfctl -t nginx_autoblock -T show

# Exibir tudo (regras + nat + states + tables + outras informações)
$ pfctl -sa


Thats all, folks.
- nothing broken, nothing missing;

ótimo resumo!

Se me permite acrescentar um:

pfctl -sa

Lista todas as regras em memóra, states, informações do pf, tables, etc. (ou seja, mostra tudo!)
Cloudfence Open Source Team

November 08, 2024, 12:13:07 AM #2 Last Edit: November 08, 2024, 12:19:21 AM by ludarkstar99
======================================================
===              OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS                 ===
======        1 Temporada: EP II - Por trás dos bastidores (configctl)          ======
======================================================
Responsável: ludarkstar99
Data: 07/11/2024
Versão: 1.0
======================================================


DESCRIÇÃO DOS COMANDOS

configctl - utilitário para interagir com o backend (configd - aquele que você não vê, mas sabe que age de formas sobrenaturais), como solicitar a execução de ações em serviços como: reiniciar um serviço, reiniciar um túnel vpn, listar os túneis vpn conectados, invocar a função de atualização de listas de bloqueio (unbound), ou mesmo remover uma lease do serviço dhcp.

# Acessar o manual do configctl
$ configctl configd actions

# Listar as ações disponíveis
$ configctl configd actions

# Listar a tabela arp (e mostrar a saída formatada. Se tiver as manha no jq, pode usá-lo para filtrar a saída)
$ configctl dhcpd list arp | json_pp

# Recarregar todos os serviços (útil para quando edita manualmente o arquivo de configuração)
$ configctl service reload all

# Recarregar a webgui
$ configctl webgui restart

# Listar os túneis OpenVPN
$ configctl openvpn connections server | json_pp

# Reiniciar uma conexão OpenVPN (este número doidão é o id da vpn obtido pelo comando acima)
$ configctl openvpn restart 643d6cee-7900-4026-a4ab-c7e17a266838

# Listar todos os serviços
$ configctl service list | grep -iE 'name'

# Reiniciar o serviço do unbound
$ configctl service restart unbound

# Dump do cache do unbound
$ configctl unbound dumpcache

# Visualizar a lista de templates disponíveis
$ configctl template list

# Gerar novamente o arquivo final de configuração do Captive Portal
$ configctl template reload OPNsense/Captiveportal


DETALHES

E onde ficam as definições destas ações/comandos?
A definições ficam dentro de cada arquivo na pasta /usr/local/opnsense/service/conf/actions.d/
Vamos tomar como exemplo o arquivo actions_crowdsec.conf dentro da pasta acima. 


[status]
command:/usr/local/etc/rc.d/oscrowdsec status; exit 0
type: script_output
message: oscrowdsec status
[...]


A ação "status" (configctl crowdsec status) invoca por debaixo dos panos o comando "/usr/local/etc/rc.d/oscrowdsec status".
Se parar para analisar o arquivo, não tem nada de complicado nele. Para criar sua própria ação, basta copiar um existente e modificar de acordo com seu comando.


CRIANDO UMA AÇÃO PERSONALIZADA
que pode ser usada no cron, agendado na própria webgui

1. criar o arquivo /usr/local/opnsense/service/conf/actions.d/actions_darkstar.conf com o seguinte conteúdo:


[update]
command:sh -c 'curl ifconfig.me > /tmp/updated_address'
parameters:
type:script_output
message:Atualiza o ip externo do firewall no ddns
description:Realiza um teste de IP externo do firewall


2. Reiniciar o serviço do backend para ler nosso arquivo de ação fresquinho.
$ service configd restart

3. Acessar o cron: menu System > Settings > Cron.
4. Criar uma nova tarefa que vai executar a cada minuto (todos os campos do agendamento com *). No campo Command, selecione a tarefa "Atualiza o ip externo do firewall no ddns".
5. Após aplicar a tarefa, aguarde 1 ou 2 minutos.
6. Verifique se foi criado o arquivo /tmp/updated_address.
7. Pronto. Você agora já sabe como agendar comandos periódicos no firewall, de forma externa. Melhor que isso só colocando uma notificação que seu comando foi executado, ou gerar um registro nos logs.
8. Por quê não criar um script que testa o túnel principal da vpn site2site, e caso esteja off, ativa o segundo e desativa o primeiro?


CENAS PÓS CRÉDITOS

Para os universitários de plantão, o daemon do configd mostra uma receita de bolo de como executar um serviço em python (modules/daemonize).

# Inspecionar na integra o conteúdo do daemon configd
$ less /usr/local/opnsense/service/configd.py
- nothing broken, nothing missing;

November 09, 2024, 03:58:02 AM #3 Last Edit: November 09, 2024, 07:01:13 AM by ludarkstar99
======================================================
===              OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS                 ===
======            1 Temporada: EP III - Você disse "Counter Strike"?             ======
======================================================
Responsável: ludarkstar99
Data: 05/11/2024
Versão: 1.1
======================================================


DESCRIÇÃO

Então você instalou a solução Crowdsec em seu firewall OPNsense e sente uma certa sensação de segurança. Quem bom! Durma bem esta noite.  Mas não vai durar para sempre essa sensação, até você descobrir que além dos IPs maliciosos tentando invadir seu firewall, e que serão bloqueados, ainda há 20% ~ 40% que irão furar essa rede de vizinhos monitorados. Além disso, como você barra os IPs que nem estão nesta lista? E os IPs de VMs na  nuvem que foram recentemente ligadas só para tentar furar sua infraestrutura? Não quero lhe assustar, quero que durma bem após ler esta publicação, mas se continuar a leitura, está por sua própria conta.


DECRIÇÃO DO CROWDSEC

Provavelmente já deve ter ouvido falar de uma rede de vizinhos monitorados, é exatamente o que o crowdsec faz. É como aquele "motoquinha" que fica passando a noite no seu condomínio buzinando. Se ele ver uma atividade suspeita, vai ligar para a central e a central vai botar a galera pra ficar esperta - é exatamente o que o crowdsec faz - se atacarem o seu vizinho, você será notificado sobre a aparência do miliante, e vai evitar abrir a porta para estranhos, principalmente se parecerem com o informado pelo rádio.


HISTÓRIA DO CROWDSEC

Fundada por 3 membros, a ideia do crowdsec surgiu quando trabalhavam para um grande e-commerce, ai um belo dia descobriram que estavam sendo atacados por um ator malicioso com posse de 6.000 IPs. aí pensaram, e se pudesse compartilhar essa informação? não seria benéfico que pudéssemos evitar este problema e até mesmo compartilhar para outros evitarem? E se outra empresa já tivesse detectado esses problema, e tivesse compartilhado conosco estas informações de inteligência (threat intel), não estaríamos mais preparados para barrar essa ameaça?
Surgiu então a ideia de usar a inteligência coletiva.
O crowdsec é como uma rede de vizinhos monitorada, só que na internet.


INSTALAÇÃO

A este ponto você já deve conhecer. Acesse o menu System > Firmware > Plugins.
Procure pelo plugin os-crowdsec e instale-o.
Atualize a página (F5) para a configuração do plugin ficar disponível no menu.
*Alternativamente pode instalar o plugin pela linha de comandos, para não ser forçado a realizar o update do firewall antes.

pkg install -y os-crowdsec



CONFIGURAÇÃO

Acesse o menu Services > Crowdsec > Settings > Guia Settings.
Certifique-se de que as quatro caixinhas estão habilitadas:
> Enable Log Processor (IDS)
> Enable LAPI
> Enable Remediation Component (IPS)
> Enable log for rules
Clique em Apply

Aparecerá uma tarja azul indicando que o serviço está sendo configurado... aguarde.
Acesse o menu Firewall > Diagnostics > Aliases.
Acesse a tela Firewall > Rules > Floating
Expanda as regras automagicamente criadas (Automatically generated rules), deverá aparecer as duas regras abaixo na lista:
> IPv4 *   $crowdsec_blacklists   *   *   *   *   *   *   CrowdSec (IPv4)   
> IPv6 *   $crowdsec6_blacklists   *   *   *   *   *   *   CrowdSec (IPv6)

Acesse o menu Firewall > Diagnostics > Aliases.
Selecione o Alias crowdsec_blacklists e confirme que há diversos IPs dentro deste alias.

Acesse o menu Services > Crowdsec > Overview.

A guia machines vai exibir somente o localhost, que é o serviço agente crowsec instalado no próprio firewall;
A guia Bouncers vai exibir somente o localhost, pois é a API responsável por comunicar com o serviço do firewall e também tomar ações como aplicar bloqueios.
A guia Collections vai exibir de onde os logs estão sendo coletados (firewall, ssh, opnsense, opnsense-gui).
A guia Scenarios vai exibir os "cenários de ataque" no qual o crowdsec tem regras para monitorar, como por exemplo um ataque ssh "slow".
A guia Parsers vai exibir as regras para ler os logs e interpretar as mensagens afim de observar algum evento interessante.
A guia Postoverflows vai exibir as regras de whitelist tardias (depois que um IP "encheu o balde", ou, quando um IP foi detectado fazendo gracinha, ainda dá tempo de fazer whitelist dele dado algum critério, como IP de origem ou mesmo País de origem).
As guias Alertas e Decisões são auto-explicativas.

Por enquanto você só irá usar as guias Alertas e Decisões, pois será onde os alertas e bloqueios irão aparecer.


TESTANDO O BLOQUEIO DO CROWDSEC

Acesse o firewall via ssh, e bloqueia seu próprio IP por alguns instantes, ou outro se preferir.
* Você irá perder o acesso por 1 minuto ao firewall. Tente atualizar a página ou acessar via ssh durante estes 1 minutos, e após.


cscli decisions add --type ban --ip $REMOTEHOST --reason teste-luciano  --duration 1m


Caso perca o acesso momentâneo, o bloqueio entrou em vigor, e você está pronto para começar a brincadeira.


COMO FUNCIONA O CROWDSEC (INTERNAMENTE)

O crowsec parece mágica - e assim resumimos a tecnologia que ainda não dominamos. Mas veja bem, é simples (não confundir com fácil):
Logfile --> CrowSec Agent --> Parser --> Enriquecimento --> Deteção --> Alerta --> Bloqueio?
     1                    2                        3            4                      5                6                    7

Um dos serviços fica responsável por ler arquivos de logs, e a esta origem de dados (arquivo de log) chamados de Datasource. Logo então que este log entra, ele é tratado, e com este termo, quero dizer que esta informação (uma linha por vez) é quebrada em pequenas informações semânticas que fazem algum sentido. Veja por exemplo a linha abaixo:


2024-11-08 23:22T0300 pf[101]: user="ludarkstar99" action="reject-auth" message="user ludarkstar99 has denied access to this terminal. session expired"


A máquina irá interpretar uma linha completa. Mas você lendo, rapidamente vai dar foco em algumas informações, como por exemplo o usuário "ludarkstar99", ou a ação que foi rejeitar uma tentativa de autenticação e também vai saber que existe uma mensagem explanatório do motivo desta ação. Mas essa interpretação é sua como serumaninho. A máquina inicialmente vai ler tudo como uma linha cheia de caracteres. Graças ao bom CrowdSec, temos algumas inteligências de ler os campos de alguns logs por padrão. E graças a outros esquisitinhos da internet, você tem uma grande quantidade de "inteligências" para interpretar os logs disponíveis no GitHub.

Depois do log ter sido quebrado em pedacinhos que podem ser indexados e testados individualmente, a próxima etapa é enriquecer esta informação, e o exemplo mais simples que tenho, é adicionar o nome do país do IP de origem do acesso, como um campo adicional (metadado).

Depois de ter sido enriquecido (como urânio), o log passa pelo professor Xavier - quero dizer, pelo motor de cenários, que vai avaliar a toda a informação do evento enriquecido com contexto e vai bater o martelo se é malicioso ou não, se atingiu um comportamento muito exagerado (ou não). só então que é gerado um alerta sobre o evento detectado e então o endereço IP (ou range) é bloqueado.

Para que um IP seja bloqueado, existe na configuração o tempo padrão dos banimentos, que são 4 horas.


OBSERVAÇÕES IMPORTANTES

- O crowdsec por si só faz bastante coisa, mas não cobre 100% de seu ambiente.
- Se estiver usando nginx como proxy reverso, provavelmente vai querer instalar a detecções de nginx e naxsi


cscli collections install crowdsecurity/naxsi
cscli collections install crowdsecurity/base-http-scenarios


- Reinicie o serviço do crowdsec para aplicar as alterações.


COMO EU..?

Testo o que seria pego em um determinado log?
cscli explain --file /var/log/audit/latest.log --type syslog

Exploro a configuração do crowdsec?
*ver conteúdo da pasta /usr/local/etc/crowdsec, em especial
> acquis.d/
> parsers/
> profile.conf
> notifications/*
> scenarios/

Ver o log pelo terminal?
tail -f /var/log/crowdsec/*.log

Listar todos os IPs que já foram bloqueados?
cscli decisions list -a

Remover do Bloqueio um Determinado IP
cscli decisions remove --ip 106.75.67.32

Como adiciono um IP Interno/Externo como whitelist?
As exceções podem ser criadas em 2 momentos, 1o enquanto o log é enriquecido (etapa s02-enrich), 2o na etapa de postoverflow (nos últimos dos 45).
Mas aqui vou abordar apenas como realizar a whitelist dizendo qual ip/rede de origem jamais deve ser bloqueada. Como isso será feito na etapa 02-enrich, iremos criar o arquivo /usr/local/etc/crowdsec/parsers/s02-enrich/luciano-whitelist.yaml com o seguinte conteúdo:


name: darkstar/luciano
description: "nao bloqueia poh"
whitelist:
  reason: "home office tiolulu"
  cidr:
    - "200.200.200.0/24"
    - "189.89.21.0/21"
    - "10.0.10.0/24"


Como testar se minha whitelist está funcionando?
Substitua o IP que é a primeira informação do log abaixo e execute o comando inteiro no ssh.



echo '10.0.10.65 - - [09/Nov/2024:02:17:32 -0300] "GET /test/luciano HTTP/2.0" 404 92 "-" "Go-http-client/1.1" "177.70.23.45"' | cscli explain --type nginx -f-


deverá produzir a seguinte saída, denotando que o IP foi ignorado com sucesso.
line: 10.0.10.65 - - [09/Nov/2024:02:17:32 -0300] "GET /test/luciano HTTP/2.0" 404 92 "-" "Go-http-client/1.1" "177.70.23.45"
        ├ s00-raw
        |       ├ 🔴 crowdsecurity/syslog-logs
        |       └ 🟢 crowdsecurity/non-syslog (+5 ~8)
        ├ s01-parse
        |       ├ 🔴 crowdsecurity/luciano-teste
        |       └ 🟢 crowdsecurity/nginx-logs (+22 ~2)
        ├ s02-enrich
        |       ├ 🟢 crowdsecurity/dateparse-enrich (+2 ~2)
        |       ├ 🔴 crowdsecurity/geoip-enrich
        |       ├ 🟢 crowdsecurity/http-logs (+7)
        |       ├ 🔴 crowdsecurity/luciano-enrich
        |       ├ 🟢 darkstar/luciano (~2 [whitelisted])
        |       └ 🔴 crowdsecurity/naxsi-logs
        └-------- parser success, ignored by whitelist (home office tiolulu) 🟢

ignored by whitelist 0/ - conseguimos com sucesso aplicar a whitelist


Leituras obrigatórias:
- https://docs.crowdsec.net/docs/next/concepts
- https://docs.crowdsec.net/docs/next/data_sources/file
- https://docs.crowdsec.net/docs/next/parsers/create/
- https://docs.crowdsec.net/docs/next/scenarios/create/
- https://docs.crowdsec.net/u/getting_started/post_installation/whitelists/
- https://app.crowdsec.net/hub/author/crowdsecurity/configurations/whitelists
- https://docs.crowdsec.net/docs/next/whitelist/intro/
- https://docs.crowdsec.net/docs/cscli/cscli_collections_install/
- https://app.crowdsec.net/hub/author/crowdsecurity/collections/base-http-scenarios


That's all folks.

- nothing broken, nothing missing;

November 15, 2024, 06:17:46 AM #4 Last Edit: December 11, 2024, 05:20:58 AM by ludarkstar99
======================================================
===              OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS                 ===
======            1 Temporada: EP IV - Escolha bem seu caminho                 ======
======================================================
Responsável: ludarkstar99
Data: 14/11/2024
Versão: 1.0
======================================================


DESCRIÇÃO

Todo homem é igual perante Deus. E talvez por isso possuímos um instinto natural de ficar perdido sem o GPS. Sabe quando você precisa chegar a um lugar de carro, não lembra o caminho de cabeça, mas é só ir dirigindo que você sabe que vai chegar lá? Pois bem, eu tive uma namoradinha na minha adolescência que, sempre que podíamos, arrumávamos uma desculpa para ir para a casa dela buscar ela e dar um rolê nos bares do Bueno Franco. Éramos alguns amigos, e eu era um dos que tinha carro na época. Eu nunca memorizei o trajeto até lá, mas era só pegar a estrada e de alguma forma chegávamos até lá. Talvez a vontade de vê-la fosse tanta que, instintivamente, a cabeça de baixo guiava o trajeto, como o pica-pau que vai atrás do frango flutuando pelo cheiro... Há diversos caminhos; alguns que não levam a lugar nenhum, alguns que estão lá só por comodidade, alguns que você nem sabia que dava para chegar lá, e outros que não têm como errar. Fato é: alguns caminhos, depois que você passa por eles, não têm mais volta.


DO INÍCIO

Há algumas pessoas que a chamam de Shell, outros de terminal, fulano chama de prompt de comandos e ciclano chama de linha de comandos. Mas todos esses termos remetem a algo que nós, profissionais de TI, reconhecemos ao ver, mas sequer sabemos sua história. Não estou aqui para falar de máquinas de escrever, até porque são apenas uma parte da história. Teríamos que falar de sinais elétricos e teoria da comunicação para chegar à base do que hoje é a interface que interage com o núcleo do sistema operacional. Sim, estou falando da tela preta e letra branca (ou "esverdeada" para alguns). Aquela tela que você vê o hacker digitando rapidamente e, de repente, aparece um alerta que ele foi descoberto ou que o firewall foi penetrado com sucesso [lá ele] (vide takedown).

O terminal com o qual você interage nada mais é que uma interface - termo genérico para designar controles dos quais você envia e recebe sinais com o outro ator que está do outro lado. Em nosso caso, nós despachamos comandos usando a interface de terminal, e o terminal repassa nossos comandos digitados para o sistema operacional. É como comprar um bilhete de metrô em São Paulo, usando um caixa com uma pessoa de verdade e não caixa eletrônico. Você diz quantos bilhetes quer, coloca ali o dinheiro, o caixa pega seu dinheiro, processa sua solicitação e lhe entrega os bilhetes, simples assim. Indo pela etimologia da palavra, "Terminal" é relativo a uma extremidade. Lembre-se dos mainframes: o CPU ficava em um lugar - em uma extremidade, e o terminal em outra extremidade. O terminal era a tela e teclado (interface) pelo qual o usuário interagia com o sistema. E é o que mantemos até hoje. Você pode acessar o firewall pelo terminal "físico", com teclado e mouse, e vai interagir com o sistema operacional enviando comandos e aguardando resultados, ou via terminal remoto. Antigamente se usava telnet; devido à sua fragilidade (simplicidade) de segurança, hoje usamos o SSH, que permite essa interação usuário/sistema via rede de forma segura, sem permitir que um curioso "ponha o ouvido no cabo" e escute os comandos que você está dizendo ao sistema operacional do outro lado.
Dei essa volta toda para lhe contar o óbvio.


O TERMINAL DO FIREWALL

Há mais de uma forma de acessar o terminal (interface para enviar comandos e receber resultados) do sistema. Vai depender um pouco do hardware e de onde você está em relação a ele. Vamos pelos mais simples: na época da vovó, em dispositivos mais simples, eles não possuíam teclado e mouse, assim como os videogames. Uma vez programados, não havia interface para administrar, ou era administrado via o software que ali rodava, com uma interface bem limitada referente ao que se podia fazer no sistema. Muitas caixas de firewall foram criadas para usarem hardware embarcado, o menor hardware possível com a maior potência, sendo específico para um determinado fim. Quando estudei no SENAI e pude participar de um treinamento para um campeonato de robótica (do qual acabei não participando no final das contas), eu estava na equipe de pneumática - usávamos um robô pronto, já vinha programado, só tínhamos que usar o software gráfico construtor de blocos para dar a lógica ao robô. Mas havia outra equipe, a da eletrônica, e o robô deles eles mesmos construíram e programaram do zero. Era muito mais interessante que o nosso... E esse robô (interessante), que era inclusive programado em C (mais tarde eu descobri que o nosso tinha SDKs e poderia ser programado em C, Java, C++ e Python, mas os coordenadores demonstraram que não era aceitável trabalhar dessa forma, pois não era para entender o robô, era só para ganhar a competição), tinha uma interface de comunicação com o mundo externo, e era uma saída Serial (RS232). Essa saída permitia que um comando por vez fosse enviado ao robô, que o processaria e então devolveria na mesma porta Serial o resultado para aquilo que estava conectado à porta (um computador quando faziam debug ou um sensor quando entrava em testes na pista). O que eu quero dizer com isso é que há hardware em que o firewall pode ser instalado e que não terá teclado e mouse, mas sim uma porta serial para comunicação do hardware com o mundo exterior. Geralmente, nesse tipo de hardware, o sistema operacional é instalado em um cartão de memória em um notebook e então levado e instalado no minicomputador do firewall. Assim, o sistema já dá boot com o S.O pré-instalado e, a partir dali, você pode se comunicar com ele via porta Serial ou se conectar a ele via rede/webgui. Mas como, nos dias atuais, ficou banal usar hardware x86 para tudo, não seria diferente com os firewalls. Tanto que o pfSense foi um dos precursores em permitir a execução de um firewall robusto em hardware x86 de desktops (você verá por aí alguns artigos chamando de commodity). Essas máquinas desktop, de maneira geral, possuem placas-mãe integradas com conectores de teclado, mouse e vídeo - famoso on-board. Para esses casos, o firewall pode ser instalado via CD-ROM (ou pendrive para os mais novos) diretamente no hardware em que será usado, e você acessa e interage inicialmente com o sistema via teclado/monitor, até que ele tenha rede e o restante você faz da sua própria mesa.

Para este artigo, estou assumindo que o firewall OPNsense está instalado em um hardware x86 e que você pode, a qualquer momento, conectar teclado e mouse na "CPU" para executar comandos no sistema.


O CONSOLE PADRÃO DO OPNSENSE

Você vai notar que, após ligar o firewall, pode acompanhar no monitor várias letras passando até que o sistema seja inteiramente carregado na memória. Essas letras são informações que o BootLoader e o *Kernel vão gerando na medida que o sistema é carregado. Uma vez pronto para operar, você é apresentado ao console padrão do OPNsense, protegido por senha.




Thu Nov 14 22:45:51 -03 2024

*** utm.citrait.corp: OPNsense 24.7.8 ***

WAN (hn1)  -> 192.168.254.2/24
LAN (hn0)    -> v4: 192.168.1.1/24
                   -> v6/t4: 2804:d45:d9e4:[:redacted:]1300/64

HTTPS: sha256 30 B7 03 7C E1 EC 1B 0F 3D 84 AE 1B EF E3 41 D3
                       93 48 85 BE 7C 72 FF AB D1 CA 97 15 AD D3 A8 ED

FreeBSD/amd64 (utm.citrait.corp) (ttyv0)

login:




Este é um TTY (console virtual) alocado para ser exibido no monitor, e através dele você já pode interagir com o sistema, claro, depois que provar que tem as chaves (login e senha). Neste momento, o console está executando um programa chamado "Login", que única e exclusivamente tem a função de validar login + senha e, se estiver errado, repetir até que uma combinação válida seja informada.
Ao fornecer uma combinação de login e senha válidos, o programa "Login" vai preparar o ambiente do usuário, ler seu shell padrão disponível no arquivo /etc/passwd e então vai invocar este shell. O shell em si é o interpretador de comandos interativo, que lê uma linha por vez, leva para o S.O, aguarda o processamento e traz de volta o resultado.

Mas qual é o Shell padrão do usuário padrão do OPNsense?
Bom, o usuário padrão é o root, e para saber qual o shell padrão, devemos verificar o arquivo /etc/passwd.


$ cat /etc/passwd

[...]
root:*:0:0:System Administrator:/root:/usr/local/sbin/opnsense-shell
[...]


Veja que o shell padrão é o último parâmetro do arquivo (aqui os parâmetros são separados por dois pontos ":"). No caso do root, o shell será o /usr/local/sbin/opnsense-shell. Para você que é curioso, basta ler o conteúdo do arquivo para entender melhor o que ele faz. Você não vai se arrepender :D


less /usr/local/sbin/opnsense-shell

[...]
#!/bin/sh

# Copyright (c) 2014-2018 Franco Fichtner <franco@opnsense.org>
# Copyright (c) 2004-2011 Scott Ullrich <sullrich@gmail.com>
# Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>
# All rights reserved.

# make sure the user can't kill us
trap : 2
trap : 3
[...]


Bem no início do arquivo nós podemos atestar aquela célebre frase: se eu cheguei longe, foi porque subi nos ombros de gigantes. o que você tá ai usando como opnsense vem de 20 anos atrás.


OPÇÕES DO SHELL PADRÃO

Ao ter acesso ao shell padrão, você é apresentado com algumas opções pré-definidas, como executar um ping para testar a conectividade da rede, reiniciar o firewall, restaurar o padrão de fábrica, e até mesmo atualizar o firmware. Basicamente este é um menu pré-definido para realizar ações rotineiras. Raramente precisaremos acessar o shell (bom, espero que você não precise, se você precisa acessar o shell, você é o tipo de pessoa que deveria estar escrevendo este artigo ao invés de lê-lo).
Mas além das opções pré-definidas do shell, há também uma opção sob o menu de número 8 chamada Shell. O shell vai permitir fazer tudo o que este menu pré-programado não permite fazer.


ESCAPE PARA A CONCHA (ESCAPE TO THE SHELL)

Bom, se já acessou alguma vez algum sistema linux, você já sabe o que fazer.


CAMINHOS IMPORTANTES NO SHELL

Assim como um sistema linux com pastas parametrizadas conforme uma hierarquia comum (FHS), o FreeBSD também possui uma estrutura semelhante de pastas e arquivos no sistema de arquivos. Entre os importantes:

/tmp => pasta de arquivo temporários. Esta pasta é uma boa decisão de armazenar informações temporárias, que serão limpar após um reboot.

/etc => para quem vem do Linux, a pasta etc é onde concentramos os arquivos de parâmetros e configurações dos serviços do sistema, como o carregador de inicialização (grub), SSH, BIND, montagem de filesystem (fstab), scripts de inicialização (rc.d), dentre diversos outros aspectos configuráveis do sistema. Aqui no FreeBSD/OPNsense você perceberá que esta pasta não leva todas as configurações e sim somente algumas... porque?

/usr/local => se você já compilou algum programa do mundo *nix na linha de comandos, sabe que comumente existe um parâmetro chamado --prefix e através dele dizemos qual a hierarquia de pastas que o programa vai gerar os arquivos quando for instalado. No linux comumente usamos os diretorios /usr, /etc, /bin, /sbin, ou seja, o prefixo para pastas e arquivos dos programas vão direto na raiz "/". Aqui no FreeBSD/OPNsense a pegada é diferente. Os programas são compilados previamente tendo o prefixo sendo a pasta /usr/local (repare o "local" - não misturar o que é sistema/s.o com o que é configuração local de programa/userland).

/usr/local/www => pasta que comporta os arquivos .php (e também html/css) do opnsense, em específico a interface web no que diz respeito a parte legada. Hoje muita coisa foi construída em cima da API e na medida que o tempo passa, mais áreas da webgui estão se adaptando a ela. Os arquivos da API fica numa pasta diferente.

/usr/local/opnsense => este é grande... basicamente manifesta a essência do OPNsense - a interface (web) que orquestra todo o ecossistema de softwares rodando por debaixo dos panos. Aqui temos a definição da webgui em modelo/visão/controller (modelo MVC para os mais íntimos da programação), além da definição do backend responsável por receber as requisições da web e transformar em arquivos de configurações (templates) para os daemons (serviços). Além disso, há vários scripts para tarefas auxiliares presentes nesta pasta. Muitos que você deveria inclusive saber se quiser entender melhor como o sistema funciona.

/usr/local/opnsense/service/templates => certa vez eu precisei alterar um parâmetro no arquivo squid.conf que o OPNsense gera. Mas sempre que reiniciava o serviço ou dava um reboot no firewall o arquivo era gerado novamente e perdia a minha customização. Nesta pasta se encontram os arquivos "template/modelo" que o opnsense usa para gerar as configurações, então se precisar ajustar algo que não está disponível na webgui, a melhor forma de fazer isso é alterando diretamente nos templates. Não aconselho alterar diretamente os arquivos do OPNsense, mas se for algo para resolver um problema ou implementar uma funcionalidade ainda não existente, você já sabe o caminho.

/usr/local/opnsense/service/conf/actions.d => pasta onde ficam os arquivos de tarefas automáticas. inclusive vimos em um episódeo passado como criar e agendar seu script crontab.

/var => alguns serviços como o dhcp e o unbound (dns) gravam dados nesta pasta. "var" é de variável, geralmente onde deveriam estar pastas e arquivos usados constantemente como uploads, bancos de dados e caches, assim como logs (registros de eventos).

/var/log => esse nem precisa de mistério.


CONCLUSÃO

Não invente problemas que não existem. Obedeça as regras e sua vida será fácil. Desvie do caminho e terá que resolver os problemas por conta própria, pois está todo mundo na linha, e ninguém é louco o suficiente para sair dela como você fez.


That's all folks.
- nothing broken, nothing missing;

November 29, 2024, 04:43:51 AM #5 Last Edit: December 10, 2024, 03:36:28 AM by ludarkstar99
======================================================
===              OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS                 ===
======            1 Temporada: EP V - Espelho espelho meu... tem algum software
===========                  mais instalável além do meu?              ===========
======================================================
Responsável: ludarkstar99
Data: 29/11/2024
Versão: 1.0
======================================================



INTRODUÇÃO

Escrever é uma arte. Programar também. Se pintar é arte, falar bem também.
Se somos todos artistas, quem não é, são as pessoas "medíocres"?
Arte é ensinado na escola como algo nato, instintivo, interno e subentendido.
Eu ao menos aprendi que arte era rabisco bonito, tinta com leveza, e curvas que contam histórias.
Monaliza é arte. Ópera também. Guns 'n roses é arte, djavan também.
Arte é terminal ascii, o hacker também. Arte é ler binário, saber compilar também.
Se arte é crime? o carceireiro também. se arte é pecado, satanás também.
prenda-me pelo meu pecado, de rimar tão bem... :D


ESPELHO ESPELHO MEU...

Bom, agora vamos ao que interessa.
Instalar programas em seu computador pode ser algo simples, como um next-next-finish (windows), montar a imagem, e clicar em instalar (naquele S.O que é mais fácil de usar do que roubar doce de criança), ou rodando um comando apt-get install no terminal (naquele sistema de quem come sheetos trancado num quarto escuro). Cada sistema tem uma forma particular de adicionar softwares a sua lista de aplicações instaláveis e usáveis ao seu sistema. Compilar programas no linux é uma boa experiência. ao menos me ensinou uma base. não é o processo como um todo - empacotar e distribuir, mas ao menos entender questão de dependências e compatibilidade. Trabalhar com sistemas complexos como o freebsd, a nível de customização, exige ter esse conhecimento bem alinhado.
Que o OPNsense é baseado no FreeBSD você já sabe, mas e como funciona o ecosistema de pacotes? Que você sabe instalar plugins no OPNsense não é nenhuma novidade, mas e os adicionais que não são instalados pela interface gráfica? Bom vamos lá.


COMO FUNCIONA O ECOSISTEMA DE PACOTES NO OPNSENSE

É simples. O OPNsense é basicamente uma interface web (não me entenda mau, é difícil explicar para gregos e romanos), e essa interface web precisa rodar em um servidor web, que por sua vez precisa estar instalado em um sistema operacional. O OPNsense usa o FreeBSD como sistema operacional, reaproveitando um sistema já consolidado e bem aceito ao invés de recriar a roda. Mas o sistema operacional é apenas a base, você ainda precisa dos programas como serviços de DNS, DHCP, filtro de pacotes, e o php mais o servidor web para rodar a aplicação no qual interagimos pelo navegador. Então existem vários locais pelos quais o software pode vir. O sistema operacional geralmente é distribuído via imagem CD-ROM para ser instalado (pendrive também, o conceito é semelhante), e já os demais programas adicionais são pré-compilados e disponibilizados para download. O pacto aqui é: O fornecedor do Sistema Operacional deixa uma lista de software pré-aprovados disponíveis em um repositório na internet - geralmente uma pasta ftp ou uma pasta compartilhada via http mesmo. A este repostiório quando houver mais de um servidor ou empresa disponibilizando os mesmos arquivos, chamamos de "mirror" pois é exatamente uma cópia do repositório de software (Mirror do inglês significa "espelho"). E você após ter instalado o Sistema Operacional, pode usar um gerenciador de pacotes (leia-se gerenciador de software instalado) para adicionar estes programas disponíveis online ao seu sistema. Mas, veja que eu disse que o desenvolvedor do Sistema operacional disponibiliza apenas alguns softwares pré-aprovados? Pois bem, e se você quiser instalar um software que acabou de ser desenvolvido? Ainda não está disponível no repositório padrão do sistema operacional. Pois bem, você tem algumas possíveis outras opções como compilar e instalar na mão o novo software, ou caso o desenvolvedor tenha disponibilizado um repositório dele você pode apontar esse repositório para seu sistema operacional buscar os arquivos neste repositório do desenvolvedor.


QUEM É O GERENCIADOR DE PACOTES (DE SOFTWARE) NO OPNSENSE

"pkg", este é o programa que gerencia os pacotes de software instalados. Através dele você pode instalar um novo programa, remover um instalado, forçar uma reinstalação e também realizar diversas outras tarefas auxiliares, como consultar versão do programa, ver se ele possui atualização disponível, além de baixar o pacote sem instalá-lo, útil para quando quer inspecionar o pacote sem de fato instalá-lo.
Agora que está passando uma série de perguntas em sua cabeça, vou tentar respondê-las:


COMO EU INSTALO UM PROGRAMA PELA LINHA DE COMANDOS?

Vamos instalar o programa tmux - multiplexador de terminais, útil para abrir vários terminais na mesma tela.
.......................................................................
| Terminal 1                   | Terminal 2                   |
---------------------------------------------------------
| ps auxwww                  | top -M                        |
| programa1.exe             | programa1.exe           |             
| programa2.exe             | \__thread1                 |
| programa3.exe             | \_thread2                   |
.......................................................................
| Terminal 3                    | Terminal 4                  |
--------------------------------------------------------
| tail -f /var/log/system/..| vi /etc/programa1...    |
| user zé authenticated     | [main]                      |
| user zé accessed the url  |  db=sqlite3               |
.......................................................................


# atualiza a lista de pacotes disponíveis para baixar
pkg update

# instala o tmux. quando perguntado, confirme com yes.
pkg install tmux


Simples, não foi?
E como o pkg sabe de onde baixar o tmux?
É simples, o pkg busca por repositórios lendo as configurações que estão na pasta /usr/local/etc/pkg/repos/
Inicialmente há os arquivos FreeBSD.conf e OPNsense.conf. Se você inspecionar o arquivo FreeBSD.conf verá que este é desabilitado por padrão.
Já ao inspecionar o repositório OPNsense, verá que ele busca a URL "https://pkg.opnsense.org/${ABI}/24.7/latest".
Se você jogar esta URL no navegador, não será possível exibir a página pois o caminho não foi encontrado. Olhando a URL mais de perto, vai perceber que existe uma Variável ${ABI} e esta deve ser substituída em tempo de execução. Mas, o que é essa tal de ABI e qual o valor dela em tempo de execução?
ABI significa Application Binary Interface, e é basicamente um meio de dizer a compatibilidade de um pacote com a versão apropriada do sistema operacional. Um programa compilado para o FreeBSD 14 amd_x64 irá funcionar no FreeBSD 14 amd_x64, mas não necessariamente no FreeBSD 12 amd_x64.
Cada versão do Sistema Operacional FreeBSD possui um valor específico para a variável ABI. Para obter este valor, você pode simplesmente fazer a matemática abaixo:

FreeBSD + ":" + Versão + ":" + Arquitetura  = FreeBSD:14:amd64


Ou, pode simplesmente executar o comando abaixo que vai te dar essa informação de forma fácil:

pkg config abi


Então se tentarmos acessar novamente a URL do repositório, mas desta vez substituindo a variável ABI, a url completa ficaria assim:
https://pkg.opnsense.org/FreeBSD:14:amd64/24.7/latest
BAM!! você verá a lista de arquivos (pra ser mais exato a listagem de diretórios)

Index of /FreeBSD:14:amd64/24.7/latest
[ICO] Name Last modified Size Description
[PARENTDIR] Parent Directory -
[DIR] All/ 2024-11-20 13:21 -
[DIR] Latest/ 2024-11-20 13:21 -
[   ] meta.conf 2024-11-20 12:15 163
[   ] meta.pkg 2024-11-20 12:15 1.4K
[   ] meta.txz 2024-11-20 12:15 1.4K
[   ] packagesite.pkg 2024-11-20 12:15 244K
[   ] packagesite.txz 2024-11-20 12:15 244K


É através desta estrutura pré-definida e hieráriquica de arquivos e metadados, que o pkg recupera a lista de programas disponíveis e também busca os arquivos de cada programa (e suas dependências). Para ter uma ideia dos arquivos disponíveis, faça o download do arquivo packagesite.txz. Extraia ele e abra com um editor de texto o arquivo packagesite.yaml, e verá que ele traz uma definição do pacote como nome,descrição, dependências e url (path relativo) para ser baixado. exemplo para o pacote zip.

{"name":"zip","origin":"archivers/zip","version":"3.0_2","comment":"Create/update ZIP files compatible with PKZIP","maintainer":"ler@FreeBSD.org","www":"https://infozip.sourceforge.net/Zip.html","abi":"FreeBSD:14:amd64","arch":"freebsd:14:x86:64","prefix":"/usr/local","sum":"c3021db3edcc23c1f9796714cc0775c28cc982693afdfae6fd228473e66182c4","flatsize":476414,"path":"All/zip-3.0_2.pkg","repopath":"All/zip-3.0_2.pkg", [...]


E como eu...
# instalo um programa pelo pkg
$ pkg install tmux

# removo um programa
$ pkg remove tmux

# vejo as informações de um programa
$ pkg info zip


COMO EU INSTALO PROGRAMAS DISPONÍVEIS NO REPOSITÓRIO FREEBSD MAS NÃO NO OPNSENSE?

O OPNsense apesar de trazer uma grande quantidade de softwares pré-compilados e plugins a um clique de instalação para complementar o firewall, não traz todos os softwares disponiveis no repositório do FreeBSD, e nem faria sentido se trouxesse, pois o firewall é especializado em programas de rede, porque faria sentido trazer plugins de jogo de cartas e interface gráfica? simplesmente não faz... mas caso esteja resolvendo algum problema específico, ou usa o firewall para alguma finalidade avançada, você pode ter acesso aos softwares do FreeBSD, bastando configurar que o pkg do OPNsense deverá buscar o repositório online do FreeBSD.


Configurando o repositório do FreeBSD

Edite o arquivo /usr/local/etc/pkg/repos/FreeBSD.conf para ficar da seguinte forma:
FreeBSD: {
   enabled: yes,
   url: "https://pkg.freebsd.org/${ABI}/latest"
}


Instalando um software do repositório FreeBSD

Agora que o OPNsense sabe onde buscar pacotes direto na fonte, vamos instalar como exemplo o programa "gping" que mostra o ping via gráfico no console.

# sincronizar a lista de pacotes com o repositório
$ pkg update

# instalar o gping
$ pkg install -y gping

# testar o ping dentro da matrix
$ gping 1.1.1.1


Ok, agora que você entendeu a pegada, vamos desativar o repostitório do FreeBSD, pois raramente vai ser necessário mexer com ele.
Edite o arquivo /usr/local/etc/pkg/repos/FreeBSD.conf e altere a linha enabled de yes para no. Salve. e pronto!


Configurar o repositório MIMUGMAIL

Um abençoado chamado mimugmail teve a genial idéia de compilar softwares geralmente úteis para o OPNsense, sem sobrecarregar o sistema com todos os pacotes do FreeBSD. Neste repositório, você encontrará utilitários como o ADGuardHome, Controladora Unifi, ElasticSearch, Grafana, entre outros.
Para habilitar este repositório, crie o arquivo /usr/local/etc/pkg/repos/Mimugmail.conf com o seguinte conteúdo:


mimugmail: {
  url: "https://opn-repo.routerperformance.net/repo/${ABI}",
  priority: 5,
  enabled: yes
}


Agora sincronize a lista de pacotes com os repositórios e instale um dos programas para testar.


# sincronizar a lista de pacotes
$ pkg update

# instalar o tema dracula
$ pkg install os-theme-dracula


Pronto! Agora você pode acessar o menu System > Settings > General, e trocar o tema para relembrar os velhos tempos de "O beijo do vampiro". Quem pegou, pegou.

Como eu listo os pacotes/plugins disponíveis no repositório do mimugmail?
Esse é simples, está na própria documentação do autor do repositório.

pkg search -g -r mimugmail \*


*https://github.com/mimugmail/opn-repo


CONCLUSÃO

Num ninho de mafagafos, haviam 5 mafagafinhos. Quando um mafagafo mafagafava, todos os mafagafos mafagafavam!
Siga o mestre. ser o mestre é árduo. ser o mestre vai fazer você ser pregado numa cruz.


That's all folks
- nothing broken, nothing missing;

December 11, 2024, 06:13:00 AM #6 Last Edit: December 12, 2024, 05:53:02 PM by ludarkstar99
======================================================
===              OPNSENSE - SOBREVIVENDO NA LINHA DE COMANDOS                 ===
======            1 Temporada: EP VI - Sorria, você está sendo filmado! ;D
===========                      ÚLTIMO EPISÓDIO                 ===============                 
===========                                                                           ===========
======================================================
Responsável: ludarkstar99
Data: 11/12/2024
Versão: 1.0
======================================================



INTRODUÇÃO

Certa vez fui atender a um chamado urgente pois o servidor do cliente havia parado de funcionar na rede.
Logo notei algo de estranho, o servidor estava meio "diferente"... estava infectado! você talvez pergunte, por gripe suína? não meu amigo... um de nossos analistas havia sido atarefado de proativamente limpar o servidor, e na sua ingenuidade baixou uma ferramenta para limpar arquivos temporários no servidor. Me pergunta como eu sei! Ele nao quis falar. Eu tive que puxar pelos logs do windows e vi que 10:30 começaram a instalar drivers com nomes estranho no sistema. Se alguém baixou alguma coisa, ou veio do USB , ou da rede ou veio da internet. Acho que nunca tive tanto orgulho de ter instalado um proxy para um cliente. Dito e feito, lá estava a URL que levou ao download (dica: application/octet-stream) do programa. E se parar pra analisar, o analista não tinha muita chance mesmo, a url era muito parecida com a original. Mas fato é, deu pra correlacionar o horário de instalação dos drivers, com o logon desse analista, com o download do arquivo. Parece até as ruas de Londres, uma câmera em cada esquina (um pub também :D).
Mas pode ficar tranquilo, apesar de eu querer o sangue ainda quente deste colega, meu chefe da época me ensinou uma grande lição. Ele estava fazendo o trabalho dele, e eu fazendo o meu (muito bem por sinal - palavras dele...). É engraçado como a vida ensina, bem diferente de uma sala de aula. Eu achava que aprenderia cálculos de excel com um engenheiro aposentado, acabei aprendendo sobre pessoas no ambiente de trabalho.


THE BIG BROTHER IS WATCHING YOU
Privacidade e monitoramento são como yin e yang. É engraçado essa relação. Se você está doente, precisa ser monitorado para diagnóstico, entretanto o hospital passa a ter seus dados, como tipo sanguíneo, e possivelmente substâncias encontradas no seu sangue (não que isso seja um problema, não é??). Nem precisa ir tão longe, para que o U.S. neutralize uma ameaça terrorista antes dela entrar em ação, precisa monitorar seus próprios moradores. Edward Snowden curtiu esse post \:-)
Quer navegar https para não ter sua senha vazada? Então tá, me diz como vamos detectar um malware nesse teu joguinho do facebook... Não tem resposta fácil. Mas a solução é monitorar... ah! e nisso a tecnologia é muito boa. Você ainda acha normal aparecer aquela propaganda de neusaudina bem no dia em que você está com dor de cabeça? Tenho uma notícia para você.


DIGA-ME ONDE LÓGAS, E EU LHE DIREI QUEM TU ÉS
Sei que talvez você chegou até aqui querendo saber como monitorar tudo que o usuário faz, para poder provar para a ANPD que o problema não é seu. E nós sabemos que não é. Mas calma lá, você que está trabalhando com tecnologia precisa entender que nem todo herói usa capa, as vezes ele só sai de madrugada para comprar sorvete pra esposa, e que ao trabalhar com open source, você vai ter que sujar um pouco a roupa.
Imagina o seguinte: Você se levantou da mesa para ir almoçar e esqueceu o computador ligado. No outro dia é chamado no RH para explicar porque enviou uma foto do neg@0 da pic0na para o diretor da companhia. (eu nunca fiz, te sugiro também não fazer). E você não tem como provar pois tudo aponta que foi você! O computador é o que você usa, o e-mail usado no disparo também foi o seu, o login do computador também foi o seu... E aí josé? Pois é. É nesses momentos que o registro de atividades pode auxiliar. Nesse caso é muito difícil  provar que não foi você, mas se buscar a hora do disparo do e-mail, com as imagens da câmera de segurança, bam! vai dar pra ver que não era você usando seu computador. A Câmera de segurança pode ser entendida como um registro de atividades.
Para ser mais exato, damos o nome de "registro de eventos", e é isso mesmo que quer dizer. Eventos são ocorrências de interações, e precisamos guardar o resultado dessas interações. Se um usuário interagiu com o formulário de login do sistema, é bom que nós saibamos, pois caso contrário se for uma tentativa de acesso indevida que vai tentar 300 vezes a senha até encontrar uma válida, nós não teremos registro e não iremos nem ficar sabendo, e nem ter como explicar. Nos anos 90 se você não "pegasse o hacker", estava tudo bem, era porque "o hacker" era habilidoso. Hoje em dia se você não ver a ameaça chegando, você é motivo de chacota pelos colegas de profissão (lembre-se, pimenta no -rabo- olho dos outros, é refresco!). Já dizia a filósofa pitty - quem não tem teto de vidro que atire a primeira pedra!


QUE HAJA LOGS!
E o que o Firewall OPNsense é capaz de registrar nos registros de eventos? Para todo efeito, iremos chamar a partir de agora somente de "logs" estes registros de eventos.
Pois bem, como qualquer sistema operacional que se preze, junto de suas aplicações, muitas das interações que ocorrem no sistema são registradas, como: login de um usuário no shell remoto (ssh), um device obteve um endereço IP emprestado do DHCP, um usuário se autenticou no Captive Portal, ou na VPN. Esses são alguns dos tipos de eventos registrados pelo OPNsense. Mas... como?
Eu sei... Eu sei... você sabe! quando precisa contar com eles, ele sempre está lá, na tela de "logs" de cada módulo. SE você precisa ver os logs do DHCP, vai no menu DHCP > Logs. Se precisa ver os logs de quem acessou a WebGui, vai em System > Log Files > Audit. Mas, e como o log vai parar lá? Tem um duende dentro do firewall??
talvez até tenha, nós vamos achar ele juntos!


"NA MINHA ÉPOCA ERÃO TÃO MAIS DIFÍCIL..." - vovô
Já parou pra se perguntar, como um programa gera um Log? Além do mais, como cada log vai parar no arquivo certinho? Indo mais além, como os logs são rotacionados diariamente e mantidos apenas os últimos 31 dias de logs (diferente de nosso primo pfSense, em que tínhamos que calcular a raiz quadrada de cosseno, para dizer quantos dias de logs seriam mantidos). E ainda subo mais um nível: como é enviado o log para um SIEM (ou um simples servidor syslog, já quebra o galho).

Para entender melhor vamos usar um programa simples de exemplo - o "logger". Não precisa se assustar, não é nenhum termo de desenvolvedor. é um programa de linha de comandos que só tem uma utilidade, gerar uma linha de log no sistema. Para usá-lo simplesmente chamamos o programa e passamos a mensagem que queremos registrar.
logger "oi, eu sou o goku"

Tá, mas e onde foi parar a mensagem?
# podemos ver nas últimas linha gravadas no log geral de sistema
# `date +"%Y%m%d"` é para pegar o arquivo com a data atual no pedaço do nome
tail /var/log/system/system_`date +"%Y%m%d"`.log

[...]
<13>1 2024-12-10T00:44:13-03:00 fwunder.citrait.local luciano 91722 - [meta sequenceId="1"] oi eu sou o goku

O log foi gerado e foi salvo. Mas, como saiu da linha de comandos e foi parar no arquivo?
Pois bem, aqui vamos entrar em mais um nível. Para quem assistiu o filme do leonardo dicaprio, inception, sabe que pode sentir náuses a qualquer momento. vamos, pois tem que ter aventura, certo?!

Iremos fazer os seguinte, vamos jogar o programa "logger" embaixo dágua, de forma que qualquer movimento que ele faça, possamos capturar em camera lenta e analisar. A analogia foi bem ruinzinha, mas acho que deu pra entender que vamos analisar o que o programa "logger" faz minuciosamente, quase uma engenharia reversa.
# truss é como o strace do linux, ele intercepta as syscalls para que possamos analisar.
# -af mostra detalhes das chamadas, -s 100 mostra até 100 caracteres de strings passadas como argumentos de funções.
truss -af -s 100 logger "oi eu sou o goku"

[...]
open("/lib/libcap_syslog.so.1",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
[...]
connect(4,{ AF_UNIX "/var/run/log" },106) = 0 (0x0)
sendto(4,"<13>1 2024-12-10T01:08:48.538926-03:00 fwunder.citrait.local luciano 83921 - - oi eu sou o goku"....
[...]

Agora em posse de uma lupa, podemos claramente ver o que acontece: o logger está importando uma biblioteca chamada syslog, e logo então abre uma conexão com um dispositivo de rede (um socket no filesystem local/AF_UNIX) e logo em seguida envia o texto do log para este socket. sockets no sistema operacional são como conexões de rede. se forem usados no filesystem local, indica que haverá uma comunicação entre processos. Logo se o "logger" está em uma ponta, deve haver outro programa/processo em outra ponta esperando a mensagem chegar.

Pois bem, lembra que comentei sobre o logger importar a biblioteca syslog. isso quer dizer algo. Syslog é um subsistema de logs. Foi desenvolvido para padronizar a bagunça que era antigamente. Imagina um servidor rodando 50 processos servidores (daemons) e todos eles competindo para gravar registro de eventos. É como ter 1 orelhao na cidade e 50 pessoas na fila querendo usar. Se for interior então, dá até briga de faca!

No OPNsense esse sistema de syslog é feito por um programa chamado syslog-ng, e sua configuração fica na pasta /usr/local/etc:
root@fwunder:/var/log # ls /usr/local/etc/syslog-ng
syslog-ng.conf         syslog-ng.conf.d/      syslog-ng.conf.dist    syslog-ng.conf.sample  syslog-ng/

E olhando de perto o arquivo syslog-ng.conf, podemos ver que ele define um socket unix justamente no caminho /var/run/log, que foi onde o logger estava gravando a linha de texto.

source s_all {
    internal();
    file("/dev/klog" follow-freq(0) flags(no-parse) program-override("kernel"));
    unix-dgram("/var/run/log" flags(syslog-protocol));
[...]


Maravilha! saímos do logger, entramos no syslog pelo arquivo/socket /var/run/log, mas e como fomos parar no arquivo system.log?
Já estamos chegando lá.
Para essa pergunta, vamos encontrar a resposta em outro arquivo de configuração do syslog-ng, que é o /usr/local/etc/syslog-ng.conf.d/syslog-ng-local.conf.

destination d_local_system {
    file(
        "/var/log/system/system_${YEAR}${MONTH}${DAY}.log"
        create-dirs(yes)
        flags(syslog-protocol)
    );
};

Agora ficou claro, que o próprio syslog-ng se encarrega de encaminhar alguns logs para o arquivo /var/log/system/system_$ano$mes$dia.log. Mas, só pra não ficar aquela dúvida... qual é mesmo a instrução que faz isso?

################################################################################
# not captured elsewhere, but relevant, send to system[__].log
################################################################################
filter f_local_system {
    not filter(f_local_wireless) and not filter(f_local_wireguard) and not filter(f_local_vpn) and not filter(f_local_suricata) and not filter(f_local_routing) and not filter(f_local_resolver) and not filter(f_local_ppps) and not filter(f_local_portalauth) and not filter(f_local_pkg) and not filter(f_local_openvpn) and not filter(f_local_ntpd) and not filter(f_local_monit) and not filter(f_local_lighttpd) and not filter(f_local_kea) and not filter(f_local_ipsec) and not filter(f_local_gateways) and not filter(f_local_firewall) and not filter(f_local_filter) and not filter(f_local_dnsmasq) and not filter(f_local_dhcrelay) and not filter(f_local_dhcpd) and not filter(f_local_configd) and not filter(f_local_audit) and not filter(f_local_squid_access)
    and level(notice..emerg)
};

destination d_local_system {
    file(
        "/var/log/system/system_${YEAR}${MONTH}${DAY}.log"
        create-dirs(yes)
        flags(syslog-protocol)
    );
};

log {
    source(s_all);
    filter(f_local_system);
    destination(d_local_system);
};

"not captured elsewhere, but relevant, send to system[__].log"
A linha log no final basicamente diz que de todas as mensagens de entrada no syslog (source s_all), será feito um filtro (filter f_local_system) em que aquilo que não corresponder com serviços conhecidos, vai se enquadrar como log de sistema e salvo no destination d_local_system. pronto. espero que não tenha ficado nenhuma dúvida. Se você entendeu até aqui, coletar logs de switches, roteadores, firewalls e até mesmo sistemas linux se torna trivial. Talvez você só precise alterar o padrão de 31 dias de logs do opnsense para 60... ou talvez queira implementar uma solução SIEM trabahando em conjunto com o OPNsense, e então esse tipo de informação se torna relevante para um engenheiro de detecção - nome bunito para quem aprendeu usar expressão regular em correlação de eventos. don't get me wrong, just kidding ;D


Vamos desmistificar outra coisa importante também, observe o formato em que a mensagem é enviada para o syslog, há um prefixo com uns números esquisitos e uma data/hora.

<13>1 2024-12-10T01:08:48.538926-03:00 fwunder.citrait.local luciano 83921 - - oi eu sou o goku

o que seria então esse prefixo? Qual a utilidade dele?
Pois bem, é um padrão e você pode ler na integra essa informação nas RFCs 3164 (mais antiga, tenta explicar a bagunça que era o syslog em que cada um fazia de um jeito), e a RFC 5424, com um padrão mais robusto na formatação das mensagens.

Por partes:

<13> := é a prioridade, mas é um valor composto. A fórmula é: Categoria do log * 8 + importância. ex.: (kernel * 8 + emerg). Ok, o cálculo parece estranho, mas emergencia e kernel na mesma frase é sinônimo de que algo está a ponto de explodir, diferente da combinação e-mail + audit.

1 := é a versão do formato syslog usado.

2024-12-10T01:08:48.538926-03:00 := é o carimbo de data/hora com informação de timezone.

fwunder.citrait.local := é o hostname do sistema.

luciano := é o progama que gerou o log. nesse caso foi gerado manualmente, então o logger botou meu nome mesmo.

83921 := é o PID do processo que gerou o evento.

- := é o ID da mensagem omitido.

"oi eu sou o goku" := é a mensagem que foi registrada pelo evento.

 
Mais uma para terminar (apenas em teste):
Habilite o repositório FreeBSD no OPNsense, e instale o pacote logstash.
Configure o pipeline do logstash como abaixo:
input {
  file {
    path => "/var/log/filter/latest.log"
  }
}
filter {
   grok {
     match => {"message" => "%{WORD:protocol},%{NUMBER:length},%{IPV4:source},%{IPV4:destination},%{NUMBER:srcport},%{NUMBER:dstport}"}
   }
}
output {
    stdout {
        codec => rubydebug
    }
}

e então execute o logstash que irá monitorar os logs do filtro de pacotes...

/usr/local/logstash/bin/logstash

[...]
{
   "protocol" => "udp",
   "@version" => "1",
"source" => "10.141.65.73",
 "@timestamp" => 2024-12-11T04:14:47.810Z,
   "host" => "utm.citrait.corp",
"dstport" => "53",
"srcport" => "1231",
"length" => "328",
   "path" => "/var/log/filter/latest.log",
"message" => "<134>1 2024-12-11T01:10:56-03:00 utm.citrait.corp filterlog 45031 - [meta sequenceId=\"4\"] 70,,,fae559338f65e11c53669fc3642c93c2,hn1,match,pass,out,4,0x10,,128,6421,0,none,17,udp,328,10.141.65.73,1.1.1.1,1231,53,308",
"destination" => "1.1.1.1"
}


E agora, que tal configurar os logs do squid irem parar no SIEM ao invés de flat text files?


CONCLUSÃO

Certa vez um sabio estava na estrada e acabou parando numa fazenda para pedir água. Viu uma família pobre, e perguntou o que eles faziam para sobreviver. "Vivemos do leite de nossa única vaca", respondeu o pai mostrando a família de 5 pessoas. O sábio foi embora, pensativo. Alguns anos depois, o mesmo sábio estava passando pela mesma estrada e se lembrou da família pobre. Resolveu procurar a casinha simples, mas havia uma grande casa com muito gado em volta. Querendo saber o trágico fim da família, foi até a casa e perguntou o que havia ocorrido com a família que morava alí. Foi surpreendido com a resposta: "Ainda somos os donos daqui. Depois que nossa única fonte de renda, que era a vaquinha, morreu, tivemos que nos virar e passamos a trabalhar fora e a ganhar dinheiro". 



That's all folks.
- nothing broken, nothing missing;