Archive for the 'Dicas' Category

Restingindo acesso com rbash

Como sysadmins vez por outra a gente precisa dar acesso a clientes, parceiros ou outro tipo de usuário temporário/untrusted aos servidores. Apesar de criar um jail root completo ser a melhor solução muitas vezes é mais trabalho do que o necessário e começa a entrar naquele cenário em que a segurança atrapalha a usabilidade e os negócios.

Uma forma simples de conseguir uma segurança bacana é utilizar o modo restrito do bash. Com isso habilitado o shell irá desabilitar as seguintes funções:

  • Mudar o diretório (cd)
  • Mudar o valor das variáveis SHELL, PATH, ENV, or BASH_ENV
  • Comandos que incluem /
  • Especificar um arquivo que contenha / como fonte para o comando “.”
  • Usar redirecionamento de output (>, >>, |)
  • etc (man bash para todas as features)

Colocando para rodar:

Crie um link do bash para o rbash e adicione o mesmo em /etc/shells:

ln -s /bin/bash /bin/rbash
echo /bin/rbash >> /etc/shells

Depois é só mudar o shell do usuário a ser restringido para usar o rbash:

usermod -s /bin/rbash username

Combinando isso com traps (do CTRL+C, por exemplo) você consegue criar um ambiente seguro o suficiente para fornecer serviços e acessos aos seus servidores e ainda assim dormir à noite.

Como diria o SuSE: Have a lot of fun!

Related posts

Não reinvente a roda você também


Preâmbulo:

Recentemente coloquei no ar o FollowUpTime, que como já disse em outros posts é um sistema de monitoração para redes e servidores.

Como podem imaginar, um bocado de linhas de código está envolvida num sistema assim e a conta só do engine principal passa das 90 mil linhas. Isso sem incluir templates, javascripts, etc.

O sistema é composto de duas partes: Uma que roda num servidor principal gerenciando a maior parte das tarefas e as “probes”. As probes são pequenos scripts que recebem instruções sobre hosts a serem testados e respondem para o servidor principal com o tempo de resposta, um OK ou um FAIL. Simples assim.

São essas probes que temos espalhados por vários cantos do planeta.

Porém quando recebi a probe dos desenvolvedores me vi com um pequeno, mas incoveniente problema. Os desenvolvedores realmente optaram pelo princípio KISS. Eles me entregaram uma excelente probe que fazia o que era necessário. E nada mais. Eu tinha nas mãos um daemon que rodava em foreground e jogava mensagens para stdout e stderr e nada mais.

Eu não me demorei e ataquei o problema da forma errada, pensando como um programador e não como um administrador Unix. E acabei reinventado a roda.

Introdução – O problema

Quando percebi o que eu tinha nas mãos logo pensei nos problemas que eu precisava resolver:

  • Preciso iniciar o daemon sempre que der boot na máquina
  • Preciso ser capaz de rodar em daemon em background, ou vai me zoar a seqüencia de boot
  • Posso precisar parar/reiniciar/iniciar manualmente este daemon
  • Se o processo morrer eu tenho que ser notificado e que, de preferência, ele seja reiniciado automaticamente
  • E sim, esse processo não deve rodar como root

Já velhaco de Linux logo pensei num script para ser colocado em /etc/init.d/ que ia resolver boa parte dos meus problemas. Com uma combinação bonita de bash scripting, várias ferramentas e comandos Linux que só se conhece depois de muito tempo de casa (como nohup, pidof, &) e gambiarras na crontab eu consegui. Consegui reinventar a roda. Não vou entrar em detalhes da solução que fiz, pois apesar de 100% funcional não era nem de perto tão bonita quanto:

A solução – Daemontools

Nosso caro amigo D.J.B, autor do famoso Qmail também já passou por um problema parecido com o meu, mas ao invés de criar um solução simples para resolver um problema pontual ele foi mais longe. Ele criou uma solução global que atende o problema dele, o meu e provavelmente também o seu.

Na página oficial do daemontools tem uma tabela, que traduzo abaixo, comparando a ferramenta dele com outras abordagens (incluindo a minha, que utilizava init.d):

Funcionalidade inittab ttys init.d rc.local /service
Fácil instalação e remoção de serviços Não Não Sim Não Sim
Simples startup inicial Não Não Não Não Sim
Reinicializações confiáveis Sim Sim Não Não Sim
Sinalização simples e confiável Não Não Não Não Sim
Estado de processo limpo Sim Sim Não Não Sim
Portabilidade Não Não Não Não Sim

Dá para perceber que o cara pensou em tudo e não tem porquê reinventar a roda. Vamos utilizar o daemontools!

Continue reading ‘Não reinvente a roda você também’

Related posts

Nested variables no Bash

Não sei ao certo como é o nome em português. Variáveis aninhadas? :-P

Me deparei com um problema assim hoje: Eu tinha uma função num script shell que recebia um parâmetro de sucesso ou erro. Eu executava algumas coisas e depois tinha que jogar uns dados no arquivo respectivo.

Então inicialmente tinha setado uma variável com os paths dos caminhos:

1
2
ARQUIVO_SUCESSO=/tmp/sucesso
ARQUIVO_ERRO=/tmp/erro

Minha função recebia o status como o primeiro argumento ($1) e por isso depois de processar eu precisaria de algo assim:

1
echo "batatinha" >> $ARQUIVO_$1

Mas logo percebi que isso não funciona. A solução, no entanto, é simples:

1
echo "batatinha" >>  $(eval echo \$ARQUIVO_$1)

Anotem ai na caixa de truques do Bash.

Related posts

Truques no Bash

Alguns truques para facilitar o seu dia-a-dia na linha de comando:

!$

Representa a última parte do último comando executado. Exemplo:

$ grep macarrao comidas.txt
macarrao
$  cat !$
cat comidas.txt
arroz
feijao
batata frita
macarrao

Expansão automática

Expande automaticamente os valores entre chaves. Uma mão na roda para loops:

$ for i in {1..4}; do echo "i vale $i"; done
i vale 1
i vale 2
i vale 3
i vale 4

Também funciona com letras:

$ for i in {a..d}; do echo "i vale $i"; done
i vale a
i vale b
i vale c
i vale d

E pode ser útil em situações assim:

$ mkdir -p diretorio{a..c}/sub-diretorio{w..z}
$ find .
.
./diretorioc
./diretorioc/sub-diretoriow
./diretorioc/sub-diretoriox
./diretorioc/sub-diretorioz
./diretorioc/sub-diretorioy
./diretoriob
./diretoriob/sub-diretoriow
./diretoriob/sub-diretoriox
./diretoriob/sub-diretorioz
./diretoriob/sub-diretorioy
./diretorioa
./diretorioa/sub-diretoriow
./diretorioa/sub-diretoriox
./diretorioa/sub-diretorioz
./diretorioa/sub-diretorioy

^antigo^novo

Executa o último comando substituindo o valor antigo pelo novo. Exemplo:

$ cat /etb/lsb-release
cat: /etb/lsb-release: No such file or directory
$ ^b^c
cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=8.10
DISTRIB_CODENAME=intrepid
DISTRIB_DESCRIPTION="Ubuntu 8.10"

!!

Reexecuta o último comando. Útil quando você esqueceu algo, como o sudo na frente do comando. Exemplo:

$ whoami
user
$ sudo !!
sudo whoami
root

Mais truques e dicas aqui.

Related posts

Lighttpd como proxy

Esses dias me deparei com a seguinte situação: Precisava implementar um serviço baseado em web. Esse serviço vai acumular bastante informações sobre a infra-estrutura da empresa e por isso precisa de autenticação para garantir que apenas as pessoas corretas tenham acesso a essas informações.

Mas por motivos que nem vale a pena citar, afinal não quero uma gastrite, o bagulho não aceita autenticação.

A forma que eu arranjei para resolver isso foi simples: A porta do serviço original é bloqueada via iptables e instalei o lighttpd para servir como proxy, já me aproveitando das features de autenticação dele.

Caso precise fazer algo parecido com isso um dia, segue abaixo como fiz:

Na sessão server.modules adicione:

            "mod_proxy",

E logo depois dessa sessão adicione:

auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/etc/lighttpd/.htpasswd"
auth.require = ( "/" =>
  (
    "method"  => "basic",
    "realm"   => "status",
    "require" => "valid-user"
  )
)

$HTTP["remoteip"] == "192.168.0.0/24" {
          proxy.server  = ( "" => (
          ( "host" => "127.0.0.1", "port" => 8080 )
           )
      )
}

Onde:

192.168.0.0/24 = Rede que poderá acessar a aplicação

“host” => “127.0.0.1″, “port” => 8080 = IP e porta originais da sua aplicação.

Related posts

Utilizando o VIM como IDE para o Bash

Como já devem saber eu sou da turminha do vi. Nada contra o Emacs, lógico, mas vi é vi.
O relacionamento com ele nunca começa bem. Lembro-me que a primeira vez que abri o vi, num SCO Unix, o único jeito que consegui sair do editor foi rebootando a máquina. Eu não tinha nem idéia de que bastava um ESC:q! para cumprir a tarefa. Mas passados 11 anos ou mais deste início traumático, posso dizer que me dou bem com o editor hoje em dia, utilizando-o inclusive para escrever posts no meu blog, como neste momento o faço.

Às vezes o que sentia falta era de alguma coisa para facilitar minha vida quando estava fazendo meus scripts. Alguns pedaços de código você usa de novo, de novo e de novo. E é um saco ficar redigitando.
Importar para dentro do arquivo atual (ESC:r /path/arquivo) ajuda, mas não resolve.

A solução

Pesquisando achei o sensacional BASH-IDE para vim. Resolveu todos os meus problemas, exceto a falta de competência como programador.
Utilizando o BASH-IDE podemos configurar um template para novos arquivos, de forma que sempre que abro um novo arquivo .sh no vim ele já adiciona o cabeçalho com informação sobre o autor, data, tag $id$ pro cvs e algumas variáveis e funções que eu coloco em todos os meus script.

O autor do BASH-IDE foi cuidadoso para facilitar a documentação de forma que vários atalhos já são auto-documentados.
Uma nova função criada utilizando o BASH-IDE automaticamente terá o seguinte aspecto:

function teste ()
{

}    # ----------  end of function teste  ----------

E ao chamar o atalho para documentação de função você recebe este template:

#===  FUNCTION  ================================================================
#          NAME:
#   DESCRIPTION:
#    PARAMETERS:
#       RETURNS:
#===============================================================================

Como tudo é baseado em arquivos texto, as customizações só dependem da sua boa vontade. E ainda vem com um uma cheat sheet em pdf pronta para imprimir e pendurar na sua baia! :)

Boa diversão

Related posts

Morre!

Uma funçãozinha muito útil do Perl é a “die”. Fica fácil gerar mensagens de erro e já abortar a execução numa tacada só.

Segue a versão primo-pobre para bash:

function die () { echo "$progname: $1"; exit ${2:-1}  ; }

Exemplos de uso:

[ ! -f /tmp/teste.txt ] && die "Arquivo não existe"

ou

[ "$A" -ne 0 ] && die "Nao encontrei o zero" 99

Related posts

Changes – Dicas

Comentei em outro post sobre changes e minha experiência com elas.

Apesar de ser um assunto complexo por natureza e ainda contar com o agravante de que cada empresa implementa de uma forma diferente, algumas dicas gerais podem ser úteis.

Planeje seus passos com antecedência

Pode parecer besteira falar isso, mas já vi muita gente (incluindo eu no início) simplesmente chegando na hora da change pra ver no que dava.

Tenha em algum lugar todos os comandos que precisará executar, de preferência separados em sessões do tipo “verificação pré-change”, “comandos para os hosts X e Y”, “comandos para o database W”, “script de checagem –full”.

Eu gosto de já deixar copiado o full path do comando e anotar pelo menos umas opções úteis.

Se a change afetará vários servidores ou sistemas que dependem uns dos outros não esqueça de colocar no seu checklist a ordem de stop/start de cada um deles.

Exagere. Minta se precisar.

Baseado na suas anotações quanto tempo você estima que a change vai levar? Multiplique por três e abra o seu change request com esse número.

Normalmente as changes passam por um comitê revisor, conforme comentei no post anterior. Dependendo do nível de babaquice da política da empresa e da criticidade do sistema, eles vão falar pra você fazer em menos tempo. Como você já multiplicou por três pode dar um desconto pra eles.

Algumas empresas mais inteligentes te dão a opção de abrir a change com uma janela de X tempo e execução de Y tempo. Isso significa que você pode abrir uma janela que será das 22:00 às 00:00 para executar uma mudança de 10 minutos. Se você tem essa possibilidade, use-a!

Continue reading ‘Changes – Dicas’

Related posts

#!/bin/bash

Falei no post anterior que to ficando nerd… Acreditem em mim…

Olha só que feature não documentada do Bash eu achei:

$ for ((i=0;i<=5;i++)); do echo Esse eh o $i; done
Esse eh o 0
Esse eh o 1
Esse eh o 2
Esse eh o 3
Esse eh o 4
Esse eh o 5

Sim. É isso mesmo. Sintaxe estilo C no nosso querido bash. Não sei qual a versão mínima pra funcionar isso, mas testei até na 3.0 e funciona.

Quer mais?

$ b=5 ; ((z = b<5?1:0)); echo $z
0
$ b=4 ; ((z = b<5?1:0)); echo $z
1

Sim! Operadores trinários!

Boa diversão. ;)

Related posts