quarta-feira, novembro 01, 2006

Knock: "O poderoso abre/fecha porta"

Nesse artigo vamos conhecer o knock, daemon que permite que portas sejam abertas ou fechadas por demanda,
dependendo "de quem bate à porta", ou seja de acordo com o IP originando a requisição. Esse artigo trata de um exemplo
prático, simples e claro do funcionamento do knock.
Este título foi o que chegou mais perto para a definição da função do Knock.

O que é Knock?

Knock é um poderoso daemon, que gerencia a abertura/fechamento das portas de um determinado computador a
apenas os usuários que obtiverem a permissão ou conhecerem.
Como funciona? O cliente envia requisições (bate) a uma série de portas predefinidas e a abre a porta desejada. No
nosso caso a porta 22 do ssh será aberta.
Requisitos prévios para nossos exercícios são algum conhecimento básico em:
ipfw ports

Instalando Knock

Sempre é recomendável atualizar a árvore dos ports para a instalação de qualquer aplicação.

Para aqueles que ainda não usam portsnap vamos baixar e extrair
#portsnap fetch extract

Atualizando o ports
#portsnap fetch update

Instalando o Knock
#cd /usr/ports/security/knock
make install clean

São mostradas as seguintes opções:
Cliente, aquele que faz a requisição remota para abertura das portas; Servidor, aquele responsável por abrir a porta.
O cliente não é tão necessário, mais tarde explico porque, mas o servidor é obrigatório para o desenrolar do artigo.
O arquivo padrão está em /usr/local/etc/knockd.conf.sample
Copiamos para o nome certo, sem .sample

#cp /usr/local/etc/knockd.conf.sample /usr/local/etc/knockd.conf
Vamos ao arquivo de configuração, com meus comentários

#vi /usr/local/etc/knockd.conf
[options]
logfile = /var/log/knockd.log # Local que serão registrados os logs de abertura de portas
interface = fxp0 #Interface que vai ouvir, normalmente a internet
#Abre o ssh
[openSSH]
sequence = 7000,8000,9000 #Sequencia de portas que o cliente deve "bater" para logar
seq_timeout = 5 #Intervalo de tempo (milisegundos) para uma requisição entre portas
command = /sbin/ipfw -q add pass proto tcp src-ip %IP% dst-port 22 #Regra a ser adicionada no firewall
tcpflags = syn #Podem ser usados as seguintes opções:syn,fin,ack e !ack,!syn,!fin
#Fecha o Ssh

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/ipfw -q delete pass proto tcp src-ip %IP% dst-port 22
tcpflags = syn
Iniciando o daemon
#/usr/local/etc/rd.d/knockd start
Não sei porque o meu não iniciou assim, mais em todo caso iniciei na mão(-d daemon, -v verbose
#knockd -dv
Vamos ao funcionamento
Primeiro bloquei o ssh na sua máquina
su-2.05b# ipfw show
00100 0 0 deny ip from any to me dst-port 22
65535 0 0 allow ip from any to any
su-2.05b#
De fora da minha rede fiz um portscan, para ver as portas abertas usando o nmap (/usr/ports/security/nmap)
su-2.05b# nmap -sS 201.21.140.208
Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-17 21:45 BRT
Interesting ports on virtua-cwbas128-208.ctb.virtua.com.br (201.21.140.208):
(The 1661 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
21/tcp filtered ftp
22/tcp filtered ssh
25/tcp filtered smtp
80/tcp filtered http
135/tcp filtered msrpc
136/tcp filtered profile
137/tcp filtered netbios-ns
138/tcp filtered netbios-dgm
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
587/tcp open submission
Nmap finished: 1 IP address (1 host up) scanned in 41.260 seconds

A porta está fechada ok?
Vamo abri-la

Existem 2 formas (De fora da rede)

1- Usando o knock cliente
#knock 201.21.140.208 7000 8000 9000

2-Usando telnet, atente para o fato de serem regras simlultaneas, pois definimos o tempo em 5 milisegundos

#telnet 201.21.140.208 7000;telnet 201.21.140.208 8000;telnet 201.21.140.208 9000
Nosso /var/log/knockd.log
[2006-10-17 21:49] 200.0.0.0: openSSH: Stage 1
[2006-10-17 21:49] 200.0.0.0: openSSH: Stage 2
[2006-10-17 21:49] 200.0.0.0: openSSH: Stage 3
[2006-10-17 21:49] 200.0.0.0: openSSH: OPEN SESAME
[2006-10-17 21:49] openSSH: running command: /sbin/ipfw -q add pass proto tcp src-ip 200.0.0.0 dst-port 22

meu ipfw
su-2.05b# ipfw show
00100 4 176 deny ip from any to me dst-port 22
65100 0 0 allow ip from any to any proto tcp src-ip 200.0.0.0 dst-port 22
65000 6488 310002 allow ip from any to any

Pronto agora a porta esta aberta. Ele adicionou a regra 65100 com o ip da maquina cliente. Use a vontade a aplicação
até necessitar que seja fechada a porta [closeSSH].
1- Usando o knock cliente
#knock 201.21.140.208 9000 8000 7000
2-Usando telnet, atente para o fato de serem regras simlultaneas, pois definimos o tempo em 5 milisegundos
#telnet 201.21.140.208 9000;telnet 201.21.140.208 8000;telnet 201.21.140.208 7000
Vamos verificar
su-2.05b# nmap -sS 201.21.140.208
Starting Nmap 4.01 ( http://www.insecure.org/nmap/ ) at 2006-10-17 22:03 BRT
Interesting ports on virtua-cwbas128-208.ctb.virtua.com.br (201.21.140.208):
(The 1661 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
21/tcp filtered ftp
22/tcp filtered ssh
25/tcp filtered smtp
80/tcp filtered http
135/tcp filtered msrpc
136/tcp filtered profile
137/tcp filtered netbios-ns
138/tcp filtered netbios-dgm
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
587/tcp open submission
Nmap finished: 1 IP address (1 host up) scanned in 20.377 seconds
su-2.05b#
Porta fechada!!!!!
Simples não??

Resalvas:
  • Nunca se sabe até aonde uma aplicação dessas deve gerenciar regras no firewall, lembre-se que ele executa comoroot, logo você é responsável pelo que faz.
  • Evite usar essas portas default, coloque qualquer coisa diferente disso, ja existem scanners que varrem estas portas.

terça-feira, julho 18, 2006

Introdução aos Níveis de Segurança do Kernel do FreeBSD

Há alguns dias na lista de discussão sobre FreeBSD da FUG-BR houve uma conversa sobre algumas questões de segurança, e comparações de modo de trabalho entre FreeBSD e OpenBSD. Uma das considerações era que no OpenBSD, suporte ao kernel tinha que ser estático, e que o sistema por segurança não permitia que módulos de kernel fossem carregados. Contudo, no FreeBSD esse comportamento também pode ser adicionado, apenas não é padrão. Trata-se de uma prerogativa do administrador de sistemas. A diferença é que o OpenBSD trabalha com nível de segurança positivo por padrão. Algo que no FreeBSD e no NetBSD apenas depende da vontade explícita do sysadmin. Giancarlo Rubio aproveitou o encejo para escrever uma introdução sobre Níveis de Segurança do Kernel do FreeBSD, os chamados Kernel Securelevel e postou esta contribuição, que você acompanha agora.


Surgiu a alguns dias um questionamento entre FreeBSD e OpenBSD, e um deles era relativo a não poder levantar módulos estáticos no kernel, entre outros.

O kernel do FreeBSD pode rodar em até 5 níves de seguran'ca, onde o -1 é o mais baixo até o 3 que é o mais alto.

Por default esse valor é -1, conforme você pode ver com o comando abaixo:

sysctl kern.securelevel
kern.securelevel: -1


Vejamos cada um destes níveis

  1. -1 Modo default, sem segurança de kernel. A única segurança aqui é em relação à permissões tradicionais do de sistemas Unix.
  1. 0 Este nível é apenas usado quando o sistema está sendo inicializado pela primeira vez, e não possui alguma característica especial. Não há motivos especiais para utilizar este nível.
  1. 1 Aqui sim você realmente começa a ter segurança
  1. Não é possivel carregar módulos ao kernel, a não ser que o mesmo seja recompilado. Veja:
# sysctl kern.securelevel=1
kern.securelevel: -1 -> 1
# kldload if_tap
kldload: can't load if_tap: Operation not permitted
  1. Nenhum programa pode escerver diretamente a memória do sistema via /dev/mem ou /dev/kmem

  2. Discos que foram montados não podem ser escritos diretamente, não sendo possível formatar partições ou usar o dd(1) nesses discos.

  3. O Gerenciador de Janelas X não pode ser iniciado (pois ele faz acesso direto aos dispositivos de memória, e isso não é mais permitido nesse nível de segurança)
  1. 2 As mesmas característacas do modo 1 alêm de:
  1. Impossibilidade de escrever direto a sistema de arquivos montados ou desmontados (exceto pelo mount(2),). Impossibilita alterar a estrutura do sistema de arquivos, redefinir ou modificar opções de montagem e também formatar newfs(8) quando o sistema estiver em multi-user.

  2. A hora somente poderá ser alterada de 1 em 1 segundo.
  1. 3 As mesmas caracteristicas do modo 2 além proibir aletrações das definições de regras de firewall, seja o firewall ipfw(8), pfctl(8) ou ipf(8), e também proibe modificações nas disciplinas alternativas de enfileiramento, com altq(4) ou dummynet(4).


Vamos colocar a mão na massa.

Para alterar o nível basta digitar no seu shell

sysctl kern.securelevel=
Exemplo: sysctl kern.securelevel=1


Para fazer o mesmo rodar a partir da inicialização coloque no seu /etc/rc.conf


kern_securelevel_enable="YES"
kern_securelevel=

Giancarlo Rubio,
PUC-PR, FUG-BR


Notas da Redação:
  • A partir do nível de segurança positivo 1 (nível 1) as flags de arquivos imutáveis e apenas concatenação no nível do sistema (schg e sunlnk) não podem mais ser removidas, nem mesmo pelo root. As flags de arquivos imutáveis e apenas concatenação do nível do usuário (uchg e uunlnk) continuam sob total controle do proprietário do arquivo bem como do root, ao manipular estas flags com chflags(1). Isso complementa a segurança que pode ser imposta ao sistema com o uso de chflags(1), e também complementa o artigo escrito por Daniel Bristot sobre chflags.

  • No FreeBSD a partir do nível de segurança 1 atributos extendidos do sistema de arquivo (apenas UFS2, portanto apenas disponível a partir do FreeBSD 5) de nível de sistema não podem mais ser modificados, nem pelo root. Já, de níveis de usuário continuam à mercê do proprietário do arquivo e do administrador (root). Máscaras máximas de privilégios para ACL (Access Control Lists - Listas de Controles de Acesso) não podem mais ser modificadas, nem pelo root. À critério do administrador de sistemas, ACLs podem ser armazenadas como atributos extendidos no nível do usuário ou no nível do sistema, exceto pela máscara que só é armazenada no nível de sistema. Se o administrador forçar que definições ACL sejam armazenadas como atributos extendidos do sistema de arquivos no nível do sistema, ACLs podem apenas ser adicionadas, mas não podem ser removidas nem editadas, à partir do nível de segurança 1.

  • MAC, Mandatory Access Control, ou Controlde de Acesso imperativo, assim como ACLs, parte das implementações POSIX.1e no FreeBSD, à partir do nível de segurança 1 não podem mais ser alteradas. Apenas novas definições MAC podem ser adicionadas para cada módulo MAC (cada subsistema MAC tem função diferente), mas as já existentes não podem ser modificadas nem removidas, mesmo pelo super usuário. A partir do nível de segurança 2 qualquer label em arquivos, sistema de arquivos, interfaces de rede, trecho de memória ou porta de rede, bem como label associada à usuários, não podem mais ser editados, removidos, nem adicionados, nem mesmo pelo super usuário (root).

  • As definições de atribuição de labels via login.conf(5) não podem mais ser modificadas. Labels (ou marcações) são identificadores disponíveis em todos os níveis do sistema operacional para fazer distinção entre exceções e aplicações de quaisquer recursos de segurança documentados na especificação POSIX.1e implementada FreeBSD, e MAC usa intensamente labels.

  • A partir do nível de segurança 1 classes geom(4) só podem ser manipuladas através de rotinas credenciadas pelo kernel (usadas pelas chamadas de sistemas das aplicações de userland que controlam cada classe), e nunca através de outros programas ainda que usem as mesmas chamadas de sistema. A partir do nível de segurança 2 providers do geom(4) só poderão ter suas estruturas modificadas pelo kernel, e apenas consumers geom(4) só poderão se associar à providers se ambos já existirem, ou à critério do kernel quando um provider previamente existente informa o kernel que algumas classes de consumers são esperadas.

  • A partir do FreeBSD 7.0, nível de segurança maior que 0 evitará que regras auditorias de chamadas de sistemas, requisições de transofações ou I/O e alocação de recursos, com o suporte à audit(4) do POSIX.1e não poderão ser mais removidas ou modificadas, e à partir do nível de segurança 2 não poderão sequer ter novas regras de auditoria criada.

Para saber mais, comece pelas seguintes referências:

Em um FreeBSD instalado, leia:

  • man securelevel
  • man 8 init
  • man 7 security
  • man 1 chflags
  • man 3 acl
  • man 4 mac
  • man 9 mac
  • man 9 extattr
  • man 2 extattr