Archive for the ‘Sysadmin’ Category

PostHeaderIcon Gerando as configurações do arquivo sources.list do seu Debian automaticamente.

Suponha que você tenha acabado de instalar uma máquina usando o Debian GNU/Linux. Caso você não tenha selecionado alguns repositórios de pacotes através da rede ao longo da instalação, não vai demorar para que você precise editar o arquivo /etc/apt/sources.list para registrá-los ao invés de ficar limitado apenas aos arquivos presentes no próprio CD de instalação, que já é configurado como um repositório padrão. 

Acontece que muita gente não lembra ou mesmo não quer perder tempo criando a configuração do arquivo sources.list manualmente. Justo, não? Bem, se você não tem um arquivo pronto para copiar, uma alternativa bem interessante é utilizar o site http://debgen.simplylinux.ch. Com uma interface muito simples e direta, você informa seu país, os repositórios padrões do Debian que deseja considerar e ainda pode selecionar alguns repositórios adicionais como o do Google, por exemplo. Depois, em um clique, você tem o conteúdo do arquivo sources.list gerado. Basta copiar e colar no arquivo /etc/apt/sources.list. Depois disso, execute um "apt-get update" e comece a usufruir os pacotes presentes em seus repositórios. 

Simples, não?

PostHeaderIcon Reduzindo o tamanho de arquivos PDF através da linha de comando.

Recentemente, precisei submeter uns arquivos no formato PDF para um site. Entretanto, o sistema tinha uma limitação com relação ao tamanho dos arquivos PDF que deveriam ser submetidos. Tentei utilizar algumas opções do editor de textos que eu havia utilizado para criar os arquivos PDF com tamanho menor, mas, infelizmente, não obtive sucesso. Ainda que essa solução funcionasse, eu deveria repeti-la, pelo menos, 15 vezes, manualmente. Foi nesse momento que resolvi encontrar uma nova solução através através do "sabre de luz" de todo administrador e usuários mais avançados do mundo Linux: a linha de comando.

A solução pode ser feita através do Ghostscript, um antigo e bem poderoso pacote de ferramentas que já vem instalado em muitas distribuições Linux. Para reduzir um arquivo PDF, usando o gs, utilizei o seguinte comando:

$ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \

     -dNOPAUSE -dQUIET -dBATCH \ 

     -sOutputFile=ArquivoReduzido.pdf ArquivoOriginal.pdf

Em poucos instantes, você tem o seu arquivo PDF com o tamanho significativamente menor. O mais interessante, entretanto, para evitar um trabalho repetitivo, é combinar esse comando em um pipe para, por exemplo, converter diversos arquivos PDF de uma única vez. Por exemplo, considerando que no diretório /tmp/PDFs estão todos os arquivos com extensão ".pdf" a serem reduzidos que devem ser armazenados no diretório /tmp/PDFzinhos, basta executar a seguinte linha de comando:

$ cd /tmp/PDFs ; ls *pdf |  xargs -t -i gs -sDEVICE … … … \

   -sOutputfile={}  /tmp/PDFzinhos/{}

(Substitua os "… … …" por todo o restante do comando gs mostrado anteriormente)

Pronto! Tudo devidamente reduzido de uma única vez!

Ainda é possível melhorar ainda mais o uso dessa linha de comando, incorporando-o a um script com diversos recursos legais. Entretanto, deixo isso como um exercício para vocês! :-)

Acho que é isso. Até a próxima!

PostHeaderIcon Removendo kernels antigos no Ubuntu.

Atualizar o kernel de seu Linux já foi uma tarefa complicada. Atualmente, o pacote de kernel e todas as suas dependências são atualizadas de maneira muito simples. Muitas vezes, basta que um alerta no seu ambiente gráfico apareça reportando que existem atualizações pendentes e pronto… tudo será atualizado, inclusive o kernel. 

Entretanto, uma atualização de kernel não substitui os pacotes das versões anteriores. Com o passar do tempo, seu sistema passa a ter um conjunto de versões mais antigas de kernel que já não são utilizadas e apenas consomem espaço. Recentemente, dei-me conta de que estava sem espaço no "/" de meu laptop. Ao investigar o que poderia ser descartado vi que existiam mais de 12 versões antigas de kernel. Uma simples consulta com dpkg foi suficiente para identificar isso:

# dpkg -l linux-image-*

A tarefa simples seria a de remover todos esses kernels antigos, um a um. Mas que trabalho tedioso seria fazer isso, não é mesmo? Obviamente, como um administrador de sistemas Linux, uma situação dessa logo desperta a vontade de resolver tudo isso de uma única vez, através da linha de comando e de um toque Jedi. Então, para quem está procurando algo parecido ou está passando pela mesma situação, aproveito o espaço para compartilhar a solução que representa, acima de tudo, uma excelente oportunidade para praticar o uso dos poderosos pipes presentes em todos os sistemas Unix. Os exemplos apresentados foram testados em um ambiente Ubuntu, entretanto com poucas modificações, pode ser utilizado em outras distribuições também.

O comando a seguir é suficiente para você ter uma relação que contenha apenas os nomes de todos kernels que estão instalados em seu sistema com exceção do kernel atual que está em execução no momento:

# dpkg -l linux-image-[0-9]* | grep -v $( uname -r) | awk '/^in/{print $2}'

O próximo passo é utilizar o próprio comando dpkg para remover os kernels que não estão mais em uso:

# dpkg -P $( dpkg -l linux-image-[0-9]* | grep -v $( uname -r) | awk '/^in/{print $2}' )

Quer entender o que foi feito em cada comando? Bem, uma dica é executar o primeiro comando, depois executá-lo com o primeiro pipe e o próximo comando e assim por diante.

Bem, acho que é isso. Até a próxima!

PostHeaderIcon Protegendo seu terminal de comandos do esquecimento…

Passo por aqui, dessa vez, para uma dica bem rápida e que, pra mim, é bastante útil. Não é raro encontrar mundo de TI afora terminais de comandos abertos em servidores (alguns deles bem importantes). Perdi as contas das vezes em que me deparei com acessos de root dados "de graça" em servidores Linux simplesmente após pressionar qualquer coisa no teclado que tirasse o monitor do modo de economia de energia para revelar uma sessão logada. Para ambientes onde existe o ambiente gráfico, isso não é um problema tão sério já que a maioria deles trava a tela após um determinado perído de tempo sem uso. Mas, e o que fazer com relação àqueles servidores onde apenas o modo texto está disponível?

Uma dica muito simples para resolver essa questão é contar com um truque "Jedi" que existe no shell (bash e outras). Trata-se da variável especial  "TMOUT". Ela determina o número de segundos em que um terminal de comandos pode permanecer aberto, sem uso, antes que seja fechado automaticamente. Quer tentar? Pra isso, basta abrir um terminal de comandos qualquer e executar o seguinte comando:

$ export TMOUT=10

Em seguida, observe, com os próprios olhos que, passados 10 segundos de inatividade, o terminal simplesmente fecha! Interessante, não?

Entretanto, como de costume, a execução do comando anterior afeta apenas o terminal onde ele foi executado. Para fazer com que essa configuração seja feita para um usuário em todos os terminais de comandos abertos por ele, basta inserir o comando anterior, por exemplo, no arquivo ".bashrc" localizado dentro do diretório home do usuário. Ou ainda, para fazer com que todos os usuários estejam sujeitos à mesma configuração, pode-se inserir o comando em arquivos como o /etc/profile ou /etc/bash.bashrc.

Bem, acho que é isso… Até a próxima!

PostHeaderIcon A lição nossa de cada dia… quando o espaço não é tudo.

Seu telefone toca durante a madrugada. Um dos sistemas mais importantes para um cliente parou subitamente de funcionar. É preciso tomar uma ação imediata. Ao tentar verificar qual foi o problema, uma rápida olhada nos logs do sistema revela algo que parece comum e, aparentemente, fácil de resolver: problemas no sistema de arquivos com a messagem “no space left on device“. Pronto… logo mais você estará com o problema resolvido e dormindo novamente. Na certeza da vitória, você executa um df, mais ou menos dessa maneira:

# df -m

Uma rápida passada de olho procurando confirmar o óbvio: alguma partição está com 100% de ocupação. Diante disso, aumenta-se o tamanho da partição ou move-se alguns arquivos para outras partições… Mas, para sua surpresa e para a infelicidade de sua noite de descanso, nenhuma das partições do sistema apresenta ocupação máxima:

[root@amhsnode01-br ~]# df -m
Filesystem           1M-blocks      Used Available Use% Mounted on
/dev/sda1                 9920      3433      5975  37% /
/dev/sda2                  961        20       892   3% /tmp
/dev/sda3                 3968       320      3444   9% /var
/dev/sda4                  996        40       905   5% /boot

O nervosismo toma conta… mais telefones irão tocar em breve. Ainda em busca da verdade e sem saber no que acreditar, você monta o sistema de arquivos que provocou o problema e tenta criar um arquivo:

# touch /var/nightmare/teste

E a mensagem aparece novamente: “no space left on device“. E agora?

Read the rest of this entry »

PostHeaderIcon Como trocar a senha de um usuário em um shell script?

Vez em quando me deparo com amigos me perguntando como é possível, a partir de um shell script, alterar a senha de um usuário. Bem, então, acho que, apesar de ser uma dica bem simples, acho que publicá-la por aqui pode ser uma boa forma ajudar outros amigos perdidos na imensidão da Internet que, eventualmente, estejam precisando de uma solução rápida para esse problema.

Bem, existem diversas maneiras de lidar com essa questão. Entretanto, comento por aqui uma alternativa que, em minha opinião, é uma das mais simples de entender, utilizar e, principalmente, lembrar quando for necessário. Para ilustrar melhor o problema: suponha que você está desenvolvendo algum shell script que cria alguns usuários e nesse processo é necessário atribuir uma senha (aleatória ou não) a eles. Supondo que o username e a senha a ser atribuídas estão armazenados nas variáveis $MYUSER e $MYPASSWORD, respectivamente, basta inserir em seu shell script algo semelhante ao seguinte comando:

MYUSERNAME="fulano"
MYPASSWORD="novasenha"
...
echo "$MYPASSWORD" | passwd --stdin "$MYUSERNAME"

Pronto! Simples, não? Bem, acho que é isso. Até mais.

PostHeaderIcon Quando a ajuda cai do “shell”…

Muitos administradores de sistemas, desenvolvedores e até usuários (mais avançadas) de GNU/Linux (e outros tipos de Unix, na verdade) costumam lidar com a famosa “tela preta” por horas todos os dias. E, como não poderia ser diferente, mudar de diretórios é uma tarefa executada dezenas ou centenas de vezes em uma simples jornada de trabalho. Com isso, errar o caminho do diretório é algo bem comum e que, além de fazer você perder tempo, pode prejudicar sua paciência!

Uma das formas de facilitar sua vida no poderoso mundo da “tela preta” é o próprio recurso do auto completion, presente em shells com o bash. Outro truque bem simples e interessante, mas deconhecido por muitos, é comando shopt. Com ele, pode-se pedir uma ajuda da shell para completar seus comandos “cd” para mudar de diretório quando há apenas um pequeno erro de digitação.

Por exemplo, suponha que ao tentar entrar no diretório /tmp, vc execute o seguinte comando:

$ cd /tmx

Obviamente que você receberá uma mensagem de que esse diretório (/tmx) não existe. Entretanto, tente executar o comando shopt dessa maneira:

$ shopt -s cdspell

Em seguinda, tente executar o comando “cd /tmx” e confira que, mesmo tendo errado o caminho, você estará dentro do diretório pretendido, ou seja, o /tmp. Se você quiser que todas os seus terminais de comandos sejam executados já com essa opção, basta inserir o comando “shopt -s cdspell” no arquivo .bashrc ou .bash_profile (conforme sua distribuição Linux ou versão de Unix).

Antes de terminar, logicamente que o título desse pequeno post é completamente baseado nas “peripécias criativas” de meu grande amigo e mestre do shell Júlio Neves. Por fim, como se pode ver, mesmo no mundo da “tela preta”, às vezes, a ajuda cai do “shell”. Até a próxima!

PostHeaderIcon Como copiar sua chave SSH mais rapidamente.

Resolver problemas remotamente utilizando SSH é um recurso presenta no dia-a-dia dos sysadmins, desenvolvedores e até usuários mais avançados de ambientes Unix/Linux. Aliás, esse é um recurso seguro e muito útil, não é mesmo? Com isso, é comum que, ao longo de suas atividades diárias, um usuário que se vale desse recurso necessite abrir sessões SSH em muitas máquinas. Obviamente que a criptografia inerente ao protolo SSH não evita a existência de um processo de autenticação. São recursos de segurança complementares. Portanto, da maneira tradicional, cada abertura de sessão SSH necessita que o usuário insira uma senha. Com o tempo, principalmente para quem costuma fazer dezenas de sessões SSH diariamente, essa pode ser uma tarefa cansativa, não é mesmo?

Para evitar isso, o protocolo SSH possui um recurso muito interessante: a autenticação por meio de chaves públicas, que evita a necessidade de prover senhas durante a abertura de sessões SSH em máquinas remotas onde a chave pública do usuário já foi previamente copiada. Normalmente, esse processo se dá através da criação de um par de chaves criptográficas por meio do comando ssh-keygen, conforme apresentado no exemplo a seguir:

jansen@scadufax $ ssh-keygen -t dsa

Nesse caso, um par de chaves (pública e privada) está sendo criado usando-se o algorimo DSA. As chaves privada e pública, recém-criadas, são gravadas, nesse caso, nos arquivos id_dsa e id_dsa.pub, respectivamente, e ficam localizadas no diretório .ssh, dentro do home do usuário. Para se valer do recurso de não precisar prover senhas é preciso, então, copiar a chave pública para o arquivo .ssh/authorized_keys nos diretórios home dos usuários remotos, usando-se, por exemplo, o seguinte comando:

jansen@scadufax $ scp ~/.ssh/id_dsa.pub jsena@smeagol:~/.ssh/authorized_keys

Nesse caso, quando o usuário jansen, a partir da máquina scadufax, tentar abrir uma sessão SSH com o usuário jsena na máquina smeagol, nenhuma senha será necessária. O processo de autenticação se dará através das chaves criptográficas. Até nenhuma novidade, certo? Entretanto, imagine que mais de um usuário deseje acessar a conta jsena na máquina smeagol. Pode até ser a mesma pessoa utilizando um par de chaves criptográficas diferentes do anterior, gerado, por exemplo, em outro computador. Nesse caso, se o mesmo procedimento anterior for utilizado, o arquivo authorized_keys, que já contém a chave pública de outro usuário, será sobrescrito, passando a invalidar o acesso cadastrado anteriormente. Para evitar esse problema, a partir do segundo usuário, seria necessário adotar outros procedimentos para a cópia da chave-pública de forma a não sobrescrever o conteúdo já existente no arquivo authorized_keys.

Para facilitar esse processo, existe um utilitário chamado ssh-copy-id que é desconhecido por uma parcela considerável dos usuários de SSH. Essa pequena ferramenta resolve esse problema da cópia de diversas chaves para um mesmo arquivo authorized_keys:

jansen@scadufax $ ssh-copy-id jsena@smeagol

Caso seja necessário copiar outras chaves para acessar a conta jsena na máquina smeagol, basta utilizar o mesmo comando. Caso um mesmo usuário tenha mais de um par de chaves (sim, isso é possível), pode-se indicar quais delas se deseja copiar para a máquina remota:

jansen@gandalf $ ssh-copy-id -i .ssh/id_rsa.pub jansen.sena@boromir

Simples, não? Bem, acho que é isso.

IMPORTANTE: Para que o mecanismo de autenticação através de chaves públicas funcione corretamente, é necessário que o servidor SSH esteja configurado para tal. Mas isso é assunto para outro momento!

PostHeaderIcon Processo “kworker” deixando seu computador inutilizável?

Recentemente, comecei a ter alguns problemas de desempenho em notebooks com o Ubuntu 11.04. Investigando melhor, não foi difícil verificar que o problema ocorria apenas quando os equipamentos estavam com suas baterias sendo carregadas. O desempenho literalmente desabava ao ponto do próprio mouse não funcionar direito. Com um simples “ps” foi possível identificar o vilão: o kworker, um processo que ajuda o kernel a desempenhar suas atividades.

Uma rápida pesquisa foi suficiente para verificar que o problema já parecia incomodar alguns usuários de Linux, incluindo aqueles de outras distribuições diferentes do Ubuntu, como o Fedora, por exemplo. Depois de algumas sugestões que não surtiram efeito, encontrei uma solução que parece ter dado “conta do recado”. Diante disso, resolvi compartilhar por aqui para poder ajudar quem possa estar, eventualmente, com o mesmo incômodo problema.

A solução, simples, consiste apenas em alterar o conteúdo da variável “/sys/module/drm_kms_helper/parameters/poll”. Para isso, abra um terminal de comandos com privilégios de super-usuário (em distribuições como o Ubuntu você pode utilizar o comando sudo, por exemplo) e execute o comando “echo”, de acordo como apresentado a seguir:

$ sudo su - 
# echo N> /sys/module/drm_kms_helper/parameters/poll

Se você estiver em frente ao seu computador com o problema de ter sua CPU “consumida” pelo kworker, o comando acima deve ser suficiente para fazer tudo voltar tudo ao normal em poucos segundos. Essa solução, entretanto, não será mais válida em seu próximo reboot. Para fazer com que ela seja permanente em seu sistema, insira a mesma configuração no arquivo /etc/modprobe.d/local.conf, conforme apresentado a seguir:

$ sudo su - 
# echo "options drm_kms_helper poll=N" >/etc/modprobe.d/local.conf

Bem, acho que é isso. Espero que possa ajudá-los.

PostHeaderIcon Fazendo seu servidor Apache “falar” um pouco menos…

Tarefa básica e que faz parte do cotidiano de um usuário: abrir o browser de sua preferência e acessar algum site na Internet. Simples, não? Do ponto de vista do usuário, sim. Mas, aos olhos de um administrador de sistemas preocupado com segurança, essa é uma atividade que merece ser um pouco mais estudada. Todas as vezes que um cliente conecta-se a um servidor Web há uma troca de informações entre ambas as partes. Nesse caso, a linguagem falada é o HTTP. A questão é que algumas dessas informações podem revelar informações do seu servidor Web úteis na elaboração de um ataque.

Para verificar algumas das informações comumente reveladas por um servidor Web aos clientes que conectam-se a ele, basta utilizar o antiquado mas ainda útil telnet. Nesse caso, é suficiente escolher um site qualquer, direcionar a conexão para a porta 80 e submeter ao servidor algumas das poucas informações obrigatórias do protocolo HTTP (GET e Host, por exemplo), conforme mostrado a seguir:

# root@scadufax:~# telnet www.xxxxx.com.br 80
Trying 201.123.123.121...
Connected to server.xxxxx.com.br.
Escape character is '^]'.
GET / HTTP/1.1
Host: www.xxxxx.com.br

Após a cláusula “Host”, pressione duas vezes Enter. Em seguida, o servidor Web deve retornar os cabeçalhos HTTP de resposta e o conteúdo da página, de acordo como mostrado abaixo:

HTTP/1.1 200 OK
Date: Fri, 08 Jul 2011 00:47:40 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny10 with Suhosin-Patch
Last-Modified: Thu, 20 Apr 2006 18:44:51 GMT
ETag: "9f132-c96-411e12ad8aec0"
Accept-Ranges: bytes
Content-Length: 3222
Content-Type: text/html; charset=ISO-8859-1

<<< CONTEÚDO DA PÁGINA>>>

Dentre os cabeçalhos de resposta, dedique atenção especial ao “Server”, em destaque. Nele, é possível identificar o servidor Web (Apache), sua versão (2.2.9), o sistema operacional (Debian) e ainda a versão do PHP (5.2.6-1+lenny10). Tais informações já ajudam um atacante a escolher quais ferramentas ele poderá ajudar em um eventual ataque. Pior ainda: o atacante consegue descobrir se seu servidor encontra-se completamente desatualizado e, portanto, possivelmente vulnerável contra um conjunto maior de exploits. Revelar essas informações no cabeçalho “Server” é o comportamento mais comum para um servidor Apache instalado diretamente dos repositórios de pacotes de sua distribuição.

Outra forma de identificar se o servidor está revelando mais informações do que deveria consiste simplesmente em provocar algum erro, acessando, por exemplo, uma página que, certamente, não existe naquele servidor Web:

http://www.xxxxx.com.br/abcdefghijklmnop

Servidor Apache revelando informações desnecessárias.

Normalmente, em sites mais bem configurados, as páginas de erro são todas customizadas. Nesses casos, algumas vezes, as informações sobre o servidor não são apresentadas.

Surpreso? É nesse estado que se encontra seu servidor? Bem, então é hora de corrigir esse problema.

O Apache possui duas configurações bem simples mas que são costumeiramente ignoradas, fundalmentalmente pelos administradores de sistemas menos experientes: ServerTokens e ServerSignature que podem impedir que o servidor revele informações mais detalhadas no cabeçalho “Server” do HTTP e que informações desnecessárias sejam apresentadas nas páginas de erro default do Apache, respectivamente. Para fazê-las desempenhar essas funções, basta adicioná-las no arquivo de configuração do Apache da seguinte maneira:

ServerTokens Prod
ServerSignature Off

Depois, reinicie o seu servidor Apache e veja se agora, seu servidor passou a “falar” um pouco menos…

Logicamente que existem muitas outras providências a serem tomadas para fazer um bom trabalho de hardening de um servidor Apache. Entretanto, deixaremos isso para uma outra oportunidade.

Bem, acho que é isso. Até o próximo post.