Categorias
Linux

Resolvendo resolv.conf

Ter mais de um dispositivo de rede pode lhe trazer problemas de prioridade. Normalmente apenas um dos dispositivos tem acesso à internet. Qualquer dispositivo de suporte compartilha a conexão ou serve dados guardados numa máquina atrás de um firewall. O problema é que o cartão sem conexão à internet pode ter prioridade sob o cartão que tem conexão à internet. Isso acontece quando ambos os cartões de rede são conectados a outras máquinas ou roteadores que atuam como servidores DHCP independentes e provêem informações conflitantes. O resultado é que os pacotes de rede destinados para a internet são roteados através do dispositivo de rede errado, cancelando a conectividade.

O problema geraldomente pode ser rastreado com um simples arquivo de configuração, /etc/resolv.conf. É aonde o seu sistema pega o endereço do servidor de nomes que é necessário para traduzir o nome do servidor legível por humanos (como rafael.bernard-araujo.com) para o endereço IP que a rede entende (208.65.202.206). Se o servidor de nomes não puder traduzir o endereço, não será possível acessar a internet usando nome de servidores, mas você pode usar o endereço IP para navegar.

É possível resolver o problema editando o resolv.conf adicionando o endereço IP do servidor de nomes do seu provedor de internet. Ainda assim, depois de uma ou duas horas a conexão pode ser interrompida. Ao olhar o resolv.conf novamente o nome dos servidores de nome estarão trocados. Um cliente DHCP está sendo executado em sua máquina e tentando determinar as configurações de conexão de tempo em tempo. O problema é que este cliente está priorizando a o cartão de rede errado e sobrescrevendo o endereço do servidor de nomes no resolv.conf.

É por isso que a solução pode ser encontrada em /etc/dhcp3/dhclient.conf. Para adicionar os servidores de nomes corretos, abra o arquivo no editor de texto e adicione servidor-de-nomes-do-dominio ipDoServidor. De agora em diante, este endereço será sempre adicionado em primeiro lugar no seu resolv.conf, antes de qualquer configuração equivocada de um servidor DHCP. Tudo ajustado.

Mais em Truques de linha de comando.

Categorias
Linux

Simples teste de falha

Há algumas vezes em que um processo de segundo plano que você confia silenciosamente falha, o que é difícil de detectar e corrigir. MythTV, por exemplo, depende de um servidor em segundo plano para gravar programas de televisão. Se o servidor falhar as gravações serão perdidas. Certo, então em primeiro lugar ele nunca deveria falhar, mas enquanto os desevolvedores se ocupam em corrigir os erros na aplicação, tudo o que podemos fazer é reiniciar o processo automaticamente.

O truqye é executar um processo que você quer reiniciar a partir de um script simples. Se ele falhar, o controle retorna ao script, que pode iniciá-lo novamente. Isto pode ser feito por um laço. Não é grande programação, mas funciona.

while true;
do
mythbackend;
done

A beleza disso é que, quando mythbackend falha, o laço while simplesmente inicia-lo-á novamente. Podemos fazer o script um pouco menos cru adicionando a verificação se mythbackend está em execução. Precisamos apenas contar o número de instâncias dos processos, o que fazemos pelo grep no retorno no número de instâncias do processo encontrados com ps. Se o mythbackend está mesmo em execução, o número de instâncias será um valor diferente de zero, o que testaremos através de um if.

Finalmente, com o script escrito, precisamos ter certeza de que ele não encerrará a si mesmo. Fazemos isso executando-o a partir de um shell com o comando hangup, nohup scriptname &.

#!/bin/bash
mcount = 'ps ax | grep "mythbackend" | grep -v grep | wc -l'
if [$mcount == 0]; then

#! Insert 'while true' code here
else
exit 1
fi

Mais em Truques de linha de comando.

Categorias
Linux

Renomear e prenomear

Na linha de comando, não conhecemos tanta gente que não utiliza o comando mv para renomear um arquivo ou diretório. É na maioria das vezes a maneira mais rápida para organizar arquivos, apesar de que pressionar F2 na maioria dos gerenciadores de arquivos vai lhe permitir fazer a mesma coisa.

As letras 'mv' são na verdade o diminutivo para 'mover' - uma descrição mais acurada do que esta ferramenta realmente faz, pois o caminho faz parte do que você quer renomear. Isso significa que você pode digitar mv /usr/bin/sux /sbin/sux não vai trocar, na verdade, o nome do arquivo, mas movê-lo do diretório /usr/bin para /sbin. É claro que você poderia ainda renomear o arquivo caso assim desejasse, talvez movê-lo para um diretório de backup e adicionar a extensão _bak. O comando é flexível o suficiente para renomear e mover arquivos simples ou diretórios, mas mv não provê isso mais de uma vez e isso se torna tedioso rápido se você precisa modificar mais do que simples arquivos.

Ainda bem que Larry Wall à mão para salvar o dia outro comando que comumente acha instalado na maioria das distribuições Linux. O comando é normalmente chamado de rename, mas você já deve ter visto alguma coisa chamada prename se rename é usado por alguma coisa no seu sistema. Como você deve ter imaginado, se Larry Wall tem algo com isso, deve ser um script Perl. Você pode até mesmo abrir arquivos com um editor de texto e verificar por si mesmo.

A coisa boa sobre prename é que é tão incrivelmente flexível para renomear grupo de arquivos. Mas é esta flexibilidade é graças ao poderoso analisador de expressões regulares do Perl que não é todo intuitivo se você é novo com expressões. Por exemplo, para adicionar _bak ao fim de cada arquivo começando com arquivo, você digitaria:

prename 's/\_bak$//' file*

Mas isso é apenas o começo e depois que você dominar o processo de gerar expressões regulares, você pode alcançar virtualmente qualquer tarefa de renomear/mover com prename - é especialmente útil para trocar nome de imagens em caixa alta que provém do windows para caixa baixa no Linux.

Mais em Truques de linha de comando.

Categorias
Linux

Linux sux

Na maioria das vezes, as pessoas usam su na linha de comando para se concederem privilégios de administrador de maneira que possam editar um arquivo de configuração importante. Mas também é possível encontrarmos usando su quando se está trabalhando no console e é preciso usar uma aplicação gráfica. Quando você tenta executar uma aplicação gráfica enquanto está autenticado com um usuário diferente, você recebe o seguinte erro:

Xlib: connection to ":0.0" refused by server.

O problema é que as chaves usadas para autenticação em sessões X não são válidas quando se usa um usuário diferente. Esta medida de segurança parece zelosa demais, mas é uma herança do sistema de um tempo em que as sessões X foram desenhadas para ser executadas através da rede. Há duas respostas para este problema.

A primeira é ter certeza de que a nova conta pode ser autenticada no servidor X. Isso utiliza o comando xhost para autenticação de novos usuários na janela da sessão X local. Apenas digite xhost +local:local com o usuário normal antes de trocar para o novo usuário e você verá 'non-network local connections being added to access control list' como saída. Agora é possível que você rode qualquer aplicação gráfica na mesma tela em que trocou de usuário. Se você quer ter este recurso a cada vez que você executa sua sessão X, simplesmente adicione o comando xhost ao seu arquivo .bashrc: ele será executado automaticamente a cada vez que você abre um terminal Bash.

A segunda solução é ainda mais fácil. É a substituição do comando su que transfere suas credenciais X para uma nova sessão automaticamente. O comando é sux, que você precisará instalar manualmente pelo gerenciador de pacotes da sua distribuição. Uma vez instalado, digite sux novousuario para trocar para o usuário com o qual você quer usar a visão X. Você perceberá que pode executar aplicações gráficas pela nova sessão sem nenhuma configuração adicional.

Mais em Truques de linha de comando.

Categorias
Linux

Mensagens de texto

Como sabemos, computadores existem para fazer as tarefas monótonas com as quais não queremos nos incomodar. Isto significa que coisas como adicionar ou subtrair números, desenhar coisas em cores bonitas e lembretes a seus mestres todo-poderosos de anotações a vir. Há dúzias de aplicações que têm a função de lembretes e que acionam uma tela chata com pequenas mensagens informando que você está atrasado para o dentista. Mas você realmente não precisa de uma: você pode exatamente o mesmo tipo de funcionalidade usando um casal de comandos do bom e velho terminal. Os comandos em questão são at e xmessage.

O comando at é uma das ferramentais mais essenciais aos usuários que circulam de um ponto a outro. Em essência, você digita 4:57 pm today na linha de comando e o at abrirá um editor de texto primitivo. No editor, você simplesmentes adiciona cada comando que deseja executar às 4:57 e pressiona Ctrl e D para indicar o final do arquivo. Cada comando deve parecer exatamente como seria na linha de comando e você pode até usar formatos diferentes para hora, como 1657 para formato 24 horas ou também 'now + 2 hours', ou ainda especificando o dia como 'Saturday' ou 'tomorrow'.

O comando que precisamos para emitir a tela do alerta é xmessage. É uma ferramenta muito simples que data dos primeiros anos das janelas X e simplesmente abre uma pequena tela no seu monitor que inclui uma mensagem de texto e um botão para fechar. A sintaxe do xmessage seria:

xmessage -display :0.0 "You are late"

A parte 'display' do comando é importante porque permite ao xmessage saber qual monitor deve ser usado. Se você adicionar o comando ao at, você tem uma maneira flexível de criar lembretes para si mesmo sem necessidade de recorrer a uma outra aplicação. É ainda mais fácil que usar o Cron, que pode ser desencorajador quando você que simplesmente executar algo como xmessage!

Mais em Truques de linha de comando.

Categorias
Linux

Avante com o Bash

O terminal do Bash é uma das coisas que as pessoas menos se dão o direito de modificar. Isso é estranho, pois é é uma simples questão de alterar o texto de cumprimentos quando você abre o shell para algo mais útil. O terminal do Bash é usado pela maioria das distribuições como o nome de usuário seguido do domínio (rafael@dollar, no meu caso).

A chave para alterar o terminal repousa em variáveis dinâmicas, o que lhe permite incorporar informações ao terminal. Para criar o terminal usuário/domínio que muitas distribuições usam você poderia digitar o que está a seguir (ou adicionar ao ~/.bash_profile ou ~/.bashrc para tornar permanente):

export PS1="[\u@\h]$"

O comando export define a variável de ambiente PS1. Ela é usada para o valor do terminal, que é o que está contido entre as aspas após o símbolo de igual.

Este valor é feito de duas varíaveis dinâmicas em ambos os lados do @; \u> exibe o nome do usuário, enquanto \h insere a primeira parte do nome do servidor. O Bash inclui outras variáveis dinâmicas, incluindo \w para o atual diretório de trabalho, \d para a data atual ou \! para a posição atual no histórico do buffer. Se elas parecem familiares é porque são seqüências de escapa, encontradas em várias aplicações e linguagens de programação e usada para formatar strings.

Há outras seqüências, como as que se seguem, que trocam o nome da janela:

"\e]2;title\a"

Houve um tempo em que a impetuosidade do hacker seria o medida por quão obtuso e complexo era o comando do terminal e não há realmente um limite para o que você queira adicionar. Muitos usam laços condicionais simples para trocar o conteúdo do terminal no momento em que uma sessão do shell é iniciada, mas usando simples seqüências de escape é fácil de trocar o terminal padrão para algo mais útil.

Mais em Truques de linha de comando.

Categorias
Ubuntu

Atualização para o Oneiric

Há algumas horas atrás eu iniciei as atualizações do 11.04 para o 11.10. Contra as sugestões, eu sempre faço a atualização diretamente, ao invés de uma instalação limpa. eu prefiro assim. Gosto de reforçar que, para quem quer, a atualização do ubuntu também funciona. Basta estar disposto.

Uma característica da atualização é que, ao final do download dos pacotes, toda a instalação é feita com o acesso a rede desabilitado. Só após a reinstalação é que a rede retorna.

No meu inspiron 1525 a atualização demorou por volta de 2 horas. Nenhum problema foi relatado e após a reinicialização estava lá o novo 11.10. Demais!

No computador de mesa, um quadcore com 4gb, eu achei que seria mais rápido. Demorou por volta de 3 horas (download e instalações) e no final pipocaram várias vezes erros de atualização do plugin do flash. Penei um pouco para conseguir reiniciar e, após isso, meu usuário principal não consegue carregar a área de trabalho. O outro usuário carrega normalmente, mas meu usuário principal não o faz. Já tentei a reinstalação de alguns pacotes, sem sucesso.

No pavillion dv4 da minha esposa parece ter demorado por volta de 2 horas e meia (engraçado, mas o computador mais fraco foi o mais rápido). Os erros do plugin do flash também pipocaram. Fiquei com medo, mas o reinício foi com sucesso e estava eu com o novo 11.10 também.

Até este momento estou sentindo que talvez a performance seja a mesma, senão um pouco mais lento do que o 11.04. Vamos acompanhar mais um pouquinho.

O erro que ocorreu em todos foi o flashplugin-installer failed.

Foi necessário o seguinte:

sudo dpkg --configure -a
sudo aptitude update
sudo aptitude install flashplugin-downloader
sudo aptitude safe-upgrade

Em um dos computadores eu não conseguia mais acessar à área de trabalho. Para este caso eu precisei instalar o gnome3, que me permitiu usar o sistema.

Categorias
Linux

Convert e mogrify

ImageMagick é tão perene quanto a grama. Encontrado em algum script PHP para aplicações KDE, é uma biblioteca caracterizada pelo processamento e edição de imagens com um batalhão de pequenas ferramentas. Há aproximadamento 100 dessas ferramentas, e duas das mais úteis são convert e mogrify - comandos que rivalizam com recursos do Gimp. Ao usá-las, você pode redimensionar, esmaecer, cortar, ajustar e transformar uma imagem sem precisar olhá-la. A diferença entre convert e mogrify é que com a última você pode sobrescrever as imagens originais ao invés de criar um novo arquivo para a imagem modificada.

Apesar de todas as funcionalidades complicadas, uma das melhores razões para usar convert é a sua função mais óbvia, que é a de modificar o formato de uma imagem. Em sua mais simples, você precisa apenas incluir os nomes de arquivo fonte e destino, e o convert vai se encarregar dos detalhes. O exemplo a seguir converta um arquivo JPEG em um PNG:

convert pic.jpg pic.png

ImageMagick é perfeito para lotes de imagens, mas ele não utiliza coringas da maneira experada. convert *.jpg *.png não funciona, por exemplo. A resposta é usar um sintaxe levemente diferente e substituir o comando convert por mogrify. Ao invés de usar um coringa para o formato de destino, define-se o tipo de extensão que se deseja. Para converter um grupo de imagens JPEG para o formato PNG precisamos digitar apenas o seguinte:

mogrify -format png *.jpg

Esta proximidade pode ser usada com qualquer parâmetro de convert e mogrify. Você pode usar o formato substituto com crop ou scale em um lote de imagens, por exemplo, se você precisar escalar ou cortar um diretório inteiro de imagens.

Mais em Truques de linha de comando.

Categorias
Linux

Ganhando argumentos

Não podemos ensiná-los a ser vitorioso em cada debate, mas podemos mostrá-lo como ser mestre em outro tipo de argumento: os da linha de comando. Você provavelmente conhece como fornecer múltiplos argumentos a um programa, como por exemplo:

someprog file1 file2 file3

O que é muito bom quando informa comandos manualmente, mas e quando precisa usar uma lista gerada por outro programa? Digamos, por exemplo, que você deseja que o Gimp abra dez imagens grandes de um diretório. Você poderia usar ls -l para encontrar quais são os maiores e então ter o trabalho de informar cada nome de arquivo em gimp arquivo1 arquivo2... Ou poderia a mágica xargs (presente em todas as distribuições).

ls -S --color=never | head -n10 | xargs gimp

xargs monta operações complicadas de linha de comando usando lista de arquivos para que você não precise digitá-las manualmente. Passe uma lista de arquivos ao xargs e ele os arranjará como arquivo1 arquivo2 arquivo3... como vimos anteriormente. Faz sentido? Considere o exemplo acima. Primeiro usamos ls para gerar a lista de arquivos do diretório atual (tendo certeza de que desabilitamos os códigos coloridos já que eles produzem caracteres indesejáveis). Então, usando o bom e velho pipe (|), enviamos o resultado para o utilitário head, que separa as primeiras dez ocorrências.

Agora então temos uma lista de dez arquivos. Como informamos ao Gimp que queremos abrí-los? Não podemos enviar diretamente os resultados de head, pois o Gimp interpretaria como se fossem simples dados gráficos. É aqui que o uso de xargs salva o dia: ele garante que o program cujo nome está a a seguir usará os dados como uma lista de arquivos ao invés de tentar trabalhar diretamente com eles. No nosso exemplo acima, ele diz "pegue os dez primeiros da lista gerada pelo head e então passe para o Gimp no formato tradicional arquivo1 arquivo2 arquivo3...". Você pode fazer muitas coisas com xargs, tudo o que esperad uma lista de arquivos, separados por caracteres de nova linha ou espaços. Como outro exemplo, este apaga todos os arquivos com mais de dez dias (use com cautela!):

find . -mtime +10 | xargs rm

Mais em Truques de linha de comando.

Categorias
PHP

Segurança no PHP II

Requisito 4: Sem erros para o usuário

Falaremos aqui de outro ponto importantíssimo na questão de segurança que é freqüentemente ignorado pelos desenvolvedores: as mensagens de erro.

As mensagens de erro foram feitas para que o desenvolvedor possa trabalhar de forma mais prática e descobrir o que ele está fazendo de errado. Observem, entretando, que, quando uma aplicação atinge maturidade suficiente para "entrar em produção", torna-se imperativo que o usuário não visualize mensagens de erro.

A razão disso é muito simples: as mensagens de erro freqüentemente trazem informações sensíveis. Observe como exemplo uma típica mensagem de falha de conexão com a base de dados:

Warning: mysql_connect() [function.mysql-connect]:
Access denied for user 'foo'@'localhost' (using password: YES)
in /usr/local/apache/htdocs/script.php on line 2

Note, através das partes destacadas, que esta mensagem me informa:

  1. O tipo de RDBMS: mysql
  2. O usuário de conexão com a base: foo
  3. Que este usuário está tentando uma conexão de dentro do servidor: localhost
  4. O caminho absoluto da raiz web: /usr/local/apache/htdocs
  5. O nome do script: script.php

É por isso que, quando colocamos uma aplicação em produção, ocultamos as mensagens de erro e as gravamos diretamente em um arquivo de log. Isto é muito simples de implementar:

Exemplo:

display_errors = Off
log_errors = On
error_log = /log/php_errors.log

Requisito #5: Esconda do servidor web o que ele não precisa acessar

Quantos de nós não usamos em nossas aplicações um arquivo, tipicamente chamado de config.php ou setup.php, onde guardamos, por exemplo, usuário e senha da base de dados?

Não há nada de errado nisso, mas cuidado: se este arquivo não gera saída de informação em HTML, por que deixá-lo acessível via web?

Para esclarecermos o problema, vamos definir 3 coisas:

  1. minha raiz web é: /usr/local/apache/htdocs
  2. meu arquivo de configuração fica localizado em /usr/local/htdocs/config/config.php
  3. este é um código típico que usa este arquivo:

require_once("/urs/local/htdocs/config/config.php");
/ bla bla bla /

Observe que o erro neste caso é confundir interpretador PHP e servidor web. O Apache (ou IIS, Xitami etc) não precisa saber onde está este arquivo. Isto é responsabilidade do interpretador.

Outro problema é que se arquivo fica desnecessariamente exposto, afinal de contas basta eu abrir um navegador e digitar:

http://www.meusite.com.br/config/config.php

Não faz sentido. Por mais que você possa argumentar que não há forma de ler o código-fonte deste arquivo, ainda assim, isto não muda o fato de que ele está desnecessariamente exposto.

A solução é simples: movemos o arquivo para fora da raiz web:

/usr/local/config/config.php

E depois apenas acertamos as permissões e corrigimos nosso código:

require_once("/urs/local/config/config.php");
/ bla bla bla /

A partir de agora nosso arquivo de configuração só pode ser lido por quem precisa dele: o interpretador PHP.

Requisito #6: Use criptografia

Dados sigilosos são chamados assim por um motivo. Quando tratamos especificamente de senhas é impressionante a quantidade de aplicações web que gravam senhas em texto puro na base de dados.

Ora, se a senha possui a importância que tem e quem a escolhe é o usuário, por que alguém mais precisa ler essa senha?

Se a senha possui este peso em nossa aplicação, não podemos nos dar o luxo de fazer com que ela trafegue pela aplicação totalmente exposta.

PHP implementa criptografia de várias formas, mas eu sugiro - para quem puder usar, pois exige instalação e configuração extra - a utilização da função mcrypt.

Os hashes MD5 e SHA-1 são opções válidas, mas o problema é a sua fragilidade: para o MD5 existe até dicionário de dados, enquanto o SHA-1 foi recentemente "quebrado" por um pesquisador chinês.

Conclusão

A implementação de regras básicas de segurança depende apena da boa vontade do desenvolvedor. Você deve ter percebido como a maior parte das soluções aqui apresentadas significam simples mudanças de hábito.

É mais do que tempo de nós, desenvolvedores PHP, deixarmos de lado nossos antigos vícios e começarmos a implementar boas práticas de programação.

Ganha o profissional, ganha a sua aplicação, ganha o seu cliente, ganha o mercado. Só quem perde nessa situação é quem tenta se aproveitar de nossa aplicação.

Referências e links sugeridos

[PHP Security Consortium] - http://phpsec.org/

Er Galvão Abbott trabalha há mais de dez anos com programação de websites e sistemas corporativos com interface web. Autodidata, teve seu primeiro contato com a linguagem HTML em 1995, quando a internet estreava no Brasil. Atualmente, além de lecionar em diversos cursos, tem se dedicado ao desenvolvimento de sistemas baseados na web, tendo nas linguagens PHP, Perl e JavaScript suas principais paixões.

Parte I