Tag Archives: shell script

Gerando senhas aleatorias em posix shell script

Cenário

Imagine que você tem que criar uma senha aleatória para um serviço ou para alguma pessoa.

Normalmente, eu usaria uma dica muito boa mesmo dada pelo megalovax Piter Punk, em seu site pessoal.

Só que, se vocês poderem constatar, o programa não usa comandos posix, fazendo com que ele não funcione em todos os lugares. Pensando nisso, quebrei a cabeça uns 5 mins. e resolvi resolver esse pequeno problema.

Solução

Bom, resolvi aqui com isso:

tr -c -d '[:graph:]' < /dev/urandom | dd count=8 bs=1 2>/dev/null  ; echo

Qual as diferencias? Todos os comando acima podem ser encontrados facilmente em qualquer plataforma, principalmente em vários Unix por ai.

Além do mais, editei o meu .bashrc para conter essa definição para facilitar minha vida e gerar as senhas com uma quantidade arbitraria de caracteres:

gerar_senha(){
	qtd_letras=8
	if [ "$1" ] ; then
		qtd_letras=$1
	fi

	LC_ALL=en tr -c -d '[:graph:]' < /dev/urandom | dd count="${qtd_letras}" bs=1 2>/dev/null  ; echo
}

No caso, usei o LC_ALL=en porque gosto de usar senhas com esse locale, além de fazer com que o locale não de erro no programa.

Advertisements

Conversor de documentos via cli com openoffice

Vai a dica, um conversor de documentos usando linha de comando usando o openoffice.

Muito útil se você precisar acessar dados em documento, usando um motor de geração bem famoso e com bastante desenvolvimento.

Eu ainda não usei, mas tem um monte de exemplo na pagina deles:

http://dag.wieers.com/home-made/unoconv/


Minicurso na semana da computação

Semana da computação

Foi realizado essa semana a primeira semana da computação na UFAL.

Acho isso uma grande iniciativa, o curso de computação precisa de mais eventos como esse que adicionam discussões interessantes e mais assuntos a vida dos estudantes do IC. Apoio muito essas iniciativas a acho muito importante, parabéns aos organizadores!
Infelizmente teve algumas coisas que eu queria ver e não pude :p. Seja por estar preparando o meu minicurso de bash script, ou porque eu o estava “ministrando”. Bom, fazer o que …. C’est la vie.

Falando nisso….

Bom, falando nisso, já devem saber que eu apresentei um minicurso na semana da computação convidado pelo pessoal, só tenho a dizer muito obrigado pela oportunidade.

Como prometi, eu disponibilizei um pacote com toda a apresentação aqui. Para quem não quer baixar 11M, aqui tem a primeira parte da apresentação. E para quem quer a segunda parte, ela esta aqui. Bom proveito :D.

Só tenho a dizer que eu estou sempre aqui para qualquer duvida. Qualquer coisa sempre podem me mandar e-mail ou me contatar por qualquer outro meio.


basename: Tirando diretorio e sufixos de uma string e outras coisas

Voltando ao simples e fácil

Muitas vezes a gente faz coisas porque não sabe que existe, isso em vaias linguagens. Atire a primeira pedra que nunca fez os parses para coisas malucas e depois descobriu que tinha algo já feito :p.

Bom, uma situação muito comum, é querer extrair o nome de um diretório de uma path que você tem ou algo que lembre uma situação assim. Por exemplo:

Você tem:

/home/psycho/teste-1000

E quer obter o nome do diretório sem o path para ele, assim:

teste-1000

Ou você tem um arquivo e quer pegar o nome dele sem a extensão, por exemplo, tento isso:

teste-1000/data-0001.txt

e quer obter algo como:

data-0001

Bom, você pode fazer isso de forma fácil! Existe a função chamada “basename” que faz este tipo de parse para você. Ela esta disponível em “C”, shell script e algumas outras linguagens.

Em “C” ela tem a seguinte assinatura:

#include <libgen.h>

char *basename(char *path);

Em shell script, que eu pretendo me ater mais, ela tem a seguinte assinatura:

basename NAME [SUFFIX]

Caso esse SUFFIX seja fornecido, ele também sera tirado da parte final de NAME.

Usos e possibilidades

Bom, para que usamos e como usamos isso?
Vamos supor que você tem um arquivo, e o nome dele diz uma informação util sobre o programa que você esta executando, então, nesse caso usamos o “basename” para pegar essa informação sem ter que fazer um parser do nome do arquivo:

echo "${FILE}"
echo -n "O processo em execução é: "
basename "${FILE}" .tmp
echo -n "Sem tirar o final: "
basename "${FILE}"
echo -n "Tirando uma parte estranha do final: "
basename "${FILE}" mp

saída esperada:

/tmp/data.343454/job-1234.tmp
O processo em execução é: job-1234
Sem tirar o final: job-1234.tmp
Tirando uma parte estranha do final: job-1234.t

Outro exemplo mais legal que eu precisei recentemente.
Eu tinha uma URL de um arquivo e precisava pegar o nome do arquivo pela URL. Se você pensar direitinho, a URL é o mesmo formato do path de um arquivo, então eu fiz:

echo URL: "${URL}"
basename "${URL}"

saída esperada:

URL: http://10.200.13.100/boot/rootfs-020520010.sqfs
rootfs-020520010.sqfs

Voua-la! Rapidamente consegui extrair o que eu queria e sobrou tempo para eu ir ver o filme do Pelé!

PS:. Antes que alguém comente(se tem alguém lendo isso aqui…), no meu caso as URL são bem definidas e da pra saber o arquivo por elas(nada de HEADERS de HTTP para mudar o nome do arquivo).

Alternativas

Bom, o “basename” é bem simples e rápido, mas ainda é necessário chamar um programa de fora para uma simples função, e isso pode remotamente gerar uma demora em uma ação simples.

Mas caso você seja um “taradinho” por performance( como eu, que preciso de um script que rode no servidor web com muitos clientes 😉 ), existe uma forma mais rápida de fazer.

Se o caminho estiver em uma variável, usando manipulação avançada de variáveis você pode fazer assim o meu ultimo exemplo anterior:

echo URL: "${URL}"
echo "${URL//*\/}"

saída esperada:

URL: http://10.200.13.100/boot/rootfs-020520010.sqfs
rootfs-020520010.sqfs

Ohhhh! Como isso foi feito Mr. M? Bom, substituição avançada com bash script, só digo isso. Fica ai a Dica, falar melhor de variáveis avançado em bash é capitulo para outro post, e esse aqui já ta grande demais ;).


Obtendo informações do sistema de forma portavel e facil com o getent

Cenário

Imagine que ter acesso a informações do sistema, como grupos, usuários,hostnames, etc…

Cada informação dessa pode ser obtida de forma diferente em sistemas diferentes, podendo se tornar um inferno para o programador, por exemplo, procurar os usuários em uma base de dados do sistema, e depois descobrir que os usuários estão em duas bases de dados diferentes.

Para esses e outros casos, quem programa em shell script tem uma boa alternativa chamada getent. Com o getent, você acessar entradas que estão no banco de dados administrativo do sistema sem depender de qual banco de dados o sistema esta usando.

Bom, e como usamos? Muito simples, o getent é usado da seguinte forma:

getent [Base de Dados] [chave]

Explicando:

Base de Dados: é a base de dados que você quer acessar :p. Se você esta procurando por algum usuário, use o “passwd“. Se você esta procurando pelo nome do host use “ahost“. Algumas das bases que o getent pode suportar são:

ahosts ahostsv4 ahostsv6 aliases ethers group hosts netgroup networks passwd protocols rpc services shadow

chave: Algo do bando de dados. Isso, como vocês podem perceber, varia de banco de dados a banco de dados. Por exemplo, a chave usada no banco de dados do passwd é um usuário. Um usuário também é usado no “shadow“, que fornece as senhas criptografadas do sistema. Mas, no “ahost” que mostra os nomes de cada ip, seria um ip a chave do banco de dados.

A chave filtra o banco de dados, deixando somente o que você precisa para trabalhar. Se você omite a chave, todo o banco de dados é mostrado. Tenha muito cuidado para saber onde você precisa de todo o banco de dados ou apenas uma entrada, para não ficar dando greps a toa no programa.


Livro: programação shell linux

Acabei de ler o livro: Programação Shell linux, do vovô do shell script. Eu acabei de ver a 5ª edição, só para esclarecer :p.

Bom, só tenho a dizer que o filme é bem legal. Explica tudo sobre shell script, e ainda de forma bem legal. Veja que eu li a 5ª edição, e já esta na 7ª edição ;).

Explica tudo mesmo, do básico, como variáveis, condicionais e comandos básicos, até coisas muito mais avançadas, como parâmetros, pipes e programas mais avançados.

Só tenho a dizer que gostei muito do livro, e recomendo. Posso dizer que o livro, junto com o livro do Aurélio(Esse eu vou falar depois…), é um tratado final sobre como programar em shell script.

 

Bom, fica ai a dica. Recomendo, e quem quiser eu tenho ;).


Meu primeiro plugin.

Bom, recentemente escrevi sobre o como não me apresentei no congresso acadêmico. Também disse que ia escrever um post explicando melhor sobre o como funciona e como era o meu plugin. Em um planeta onde promessas não precisam ser compridas, resolvi cumprir uma ;). Vou apresentar aqui no meu post o que eu não consegui apresentar no congresso acadêmico. . .

Antes de tudo, o “porque”.

Quando se fala em ataques por força-bruta, normalmente vemos que esses ataques são de fácil de rastreamento e muito perceptíveis. Normalmente agressores usam na verdade maquinas “zumbis”, que tem nenhum rastro para quem esta ordenando o ataque.

Eu estava usando um programa (DenyHosts), que tem como objetivo bloquear ataques de força-bruta em um servidor ssh. Nada mais simples: Caso seja detectado um possível ataque de força-bruta, o programa bloqueia o ip do atacante para que não acesse o servidor ssh, então o ataque de força bruta termina.

Essa abordagem acaba com o problema de ataques de força-bruta, mas isso infelizmente não acaba com o problema como um todo. Porque se o atacante não pode lhe atacar mais, ele passa para o próximo endereço de ip, e continua atacando alguem. Faz-se necessário que o responsável pela rede que tem a maquina comprometida em sua rede ou ate mesmo avisar a quem e dono da maquina que ela esta comprometida.

Essa tarefa(a de informar) é muito trabalhosa :(. Coletar informações sobre um ip e entrar em contato com alguem responsável por esse ip é extremamente custoso. Principalmente quando se tem muito ip’s atacando constantemente o seu servidor ssh. Então, assim como os atacantes tem maneiras de automatizar seus ataques, faz se necessário automatizar a passagem de mensagens para os possíveis responsáveis sobre uma maquina possivelmente comprometida em sua rede.

Foi nesse cenário que eu resolvi usar algum sistema automático para notificação de ISP’s. Comecei a usar um desenvolvido em ruby e feito pelo Nazar da lista do DenyHosts. Depois de um tempo usando esse plugin do Nazar, começou a aparecer os erros. Primeiro, o plugin travava e o programa DenyHosts travava junto com o plugin. Concertei essa parte fazendo uma gambiarra e adicionado uma camada entre o DenyHosts e a chamada do plugin. So que apesar de ter funcionado, ainda existiam outros problemas.

Bom, resumindo. Depois de muito usar e reparar os erros no plugin, e ate entrar em contato com o desenvolvedor( que me afirmou que não ia consertar os bugs que eu passei. . . ), resolvi criar o plugin baseado no antigo só que em bash script, resolvendo todos os problemas do antigo e ainda adicionando algumas coisas que o antigo não tinha.

O que ele faz?

Primeiramente é fornecido um ip para o programa como o primeiro parâmetro.

A idéia básica do plugin e consulta no whois de algum ip dado para obter informações sobre os administradores daquele ip. Dessa consulta ao whois, usando um filtro, e extraido os endereços de e-mail. Todos os endereços de e-mail contidos no whois são de pessoas que são responsáveis de alguma forma por aquele ip.

Depois, se foi passado um ip para o programa, e tentado achar o nome correspondente a aquele ip na internet e depois é feito uma procura de sub-domínio em sub-domínio para se achar mais informações de whois para que se possa extrair e-mails. Nesse caso e necessário para que também se possa avisar ao maior numero de pessoas possíveis.

De posse da lista de e-mail, e verificado se existe alguma mensagem de log para o ip que foi passado para o programa. Se não existir mensagem de log, alguma coisa esta errada e o plugin para. Essas mensagens de log serão passadas para os administradores do ip que foi passado para o programa para que possa ser confirmado o ataque.

Também é verificado se já não foi passado e-mail para esse ip, para evitar repetidas mensagens.

Depois é gerado e passado um e-mail para cada e-mail que foi conseguido extrair do whois. Esse e-mail contem informações do log do ssh, o timezone do computador e o ip de onde veio o ataque.

O que tem a mais?

O que diferencia a minha versão das outras? Que tipos de características a mais o meu plugin tem a mais?

Bom, isso é fácil de dizer ;).

Primeiro, o meu plugin foi feito para não travar. No antigo plugin que eu usava, ele trava quando eu consulto o whois. Por algum motivo tem alguns whois que não acabam de mandar informações ou ficam com problemas. Então, a consulta ao whois “aparentemente” nunca acaba. Então, eu estipulei um tempo para a consulta ao whois, se a consulta não tiver acabado no final desse tempo, ela é finalizada forçadamente e assim o plugin não trava.

Outra vantagem é que você pode colocar uma lista de e-mail que não se deve enviar as mensagens. Essa lista deve ser separada por vírgula. Como por “@lanic.com,@cnnic.com”.

Também pode ser colocado o campo “From” do e-mail de qualquer canto. Também se pode definir um numero máximo de e-mail que se deve ser enviados por ip. log no estilo do syslog, e outras coisinhas a mais. . .

Tudo isso melhor feito ou não implementado no antigo plugin. De fato, ate entrei em contato com o cara desenvolvedor do plugin para colocar o meu no lugar do dele :p.

Mais isso e outra historia.


%d bloggers like this: