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.392 ]

Por: Davidson Esteves Nunes em 30/03/2006


A solução



A resposta veio de uma forma simples: não vou mudar as portas padrão de acesso, mas restringir o acesso a elas através um sistema de autenticação. O que eu fiz foi criar uma simples página em PHP de login com consulta em um banco de dados.

Ao ser autenticado, o script captura o IP que fez a requisição e o registra na base de dados. Um segundo script, feito em Perl, roda a cada minuto checando a tabela de IPs autorizados executando um iptables em cada um deles, liberando assim a acesso àquela determinada porta.

No final das contas ficou assim:

Página anterior     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

Criando discos virtuais em máquinas remotas

Fazendo seu Linux hibernar

Compilando e testando o novo X11R6.9

Leitura recomendada

Desligamento automático seletivo com apcupsd

Servidor Samba "Autoservice"

Ping - O que há por trás?

Hotspot rápido com Coovachilli

Recon and Scan with Metasploit

  
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