Post em Destaque

Script para instalar o bash e configurar o ambiente com aliases e vim

Comecei minha vida *NIX usando Xenix e SCO Unix, nessa época usava “sh” como shell e “vi” como editor, isso era em 1991 à 1994 se eu me recordo bem. Nessa época eu era Programador Clipper Summer 87 no mundo DOS e Programador COBOL no mundo *NIX. Em 1996 me apresentaram minha...

Leia mais...

Melhorando a segurança no FreeBSD – Parte 2

Posted by gondim | Posted in Dicas, FreeBSD, Segurança | Posted on 20-05-2012

Tags:, , , , ,

0

Dando continuidade nas melhorias de segurança no FreeBSD veremos mais algumas coisas que não foram abordadas aqui. O usuário root sempre foi um cara muito privilegiado e por isso devemos evitá-lo ao máximo e também não permitir que outras pessoas usem ele. Logicamente que segurança física sempre foi o Calcanhar de Aquiles da Segurança da Informação, mas podemos tomar alguns cuidados. Abaixo vamos seguir algumas dicas:

Remoção do usuário “toor”. Não tem utilidade para o sistema e possui “UID 0” que é um perigo para o sistema. Reparem que o perigo não está no nome do usuário e sim no UID (User ID) que sendo 0, é o grande perigo. Só o nome root não seria perigoso se o UID dele fosse diferente de 0.

Para remover o toor basta executar: vipw ir na linha abaixo e apagar teclando “dd”, depois “shift :” e “wq!” para sair gravando. Bem precisa conhecer um pouco de vi.  🙂

toor:*:0:0::0:0:Bourne-again Superuser:/root:

Outra coisa é retirar o shell de todos os usuários que não necessitarem de shell. Serviços não precisam que seus usuários tenham shell. Para isso verifique como está o seu /etc/master.password com o vipw. No FreeBSD 9.0 eles já são instalados com /usr/sbin/nologin como shell das contas. Mas quem ainda usa versões anteriores vão precisar alterar. Deve ficar parecido com o exemplo abaixo:

# $FreeBSD: release/9.0.0/etc/master.passwd 218047 2011-01-28 22:29:38Z pjd $
#
root:$1$ensO.a5U$02Vji3o598eieKtAf6Lpm.:0:0::0:0:Charlie &:/root:/usr/local/bin/bash
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
bin:*:3:7::0:0:Binaries Commands and Source:/:/usr/sbin/nologin
tty:*:4:65533::0:0:Tty Sandbox:/:/usr/sbin/nologin
kmem:*:5:65533::0:0:KMem Sandbox:/:/usr/sbin/nologin
games:*:7:13::0:0:Games pseudo-user:/usr/games:/usr/sbin/nologin
news:*:8:8::0:0:News Subsystem:/:/usr/sbin/nologin
man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/usr/sbin/nologin
sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
smmsp:*:25:25::0:0:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin
mailnull:*:26:26::0:0:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin
bind:*:53:53::0:0:Bind Sandbox:/:/usr/sbin/nologin
proxy:*:62:62::0:0:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin
_pflogd:*:64:64::0:0:pflogd privsep user:/var/empty:/usr/sbin/nologin
_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin

Reparem que só o root tem shell que no meu caso é o bash.

Próxima melhoria seria aumentar a segurança da senha do root trocando md5 para blowfish. Para essa tarefa precisamos editar o arquivo /etc/login.conf:

default:\
        :passwd_format=md5:\

Para:

default:\
        :passwd_format=blf:\

Após alterar o arquivo login.conf precisamos rodar o seguinte comando para que seja gerado o /etc/login.conf.db, cujo arquivo é o que o sistema realmente usa.

# cap_mkdb /etc/login.conf

Mas não acabamos com a senha ainda. Após feito isso precisamos alterar novamente as senhas que desejamos para que essas agora estejam em blowfish e isso pode ser feito com o comando passwd. Reparem na diferença dos tipos:

MD5:

root:$1$9kaWUo5i$fIoOwZFsBsZG9WR/.nqhh1:0:0::0:0:Charlie &:/root:/usr/local/bin/bash

Blowfish:

root:$2a$04$qXWwmvWbpMrp7qpwDbxX/uVccYR3jfhET/hD1U2h9ZN7QyP13yW26:0:0::0:0:Charlie &:/root:/usr/local/bin/bash

Blowfish é bem mais forte (seguro) que md5. Obs: antigamente se usava o /etc/auth.conf para essa configuração.

Outra coisa boa é definir um idle timeout para o root, no caso de você acidentalmente esquecer o usuário root logado no servidor. Se você estiver usando bash como shell, basta adicionar essa variável em /etc/profile:

TMOUT=300

A variável acima trabalha em segundos, ou seja, se o root ficar sem fazer nada por 5 minutos, automaticamente este é deslogado.

Se estiver usando csh como shell, adicione a seguinte linha em /etc/csh.login:

set autologout=5

O autologout trabalha em minutos e vai fazer a mesma função do TMOUT no csh.

Se usa outro shell você precisará pesquisar se este possui uma variável de controle para essa finalidade.

Infelizmente no sh não existe um equivalente para essa finalidade.

Continuando com a nossa melhoria de segurança se você não quiser que alguém logue como root na console do seu servidor podemos editar o arquivo /etc/ttys cujo exemplo está abaixo:

# If console is marked “insecure”, then init will ask for the root password
# when going to single-user mode.
console none                            unknown off secure
#
ttyv0   “/usr/libexec/getty Pc”         xterm   on  secure
# Virtual terminals
ttyv1   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv2   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv3   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv4   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv5   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv6   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv7   “/usr/libexec/getty Pc”         xterm   on  secure
ttyv8   “/usr/local/bin/xdm -nodaemon”  xterm   off secure
# Serial terminals
# The ‘dialup’ keyword identifies dialin lines to login, fingerd etc.
ttyu0   “/usr/libexec/getty std.9600”   dialup  off secure
ttyu1   “/usr/libexec/getty std.9600”   dialup  off secure
ttyu2   “/usr/libexec/getty std.9600”   dialup  off secure
ttyu3   “/usr/libexec/getty std.9600”   dialup  off secure
# Dumb console
dcons   “/usr/libexec/getty std.9600”   vt100   off secure

Basta mudar a coluna secure para insecure conforme abaixo:

# If console is marked “insecure”, then init will ask for the root password
# when going to single-user mode.
console none                            unknown off insecure
#
ttyv0   “/usr/libexec/getty Pc”         xterm   on  insecure
# Virtual terminals
ttyv1   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv2   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv3   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv4   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv5   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv6   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv7   “/usr/libexec/getty Pc”         xterm   on  insecure
ttyv8   “/usr/local/bin/xdm -nodaemon”  xterm   off insecure
# Serial terminals
# The ‘dialup’ keyword identifies dialin lines to login, fingerd etc.
ttyu0   “/usr/libexec/getty std.9600”   dialup  off insecure
ttyu1   “/usr/libexec/getty std.9600”   dialup  off insecure
ttyu2   “/usr/libexec/getty std.9600”   dialup  off insecure
ttyu3   “/usr/libexec/getty std.9600”   dialup  off insecure
# Dumb console
dcons   “/usr/libexec/getty std.9600”   vt100   off insecure

Cuidado com a linha “console none                            unknown off insecure” porque se você colocar ela como insecure quando precisar entrar em sigle mode para recuperar algo no sistema, será pedido a senha de root. Isso pode ser ruim se caso estiver tentando recuperar senhas. Logo ficará ao seu critério colocar a console como insecure. Qualquer tty definida como insecure não será possível acessar como root.

Agora vamos restringir certos acessos, mas chequem se alguma aplicação de vocês precisará de acesso à um desses arquivos em específico:

# chflags noschg /usr/bin/crontab

# echo “root” > /var/cron/allow
# echo “root” > /var/at/at.allow
# chmod o= /etc/crontab
# chmod o= /usr/bin/crontab
# chmod o= /usr/bin/at
# chmod o= /usr/bin/atq
# chmod o= /usr/bin/atrm
# chmod o= /usr/bin/batch

# chflags schg /usr/bin/crontab

Alguns arquivos já tem vindo com proteções usando chflags e por isso precisamos removê-las para alterar as permissões e depois adiciona-las novamente. Para ver se algum arquivo está com chflags setado use o ls com o parâmetro “o”. Abaixo um exemplo:

# ls -laAGo/usr/bin/crontab
-r-sr-xr-x  1 root  wheel  schg  27404 Feb  9 15:17 /usr/bin/crontab

Repare na quinta coluna a flag schg que diz que esse arquivo é imutável.

Continuando… acima estamos restringindo o uso do cron e at somente para o root. Nenhum outro usuário do sistema poderá usá-los. Também estamos removendo as permissões de usuários regulares dos arquivos pertinentes ao cron e at.

Abaixo mais restrições aos usuários regulares para que não acessem alguns conteúdos pois não deveriam ser de interesse deles:

# chmod o= /etc/fstab
# chmod o= /etc/ftpusers
# chmod o= /etc/group
# chmod o= /etc/hosts
# chmod o= /etc/hosts.allow
# chmod o= /etc/hosts.equiv
# chmod o= /etc/hosts.lpd
# chmod o= /etc/inetd.conf
# chmod o= /etc/login.access
# chmod o= /etc/login.conf
# chmod o= /etc/newsyslog.conf
# chmod o= /etc/rc.conf
# chmod o= /etc/ssh/sshd_config
# chmod o= /etc/sysctl.conf
# chmod o= /etc/syslog.conf
# chmod o= /etc/ttys

Quanto aos logs também pode ser feito uma coisa interessante com chflags mas tenham em mente que fazendo isso o rotacionamento de logs não funcionará mais. Minha sugestão, se você quiser uma boa segurança nesse aspecto, é você montar um servidor de logs e configurar os demais servidores para enviarem os logs para esse servidor. Aí sim nesse servidor específico você poderia até fazer o que está abaixo:

# chmod o= /var/log
# chflags sappnd /var/log
# chflags sappnd /var/log/*

Com essa conf acima, os arquivos de log estarão em append only e não poderá ser removida qualquer linha deles, somente adicionada.

Mais restrições à usuários regulares para que não tenham informações importantes do sistema como quem está logado, listar jails, quem logou e por aí vai:

# chmod o= /usr/bin/users
# chmod o= /usr/bin/w
# chmod o= /usr/bin/who
# chmod o= /usr/bin/lastcomm
# chmod o= /usr/sbin/jls
# chmod o= /usr/bin/last
# chmod o= /usr/sbin/lastlogin

Desabilitar o uso do rlogin e do rsh:

# chflags noschg /usr/bin/rlogin /usr/bin/rsh

# chmod ugo= /usr/bin/rlogin
# chmod ugo= /usr/bin/rsh

# chflags schg /usr/bin/rlogin /usr/bin/rsh

O syslogd vem por default habilitado para receber logs e por isso abre uma porta de acesso ao mesmo. Como falei anteriormente acho mais seguro fazer isso em um servidor separado e por isso vamos desabilitar essa função no syslogd local e deixá-la habilitada no servidor de logs. O syslogd continuará funcionando do mesmo jeito só não haverá nenhuma porta escutando uma conexão.

# echo ‘syslogd_flags=”-ss”‘ >> /etc/rc.conf

Vamos partir agora para variáveis da systcl. Existem 2 variáveis que habilitam o recurso log_in_vain que é muito útil quando queremos saber se alguém está tentando acessar alguma porta de serviço que não esteja habilitada no nosso servidor. Para habilitar é muito simples adicione as linhas abaixo no seu /etc/sysctl.conf. Isso também pode ser habilitado pelo /etc/rc.conf, para isso consulte o /etc/defaults/rc.conf.

sysctl net.inet.tcp.log_in_vain=1
sysctl net.inet.udp.log_in_vain=1

Fazendo um teste de uma outra máquina, tentei fazer um telnet na máquina protegida (10.255.0.12) na porta 9998/tcp o que resultou no log abaixo:

/var/log/messages:May 20 11:52:11 protheus kernel: TCP: [192.168.255.1]:59486 to [10.255.0.12]:9998 tcpflags 0x2<SYN>; tcp_input: Connection attempt to closed port

Agora vamos bloquear que outros usuários possam ver processos de outros usuários, colocando a linha abaixo também no /etc/sysctl.conf:

security.bsd.see_other_uids=0

Muitas das coisas do post acima, retirei dessa documentação do Jon LaBass. Pelo menos as que achei mais interessantes e adicionei algumas mudanças pois uma coisa que foi citada em seu texto, ainda não existe implementação no FreeBSD que foi o caso do idletime no /etc/login.conf. Ela existe para uso de aplicações de terceiros mas não na base do FreeBSD, ou seja, o fato de setar ela não irá funcionar e por isso usei outros recursos como o TMOUT e o autologout. Existem outras alterações citadas por ele mas preferi expor apenas as que me interessei.

É isso aí pessoal e até a próxima.

Não deixem de ler o meu primeiro post sobre Melhorando a Segurança no FreeBSD com securelevel + chflags aqui.

Share Button

Melhorando a segurança no FreeBSD com securelevel + chflags

Posted by gondim | Posted in Dicas, FreeBSD, Segurança | Posted on 04-05-2012

Tags:,

4

Um dos recursos muito interessante que o FreeBSD possui é o Secure Level que bloqueia até mesmo o root de executar certas funções. O FreeBSD possui 5 níveis.

-1 e 0 (Permanently Insecure Mode e Insecure Mode): são os níveis mais inseguros, permitem que o root faça qualquer coisa no sistema. O default do sistema é -1.

1 (Secure Mode): nesse nível já existe uma melhora na segurança pois as flags append-only dos arquivos não podem ser alteradas, /dev/kmem e /dev/mem não podem ser abertos para escrita, /dev/io não pode ser aberto para nada e modulos de kernel não podem ser carregados ou descarregados.

2 (Highly Secure Mode): faz tudo que o Secure Mode faz e mais… discos não podem ser abertos para escrita exceto pelo mount. Protege o sistema de arquivos mesmo com este desmontado e não aceita usar o newfs em modo multi-usuário. Tentativas de ajustar data e hora do sistema geram logs e não são aceitas com diferanças superiores à 1 segundo.

3 (Network Secure Mode): faz tudo que o Highly Secure Mode faz e mais… não permite qualquer mudança nas regras de firewall e controle de banda.

Os modos podem ser alterados de 2 formas: através do /etc/sysctl.conf ou pelo /etc/rc.conf. No sysctl.conf seria usando kern.securelevel e no /etc/rc.conf usando as entradas abaixo como exemplo:

kern_securelevel_enable=”YES”

kern_securelevel=”2″

Usando o sysctl você pode alterar em tempo de execução o secure level. Um exemplo abaixo:

# sysctl kern.securelevel=2

kern.securelevel: -1 -> 2

Outro detalhe importante: depois que você sobe de level não é possivel descer:

# sysctl kern.securelevel=-1

sysctl: kern.securelevel: Operation not permitted

Se você acrescentou no /etc/sysctl.conf ou no /etc/rc.conf o secure level e quiser voltar para algum level específico, então você vai precisar alterar o arquivo que você editou e re-iniciar o sistema para que tenha efeito.

Até aqui nada de muito extraordinário e você deve estar se perguntando: ah mas aí e se o cara invadir, basta alterar o arquivo e re-iniciar? Sim mas aí entra um outro recurso do FreeBSD chamado flags e que pode ser alterado com o chflags. O chflags permite mudarmos as características dos arquivos e deixá-los como por exemplo append-only e até imutáveis. Nesse caso se tiver usando secure level de 1 à 3, eles não poderão ter essas flags removidas dos arquivos. Vamos dizer que queremos colocar nosso sistema com secure level 2 e adicionamos as linhas mencionadas acima no /etc/rc.conf. Agora fazemos isso:

# chflags schg /etc/rc.conf

# chflags schg /etc/sysctl.conf

Os comandos acima transformam esses 2 arquivos em imutáveis, ou seja, não poderão ser alterados. Após re-iniciado o sistema além deles estarem imutáveis, estaremos usando secure level 2. Nesse caso um  invasor não poderia alterar esses arquivos e o único jeito seria re-iniciando o sistema, entrar em modo single-user, aí sim alterar com o chflags esses arquivos e editá-los. Reparem que essa tarefa não é nada boa para manutenções remotas e por isso muito cuidado.

Junto à isso imaginem fazer coisas como:

# chflags schg /usr/local/bin/*
# chflags schg /bin/*
# chflags schg /usr/local/sbin/*
# chflags schg /usr/sbin/*
# chflags schg /sbin/*

# chflags schg /usr/lib/*
# chflags schg /usr/local/lib/*
# chflags schg /usr/libexec/*
# chflags schg /usr/local/libexec/*

Dessa forma em uma invasão mesmo o cara sendo root não conseguria alterar esses arquivos acima pois estariam imutáveis. O mesmo pode ser feito com logs usando o parâmetro sappnd no lugar de schg que faz o arquivo se tornar append-only. Para remover essas flags é necessário estar em level -1 ou 0 e o parâmetro seria noschg ou nosappnd. Exemplo abaixo:

# chflags noschg /usr/local/bin/*
# chflags noschg /bin/*
# chflags noschg /usr/local/sbin/*
# chflags noschg /usr/sbin/*
# chflags noschg /sbin/*

# chflags noschg /usr/lib/*
# chflags noschg /usr/local/lib/*
# chflags noschg /usr/libexec/*
# chflags noschg /usr/local/libexec/*

Fazendo a proteção acima lembrem-se que sempre que forem atualizar o sistema, seja usando o cvsup ou pacotes do ports, removam as flags de proteção dos arquivos porque senão vários erros ocorrerão por tentarem alterar os arquivos protegidos.

Mais informações sobre Secure Level e chflags usem o man: man security e man chflags.

Be happy!!!

 

Share Button