Implementando a segurança em servicos de acesso remoto

Neste artigo demonstro como criar uma solução de melhoria de segurança no acesso a serviços remotos como FTP e SSH usando Apache/PHP e Perl. Tal solução foi implementada na empresa onde trabalho e funciona perfeitamente.

[ Hits: 43.393 ]

Por: Davidson Esteves Nunes em 30/03/2006


O risco em se prover acesso remoto



Uma dos maiores prós da Internet é permitir o uso de ferramentas de acesso remoto para se trabalhar de qualquer lugar. Eu mesmo não saberia viver sem o SSH. O risco reside no fato de não vivermos num mundo perfeito, onde todas as pessoas são felizes, sempre existem pessoas interessadas em jogar areia no seu arroz.

SSH e FTP são dois grandes alvos de tentativas de invasão. Recentemente, ao analisar o log do meu SSHD, descobri que um lammer chinês estava tentando fazer milhares de tentativas de quebra de senha através de um desses "scripts kiddie" de "brute force attack". Aquilo me incomodou bastante e fui obrigado a mudar a porta do meu server tirando do padrão 22 (aliás o que é extremamente recomendado). Mas isso não me fez dormir mais seguro naquela noite. Fiz algumas considerações:
  • Um sistema remoto é sempre alvo de possíveis ataques;
  • Mesmo mudando a porta de determinado serviço, ela pode ser descoberta através de um paciente "portscan";
  • Preciso prover acesso remoto para meus clientes e nem todos estarão afim de reconfigurar seus clientes de acesso toda a semana;
  • Pode ser que um dia eu saia da empresa e é sempre positivo para seu currículo que um sistema que você configurou permaneça seguro mesmo você não estando mais lá para administrar;
  • Não dava pra restringir acesso remoto para apenas alguns IPs cadastrados, pois clientes ADSL mudam de IP o tempo todo.

    Próxima página

Páginas do artigo
   1. O risco em se prover acesso remoto
   2. A solução
   3. No MySQL
   4. Agora em PHP
   5. Script em Perl
   6. Finalizando
Outros artigos deste autor

Compilando e testando o novo X11R6.9

Criando discos virtuais em máquinas remotas

Fazendo seu Linux hibernar

Leitura recomendada

Enviando alertas do Snort por SMS

Reaver - Descobrindo senhas Wi-Fi

Instalando um firewall em ambientes gráficos leves

Antivírus Clamav no Linux

Implementação de WAF mod_security e integração com Graylog utilizando Filebeat e Logstash

  
Comentários
[1] Comentário enviado por pcnmota em 30/03/2006 - 16:59h

Cara, parabens pela ideia.. simples e funcional.

valew...

[2] Comentário enviado por tiagoalgodas em 30/03/2006 - 17:45h

Olá amigo. Parabéns pelo artigo, é de extrema importancia esses aspectos levantados por você sobre segurança. Apenas uma coisa, me corrija se estiver errado, por padrão na filtragem de pacotes, os pacotes direcionados a porta correpsondente ao ssh devem ser "DROPADOS" confere ? abraço e parabéns.

[3] Comentário enviado por mbmaciel em 30/03/2006 - 19:43h

Olá,

Muito bom artigo! vou testar na empresa. Mas achei um erro no script perl

na linha:
my $cursor = $db->prepare("select login,ip from autenticado where expira >= $agora");

mudar p/:
my $cursor = $db->prepare("select login,ip from autenticado where expira_em >= $agora");

abraços.

[4] Comentário enviado por agk em 30/03/2006 - 20:19h

Parabéns, muito bom.
Isso já ajuda a impedir os ataques de brute force e no caso de alguém descobrir que tem que entrar na página X, essa página poderia ter algum código especifico que só o cliente saiba para poder liberar o acesso para ele.
O iptables também um módulo que ajuda a aumentar a segurança, chama-se port-knock-out, tem uma dica ou artigo aqui no VOL que fala sobre isso.
[ ]'s.

[5] Comentário enviado por mbmaciel em 30/03/2006 - 20:23h

opa!

Mais um erro. Agora no script autentica.php.

Na linha:
mysql_query("insert into acesso_autenticado(login,ip,data,expira) values('$usuario','$ip',$agora,$expira)");
}
?>

mudar para:
mysql_query("insert into autenticado(login,ip,conectou_em,expira_em) values('$usuario','$ip',$agora,$expira)");

that's it

[6] Comentário enviado por davidsonbhz em 31/03/2006 - 09:31h

Opas! Viajei no nome do campo expira_em, deve ter sido empolgacao. Em relacao a pergunta do tiagoalgodas sobre os pacotes serem dropados por padrao, seria uma coisa do tipo:

iptables -I INPUT -p tcp --dport 22 -j DROP

colocando isso na primeira linha do script de firewall impede qualquer tentativa de conexao na porta 22, em seguida eu acrescento

iptables -I INPUT -s ip_do_cara_autenticado1 -p tcp --dpor 22 -j ACCEPT
iptables -I INPUT -s ip_do_cara_autenticado2 -p tcp --dpor 22 -j ACCEPT
iptables -I INPUT -s ip_do_cara_autenticado3 -p tcp --dpor 22 -j ACCEPT

isso permite que apenas os caras autenticados acessem a porta 22. Lembrando que o parametro -I do input insere a regra no topo da cadeia do iptables empurrando as outras pra baixo.

Espero ter esclarecido!
Abracos!

[7] Comentário enviado por shocker em 31/03/2006 - 11:24h

Ei! Parabéns pelo artigo.
Solução simples e funcional!

[]'s
Alan Cota.

[8] Comentário enviado por removido em 31/03/2006 - 13:15h

Só uma coisa que não ficou clara para mim...
Em que momento está ocorrendo a exclusão do redirecionamento do IpTables?
Entendi todo o resto do sistema, só não localizei essa parte...

Abraços

[9] Comentário enviado por jov em 31/03/2006 - 14:50h

Achei excelente a idéia, mas acho que tem um porém,o ideal não seria colocar uma rotina no script perl que quando expirasse o tempo dropasse as regras que foram incluídas?

Abraços

[10] Comentário enviado por davidsonbhz em 31/03/2006 - 17:26h

Boa ideia Jov, seria algo mais ou menos do tipo:

Acrescentamos na tabelas de autenticados um campo char para indicar a validade da sessao.

mysql> alter table acesso_autenticado add expirout char default 'N'


Depois criamos um script para verificar a validade das sessoes

#!/usr/bin/perl

$agora = time;

my $db = DBI->connect("DBI:mysql:banco_de_dados:$server",$user,$pass) or die $DBI::errstr;
my $cursor = $db->prepare("select login,ip from acesso_autenticado where expira <= $agora and expirou='N'");
$cursor->execute;

my @columns;
while(@columns = $cursor->fetchrow) {
$login = @columns[0];
$ip = @columns[1];
system("/usr/sbin/iptables -D INPUT -s $ip -j ACCEPT");

print "A sessao do $ip expirou! \n";
}

#depois que a gente removeu os expirados do iptables, marcamos eles como expirados na tabela
my $cursor = $db->prepare("update acesso_autenticado set expirou='S' where expira <= $agora and expirou='N'");
$cursor->execute;


Abracos!

[11] Comentário enviado por ramonklown em 31/03/2006 - 19:00h

Ótima davidsonbhz, é algo simples e prático. Depois de ler o artigo pensei logo em restringir por ip logado e você colocou.

Valeu

[12] Comentário enviado por mlegidio em 03/04/2006 - 00:15h

Parabens pelo artigo. E daki por diante ficarei mais atento nos logs dos servicos de acesso remoto para ver a necessidade desta implementacao.

[13] Comentário enviado por guilhermerezende em 03/04/2006 - 14:32h

Gostei da idéia!! Parabéns pela sua idéia, gostei bastante

[14] Comentário enviado por prota em 04/04/2006 - 01:57h

Muito boa sua idéia cara, parabéns. O único problema é que se voce entrar com anything' OR 'x'='x nos campos usuario e senha, o acesso sera liberado da mesma forma.

[15] Comentário enviado por davidsonbhz em 05/04/2006 - 09:40h

Isso que o prota falou eh verdade! Eh muito importante que quando se implementar o esquema, eh necessario tratar os campos de usuario e senha pra evitar o famoso "sql injection".
Algumas precaucoes simples podem ajudar nisso como remover os espacos em branco, aspas e coisas que podem comprometer. Limitar o tamanho dos campos de usuario e senha tambem ajuda!

[16] Comentário enviado por douglas_moreno em 06/04/2006 - 11:16h

Muito bom...Vou testar assim q possível !!!

[17] Comentário enviado por pitombera em 07/04/2006 - 09:48h

Estáis de parabéns pelo artigo, mas não entendo bem... teria cm gerenciar a questão de ip's pelo php com sessions ( creio eu ), assim o clinte teria q estar logado na página e ao dar um logout ele rodaria um outro perl semelhante ou o msm só q fazendo o inverso, retirando a regra :
iptables -D INPUT -s ip_do_cara_autenticado1 -p tcp --dpor 22 -j ACCEPT
Achei mto interessante e curti pacas seu script mas achei falho a questão da retirada de ips, mais por estética e talz... mas não gosto de um INPUT cheio de regras .. mas ai fica minha opinião e não tenho certeza se é a mais correta mas... comentem ai x)

[18] Comentário enviado por removido em 07/04/2006 - 12:13h

Caro Colega.
Muito bom seu artigo. Uma ótima idéia.
Vou testar, e até me basear para fazer um trabalho de faculdade.
Parabéns.

[19] Comentário enviado por davidsonbhz em 07/04/2006 - 15:27h

Interessante o que o pitombera disse. Esse método de validação de ips pode ser implementado de diversas maneiras. Estarei trabalhando em outro artigo que mostrará a solução completa do sistema, por enquanto eu quis apenas expor a idéia! Pelo que estou percebendo um projeto pode nascer aqui, mandem suas sugestões!

Abraços!

[20] Comentário enviado por kadu em 10/09/2007 - 09:49h

Uma dica, não sei se vulnerável, mas seria eficiente colocar o PHP pra rodar o script perl, pois assim seria adicionada a regra em tempo real e não rodaria o mesmo quando desnecessário.

Pensei em faze-lo com o sudo da seguinte forma:
---------------
~# visudo

www-data ALL= NOPASSWD:/local/do/script.pl, !/local/do/script.pl root

---------------
No PHP acrescentar após a inserção dos dados no banco MySQL a linha:

system("sudo /local/do/script.pl");

---------------

Está aí a dica !!!

Obs: não testei mas acredito que funciona perfeitamente, pois uso algo parecido num gerenciador de emails para criar a pasta do usuário, mudar a permissão da pasta, e adicionar as pastas padrões com maildirmake.

Abraços []'s

[21] Comentário enviado por kadu em 10/09/2007 - 09:57h

Outra coisa, gostei muito do artigo.

E segue outra dica de seguraça de portas muito interessante usando iptables: http://www.vivaolinux.com.br/dicas/verDica.php?codigo=6031

Mas creio não ser uma coisa muito pratica para quando tratamos de acessos remotos feito por usuários finais. Pois normalmente preferem algo mais pratico e de facil manuseio.

[]'s


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts