sábado, 30 de agosto de 2008

Recuperando o grub

Eu uso muito pouco os produtos da M$ em casa. E tempos atrás o Windows deu pau pra variar. Fosse outra época, eu gastaria dias recuperando o sistema, os documentos, etc... Mas já faz muito tempo que não tenho saco pra ele.

Existem uns pouquíssimos motivos para eu continuar com ele na minha máquina, mas ele ainda é necessário sim. Pois bem, depois de muito postergar resolvi meter a mão na massa e fazer o odioso ritual do formata-e-instala.

Qual minha surpresa quando vou procurar no meio dos CDs e lembro que joguei fora o CD de instalação do Windows. Solução: deixar a madrugada inteira baixando um torrent. Terminado o download, vejo que o arquivo de imagem não era uma iso e sim um nrg, que é um formato de imagem proprietária do Nero, e não dava pra gravar direto pelo meu querido K3B. Nada de mais, uma googlada e pronto, eis uma linha de comando para fazer a conversão. Isso mesmo. Com uma linha deu pra fazer a conversão de nrg para iso, e enfim gravar a imagem num CD.

Ah sim a linha em questão é:
$dd bs=1k if=imagem.nrg of=imagem.iso skip=300

Enfim, comecei a via sacra... formata, instala, instala drivers, aplicativos básicos, aplicativos de segurança, configura uma coisa, configura outra, restaura os backups...

Hora de restaurar o grub, o bootloader do Linux, para que eu pudesse deixar a máquina novamente com dual boot.

Vou dar o boot com o CD do Linux e trava. Tento de novo e de novo e nada. O CD foi pro espaço tbm. Solução: baixar o Linux, gravar num CD e daí sim recuperar o meu mojo.

Depois de iniciar o boot com o CD do Linux, abri um terminal e fiz:

$sudo grub
>find /boot/grub/stage1

daí usei a saída do comando acima no comando abaixo

>root (hd0,0)
>setup (hd0)
>quit

Reiniciei e pronto. Tudo funcionando como deveria ser, nos trilhos.

E agora consegui passar as fotos do meu aniversário para o PC (sim, a minha câmera é um dos motivos para eu ainda manter o Rwindows aqui).

Hasta la vista.
-----------
keepReading

sábado, 16 de agosto de 2008

IFS - Internal Field Separator

No post anterior, eu disse que o script reconhecia nomes de arquivos que incluiam espaços e outros caracteres especiais, mas não escrevi sobre como fiz isso. Aliás, este foi um dos passos que mais me deu dor de cabeça durante o desenvolvimento do script.

Voltando um pouco na causa... minha esposa e eu temos o costume de renomear em massa os arquivos e as cópias que ela faz, usando espaços nos nomes, tanto dos arquivos quanto dos diretórios. Porém quando fui criar o script me deparei com o problema. A saída do comando find. Sempre que havia um espaço em branco nos nomes de diretórios e arquivos, era como se fosse um valor diferente para o loop for.

Após muita pesquisa, vi que o problema era uma variável especial do shell, o IFS. Ela é uma variável criada pelo shell (builtin) e é extensivamente usada para reconhecimento e expansão de strings. Seu valor padrão é "", e ela afeta o comportamento de vários outros comandos, como grep, cut, ls... Assim, "o pulo do gato" foi definir o valor dessa variável para "".

Bem, além de mais elegante e eficiente, esse tipo de tranformação ajuda a diminuir o tempo de execução, o que pode tornar o uso racional desse recurso muito interessante quando temos de lidar com grandes quantidades de dados, por exemplo importação/exportação de valores em bancos de dados.

Agora cabe algumas observações sobre o uso do IFS.
- É recomendável que você guarde o valor antigo e retorne ele ao normal no final do script.
- Definir o novo valor de forma direta funciona apenas para a atual instância do shell onde se trabalha. Se você cria subshells, você deve usar o comando (também builtin) export.
- Essa é uma variável existente para vários sabores de shell (sh, dash, bash, ksh, zsh).

E para fechar, dois links para aprofundar a leitura:
- http://www.dicas-l.com.br/cantinhodoshell/cantinhodoshell_20070103.php
- http://nixshell.wordpress.com/2007/09/26/ifs-internal-field-separator/

See ya.
-----------
keepReading

quinta-feira, 7 de agosto de 2008

Script para remover arquivos duplicados

Fala pessoal, tudo certo?

Venho postar aqui pela primeira vez um presente meu para vocês: um scriptzinho (em shell script) para remover arquivos duplicados. O link é esse aqui. Tá no 4shared, então não tem complicação para fazer o download.

O uso do mesmo é bem simples.
$./check_dups.sh /dir/to/scan/ /another/dir/to/scan/ /and/one/more/


O script lê todos os arquivos dentro dos diretórios passados, inclusive nos seus subdiretórios. Reconhece arquivos que contenham caracteres especiais no nome como espaço e parênteses. Remove os duplicados (com base no hash MD5 deles), deixando apenas um, e gera um log no formato HTML, com o arquivo que ficou, e quais que tinham o mesmo conteúdo que foram removidos. Tudo organizadinho.

Esse script me custou umas boas horas e eu realmente tinha a necessidade dele. Como não achei nada que fizesse isso, criei e agora espero que seja útil para alguém.

Críticas e sugestões são bem-vindas.

Abraços.
-----------
keepReading

quarta-feira, 6 de agosto de 2008

Um pouquinho de velocidade

Fala pessoal.

Como sempre venho trazer alguma coisa para vocês, baseada em erros comuns que vejo. E hoje trago algumas dicas de como melhorar o desempenho em bancos de dados.

Tempos atrás eu já tinha publicado algo sobre isso em relação ao Postgre aqui.

Bem, negócio seguinte, quando tratamos com uma quantidade grande de dados (1GB ou mais), algumas mudanças podem e devem ser feitas para acelerar o andamento das atividades (importar, exportar, selecionar, filtrar, pesquisar, etc...).

Primeiro em relaçãoà modelagem de dados. Veja se a estrutura não precisa de modificações, como por exemplo partições nas tabelas, índices, etc...

Depois, veja se a tabela está em dia. Um ANALYZE TABLE faz milagres. Agendar ele no CRON para rodar todo dia num horário de pouco uso, nem se fala.

Se tem uma opção mais eficiente que essa, é o OPTIMIZE TABLE do MySQL.

Para importar/exportar quantidades muito grandes de informação, evite usar alguma linguagem de programação. Faça pela linha de comando, usando recursos do próprio banco de dados. Prepare scripts para automatizar estas tarefas. Se for necessária alguma verificação, faça com stored procedures. Isso aumenta absurdamente a performance.

Outra coisa, em caso de queries complexas, use o EXPLAIN. Aprenda a otimizar suas queries com ele (a ordem dos joins importa, assim como a sua quantidade e o método usado).

Por último, nos casos mais críticos, verifique a condição física da máquina. Se a operação que está sendo executada começa a usar espaço em disco (swap/arquivo de paginação) é hora de rever alguns parâmetros do banco de dados, do sistema operacional ou mesmo instalar mais memória.

[]'s

-----------
keepReading

terça-feira, 22 de julho de 2008

Dica rápida (1) - baixar sites

Fala pessoal. Enquanto arrumo os preparativos para o primeiro artigo no novo formato, vai aí uma dica retirada do VOL (mais especifamente, daqui) e que me quebrou um galhão.

O problema: queria baixar todo o conteúdo de um site. (nada de pirataria, era para abaixar apostilas e tudo o mais de uma vez só, porque enche o saco ficar clicando e salvando um por um).

A solução: depois de experimentar vários plugins do Firefox, e coisa e coisa e tal, sem obter um resultado satisfatório, finalmente encontrei a solução. Supondo que você queira baixar todo o conteúdo do site http://www.algumsite.bar/, vá na linha de comando e digite:

$wget -cpr http://www.algumsite.bar/ -o logfile.log


Este comando irá baixar TUDO (conteúdo, folhas de estilo CSS, scripts, imagens, e vai seguir os links dentro do domínio, baixando tudo também). O parâmetro -o logfile.log irá gerar um arquivo chamado logfile.log, com toda a saída do comando, ou seja, uma lista com todas as páginas baixadas e o que eventualmente não deu certo. Para dar uma conferida geral nisso, recomendo que se rode na mesma linha de comando, logo após o download, você faça:

$grep 404 logfile.log


Para vc ter uma idéia de quantos arquivos não foram encontrados. Se houver algum erro, aí é melhor abrir o log com o gedit ou similar e usar o ctrl-f para localizar as ocorrências.

Enjoy.
-----------
keepReading

domingo, 20 de julho de 2008

Depois do novo visual, novos bagulhos

Fala pessoal. Tudo certo?

Depois de mudar o layout dos meus blogs, foi hora de implementar algumas melhorias. Primeiro foi no meu outro blog, e agora trago as mudanças à este.

Ainda estou organizando muita coisa aqui no meu PC depois de um baita upgrade, mas fica a promessa de que em breve um novo formato, modéstia à parte, bem mais interessante, será implementado aqui. Inclusive já há uma fornada fresquinha de artigos e tutoriais só esperando para serem publicados.

See ya.
-----------
keepReading

sexta-feira, 4 de julho de 2008

Rootkits - checando a sua máquina

Fala pessoal.

Aqui vai uma dica rápida de dois programas que podem ser uma mão na roda na hora de checar a sua máquina quando algo suspeito acontece, no ambiente GNU/Linux.

chkrootkit
Você pode baixá-lo em http://www.chkrootkit.org/. Após descomprimir o tarball, basta entrar no diretório criado e compilar com:
# make sense

Para ver os testes disponíveis, use:

#./chkrootkit -l


Para fazer o checkout completo oferecido por ele:

#./chkrootkit


Rootkit Hunter
O site oficial do rkhunter é http://www.rootkit.nl/projects/rootkit_hunter.html.

Após descompactar o tarball, é recomendável atualizar as referências de rootkits. Para isso, entre no diretório criado na descompactação. Uma vez lá, entre no diretório files, e então execute:

#./rkhunter --propupd
#./rkhunter --update


E partir daí para fazer uma varredura do sistema, basta usar:

#./rkhunter --check



Acima está o basicão, e recomendo a leitura dos manuais e do material disponível nos sites, bem como as instruções já disponíveis com os pacotes - o chkrootkit tem um README, e o rkhunter tem a opção --help.

So, have fun!
-----------
keepReading

domingo, 29 de junho de 2008

Uma conversa sobre boas práticas de desenvolvimento

Quando começamos a desenvolver, a principal meta é obter uma aplicação que funcione. E com o tempo vamos melhorando nossas práticas, facilitando e polindo nosso código - claro que estou me referindo aos verdadeiros profissionais.

Mas mesmo assim, na enorme maioria das vezes os desenvolvedores não vão tão a fundo sobre o funcionamento da aplicação, sendo que isto muitas vezes pode ser muito útil. Seja por falta de informação, ou na dificuldade de encontrar e entender a mesma.

Por exemplo, quantos de vocês já pararam para pensar sobre o processo de requisição de uma simples página de internet? Vamos fazer uma pequena viagem neste processo (acredite, isso é a forma simplificada!).

Ao clicar num link para uma página, o seu navegador pede ao sistema operacional que envie um pacote de requisição pela interface de rede. Este pacote contém os request headers, ou seja informações sobre o destino solicitado (o SO é que acrescenta o endereço de origem), informações sobre o navegador, quais linguagens e encodings ele aceita, etc.. Essa solicitação é resolvida num servidor DNS, que converte o nome para um endereço IP, e a saga do pacote continua de roteador em roteador até que o IP da página requisitada seja encontrado. Chegando lá, o SO do servidor, vai direcioná-lo para o servidor HTTP (geralmente o Apache), onde será enfim processado.

O servidor é responsável por localizar qual arquivo está sendo solicitado, checar regras e políticas de segurança junto ao SO, formatá-lo, codíficá-lo se for o caso, e por fim, enviar de volta o arquivo em pacotes, fazendo o caminho inverso. Se o seu navegador, ao reconstruir os pacotes, identificar que existem outros arquivo sendo solicitados na própria página, como folhas de estilo externas (CSS), arquivos javascript, imagens, arquivos flash, ou mesmo frames, ele irá enviar novas solicitações ao servidor para que este envie os arquivos necessários.

Com tudo recebido, o seu navegador monta a página, rederiza o CSS sobre os elementos, e carrega os javascripts para execução.

Bastante coisa não? Vamos deixar um pouco de lado a parte do seu navegador e vamos focar em duas coisas: o processamento do lado do servidor, e o tráfego de rede.

O servidor tem que alocar memória para cada requisição feita. Este processo também demanda processamento, tanto do servidor HTTP, quanto do SO. Ele tem que gerenciar muitas coisas, ainda mais quando se tem várias requisições chegando ao mesmo tempo.

Agora quando uma página dinâmica é solicitada, o trabalho do lado do servidor acaba aumentando bastante. Ao identificar que se trata de uma página PHP ou Python, por exemplo, o servidor HTTP precisa ler o arquivo e passá-lo ao engine responsável pelo processamento. Isso faz com que o SO reserve mais memória e consuma mais processamento, pois há mais um aplicativo participando da bricadeira. Pelo amor de Deus, eu não estou falando para criar apenas páginas estáticas, mas estou dando uma visão geral para que vocês entendam a importância de uma polida no código no sentido de otimização quando forem fazer um sistema.

Bem, vamos lá... temos um SO gerenciando vários processos e alocando memória para o Apache e para o engine do PHP. Até aí nenhum problema, os softwares são bem escritos e as máquinas de hoje dão conta do recado sem precisar fazer muita força. Mas o mundo não é feito só de hello world's, e de scripts para mostrar que horas são em Estocolmo.

Então, não raro o seu script PHP vai precisar acessar um banco de dados ou arquivos. E aí é onde a coisa pode começar a complicar. Quando acessa um banco de dados, o PHP carrega um módulo, com uma API para o banco de dados, e então ele abre uma conexão para o banco de dados. O processo é muito parecido com a requisição de uma página (exceto, geralmente, o que diz respeito a ficar passando de roteador em roteador para encontrar o banco de dados). E o servidor de banco de dados trabalha de forma muito parecida (guardando-se as devidas proporções) com o servidor HTTP. Ele válida a sessão, reserva memória e começa a processar prioridades de acesso - em outras palavras, mais memória alocada, mais processamento consumido.

Aí voltamos ao seu script. Ele se conectou no banco de dados. Hora de enviar as queries. Para cada query enviada, uma nova requisição é enviada ao banco de dados, através da conexão que você abriu (sim, isto é tráfego de rede). Ao receber a requisição, o engine do banco de dados realiza primeiro o que é chamado de execution plan. Ele estima algumas formas de como pode executar sua requisição, e executa aquela que ele julga ser a mais apropriada (com menor custo ao sistema). Isso é assunto pra tese de doutorado, então não vou me ater a explicações profundas sobre isso. Mas só para constar, triggers, rules, reconstrução de índices, validação de constraints e outros recursos também entram nas contas das estimativas do execution plan, daí você imagina o trabalho do servidor de banco de dados ao decodificar cada query ANTES de executá-la.

Executar a query, envolve além de consumo de processamento e memória, acesso a discos, e possivelmente gravação neles (o que nos trás de volta ao SO, que é o responsável por essa parte de acesso e gravação em discos).

Terminada a maratona da execução, o banco de dados retorna o resultado disso para o PHP (através daquela conexão que ele tem, lembra?). Para daí em diante o PHP continuar o seu processamento. Lembre-se que tudo o que foi descrito acima vale para CADA QUERY enviada. Chegando ao fim do script, o PHP fornece o seu produto ao Apache, que o formata, codifica, etc... e envia em gentis pacotes ao cliente através da rede.

Agora, o que aconteceria se enviássemos menos queries? Conseguem ver a vantagem? Este é o motivo pelo qual é muito importante usar de forma eficiente e inteligente os recursos que os servidores de bancos de dados oferecem. Isso deixa os códigos mais elegantes e limpos, o sistema gerlamente fica mais seguro, mais fácil de fazer manutenção, e otimizado (sem contar que dá pra cobrar uma grana a mais pelo serviço mais profissional).

Dou o artigo como encerrado por aqui. Em breve escrevo mais sobre otimização e segurança no lado dos BDs, e no PHP em si.

See ya.
-----------
keepReading

sábado, 17 de maio de 2008

Toolbox

Começo este post como o anterior. Com uma historinha, um desabafo. Claro que o objetivo também é levar conhecimento – um pouco do pouco que tenho.

Hoje vou falar sobre ferramentas. Eu tenho um sério problema com ferramentas que facilitam a vida como frameworks, códigos prontos, e outras coisas empacotadas para viagem.

Isso começou a mais de uma década – nossa, agora eu me senti um velhão. Comecei a procurar sobre segurança da informação. Os programas da moda eram o Back Orifice e o Netbus. Nunca cheguei a sequer baixá-los simplesmente porque eu não apreciava a idéia do uso de uma ferramenta. Mais que isso. Achava, e ainda acho, que verdadeiros hackers – pelo amor de Deus não vamos discutir o termo em si, mas para efeitos de satisfação parcial “black hats” - são aqueles que criavam esses programas e não quem simplesmente os usava – anos depois vim a ter o conhecimento da denominação script kiddie.

Enfim, sempre tive esse ceticismo em relação à este assunto. Depois comecei a usar GNU/Linux. E aí vieram alguns nomes: Iptables, Snort, Ethereal, Netcat, Nessus, tcpdump... E mais recentemente chkrootkit, metasploit, nmap...
Pois bem, agora vou falar um pouco de algumas delas – as que descobri e/ou usei recentemente - e também algumas mudanças que ocorreram com o que eu penso delas.

chkrootkit – é um programa simples e pra lá de eficiente. Ele faz uma breve auditoria para detectar rootkits na sua máquina. Vai desde checar se programas como o netstat ou ps foram alterados, até detectar LKMs. Eu achava que ele era complicado até baixar, compilar e executar. Me deu mais trabalho escrever este parágrafo do que usá-lo.

Nessus – faz um tempão desde a primeira vez que tentei usá-lo. Na época eu não entendi muito bem a estrutura cliente-servidor. Mas enfim, ele não é difícil de usar e é bastante eficiente. Ele pode detectar vulnerabilidades e simular ataques. Mas o pulo do gato são os plugins. Ele é extensível e através desses plugins novos tipos de ataque podem ser adicionados e executados, encontrando assim outras vulnerabilidades.

Metasploit – é um framework para exploits. É mais fácil ainda de encontrar alguma vulnerabilidade através dele. Ainda não o usei, mas vi um vídeo no milw0rm com o mesmo em ação. Tira todo o charme de se desenvolver um exploit, mas pode ser muito útil numa auditoria ou num showdown.

See you.
-----------
keepReading

Polindo bytes

Depois de um enorme recesso, volto a publicar alguma coisa. O meu maior bloqueio em escrever algo, é minha preocupação em escrever algo realmente instrutivo. Algo que eu gostaria de ler. Que ensinasse as coisas sem muita encheção de lingüiça. Porém sempre acho que tudo o que quero escrever já foi escrito, ou que pouco acrescentaria a algum bom tutorial que eu tenha lido.

Mas, até como é o propósito desse blog, a pretensão é divulgar o que é difícil de se encontrar. Assim sendo, vou dedicar este post a indicar fontes e fontes de fontes (calma, não é tão ruim quanto pode parecer). Após vasculhar bastante – mas põe bastante - nisso e ter alguma orientação de um amigo (que manja muuuuito), cheguei ao ponto de criar este post.

Antes de começar com as indicações, vou contar uma história para ilustrar como cheguei a este ponto e onde foi que eu “errei”. Sempre quis aprender mais sobre computadores. Sempre quis ir mais a fundo, mais além. Lendo um pouquinho aqui, praticando um pouquinho ali, garimpando um pouquinho lá, fui juntando informações. Esse é o curso natural da coisa.

Pequei em dois pontos. Um deles foi não estudar exploits. Sempre achei que soluções prontas não eram muito válidas. E deixei de aprender muito ao não ao menos ler alguns desses códigos. O outro erro foi pior. Sempre associei o termo shellcode a shell script. E isso me custou mais um valioso aprendizado. Ao conversar um dia desses com esse meu amigo, eu disse que eu tinha uma certa dificuldade, principalmente por não saber por onde começar. Ele me disse para começar do basicão: buffer overflows, integer overflows, stack overflows, shellcodes... Foi quando eu questionei a respeito dos shellcodes e ele disse que não tinha nada a ver com shell script... Me senti uma anta. Literalmente. Ele foi até gentil com o noob que vos escreve e me deu alguns links de tutoriais.

Após alguns dias garimpando, e mais umas horas relembrando de velhas fontes, e estou aqui.

Bem, chega de enrolação. Vamos ao que interessa: fontes, links e utilidades.

Se você manda mal no inglês (que é fundamental) lá vai o primeiro link:
http://www.inglescurso.net/


Para linguagem C
http://gcc.gnu.org/onlinedocs/
http://www.gnu.org/software/libc/manual/
Também recomendo os livros
The ANSI C Programming Language (Kerningham & Ritchie)
C Total e Completo (Herbert Schildt)

Para Assembly
http://numaboa.com.br/informatica/oiciliS/
http://asm.sourceforge.net/
http://tldp.org/HOWTO/Assembly-HOWTO/

Estrutura de dados
http://www.icmc.sc.usp.br/manuals/sce183/
http://www.icmc.sc.usp.br/manuals/sce182/
http://www.icmc.sc.usp.br/manuals/ssce763/

Repositórios de especificações de formatos de arquivo
http://www.wotsit.org/
http://www.file-extensions.org/
http://www.fileinfo.net/

Padrões de internet e protocolos
http://www.rfc-editor.org/rfcxx00.html
http://www3.tools.ietf.org/rfc/index
http://www.iana.org/protocols/
http://graphcomp.com/info/rfc/
http://en.wikipedia.org/wiki/List_of_RFCs

Zines e Hot sites
http://www.thebugmagazine.org/
http://www.phrack.org/
http://packetstormsecurity.org/
http://www.milw0rm.com/
http://neworder.box.sk/
http://www.smashthestack.org/ -- este aqui é um jogo!
http://www.phreak.org/html/main.shtml
http://br.geocities.com/d4rwinetico/zines.html



Vale umas dicas aí...
no milw0rm, existe a seção papers, porém não há link direto. Você precisa acessar:
http://www.milw0rm.com/papers/
para entrar na seção. O milw0rm deixa disponibiliza o download dos exploits num tarball, que vem inclusive muito bem organizado. Porém os artigos (papers) não vêm. Então aí vai um shell script básico para facilitar sua vida e baixar todos os papers.

#!/bin/bash

i=0;

echo " " > error.txt;

while [ $i -lt 200 ]; # atualmente a existem cerca de 200 artigos no milw0rm
do
echo "baixando Paper # $i";
url="http://www.milw0rm.com/papers/"$i;
wget $url;
if [ $? -eq 0 ];
then
echo "milw0rm paper # $i baixado com sucesso!";
else
echo "Download de paper # $i falhou";
echo $i >> error.txt;
fi
let i++;
done;


O Phrack também disponibiliza a última edição para download num tarball. Mas, via de regra, aí tbm vai um shell script para tornar sua vida menos tediosa.

#!/bin/bash

i=1;

echo " " > error.txt;

while [ $i -lt 66 ]; # atualmente a phrack está na edição 65
do
echo "baixando Phack # $i";
url="http://www.phrack.org/archives/tgz/phrack"$i".tar.gz";
wget $url;
if [ $? -eq 0 ];
then
echo "Phrack # $i baixado com sucesso!";
else
echo "Download de phrack # $i falhou";
echo $i >> error.txt;
fi
let i++;
done;


E aí vai como conseguir artigos do insecure.org através de um google hacking
http://www.google.com/search?q=+site%3Ainsecure.org%2Fstf%2F

Vale lembrar que quase todos os sites acima citados, além do conteúdo, têm vários outros links valiosos, sendo este o motivo de estarem aqui.

O material é realmente extenso. Mas vale a pena se você quer aprender mais. Vá lendo conforme a necessidade aparecer. Por último, mais algumas sugestões de leitura que geralmente deixamos pra depois ou que são simplesmente ignoradas – estou falando de algumas man pages e info pages. Leia quando possível as man pages e info pages dos interpretadores de comando (sh, csh, bash, ksh, zsh...) e das ferramentas de desenvolvimento (gcc, as, gdb, objdump, nm,...).

Bons downloads e boa leitura.
-----------
keepReading

domingo, 2 de março de 2008

Reforma total

A tempos eu estava deixando um upgrade para depois... e até que enfim realizei.

Eu tinha um pente de memória DDR 333 de 512MB, e uma placa de vídeo GeForce XFX 5200 (com 64MB de memória) AGP.

Tirei o pente de memória e enchi a placa com 3 pentes de memória DDR 400 de 1GB, chegando ao máximo de memória e podendo elevar o clock do processador a 3200 GHz, além de trocar a placa de vídeo - coloquei uma GeForce XFX 6200 (com 256MB de memória) e que tem um monte de recursos a mais.

O desempenho foi lá em cima. É uma outra máquina. Só por isso já havia valido tudo, mas resolvi também dar um upgrade no SO.

Eu tinha o Ubuntu 6.06. Coloquei o 7.10.

Melhor que o que está agora, só se for com o Arch ou com o Gentoo que têm um desempenho superior, mas como me falta tempo (e saco) para tal tarefa, fiquei com a solução mais cômoda mesmo.

Aliás, solução da qual nem tenho do que reclamar: agora tenho o compiz e suas dezenas de efeitos, um pacote de desenvolvimento para deixar qualquer programador animado, Skype, Mercury (cliente para MSN, com suporte a web cam e tudo mais o que vc tem direito, inclusive à integração com players de mídia), o Thunderbird + Lightning como cliente de email, Limewire, gtk-recordmydesktop, Audacity, Amarok...

Enfrentei alguma dificuldade com as fontes do Firefox e do Thunderbird (não do conteúdo dos sites, mas as fontes da interface dos programas propriamente ditos). Nada que uma googlada não resolvesse. Bastou configurar o path correto das fontes xorg.conf, as resoluções no GNOME e no "KDE" - isto porque eu instalei alguns aplicativos como o Amarok, o Quanta Plus, o Kino...

Ajustei isso, e pronto. Sem problemas com fontes. Gráficos excelentes, qualidade e velocidade. Além da beleza. O compiz é realmente impressionante.

Mas como nem tudo são flores... hoje eu estava tentando encontrar algum software, script, plugin para o GIMP, etc, para redimensionar e renomear várias fotos ao mesmo tempo.

Procurei e cheguei até a instalar algumas coisas pelo Synaptic, mas depois vi um software que já acompanha o Ubuntu 7.10 chamado F-Spot. Sensacional.

Ele é um gerenciador de fotos. E mais que isso. Muito mais que isso. O software realmente me surpreendeu.

Você pode importar fotos direto de dispositivos como câmeras e CDs... depois pode atribuir-lhes tags e descrições. Tudo de uma forma muito intuitiva e simples. Você pode inclusive editar as fotos - tirar olhos vermelhos por exemplo - de uma forma tão fácil, mas tão fácil que chega a assutar. É daquelas coisas que você vê e pensa: como ninguém fez isso antes!

Mas não é só isso. A grande sacada deste software é que você pode usá-lo para exportar diretamente as fotos para o Flickr, Picasa, e mais uma porrada de sites similares.

Você seleciona as fotos, manda exportar, escolhe o site para onde você quer enviar - aqui ele mostra todas as atuais possibilidades exatamente como no site, como permissões, etc... - e manda fazer o upload. Você pode inclusive exportar suas tags e descrições - já vai pronto! E tem um plus: você pode alterar o tamanho para upload. Isso mesmo.

Você tem uma foto com de 2848x2136 pixels. Enorme. E o tamanho dela se reflete no tamanho do arquivo, claro. Então vc terá um upload demorado... poderá subir menos fotos...

É aí que o grande F-Spot entra em ação. Você pode definir um tamanho na hora de subir os arquivos, por exemplo 800 pixels - que é um ótimo tamanho para se pôr à exposição. No caso do 2848x2136 isso vai transformar a foto em 800x600 - bem menor - o que fará com que o upload seja mais rápido. O arquivo original fica intacto, o redimensionamento é apenas on-demand para o upload (a foto do site vai ficar com o tamanho máximo de 800x600).

Genial. Era tudo o que eu estava procurando e muito mais.

Bem, é isso. Só queria compartilhar o boost na experiência com o Desktop que estou experimentando.

Abraços.

-----------
keepReading

segunda-feira, 4 de fevereiro de 2008

Conexão segura - Apache2 + OpenSSL no Linux

Com certeza falei neste blog e no meu outro que sempre quis montar uma estação de trabalho para web development bacana em Linux.

Batalhei bastante com isso, mas nunca de forma contínua. Sempre foram de saltos, afinal também preciso estudar, trabalhar e dividir minhas atenções com entes queridos.

Para mim a estação de desenvolvimento ideal é aquela que simula os recursos disponíveis nos servidores. Então além de um servidor web, também deve ter um servidor de e-mail, interpretadores de código (PHP, Perl, Python...), container Java (Tomcat), servidores de bancos de dados (MySQL, Postgre), e por aí vai... Além de ferramentas que ajudem em outras funções, como programar (Eclipse, Quanta Plus, Bluefish) e criar layouts (GIMP, Inkscape)...

Faz um tempão que eu estava querendo colocar aqui SSL, para simular ambientes de produção onde se reproduzem operações seguras, em geral financeiras; hoje realizei. Passei o final da tarde da segundona de carnaval aprontando essa e vou compartilhar aqui com vocês.

O ambiente: Ubuntu 6.06 + Apache 2 (instalado pelo Synaptic) + OpenSSL (também instalado pelo Synaptic).

Creio que as únicas diferenças significativas aqui para que este tutorial se torne válido para outros sabores do GNU/Linux, e formas de instalação (via pacotes RPM, compilando na unha, por outro gerenciador de pacotes) são:
- a localização de alguns arquivos e paths;
- a instalação pelo Synaptic deixa o httpd.conf bem fragmentado. Citarei vários arquivos aqui que nada mais são que partes do httpd.conf que foram separadas.

Bem vamos ao desafio:
Quero que uma parte do site seja pública (passando por uma conexão comum) e outra privada (passando por SSL).

Então criei um diretório para o site e dois subdiretórios, assim:
/var/www/meusite/
/var/www/meusite/public/
/var/www/meusite/private/

Quero que a parte pública seja acessada como "http://www.meusite.com/" e que a parte privada seja acessada como "https://secure.meusite.com/

O primeiro passo é instalar os pacotes. Deixo isso por sua conta o que importa é ter o Apache 2.0 e o OpenSSL instalados. Tem muitos tutoriais de como se fazer isso e como não vou reinventar a roda, dê uma boa lida nas documentações. Estes tutoriais aqui podem dar uma simplificada na sua vida: este e este.

O que interessa é dividir o site em duas partes. Edite o arquivo /etc/hosts. Acrescente lá os sites que você quer. Eu acrescentei as linhas:

127.0.0.1 meusite www.meusite.com
127.0.0.1 secure.meusite secure.meusite.com


E dê uma conferida no arquivo "/etc/host.conf", ele deve conter uma linha assim:

order hosts,bind


Isso significa que quando uma requisição for feita, sua máquina olhará primeiro no arquivo hosts que acabamos de editar, depois vai para os resolvedores de nome. Isso é o que permite que você possa ter e acessar um site com o nome www.algumacoisa.com no seu PC sem conflitar com um da internet (note que se você nomear o site com algum nome existente como google.com, por exemplo - você não conseguirá mais acessar este site pelo nome, já que o arquivo /etc/hosts vai resolver ele antes de procurar nos resolvedores de nome!).

Agora para configurar os virtual hosts no Apache.
Para o parte pública acrescente:

<VirtualHost *>
ServerName www.meusite.com
DocumentRoot /var/www/meusite/public
</VirtualHost>


No httpd.conf ou no arquivo /etc/apache2/sites-available/default
Se você criou o arquivo /etc/apache2/sites-available/ssl
acrescente isso como conteúdo dele:

NameVirtualHost *:443
<VirtualHost *:443 >
ServerName secure.meusite.com
DocumentRoot /var/www/meusite/private

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
</VirtualHost>


Ou acrescente isso depois dos outros virtual hosts comuns.

Isso deve dar conta do recado.
Confira se você não esqueceu de colocar a porta 443 na escuta. No httpd.conf ou no ports.conf deve estar uma linha assim:

Listen 443


Também não esqueça de gerar e corrigir os nomes e paths dos certificados.

Se tudo der certo, depois de você reiniciar o Apache, abra um navegador e digite:
http://www.meusite.com/
https://secure.meusite.com/

E veja o resultado =]

Até mais.
-----------
keepReading

quarta-feira, 9 de janeiro de 2008

PostgreSQL - Inserindo múltiplas linhas só depois da versão 8.2

A batalha de hoje foi contra um velho costume (mal) adquirido do MySQL.

Criei uma tabela muito simples no PostgreSQL através do psql, na linha de comando mesmo.

CREATE TABLE pessoas (
id INT,
nome varchar(40),
sexo char(1)
);


Incluí um registro. Ótimo. Depois tentei incluir mais de um com um comando só:

INSERT INTO pessoas (id, nome, sexo) VALUES (2, 'José', 'M'), (3, 'Maria', 'F');


E ganhei um erro próximo dá vírgula.

...('M'), (3,...
^


Não ia nem com reza. Horas de pesquisa depois descobri algumas coisas interessantes.
1 - Esse tipo de construção não faz parte da norma SQL.
2 - Ela é popular devido ao popular MySQL (que disponibiliza essa construção como válida) e do seu fiel parceiro phpMyAdmin (que além de permitir a inclusão de múltiplos registros, ainda mostra o código SQL que foi executado, para todo mundo aprender como se faz!).
3 - Este tipo de construção é aceita pelo PostgreSQL 8.2 ou posterior. O server que tenho é o 8.1. E o manual que eu estava lendo do 8.3!
4 - Vou dar uma estudada em Java ou Shell Script para relaxar.

Té+
-----------
keepReading

segunda-feira, 7 de janeiro de 2008

PostgreSQL - instalando

A tempos atrás instalei o PostgreSQL 8.0 na minha máquina. Lembro que foi um tanto penoso para entender como proceder logo após a instalação dele no sistema, pensei até em escrever aqui mas devido à falta de tempo não escrevi nada, e é o que venho fazer agora.

O material é um tanto escasso em português, e as explicações geralmente confusas. Vou tentar dar um passo-a-passo.

Instalei no Ubuntu 6.06 pelo Synaptic (bem fácil), mas creio que o processo de compilação está bem descrito na documentação do PostgreSQL, então não vou me ater à este processo. O galho me veio após a instalação. Também recomendo que se instale o phppgAdmin, que dá uma interface mais agradável de trabalhar (nesse caso você precisará do Apache2 e do PHP5).

Primeiramente, saiba que quando se instala o PostgreSQL, assim como o Apache, o CUPS, é criado um usuário no sistema, para que este possa iniciar o servidor. É mais uma questão de organização e controle. Não se preocupe com isso, basta saber que o nome do usuário é postgres.

Além de criar este usuário, alguns comandos são adicionados ao sistema. São comandos administrativos que podem ser chamados direto pelo terminal.

Mais um detalhe importante: o PostgreSQL não permite que se crie e faça login com usuários com nomes sugestivos como admin, root, etc... Anotado? Então vamos lá, temos comandos para agir externamente e sabemos que não podemos criar nenhum usuário com nome sugestivo.

Abra um terminal e digite o comando:

$sudo su - postgres createuser seu_nome_de_usuario_do_linux

Se não funcionar dessa forma tente:

$sudo su - postgres
$createuser seu_nome_de_usuario_do_linux

A seguir serão feitas algumas perguntas (o novo usuário poderá criar um super-usuário? o novo usuário poderá criar bancos de dados?...poderá criar um novo usuário?). Responda a estas perguntas (sugiro um não-sim-não).

NOTA: o seu_nome_de_usuário_do_linux irá facilitar sua vida na hora de criar bancos de dados e fazer manutenção.

Temos um usuário criado, mas ele não tem senha ainda.
Faça assim:

$sudo su - postgres psql

Se não der certo tente:

$sudo su - postgres
$psql

Isso irá abrir um outro tipo de terminal, um terminal interativo com o servidor de banco de dados. Entre com a seguinte linha nele:

postgres=#ALTER ROLE seu_nome_de_usuário_do_linux WITH PASSWORD 'sua_senha';

Dê enter (aí você acaba de setar sua senha) e depois digite:

postgres=#\q

E dê enter novamente (para sair do terminal interativo do PostgreSQL).

Pronto. Agora você tem um usuário e senha do PostgreSQL com o qual poderá criar e editar seus bancos de dados no PostgreSQL.

Você pode criar um banco de dados mesmo sem senha com o comando:

$createdb nome_do_banco

Mas para logar pelo phppgAdmin a senha se faz necessária.

Agora vamos supor que você tenha criado um banco com o nome dummy. Para acessá-lo pelo terminal interativo do postgreSQL, basta fazer:

$psql -d dummy

E a partir daí enviar suas queries à este banco.

Espero que isso tenha ajudado a dar o ponta-pé inicial para o uso do PostgreSQL. Abaixo passo alguma informações extras.

Os comandos que podem ser usados direto pelo terminal são:
clusterdb -- cluster a PostgreSQL database
createdb -- create a new PostgreSQL database
createlang -- define a new PostgreSQL procedural language
createuser -- define a new PostgreSQL user account
dropdb -- remove a PostgreSQL database
droplang -- remove a PostgreSQL procedural language
dropuser -- remove a PostgreSQL user account
ecpg -- embedded SQL C preprocessor
pg_config -- retrieve information about the installed version of PostgreSQL
pg_dump -- extract a PostgreSQL database into a script file or other archive file
pg_dumpall -- extract a PostgreSQL database cluster into a script file
pg_restore -- restore a PostgreSQL database from an archive file created by pg_dump
psql -- PostgreSQL interactive terminal
reindexdb -- reindex a PostgreSQL database
vacuumdb -- garbage-collect and analyze a PostgreSQL database

-----------
keepReading

O MySQL não checa chaves estrangeiras!

Dando uma lida na documentação recentemente fiquei pasmo ao descobrir que as chaves estrangeiras não servem para absolutamente nada funcional no MySQL.

Sim, você leu direito. As chaves estrangeiras não servem para absolutamente nada no MySQL.

Ao definí-las, elas podem ser usadas como um lembrete, um aviso, etc... Mas os engines, com exceção ao InnoDB, não fazem checagem se o mesmo existe (na verdade eles não checam nem se a tabela onde é feita a referência!).

No InnoDB elas funcionam normalmente, mas nos outros a criação de chaves estrangeiras apenas criam uma coluna. Nem ao menos um índice é criado.

Uma vergonha para um banco com tantas funções, recursos, tipos de dados, extensões, conectores, etc...

A manual em questão é da versão 5.1 do MySQL, mais especificamente na seção 3.6.6.

Isso moçada: fiquem de olho.

-----------
keepReading

domingo, 6 de janeiro de 2008

Dicas de otimização e segurança

Olá, amigos. Depois de muito tempo away deste blog volto a publicar algumas informações coletadas e experimentadas.

Estudei bastante e fiz várias anotações durante os últimos meses. Além deste post se preparem para mais novidades legais em breve.

Neste reinício trago a vocês dicas sobre otimização e segurança. Algumas boas práticas que espero ser de valia.

Uma das decisões mais importantes durante o desenvolvimento de um sistema é onde implementar as regras do negócio. É comum deixar as regras ao encargo do linguagem de programação, mas quero mostrar que o melhor lugar para se fazer isso, sempre que possível, é no banco de dados.

Quando se implementa a lógica do negócio na linguagem de programação algumas coisas aumentam, como o tempo de desenvolvimento, o volume de códigos e a dificuldade em se fazer manutenção. Além de diminuir a portabilidade da aplicação (no caso de uma migração por exemplo).

Isso sem falar no ponto mais crítico: o aumento do tráfego e do processamento.

Vou exemplificar com um cenário comum - Apache 2, PHP 5 e MySQL 5.

Quando se tem a lógica implementada nos scripts/classes PHP, o fluxo segue mais ou menos como na figura:


Explicando... o cliente faz uma requisição ou envia um form. Estas informações são recebidas pelo servidor web que chamará o engine. O engine irá processar as requisições, se conectar com o banco de dados, enviar a(s) query(ies), processar a(s) resposta(s), fechar a conexão com o banco de dados, preparar a saída, repassá-la para o servidor e este por fim enviará para o cliente.

Isso é o processo que acontece geralmente em qualquer aplicação. Mas note que quando se deixa a regra dos negócios para o engine resolver, podem ser necessárias várias conexões e consultas ao banco de dados, e é aí onde o sistema perde performance - e muita.

A meta é diminuir este gargalo e aliviar este ponto crítico (a conversa entre o engine e o banco de dados). Deixando a lógica de dados implementada no banco de dados, o engine que trabalha com ele fará menos conexões, diminuirá a carga de processamento e melhorará o tempo de resposta, além de deixar o sistema mais robusto.

Assim, é altamente recomendável lançar mão de recursos como Views, Triggers, Procedures, Functions, e fazer um bom uso de índices e chaves disponíveis no banco de dados.

Digo isso porque tive uma experiência realmente dura em um sistema onde TODA a lógica dos dados estava implementada com o design pattern MVC. E para retornar um simples relatório com 50 linhas o sistema demorava uns 6 minutos - simplesmente crítico.

O problema é que haviam várias tabelas com relação Muitos-para-Muitos e a cada linha que se queria obter era necessário realizar uma série de queries e filtragens. Posso citar um dos casos onde para cada usuário era feita uma consulta numa tabela de relacionamento que retornava cerca de 8 chaves, que depois seriam pesquisadas em outra tabela, comparados, validados segundo sua data, organizados (aí já tinha apenas uns 2 ou 3 registros que realmente seriam úteis para o relatório), para depois fazer mais queries em duas ou três tabelas.

Ou seja para produzir uma linha, era necessário um volume de tráfego e processamento absurdo, sendo que isso poderia ser facilmente resolvido (ou pelo menos fortemente otimizado) com a criação de uma view e de uma function.

Aqui cabe um adendo: a diferença entre o modelo entidade-relacional dos bancos de dados e do que se pode implementar na programação orientada a objeto se chama impedância, e as boas práticas aqui citadas visam diminuir este problema. Eis um bom artigo aqui: http://www.linhadecodigo.com.br/ArtigoImpressao.aspx?id=70

Então a dica de otimização é essa: implemente a lógica de dados sempre que possível na própria base de dados.

Mas e a linguagem de programação seria útil para quê então?
Ora, para validar os dados enviados, fazer a conexão, enviar e receber dados do servidor, enviar e-mails, montar páginas dinamicamente... as mesmas coisas que antes. O que quero dizer é que ao invés de rechear seus scripts e classes com ifs, elses, switch cases e queries, você deve diminuir isso e usar apenas onde for realmente necessário.

Em relação à segurança, ela aumenta quando se adota esse procedimento e estes cuidados. Além disso você terá mais tempo livre para criar validações nos seus scripts server-side, e contará com mais uma camada de validação - a do servidor de bancos de dados.

É mais econômico para o sistema você checar se, por exemplo, um id existe numa determinada tabela do que fazer uma query select e depois uma comparação no script.

Algo assim: ao invés de fazer
<?
...
$valid_user = 0;
$sql = "SELECT 1 FROM users WHERE id = $posted_id";
$result = mysql_query($sql);
$x = mysql_fetch_assoc($result);
if ($x) {
$valid_user = 1;
}

if ($valid_user == 1) {
$sql_2 = "INSERT INTO...";
...
}
...

?>


Faça assim:
<?
$sql = INSERT INTO table_x VALUES ($x,$y,$z) WHERE $z INTO (SELECT id FROM users);
?>


Ou que você crie uma function no banco de dados para fazer isso.

Até mais.
-----------
keepReading