Boa tarde pessoal!!!
Após um bom tempo sem postar nada (porque não tinha nada de interessante para postar), resolvi postar esse script que eu desenvolvi para incluir, excluir e listar endereços na blacklist e whitelist do Zimbra 8.8.11 (não testei em outras versões).
Depois de muuuuuuuuuito pesquisar, eu cheguei à forma correta de controlar as listas de spam do Zimbra. Na internet existem muitas informações desencontradas, ou que não funcionam mais, etc. Então abaixo está o script que eu fiz e que está funcionando perfeitamente no meu ambiente, espero que ajude:
#!/bin/bash
# Controle de blacklist e whitelist
# Desenvolvido por Rodrigo Garcia em 12/04/2019
# Contato rodrigogarcia.ti@gmail.com
DOMAIN="seudominio.com.br"
# Adiciona um único endereço ou domínio à blacklist
fn_AddDomainBlack(){
until [ $OP == "n" ]
do
clear
read -p "Digite o endereço (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESS
read -p "Confirma a adição do domínio $ADDRESS à blacklist (s/n)?" RESP
if [ $RESP == "s" ]
then
echo "Verificando se o endereço já existe..."
su - zimbra -c "zmprov gd $DOMAIN amavisBlacklistSender" | grep -w $ADDRESS > /dev/null
if [ $? != 0 ]
then
echo "Adicionando $ADDRESS à blacklist..."
su - zimbra -c "zmprov md $DOMAIN +amavisBlacklistSender $ADDRESS"
echo -e "Concluído!!!\n"
else
echo "Endereço já existe na blacklist!!!"
fi
fi
read -p "Deseja adicionar outro endereço (s/n)?" OP
done
unset OP
}
# Adiciona uma lista de endereços ou domínios à blacklist lendo o arquivo blacklist.conf
# Formato exemplo@exemplo.com ou exemplo.com
fn_ListaBlack(){
clear
while read LINE
do
su - zimbra -c "zmprov gd $DOMAIN amavisBlacklistSender" | grep -w $ADDRESS > /dev/null
if [ $? != 0 ]
then
echo "Adicionando $LINE à blacklist..."
su - zimbra -c "zmprov md $DOMAIN +amavisBlacklistSender $LINE"
else
echo "$ADDRESS já existe!!!"
fi
done < blacklist.conf
echo -e "Concluído!!!\n"
read -rsp $'Pressione enter para voltar...\n'
}
# Exclui um endereço ou domínio da blacklist
fn_DelDomainBlack(){
until [ $OP == "n" ]
do
clear
read -p "Digite o domínio (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESS
read -p "Confirma a exclusão do domínio $ADDRESS da blacklist (s/n)?" RESP
if [ $RESP == "s" ]
then
echo "Verificando se o endereço existe..."
su - zimbra -c "zmprov gd $DOMAIN amavisBlacklistSender" | grep -w $ADDRESS > /dev/null
if [ $? == 0 ]
then
echo "Excluíndo $ADDRESS da blacklist..."
su - zimbra -c "zmprov md $DOMAIN -amavisBlacklistSender $ADDRESS"
echo -e "Concluído!!!\n"
else
echo "Endereço não encontrado!!!"
fi
fi
read -p "Deseja remover outro endereço (s/n)?" OP
done
unset OP
}
# Consulta um endereço ou domínio na blacklist
fn_BuscaBlack(){
until [ $OP == "n" ]
do
clear
read -p "Digite o domínio para busca (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESSBL
echo "Buscando $ADDRESSBL ..."
su - zimbra -c "zmprov gd $DOMAIN amavisBlacklistSender" | grep -w $ADDRESSBL
if [ $? != 0 ]
then
echo -e "Endereço ou domínio não encontrado!!!\n"
fi
read -p "Deseja buscar outro endereço (s/n)?" OP
done
unset OP
}
# Faz cópia de segurança da blacklist e whitelist
fn_BkpList(){
clear
echo -e "Fazendo backup das listas...\n"
su - zimbra -c "zmprov gd $DOMAIN amavisBlacklistSender" | cut -d" " -f2 > blacklist.conf.bkp
echo -e "Backup da blacklist criado com sucesso em blacklist.conf.bkp\n"
su - zimbra -c "zmprov gd $DOMAIN amavisWhitelistSender" | cut -d" " -f2 > whitelist.conf.bkp
echo -e "Backup da whitelist criado com sucesso em whitelist.conf.bkp\n"
read -rsp $'Pressione enter para voltar...\n'
}
# Adiciona endereço ou domínio à whitelist
fn_AddDomainWhite(){
until [ $OP == "n" ]
do
clear
read -p "Digite o domínio (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESS
read -p "Confirma a adição do domínio $ADDRESS à whitelist (s/n)?" RESP
if [ $RESP == "s" ]
then
echo "Verificando se o endereço já existe..."
su - zimbra -c "zmprov gd $DOMAIN amavisWhitelistSender" | grep -w $ADDRESS > /dev/null
if [ $? != 0 ]
then
echo "Adicionando $ADDRESS à whitelist..."
su - zimbra -c "zmprov md $DOMAIN +amavisWhitelistSender $ADDRESS"
echo -e "Concluído!!!\n"
else
echo "Endereço já existe na whitelist!!!"
fi
read -p "Deseja adicionar outro endereço (s/n)?" OP
fi
done
unset OP
}
# Adiciona uma lista de endereços ou domínios à whitelist lendo o arquivo whitelist.conf
# Formato exemplo@exemplo.com ou exemplo.com
fn_ListaWhite(){
clear
while read LINE
do
su - zimbra -c "zmprov gd $DOMAIN amavisWhitelistSender" | grep -w $ADDRESS > /dev/null
if [ $? != 0 ]
then
echo "Adicionando $LINE à whitelist..."
su - zimbra -c "zmprov md $DOMAIN +amavisWhitelistSender $LINE"
else
echo "$ADDRESS já existe!!!"
fi
done < whitelist.conf
echo -e "Concluído!!!\n"
read -rsp $'Pressione enter para voltar...\n'
}
# Exclui um endereço ou domínio da whitelist
fn_DelDomainWhite(){
until [ $OP == "n" ]
do
clear
read -p "Digite o domínio (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESS
read -p "Confirma a exclusão do domínio $ADDRESS da whitelist(s/n)?" RESP
if [ $RESP == "s" ]
then
echo "Verificando se o endereço existe..."
su - zimbra -c "zmprov gd $DOMAIN amavisWhitelistSender" | grep -w $ADDRESS > /dev/null
if [ $? == 0 ]
then
echo "Excluíndo $ADDRESS da whitelist..."
su - zimbra -c "zmprov md $DOMAIN -amavisWhitelistSender $ADDRESS"
echo -e "Concluído!!!\n"
else
echo "$ADDRESS não encontrado!!!"
fi
fi
read -p "Deseja remover outro endereço (s/n)?" OP
done
unset OP
}
# Consulta endereço ou domínio na whitelist
fn_BuscaWhite(){
until [ $OP == "n" ]
do
clear
read -p "Digite o domínio para busca (Ex: exemplo@exemplo.com ou exemplo.com): " ADDRESSWL
su - zimbra -c "zmprov gd $DOMAIN amavisWhitelistSender" | grep $ADDRESSWL
echo "Buscando $ADDRESSWL ..."
if [ $? != 0 ]
then
echo -e "\nEndereço ou domínio não encontrado!!!\n"
fi
read -p "Deseja buscar outro endereço (s/n)?" OP
done
unset OP
}
# Adiciona um IP na Blacklist do Postfix
fn_BlackIp(){
until [ $OP == "n" ]
do
clear
read -p "Digite o IP a ser bloqueado: " BLACKIP
echo "Buscando IP $BLACKIP ..."
cat /opt/zimbra/conf/postfix_rbl_override | grep -w $BLACKIP > /dev/null
if [ $? != 0 ]
then
echo "Adicionando o IP $BLACKIP à Blacklist..."
echo "$BLACKIP REJECT" >> /opt/zimbra/conf/postfix_rbl_override
su - zimbra -c "postmap /opt/zimbra/conf/postfix_rbl_override"
echo "IP adicionado com sucesso à Blacklist!!!"
else
echo -e "\nEndereço IP já existe na Blacklist!!!"
fi
read -p "Deseja adicionar outro IP à Blacklist (s/n)?" OP
done
unset OP
}
# Executa o código
until [ $DO = "0" ]
do
clear
echo "############################################################################################"
echo "# Bem vindo, o que você deseja?"
echo "############################################################################################"
echo "1- Consultar um endereço ou domínio na blacklist"
echo "2- Adicionar um endereço ou domínio à blacklist"
echo "3- Adicionar uma lista de endereços e/ou domínios à blacklist (crie a lista blacklist.conf)"
echo "4- Remover um endereço ou domínio da blacklist"
echo "5- Consultar um endereço ou domínio na whitelist"
echo "6- Adicionar um endereço ou domínio à whitelist"
echo "7- Adicionar uma lista de endereços e/ou domínios à whitelist (crie a lista whitelist.conf)"
echo "8- Remover um endereço domínio da whitelist"
echo "9- Fazer backup das listas (whitelist e blacklist)"
echo "10- Adicionar um IP à Blacklist do Postfix"
echo "0- Sair"
read -p "Escolha uma ação: " DO
case $DO in
"1")
fn_BuscaBlack
;;
"2")
fn_AddDomainBlack
;;
"3")
fn_ListaBlack
;;
"4")
fn_DelDomainBlack
;;
"5")
fn_BuscaWhite
;;
"6")
fn_AddDomainWhite
;;
"7")
fn_ListaWhite
;;
"8")
fn_DelDomainWhite
;;
"9")
fn_BkpList
;;
"10")
fn_BlackIp
;;
"0")
clear
exit
;;
esac
done
Até a próxima!!!
Rodrigo Garcia
segunda-feira, 29 de abril de 2019
segunda-feira, 1 de fevereiro de 2016
Problema no Squid
Olá a todos,
Esses dias aconteceu um problema com o proxy, ele simplesmente abortava (SIGABRT) e reiniciava alguns segundos depois, porém várias vezes por hora. A primeira coisa que fiz foi olhar o syslog, o qual mostrava que a aplicação saía com sinal 6 (SIGABRT):
"Squid Parent: (squid-1) process 32031 exited due to signal 6 with status 0"
Olhando no cache.log, não tinha muitas informações, apenas uma linha:
"kid1| assertion failed: String.cc:201: "len_ + len < 65536""
Com esses dados, fui para o Google buscar alguma informação, e o que eu descobri foi que o Squid tem um limite de tamanho de string que não pode ultrapassar 64 KB ou 65535 bytes. Isso foi tudo o que eu consegui. Acontece que não se tem informação de onde ele aceita essa string, se na url dos endereços, se na autenticação, se no corpo da página, enfim, e então eu tentei várias ações diferentes e monitorei por alguns dias sem sucesso algum, até que eu resolvi colocar o Squid para debugar e coloquei a opção "debug 9,ALL" no squid.conf e passei a monitorar o syslog em conjunto com o cache.log, e no momento em que houve um crash, pegando o horário exato no syslog, eu fui ao cache.log buscar alguma informação a respeito.
Notei (depois que eu ativei o debug) que em várias ocasiões onde o programa fechava, aconteciam imadiatamente antes acessos a um mesmo site específico, e o log mostrava especificamente um arquivo de folha de estilos (.css), e então logo depois mostrava a linha mencionada acima. Pois bem, fui verificar o arquivo css em questão e fiquei impressionado com o tamanho das strings utilizadas nele e na hora já consegui entender que esse arquivo era o problema. Simplesmente mudei a regra de acesso a esse site (alelo.com.br), colocando para sair sem autenticação, e pronto!!! Nunca mais o Squid foi abortado...
Espero ter sido últil!!! Até a próxima!!!
P.S: E você? Precisa de um proxy robusto e poderoso como o Squid em sua empresa mas não tem idéia de como configurar? Entre em contato, tenho certeza de que encontraremos a melhor configuração para que você tenha um proxy de alta qualidade sem gastar nada com licenças de softwares proprietários, e ainda poderá contar com suporte remoto ou presencial (dependendo da localidade).
Esses dias aconteceu um problema com o proxy, ele simplesmente abortava (SIGABRT) e reiniciava alguns segundos depois, porém várias vezes por hora. A primeira coisa que fiz foi olhar o syslog, o qual mostrava que a aplicação saía com sinal 6 (SIGABRT):
"Squid Parent: (squid-1) process 32031 exited due to signal 6 with status 0"
Olhando no cache.log, não tinha muitas informações, apenas uma linha:
"kid1| assertion failed: String.cc:201: "len_ + len < 65536""
Com esses dados, fui para o Google buscar alguma informação, e o que eu descobri foi que o Squid tem um limite de tamanho de string que não pode ultrapassar 64 KB ou 65535 bytes. Isso foi tudo o que eu consegui. Acontece que não se tem informação de onde ele aceita essa string, se na url dos endereços, se na autenticação, se no corpo da página, enfim, e então eu tentei várias ações diferentes e monitorei por alguns dias sem sucesso algum, até que eu resolvi colocar o Squid para debugar e coloquei a opção "debug 9,ALL" no squid.conf e passei a monitorar o syslog em conjunto com o cache.log, e no momento em que houve um crash, pegando o horário exato no syslog, eu fui ao cache.log buscar alguma informação a respeito.
Notei (depois que eu ativei o debug) que em várias ocasiões onde o programa fechava, aconteciam imadiatamente antes acessos a um mesmo site específico, e o log mostrava especificamente um arquivo de folha de estilos (.css), e então logo depois mostrava a linha mencionada acima. Pois bem, fui verificar o arquivo css em questão e fiquei impressionado com o tamanho das strings utilizadas nele e na hora já consegui entender que esse arquivo era o problema. Simplesmente mudei a regra de acesso a esse site (alelo.com.br), colocando para sair sem autenticação, e pronto!!! Nunca mais o Squid foi abortado...
Espero ter sido últil!!! Até a próxima!!!
P.S: E você? Precisa de um proxy robusto e poderoso como o Squid em sua empresa mas não tem idéia de como configurar? Entre em contato, tenho certeza de que encontraremos a melhor configuração para que você tenha um proxy de alta qualidade sem gastar nada com licenças de softwares proprietários, e ainda poderá contar com suporte remoto ou presencial (dependendo da localidade).
quinta-feira, 5 de novembro de 2015
Removendo Kernels No Ubuntu
Boa tarde pessoal!!!
Criei um script para remover kernels no Ubuntu de forma simplificada. Sei que já existem scripts para isso mas gosto de criar os meus e compartilhar com a comunidade. É necessário que o sistema tenha o aptitude instalado, pois ele trata melhor as dependências do que o apt. O script é bem simples, e basicamente lista os kernels instalados no sistema e te dá a escolha de removê-los:
Espero ter sido útil e até a próxima!!!
Criei um script para remover kernels no Ubuntu de forma simplificada. Sei que já existem scripts para isso mas gosto de criar os meus e compartilhar com a comunidade. É necessário que o sistema tenha o aptitude instalado, pois ele trata melhor as dependências do que o apt. O script é bem simples, e basicamente lista os kernels instalados no sistema e te dá a escolha de removê-los:
#!/bin/bash # Desenvolvido por Rodrigo Garcia em 05/11/2015 # Descobrir o total de kernels instalados no sistema NUM=$(dpkg -l | grep "ii linux-image-" | grep -v "image-generic" | grep -v "linux-image-$(uname -r)" | grep -v "extra" | awk '{ print $2 }' | wc -l) # Contador X=1 while [ $X -le $NUM ] do # Atribui o nome dos kernels um a um dentro de um array e lista KERNEL[$X]="$(dpkg -l | grep "ii linux-image-" | grep -v "image-generic" | grep -v "linux-image-$(uname -r)" | grep -v "extra" | cat -n | sed -n "$(echo $X)p" | awk '{print $3}')" echo "$X) ${KERNEL[$X]}" X=$(expr $X + 1) done # Escolha e remoção do kernel desejado echo -e "Escolha o kernel a ser removido: " read Y echo -e "Deseja realmente remover o kernel ${KERNEL[$Y]}?(s/n): " read ANSWER case $ANSWER in s) aptitude remove ${KERNEL[$Y]} ;; n) exit ;; *) echo "Opção Inválida!!!" exit ;; esac
Espero ter sido útil e até a próxima!!!
sexta-feira, 28 de agosto de 2015
Certificado Squid
Olá a todos,
Essa é uma pequena postagem apenas para ajudar aqueles que não conseguem encontrar os comandos corretos para criar um certificado para o Squid3 quando a opção de ssl-bumping (proxy https) está habilitada. Essa opção permite que sites em https também sejam filtrados, agindo o Squid como man-in-the-middle entre o cliente e o servidor, e por isso é necessário um certificado autoassinado. O Squid descriptografa a conexão, analisa o tráfego e decide se bloqueia ou não (ou alguma outra ação).
Para ativar a opção é necessário que o Squid3 seja compilado com as opções --enable-ssl e --enable--ssl-crtd. E então colocar no squid.conf a linha:
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB key=/etc/squid3/ssl_cert/mycert.key cert=/etc/squid3/ssl_cert/mycert.pem
Esta parte eu coloquei no final do squid.conf:
always_direct allow all
ssl_bump none localhost
acl bypass_ssl dstdomain -i "/etc/squid3/acls/bypass_ssl"
acl reverse dstdomain -i "/etc/squid3/acls/reverse"
ssl_bump none bypass_ssl
ssl_bump client-first reverse
ssl_bump server-first "nomes das acls"
ssl_bump none all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
sslcrtd_program /usr/lib/squid3/ssl_crtd -s /usr/lib/squid3/ssl_db -M 4MB
sslcrtd_children 5
Não vou explicar cada linha porque o foco aqui é a criação do certificado, então vamos a ele. Os seguintes comandos devem ser executados no servidor onde está rodando o squid:
openssl genrsa -des3 -out mycert.key 1024
openssl req -new -key mycert.key -out mycert.csr
cp mycert.key mycert.key.old
openssl rsa -in mycert.key.old -out mycert.key
openssl x509 -req -days 365 -in mycert.csr -signkey mycert.key -out mycert.crt
cat mycert.key mycert.crt > mycert.pem
O arquivo "mycert.crt" deve ser colocado nos navegadores para permitir a filtragem https, do contrário nenhum site que utilize https funcionará.
Espero ter ajudado e até a próxima!!!
Essa é uma pequena postagem apenas para ajudar aqueles que não conseguem encontrar os comandos corretos para criar um certificado para o Squid3 quando a opção de ssl-bumping (proxy https) está habilitada. Essa opção permite que sites em https também sejam filtrados, agindo o Squid como man-in-the-middle entre o cliente e o servidor, e por isso é necessário um certificado autoassinado. O Squid descriptografa a conexão, analisa o tráfego e decide se bloqueia ou não (ou alguma outra ação).
Para ativar a opção é necessário que o Squid3 seja compilado com as opções --enable-ssl e --enable--ssl-crtd. E então colocar no squid.conf a linha:
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB key=/etc/squid3/ssl_cert/mycert.key cert=/etc/squid3/ssl_cert/mycert.pem
Esta parte eu coloquei no final do squid.conf:
always_direct allow all
ssl_bump none localhost
acl bypass_ssl dstdomain -i "/etc/squid3/acls/bypass_ssl"
acl reverse dstdomain -i "/etc/squid3/acls/reverse"
ssl_bump none bypass_ssl
ssl_bump client-first reverse
ssl_bump server-first "nomes das acls"
ssl_bump none all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
sslcrtd_program /usr/lib/squid3/ssl_crtd -s /usr/lib/squid3/ssl_db -M 4MB
sslcrtd_children 5
Não vou explicar cada linha porque o foco aqui é a criação do certificado, então vamos a ele. Os seguintes comandos devem ser executados no servidor onde está rodando o squid:
openssl genrsa -des3 -out mycert.key 1024
openssl req -new -key mycert.key -out mycert.csr
cp mycert.key mycert.key.old
openssl rsa -in mycert.key.old -out mycert.key
openssl x509 -req -days 365 -in mycert.csr -signkey mycert.key -out mycert.crt
cat mycert.key mycert.crt > mycert.pem
O arquivo "mycert.crt" deve ser colocado nos navegadores para permitir a filtragem https, do contrário nenhum site que utilize https funcionará.
Espero ter ajudado e até a próxima!!!
quinta-feira, 16 de julho de 2015
Mudar Autenticação Squid Para Alguns Clientes
Olá a todos,
Onde eu trabalho implantei o Squid3 com autenticação no AD, delay pools, proxy https, etc. Temos alguns logins genéricos, que são usados em máquinas compartilhadas que também estão no AD. A idéia era bloquear o acesso à Internet para esses logins genéricos para que a pessoa quando abrisse o navegador inserisse o login e senha individuais. O bloqueio funcionou, e quando abria o navegador a janela de autenticação aparecia, mas não conseguia autenticar.
Depois de muito quebrar a cabeça, cheguei à conclusão de que o navegador não conseguia autenticar porque ele simplesmente não entendia que deveria usar a autenticação básica, já que a máquina está no domínio e já tem um usuário do domínio logado nela. Foi aí que eu comecei a fuçar na Internet atrás de uma solução, e quando estava quase desistindo, consegui encontrar algo sobre http-violations.
Essa opção de compilação, habilita o Squid a violar o cabeçalho http e mudar alguns parâmetros nele. Vi algumas pessoas mudando o tipo de autenticação para o Java, pois ele também não autentica usando NTLM, testei com o meu cenário e funcionou! A dica é simples, depois do Squid compilado com a opção --enable-http-violations, basta inserir no squid.conf:
acl maquinas-compartilhadas srcdomain -i "/etc/squid3/acls/maquinas_compartilhadas"
reply_header_access Proxy-Authenticate deny maquinas-compartilhadas
reply_header_replace Proxy-Authenticate Basic realm="DOMINIO.COM.BR"
http_access deny rede_local logins_genericos
Com essas opções, o tipo de autenticação nas máquinas informadas (por FQDN) na ACL "maquinas-compartilhadas" vai ser mudado para o tipo "Basic", e o navegador vai conseguir autenticar tranquilamente quando a janela de autenticação for aberta. Dica simples que pode salvar bastante gente.
Até a próxima!!!
Onde eu trabalho implantei o Squid3 com autenticação no AD, delay pools, proxy https, etc. Temos alguns logins genéricos, que são usados em máquinas compartilhadas que também estão no AD. A idéia era bloquear o acesso à Internet para esses logins genéricos para que a pessoa quando abrisse o navegador inserisse o login e senha individuais. O bloqueio funcionou, e quando abria o navegador a janela de autenticação aparecia, mas não conseguia autenticar.
Depois de muito quebrar a cabeça, cheguei à conclusão de que o navegador não conseguia autenticar porque ele simplesmente não entendia que deveria usar a autenticação básica, já que a máquina está no domínio e já tem um usuário do domínio logado nela. Foi aí que eu comecei a fuçar na Internet atrás de uma solução, e quando estava quase desistindo, consegui encontrar algo sobre http-violations.
Essa opção de compilação, habilita o Squid a violar o cabeçalho http e mudar alguns parâmetros nele. Vi algumas pessoas mudando o tipo de autenticação para o Java, pois ele também não autentica usando NTLM, testei com o meu cenário e funcionou! A dica é simples, depois do Squid compilado com a opção --enable-http-violations, basta inserir no squid.conf:
acl maquinas-compartilhadas srcdomain -i "/etc/squid3/acls/maquinas_compartilhadas"
reply_header_access Proxy-Authenticate deny maquinas-compartilhadas
reply_header_replace Proxy-Authenticate Basic realm="DOMINIO.COM.BR"
http_access deny rede_local logins_genericos
Com essas opções, o tipo de autenticação nas máquinas informadas (por FQDN) na ACL "maquinas-compartilhadas" vai ser mudado para o tipo "Basic", e o navegador vai conseguir autenticar tranquilamente quando a janela de autenticação for aberta. Dica simples que pode salvar bastante gente.
Até a próxima!!!
quinta-feira, 21 de maio de 2015
Utilizando a Class 4 do Squid3 Integrado ao AD
Olá a todos,
Nesses dias eu recebi a tarefa de configurar um proxy (não, esse não é um tutorial de como integrar o Squid ao AD) que entre as funcionalidades mais comuns (bloqueio de sites por domínio, palavra-chave, que fosse integrado ao AD, etc), tivesse controle de banda por login de usuário. Dentre as várias opções disponíveis, optei pelo delay_pools do Squid, e achei bastante documentação sobre sua implementação com exceção de uma coisa: A limitação por login foi implementada a partir do Squid3 (class 4) e sobre isso não tem muita documentação, aliás quase nada, apenas syntaxe de parâmetros no geral.
Depois de finalmente entender a class 4, tive dificuldade de integrar à solução que eu havia configurado. Tudo o que o site do Squid informa sobre essa classe é:
class 4 Tudo como a classe 3 de delay_pool, com um
limite adicional baseado em usuário. Isto só
tem efeito se o username foi estabelecido
previamente - forçando uma autenticação em
suas regras de http_access.
http://www.squid-cache.org/Doc/config/delay_class/
E também sobre os delay_parameters:
Para um delay_pool class 4:
delay_class pool 4
delay_parameters pool agregado rede individual usuário
http://www.squid-cache.org/Doc/config/delay_parameters/
E por mais que eu procurasse, tudo o que eu encontrava era isso. Estava quase desistindo e fazendo as limitações por IP (class 3) quando me ocorreu uma idéia: Conforme a documentação do site do Squid, a classe 4 funciona com usuários previamente autenticados nas acls, mas eu uso usuários do AD, então eu criei um http_access permitindo acesso aos grupos das velocidades e funcionou perfeitamente!!! Então a linha da acl ficou assim:
external_acl_type ad_Group ttl=60 %LOGIN /usr/lib/squid3/wbinfo_group.pl # Helper que busca grupos do AD (em versões mais recentes do Squid3 o nome do helper é ext_wbinfo_group_acl
...
acl acesso_100KB external grupo Internet-100KB
E então nas regras http_access eu fiz:
http_access allow rede_local acesso_100KB acesso_padrao !sites_proibidos !palavras_proibidas !libera_skype
Isso significa que o acesso será liberado para máquinas da rede local, que tenham usuários no grupo acesso_100KB que também estejam no grupo acesso_padrao, aos sites que não estejam nas listas sites_proibidos, palavras_proibidas e acesso_skype. Você pode criar uma linha dessa para cada limite que você quiser, daí pessoas que estão no grupo padrão podem ter várias opções de velocidades. Depois de fazer isso, então eu criei o delay_pool:
delay_pool 1 # Quantidade de pools
delay_class 1 4 # Classe do pool nº 1
delay_access 1 allow acesso_100KB # Libera acesso ao grupo acesso_100KB que já foi previamente autenticado
delay_access 1 deny # Nega acesso ao pool para todos os outros
delay_parameters 1 1 -1/-1 -1/1 102400/102400 102400/102400 # Os parâmetros do pool 1 informam que não há limite da banda total, não há limite da banda por rede, limite individual de 1 mbps e limite por username de 1 mbps
Dependendo da sua banda, você deve alterar esses parâmetros. Para mim está funcionando perfeitamente da forma que está, as páginas estão sendo bloqueadas por domínio e por palavra e a banda sendo limitada de acordo com o usuário logado. Pronto, agora na Internet já tem uma ajuda para quem quiser utilizar o delay_class 4 integrado ao AD. Espero ter ajudado, e até a próxima!!!
Nesses dias eu recebi a tarefa de configurar um proxy (não, esse não é um tutorial de como integrar o Squid ao AD) que entre as funcionalidades mais comuns (bloqueio de sites por domínio, palavra-chave, que fosse integrado ao AD, etc), tivesse controle de banda por login de usuário. Dentre as várias opções disponíveis, optei pelo delay_pools do Squid, e achei bastante documentação sobre sua implementação com exceção de uma coisa: A limitação por login foi implementada a partir do Squid3 (class 4) e sobre isso não tem muita documentação, aliás quase nada, apenas syntaxe de parâmetros no geral.
Depois de finalmente entender a class 4, tive dificuldade de integrar à solução que eu havia configurado. Tudo o que o site do Squid informa sobre essa classe é:
class 4 Tudo como a classe 3 de delay_pool, com um
limite adicional baseado em usuário. Isto só
tem efeito se o username foi estabelecido
previamente - forçando uma autenticação em
suas regras de http_access.
http://www.squid-cache.org/Doc/config/delay_class/
E também sobre os delay_parameters:
Para um delay_pool class 4:
delay_class pool 4
delay_parameters pool agregado rede individual usuário
http://www.squid-cache.org/Doc/config/delay_parameters/
E por mais que eu procurasse, tudo o que eu encontrava era isso. Estava quase desistindo e fazendo as limitações por IP (class 3) quando me ocorreu uma idéia: Conforme a documentação do site do Squid, a classe 4 funciona com usuários previamente autenticados nas acls, mas eu uso usuários do AD, então eu criei um http_access permitindo acesso aos grupos das velocidades e funcionou perfeitamente!!! Então a linha da acl ficou assim:
external_acl_type ad_Group ttl=60 %LOGIN /usr/lib/squid3/wbinfo_group.pl # Helper que busca grupos do AD (em versões mais recentes do Squid3 o nome do helper é ext_wbinfo_group_acl
...
acl acesso_100KB external grupo Internet-100KB
E então nas regras http_access eu fiz:
http_access allow rede_local acesso_100KB acesso_padrao !sites_proibidos !palavras_proibidas !libera_skype
Isso significa que o acesso será liberado para máquinas da rede local, que tenham usuários no grupo acesso_100KB que também estejam no grupo acesso_padrao, aos sites que não estejam nas listas sites_proibidos, palavras_proibidas e acesso_skype. Você pode criar uma linha dessa para cada limite que você quiser, daí pessoas que estão no grupo padrão podem ter várias opções de velocidades. Depois de fazer isso, então eu criei o delay_pool:
delay_pool 1 # Quantidade de pools
delay_class 1 4 # Classe do pool nº 1
delay_access 1 allow acesso_100KB # Libera acesso ao grupo acesso_100KB que já foi previamente autenticado
delay_access 1 deny # Nega acesso ao pool para todos os outros
delay_parameters 1 1 -1/-1 -1/1 102400/102400 102400/102400 # Os parâmetros do pool 1 informam que não há limite da banda total, não há limite da banda por rede, limite individual de 1 mbps e limite por username de 1 mbps
Dependendo da sua banda, você deve alterar esses parâmetros. Para mim está funcionando perfeitamente da forma que está, as páginas estão sendo bloqueadas por domínio e por palavra e a banda sendo limitada de acordo com o usuário logado. Pronto, agora na Internet já tem uma ajuda para quem quiser utilizar o delay_class 4 integrado ao AD. Espero ter ajudado, e até a próxima!!!
segunda-feira, 24 de fevereiro de 2014
Removendo discos de storage no Red Hat
Olá a todos!!!
No ano passado eu postei um tutorial sobre como adicionar um vdisk de storage HP num servidor Red Hat. Esse tutorial ensina como remover a referência de um disco que já foi removido mas que impede a criação de um pv em um novo disco. Quando tentamos criar um pv em um vdisk novo e recebemos a seguinte mensagem:
"Can't open /dev/sdb exclusively. Mounted filesystem?"
Isso significa que o disco removido era reconhecido como /dev/sdb e ainda existem referências a ele no multipath. Então precisamos descobrir quais são essas referências e removê-las:
cat /proc/partitions
8 0 143247360 sda
8 1 104391 sda1
8 2 143139150 sda2
8 16 292444160 sdb
253 0 20840448 dm-0
253 1 5111808 dm-1
253 2 5111808 dm-2
253 3 5111808 dm-3
253 4 4096000 dm-4
253 5 292444160 dm-5
Agora que descobrimos o major e minor numbers, vamos descobrir qual o alias do multipath eles estão associados:
dmsetup status
RootVG-swap: 0 8192000 linear
RootVG-root: 0 10223616 linear
RootVG-root: 10223616 31457280 linear
mpath8: 0 584888320 multipath 2 0 0 0 1 1 A 0 1 0 8:16 A 0
RootVG-tmp: 0 10223616 linear
RootVG-usr: 0 10223616 linear
RootVG-var: 0 10223616 linear
Pronto, agora descobrimos que o alias utilizado pelo disco removido era o mpath8 e agora podemos removê-lo efetivamente:
dmsetup remove mpath8
O próximo passo é apagá-lo do sistema:
echo 1 > /sys/block/sdb/device/delete
Em seguida devemos apagar o disco do /dev:
cd /dev/disk/by-id
ls -l
scsi-36001438005dff2f10000400000c90000 -> ../../sdb
rm -rf scsi-36001438005dff2f10000400000c90000
cd /dev
rm -rf sdb
E pronto! Agora basta reescanear os novos discos:
hp_rescan -a
E adicioná-lo normalmente. Espero ter ajudado.
Até a próxima!!!
Fonte: www.linuxquestions.org
No ano passado eu postei um tutorial sobre como adicionar um vdisk de storage HP num servidor Red Hat. Esse tutorial ensina como remover a referência de um disco que já foi removido mas que impede a criação de um pv em um novo disco. Quando tentamos criar um pv em um vdisk novo e recebemos a seguinte mensagem:
"Can't open /dev/sdb exclusively. Mounted filesystem?"
Isso significa que o disco removido era reconhecido como /dev/sdb e ainda existem referências a ele no multipath. Então precisamos descobrir quais são essas referências e removê-las:
cat /proc/partitions
8 0 143247360 sda
8 1 104391 sda1
8 2 143139150 sda2
8 16 292444160 sdb
253 0 20840448 dm-0
253 1 5111808 dm-1
253 2 5111808 dm-2
253 3 5111808 dm-3
253 4 4096000 dm-4
253 5 292444160 dm-5
Agora que descobrimos o major e minor numbers, vamos descobrir qual o alias do multipath eles estão associados:
dmsetup status
RootVG-swap: 0 8192000 linear
RootVG-root: 0 10223616 linear
RootVG-root: 10223616 31457280 linear
mpath8: 0 584888320 multipath 2 0 0 0 1 1 A 0 1 0 8:16 A 0
RootVG-tmp: 0 10223616 linear
RootVG-usr: 0 10223616 linear
RootVG-var: 0 10223616 linear
Pronto, agora descobrimos que o alias utilizado pelo disco removido era o mpath8 e agora podemos removê-lo efetivamente:
dmsetup remove mpath8
O próximo passo é apagá-lo do sistema:
echo 1 > /sys/block/sdb/device/delete
Em seguida devemos apagar o disco do /dev:
cd /dev/disk/by-id
ls -l
scsi-36001438005dff2f10000400000c90000 -> ../../sdb
rm -rf scsi-36001438005dff2f10000400000c90000
cd /dev
rm -rf sdb
E pronto! Agora basta reescanear os novos discos:
hp_rescan -a
E adicioná-lo normalmente. Espero ter ajudado.
Até a próxima!!!
Fonte: www.linuxquestions.org
VDisk Não Aparece no HP-UX
Olá a todos!!!
Recentemente eu tive problemas ao adicionar um vdisk em um HP-UX 11.31. O disco era apresentado, porém não tinha ioscan que o fizesse aparecer. O problema acontece quando a mesma lunpath do disco já tinha sido utilizada por outro disco que foi removido. Depois de muito pesquisar, recebi ajuda de um especialista que me ensinou o seguinte:
Primeiro precisamos saber quais são as instâncias da lun que estão apresentando o problema, e para isso devemos checar o syslog:
tail -20 /var/adm/syslog/syslog.log
"vmunix: Evpd inquiry page 83h/80h failed or the current page 83h/80h data do not match the previous known page 83h/80h data on LUN id 0x0 probed beneath the target path (class = tgtpath, instance = 5) The lun path is (class = lunpath, instance 45).Run 'scsimgr replace_wwid' command to validate the change"
Conseguimos ver que a instância é a de número 45. Podem aparecer várias com erro e o procedimento deve ser repetido para cada uma delas. Após descobrirmos a instância, vamos confirmar se corresponde realmente ao disco que queremos adicionar:
scsimgr get_info -C lunpath -I 45
STATUS INFORMATION FOR LUN PATH : lunpath45
Generic Status Information
SCSI services internal state = STANDBY
Open close state = STANDBY
Protocol = fibre_channel
EVPD page 0x83 description code = 1
EVPD page 0x83 description association = 0
EVPD page 0x83 description type = 3
World Wide Identifier (WWID) = 0x6001438005dff29400004000015a0000
Total number of Outstanding I/Os = 0
Maximum I/O timeout in seconds = 30
Maximum I/O size allowed = 2097152
Maximum number of active I/Os allowed = 8
Maximum queue depth = 8
Queue full delay count = 0
Asymmetric state = ACTIVE/NON-OPTIMIZED
Device preferred path = No
Relative target port identifier = 1
Target port group identifier = 1
As informações acima já correspondem ao problema resolvido, mas a saída será bem semelhante. O que interessa aqui é o campo:
World Wide Identifier (WWID) = 0x6001438005dff29400004000015a0000
É nesse campo que contém o ID do disco que queremos adicionar. Se o ID corresponder, então vamos executar o próximo passo:
scsimgr -f replace_wwid -C lunpath -I 45
Esse comando vai dar um replace do disco na lunpath que já havia sido utilizada, informando que esse path agora corresponde ao novo disco. A saída do comando demora de 5 a 10 segundos. Após a saída confirmando que a mudança foi bem sucedida, os seguintes comandos devem ser executados:
ioscan -fn
insf -e
E pronto! O novo disco estará disponível para adicioná-lo a um VG, criar outro VG, etc. Espero ter ajudado.
Até a próxima!!!
Recentemente eu tive problemas ao adicionar um vdisk em um HP-UX 11.31. O disco era apresentado, porém não tinha ioscan que o fizesse aparecer. O problema acontece quando a mesma lunpath do disco já tinha sido utilizada por outro disco que foi removido. Depois de muito pesquisar, recebi ajuda de um especialista que me ensinou o seguinte:
Primeiro precisamos saber quais são as instâncias da lun que estão apresentando o problema, e para isso devemos checar o syslog:
tail -20 /var/adm/syslog/syslog.log
"vmunix: Evpd inquiry page 83h/80h failed or the current page 83h/80h data do not match the previous known page 83h/80h data on LUN id 0x0 probed beneath the target path (class = tgtpath, instance = 5) The lun path is (class = lunpath, instance 45).Run 'scsimgr replace_wwid' command to validate the change"
Conseguimos ver que a instância é a de número 45. Podem aparecer várias com erro e o procedimento deve ser repetido para cada uma delas. Após descobrirmos a instância, vamos confirmar se corresponde realmente ao disco que queremos adicionar:
scsimgr get_info -C lunpath -I 45
STATUS INFORMATION FOR LUN PATH : lunpath45
Generic Status Information
SCSI services internal state = STANDBY
Open close state = STANDBY
Protocol = fibre_channel
EVPD page 0x83 description code = 1
EVPD page 0x83 description association = 0
EVPD page 0x83 description type = 3
World Wide Identifier (WWID) = 0x6001438005dff29400004000015a0000
Total number of Outstanding I/Os = 0
Maximum I/O timeout in seconds = 30
Maximum I/O size allowed = 2097152
Maximum number of active I/Os allowed = 8
Maximum queue depth = 8
Queue full delay count = 0
Asymmetric state = ACTIVE/NON-OPTIMIZED
Device preferred path = No
Relative target port identifier = 1
Target port group identifier = 1
As informações acima já correspondem ao problema resolvido, mas a saída será bem semelhante. O que interessa aqui é o campo:
World Wide Identifier (WWID) = 0x6001438005dff29400004000015a0000
É nesse campo que contém o ID do disco que queremos adicionar. Se o ID corresponder, então vamos executar o próximo passo:
scsimgr -f replace_wwid -C lunpath -I 45
Esse comando vai dar um replace do disco na lunpath que já havia sido utilizada, informando que esse path agora corresponde ao novo disco. A saída do comando demora de 5 a 10 segundos. Após a saída confirmando que a mudança foi bem sucedida, os seguintes comandos devem ser executados:
ioscan -fn
insf -e
E pronto! O novo disco estará disponível para adicioná-lo a um VG, criar outro VG, etc. Espero ter ajudado.
Até a próxima!!!
quarta-feira, 17 de julho de 2013
Hardening
Muitos administradores (muitos mesmo) ao instalarem um servidor acabam esquecendo (ou são pressionados a terminarem depressa) de uma parte importante do sistema operacional, que é a segurança. Nesse artigo eu pretendo mostrar algumas dicas, técnicas e ferramentas muito legais que visam proteger um firewall. Juntamente com o script de firewall corporativo que foi postado nesse blog, trarão muito mais segurança e minimizarão os riscos de ataques diretamente em seu firewall de borda.
A primeira dica é já para a instalação do SO, mais precisamente na parte de particionamento. Para facilitar a manipulação de partições eu costumo utilizar LVM, pois permite redimensionamentos posteriores, extends de disco, etc. A dica aqui é criar partições separadas para pontos de montagem estratégicos do sistema operacional. Dessa forma podemos definir opções de montagem para cada uma separadamente. Como exemplo, podemos definir que o /home, /tmp e /var não terão permissão de execução, isso quer dizer que nenhum programa malicioso (rootkit, backdoor, exploit) será executado nesses pontos de montagem (comuns nesses casos).
Um esquema bem legal de particionamento seria separar as partições da seguinte forma:
/
/boot
/home
/opt
/tmp
/usr
/var
/var/log
O /home em um firewall não deve conter arquivos pessoais, muito menos executáveis e por isso tiraremos a permissão de execução de binários nessa partição. O mesmo acontece em /tmp e em /var (lembrando que deveremos dar permissão de execução nessas duas partições para utilizarmos ferramentas como apt ou aptitude, mas veremos um script para isso mais adiante). O /opt em geral contém os pacotes que são baixados e instalados pelo próprio usuário, e é bom separarmos a partição para limitarmos o espaço que teremos para esse fim, além de retirarmos a permissão de execução de binários com SUID BIT. A partição /usr conterá os binários do sistema e sua separação aqui é mais para limitar o tamanho mesmo. A partição /var/log também não terá permissão de execução e será limitada para que os logs não venham ocasionalmente a preencher o espaço disponível em disco para o / que dispensa explicações. O /boot é necessário para armazenar o kernel e as informações do GRUB, etc. Essa não faz parte do LVM, é uma partição física formatada em EXT2.
Agora que já temos nosso esquema de particionamento, instalamos o SO e ao término, faremos as atualizações e configurações necessárias. Depois disso vamos modificar as permissões das partições editando o arquivo /etc/fstab (faça backup dele antes). Vamos tomar por exemplo a linha da partição /var:
/dev/mapper/servidor-var /var ext4 defaults 0 2
Essa é a linha original do arquivo, com as permissões padrão do sistema. Vamos alterá-la para que fique assim:
/dev/mapper/servidor-var /var ext4 defaults,nosuid,noexec 0 2
Dessa forma, tiramos a permissão de execução na partição e também a permissão de execução de arquivos com SUID BIT ligado. Devemos fazer isso nas partições /home, /tmp, /var, /var/log. Na partição /opt devemos tirar a permissão de execução de SUID BIT (opção "nosuid"). Ao terminar (faça em todas as partições descritas acima), reinicie o sistema para que as alterações tenham efeito ou remonte cada partição:
"mount -o remount /var"
Depois disso, execute um mount para conferir se as alterações foram aplicadas:
"mount"
Para que possamos fazer instalação de pacotes utilizando apt ou aptitude, devemos sempre remontar as partições /tmp e /var com permissão de execução e retirar as permissões após a instalação. Para facilitar, podemos fazer um script simples:
#!/bin/bash
case $1 in
start)
mount -o remount,rw,noexec /var
mount -o remount,rw,noexec /tmp
echo "Partições SEM permissão de execução"
;;
stop)
mount -o remount,rw,exec /var
mount -o remount,rw,exec /tmp
echo "Partições COM permissão de execução"
;;
*)
echo "Modo de uso $0 {start|stop}"
exit 0
;;
esac
exit 1
Crie a pasta /root/admin_scripts e coloque esse script lá. Dê permissão de execução chmod +x script.sh. Sempre que ele for executado com a opção "stop" ele dará permissão de execução nas partições, e com a opção "start" ele removerá a permissão de execução das partições.
Nosso próximo passo é remover a permissão de SUID BIT dos binários que não precisam dessa permissão. O que é SUID BIT? É a permissão de execução do dono do arquivo. Isso é, se o dono do arquivo for o root, ele vai ser executado como root e isso pode ser explorado para ganho de acesso administrativo ao sistema operacional. Apenas alguns arquivos tem a real necessidade de serem executados com SUID BIT, e o script abaixo retira as permissões dos demais:
#!/bin/bash
# Script para remover SUID BIT de binários Linux
# Desenvolvido por Rodrigo Garcia em 17/06/2013
FN_LISTASUID()
{
find / -perm -4000 2> /dev/null | egrep -v "/passwd|/sudo|/su|/sudoedit" > suid.txt
if [ $? = 0 ]
then
cat suid.txt
else
echo "Não há arquivos com SUID BIT ligado no sistema!!!"
exit 0
fi
}
FN_RMSUID()
{
FN_LISTASUID
echo -n "Deseja realmente remover o SUID BIT dos arquivos listados (S/n)?: "
read RESPOSTA
if [ -z $RESPOSTA ]
then
RESPOSTA=$(echo "s")
fi
case $RESPOSTA in
s)
while read line
do
chmod -s $line
done < "suid.txt"
echo "SUID BIT removido com sucesso!!!"
;;
n)
exit
;;
*)
echo "Opcao Invalida!!!"
exit
;;
esac
}
FN_HLP()
{
echo "Script para remover SUID BIT de Binários GNU/Linux"
echo "Desenvolvido por Rodrigo Garcia em 17/06/2013"
echo "Use $0 [opcao]"
echo "-l --lista Lista os binários com SUID BIT ligado;"
echo "-r --remove Lista os binários com SUID BIT ligado e remove a permissão;"
echo "-h --help Mostra essa mensagem;"
}
case $1 in
-l)
FN_LISTASUID
exit
;;
--lista)
FN_LISTASUID
exit
;;
-r)
FN_RMSUID
;;
--remove)
FN_RMSUID
;;
-h)
FN_HLP
;;
--help)
FN_HLP
;;
*)
echo "Use $0 [opcao] -h ou --help para mais informacoes"
exit
;;
esac
Salve-o como /root/admin_scripts/rmsuid.sh e dê permissão de execução (chmod +x rmsuid.sh). Sua execução é bem simples, ./rmsuid.sh --lista ou (-l) busca no sistema os arquivos que não precisam de SUID BIT ligado, salva a lista em um arquivo texto e mostra na tela. A opção --remove (ou -r) mostra os arquivos e confirma a remoção de SUID BIT dos arquivos desnecessários, e pronto!
Agora vamos em busca dos pacotes desnecessários que estão instalados no sistema. Temos um script também que faz isso:
#!/bin/bash
dpkg -l | awk 'NR >= 6 { print $1 FS $2 }' > pacotes.txt
Esse script lista todos os pacotes do sistema e salva seu nome e sua versão no arquivo pacotes.txt para ser analisado, e então coerentemente o administrador removerá os pacotes (por exemplo, se o pacote "apache2" estiver instalado no firewall, é melhor removê-lo). Salve-o como /root/admin_scripts/pacotes.sh e dê permissão de execução.
Em seguida, precisamos manter acesso externo ao firewall para que possamos administrá-lo remotamente (sempre existirá essa necessidade). Mas não podemos deixar a porta 22 do SSH aberta direto, pois sofreremos muitas tentativas de invasão. Então vamos começar mudando a porta padrão do SSH por outra aleatória (recomendo acima da porta 1024). Para isso precisamos editar o arquivo /etc/ssh/sshd_config e alterar a linha:
Port 22
Para:
Port "porta qualquer acima da 1024"
Mas isso ainda não resolve o nosso problema, pois teremos sempre a porta de conexão do SSH que escolhermos aberta para a internet. A solução encontrada aqui é o uso da ferramenta "knockd" que trabalha com uma técnica chamada "port knocking" que consiste em uma conbinação de portas do firewall que o cliente tem que "bater" para que outra porta seja aberta, como um cofre que possui uma combinação pré definida. Vamos instalar o knockd:
/root/admin_scripts/noexec.sh stop
aptitude install knockd
/root/admin_scripts/noexec.sh start
Após a instalação, vamos configurar o serviço editando o arquivo /etc/knockd.conf nas seguintes linhas:
[openSSH]
sequence = escolher uma sequência aleatória de 3 portas (recomendo acima de 1024), ex: 1028,2056,4112
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
tcpflags = syn
E também as linhas:
[closeSSH]
sequence = O inverso da sequência acima, ex: 4112,2056,1028
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
tcpflags = syn
Salvamos o arquivo e saímos. Em seguida devemos editar o arquivo /etc/default/knockd na seguinte linha:
START_KNOCKD=0
Mudar para
START_KNOCKD=1
Essa mudança permite a inicialização do serviço knockd. Após isso iniciamos o serviço:
service knockd start
Na máquina cliente devemos também instalar o knockd mas não precisamos configurar nada, e para utilizá-lo devemos executar o seguinte comando:
knock ip.do.seu.firewall 1028 2056 4112
Isso vai executar o comando do knockd.conf e abrir o firewall para a porta do SSH que definimos. Para terminarmos o acesso, nós saímos do SSH e executamos o mesmo comando invertendo as portas:
knock ip.do.seu.firewall 4112 2056 1028
E a porta será fechada novamente. E para finalizar, apenas a recomendação de executar periodicamente os scripts de busca de SUID BIT e de listagem de pacotes, e sempre manter o sistema operacional atualizado a fim de mantermos o mais seguro possível. Espero ter sido útil!!!
Até a próxima!!!
A primeira dica é já para a instalação do SO, mais precisamente na parte de particionamento. Para facilitar a manipulação de partições eu costumo utilizar LVM, pois permite redimensionamentos posteriores, extends de disco, etc. A dica aqui é criar partições separadas para pontos de montagem estratégicos do sistema operacional. Dessa forma podemos definir opções de montagem para cada uma separadamente. Como exemplo, podemos definir que o /home, /tmp e /var não terão permissão de execução, isso quer dizer que nenhum programa malicioso (rootkit, backdoor, exploit) será executado nesses pontos de montagem (comuns nesses casos).
Um esquema bem legal de particionamento seria separar as partições da seguinte forma:
/
/boot
/home
/opt
/tmp
/usr
/var
/var/log
O /home em um firewall não deve conter arquivos pessoais, muito menos executáveis e por isso tiraremos a permissão de execução de binários nessa partição. O mesmo acontece em /tmp e em /var (lembrando que deveremos dar permissão de execução nessas duas partições para utilizarmos ferramentas como apt ou aptitude, mas veremos um script para isso mais adiante). O /opt em geral contém os pacotes que são baixados e instalados pelo próprio usuário, e é bom separarmos a partição para limitarmos o espaço que teremos para esse fim, além de retirarmos a permissão de execução de binários com SUID BIT. A partição /usr conterá os binários do sistema e sua separação aqui é mais para limitar o tamanho mesmo. A partição /var/log também não terá permissão de execução e será limitada para que os logs não venham ocasionalmente a preencher o espaço disponível em disco para o / que dispensa explicações. O /boot é necessário para armazenar o kernel e as informações do GRUB, etc. Essa não faz parte do LVM, é uma partição física formatada em EXT2.
Agora que já temos nosso esquema de particionamento, instalamos o SO e ao término, faremos as atualizações e configurações necessárias. Depois disso vamos modificar as permissões das partições editando o arquivo /etc/fstab (faça backup dele antes). Vamos tomar por exemplo a linha da partição /var:
/dev/mapper/servidor-var /var ext4 defaults 0 2
Essa é a linha original do arquivo, com as permissões padrão do sistema. Vamos alterá-la para que fique assim:
/dev/mapper/servidor-var /var ext4 defaults,nosuid,noexec 0 2
Dessa forma, tiramos a permissão de execução na partição e também a permissão de execução de arquivos com SUID BIT ligado. Devemos fazer isso nas partições /home, /tmp, /var, /var/log. Na partição /opt devemos tirar a permissão de execução de SUID BIT (opção "nosuid"). Ao terminar (faça em todas as partições descritas acima), reinicie o sistema para que as alterações tenham efeito ou remonte cada partição:
"mount -o remount /var"
Depois disso, execute um mount para conferir se as alterações foram aplicadas:
"mount"
Para que possamos fazer instalação de pacotes utilizando apt ou aptitude, devemos sempre remontar as partições /tmp e /var com permissão de execução e retirar as permissões após a instalação. Para facilitar, podemos fazer um script simples:
#!/bin/bash
case $1 in
start)
mount -o remount,rw,noexec /var
mount -o remount,rw,noexec /tmp
echo "Partições SEM permissão de execução"
;;
stop)
mount -o remount,rw,exec /var
mount -o remount,rw,exec /tmp
echo "Partições COM permissão de execução"
;;
*)
echo "Modo de uso $0 {start|stop}"
exit 0
;;
esac
exit 1
Crie a pasta /root/admin_scripts e coloque esse script lá. Dê permissão de execução chmod +x script.sh. Sempre que ele for executado com a opção "stop" ele dará permissão de execução nas partições, e com a opção "start" ele removerá a permissão de execução das partições.
Nosso próximo passo é remover a permissão de SUID BIT dos binários que não precisam dessa permissão. O que é SUID BIT? É a permissão de execução do dono do arquivo. Isso é, se o dono do arquivo for o root, ele vai ser executado como root e isso pode ser explorado para ganho de acesso administrativo ao sistema operacional. Apenas alguns arquivos tem a real necessidade de serem executados com SUID BIT, e o script abaixo retira as permissões dos demais:
#!/bin/bash
# Script para remover SUID BIT de binários Linux
# Desenvolvido por Rodrigo Garcia em 17/06/2013
FN_LISTASUID()
{
find / -perm -4000 2> /dev/null | egrep -v "/passwd|/sudo|/su|/sudoedit" > suid.txt
if [ $? = 0 ]
then
cat suid.txt
else
echo "Não há arquivos com SUID BIT ligado no sistema!!!"
exit 0
fi
}
FN_RMSUID()
{
FN_LISTASUID
echo -n "Deseja realmente remover o SUID BIT dos arquivos listados (S/n)?: "
read RESPOSTA
if [ -z $RESPOSTA ]
then
RESPOSTA=$(echo "s")
fi
case $RESPOSTA in
s)
while read line
do
chmod -s $line
done < "suid.txt"
echo "SUID BIT removido com sucesso!!!"
;;
n)
exit
;;
*)
echo "Opcao Invalida!!!"
exit
;;
esac
}
FN_HLP()
{
echo "Script para remover SUID BIT de Binários GNU/Linux"
echo "Desenvolvido por Rodrigo Garcia em 17/06/2013"
echo "Use $0 [opcao]"
echo "-l --lista Lista os binários com SUID BIT ligado;"
echo "-r --remove Lista os binários com SUID BIT ligado e remove a permissão;"
echo "-h --help Mostra essa mensagem;"
}
case $1 in
-l)
FN_LISTASUID
exit
;;
--lista)
FN_LISTASUID
exit
;;
-r)
FN_RMSUID
;;
--remove)
FN_RMSUID
;;
-h)
FN_HLP
;;
--help)
FN_HLP
;;
*)
echo "Use $0 [opcao] -h ou --help para mais informacoes"
exit
;;
esac
Salve-o como /root/admin_scripts/rmsuid.sh e dê permissão de execução (chmod +x rmsuid.sh). Sua execução é bem simples, ./rmsuid.sh --lista ou (-l) busca no sistema os arquivos que não precisam de SUID BIT ligado, salva a lista em um arquivo texto e mostra na tela. A opção --remove (ou -r) mostra os arquivos e confirma a remoção de SUID BIT dos arquivos desnecessários, e pronto!
Agora vamos em busca dos pacotes desnecessários que estão instalados no sistema. Temos um script também que faz isso:
#!/bin/bash
dpkg -l | awk 'NR >= 6 { print $1 FS $2 }' > pacotes.txt
Esse script lista todos os pacotes do sistema e salva seu nome e sua versão no arquivo pacotes.txt para ser analisado, e então coerentemente o administrador removerá os pacotes (por exemplo, se o pacote "apache2" estiver instalado no firewall, é melhor removê-lo). Salve-o como /root/admin_scripts/pacotes.sh e dê permissão de execução.
Em seguida, precisamos manter acesso externo ao firewall para que possamos administrá-lo remotamente (sempre existirá essa necessidade). Mas não podemos deixar a porta 22 do SSH aberta direto, pois sofreremos muitas tentativas de invasão. Então vamos começar mudando a porta padrão do SSH por outra aleatória (recomendo acima da porta 1024). Para isso precisamos editar o arquivo /etc/ssh/sshd_config e alterar a linha:
Port 22
Para:
Port "porta qualquer acima da 1024"
Mas isso ainda não resolve o nosso problema, pois teremos sempre a porta de conexão do SSH que escolhermos aberta para a internet. A solução encontrada aqui é o uso da ferramenta "knockd" que trabalha com uma técnica chamada "port knocking" que consiste em uma conbinação de portas do firewall que o cliente tem que "bater" para que outra porta seja aberta, como um cofre que possui uma combinação pré definida. Vamos instalar o knockd:
/root/admin_scripts/noexec.sh stop
aptitude install knockd
/root/admin_scripts/noexec.sh start
Após a instalação, vamos configurar o serviço editando o arquivo /etc/knockd.conf nas seguintes linhas:
[openSSH]
sequence = escolher uma sequência aleatória de 3 portas (recomendo acima de 1024), ex: 1028,2056,4112
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
tcpflags = syn
E também as linhas:
[closeSSH]
sequence = O inverso da sequência acima, ex: 4112,2056,1028
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
tcpflags = syn
Salvamos o arquivo e saímos. Em seguida devemos editar o arquivo /etc/default/knockd na seguinte linha:
START_KNOCKD=0
Mudar para
START_KNOCKD=1
Essa mudança permite a inicialização do serviço knockd. Após isso iniciamos o serviço:
service knockd start
Na máquina cliente devemos também instalar o knockd mas não precisamos configurar nada, e para utilizá-lo devemos executar o seguinte comando:
knock ip.do.seu.firewall 1028 2056 4112
Isso vai executar o comando do knockd.conf e abrir o firewall para a porta do SSH que definimos. Para terminarmos o acesso, nós saímos do SSH e executamos o mesmo comando invertendo as portas:
knock ip.do.seu.firewall 4112 2056 1028
E a porta será fechada novamente. E para finalizar, apenas a recomendação de executar periodicamente os scripts de busca de SUID BIT e de listagem de pacotes, e sempre manter o sistema operacional atualizado a fim de mantermos o mais seguro possível. Espero ter sido útil!!!
Até a próxima!!!
terça-feira, 25 de junho de 2013
Watch Dog para Nagios
Olá a todos!!!
Como todos já sabem, é possível fazer infinitas customizações no Nagios. Eu mesmo já criei meus próprios plugins usando shell script. Dessa vez, eu tentei algo um pouco mais ousado, que é a criação de um watch dog (sistema automático que detecta falhas e tenta corrigir sozinho) para serviços monitorados pelo Nagios. Na verdade é bem simples, um shell script básico que é executado pelo plugin NRPE. No tutorial que está nesse mesmo blog, vemos que quando utilizamos o NRPE nós configuramos comandos a serem executados no host monitorado através do arquivo nrpe.cfg:
A linha comum para monitorar o Apache num servidor seria:
command[check_http]=/usr/lib/nagios/plugins/check_http -I localhost
O que eu fiz foi criar um script que chama cada comando, ex:
command[check_http]=/usr/lib/nagios/plugins/watch_dog.sh "check_http -I localhost" apache2
Caso o serviço não esteja rodando, ele executa o comando para iniciar o serviço no sistema operacional. Simples, não? Abaixo o script:
#!/bin/bash
# Watch Dog para Nagios 1.0
# Desenvolvido por Rodrigo Garcia em 25/06/2013
# Informe em PDIR="" o caminho para os plugins do Nagios
PDIR="/usr/local/nagios/libexec"
SERV=$(which service)
# O script deve ser chamado colocando como primeiro argumento ($1) o nome do plugin do Nagios e seus argumentos entre aspas
# O segundo argumento ($2) é o nome do serviço a ser executado caso o mesmo não esteja rodando.
$PDIR/$1 $2 > /dev/null
case $? in
"0")
$PDIR/$1 $2
;;
"1")
$PDIR/$1 $2
;;
"2")
$SERV $2 restart
if [ $? != "0" ]
then
$PDIR/$1 $2
fi
;;
esac
Por enquanto só funciona em Linux. Talvez mais para frente eu desenvolva algo para Windows.
Abraço e até a próxima!!!
Como todos já sabem, é possível fazer infinitas customizações no Nagios. Eu mesmo já criei meus próprios plugins usando shell script. Dessa vez, eu tentei algo um pouco mais ousado, que é a criação de um watch dog (sistema automático que detecta falhas e tenta corrigir sozinho) para serviços monitorados pelo Nagios. Na verdade é bem simples, um shell script básico que é executado pelo plugin NRPE. No tutorial que está nesse mesmo blog, vemos que quando utilizamos o NRPE nós configuramos comandos a serem executados no host monitorado através do arquivo nrpe.cfg:
A linha comum para monitorar o Apache num servidor seria:
command[check_http]=/usr/lib/nagios/plugins/check_http -I localhost
O que eu fiz foi criar um script que chama cada comando, ex:
command[check_http]=/usr/lib/nagios/plugins/watch_dog.sh "check_http -I localhost" apache2
Caso o serviço não esteja rodando, ele executa o comando para iniciar o serviço no sistema operacional. Simples, não? Abaixo o script:
#!/bin/bash
# Watch Dog para Nagios 1.0
# Desenvolvido por Rodrigo Garcia em 25/06/2013
# Informe em PDIR="" o caminho para os plugins do Nagios
PDIR="/usr/local/nagios/libexec"
SERV=$(which service)
# O script deve ser chamado colocando como primeiro argumento ($1) o nome do plugin do Nagios e seus argumentos entre aspas
# O segundo argumento ($2) é o nome do serviço a ser executado caso o mesmo não esteja rodando.
$PDIR/$1 $2 > /dev/null
case $? in
"0")
$PDIR/$1 $2
;;
"1")
$PDIR/$1 $2
;;
"2")
$SERV $2 restart
if [ $? != "0" ]
then
$PDIR/$1 $2
fi
;;
esac
Por enquanto só funciona em Linux. Talvez mais para frente eu desenvolva algo para Windows.
Abraço e até a próxima!!!
sexta-feira, 14 de junho de 2013
Plugin do Nagios para HP-UX
Olá,
Como não encontrei um plugin satisfatório na net que verifcasse a memória no HP-UX eu adaptei um plugin que eu criei para Linux. Abaixo o código para versão 11.31 (para a versão 11.23 mudar o "NR == 5" para "NR == 6"):
#!/sbin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
TMEM=$(swapinfo -tam | awk 'NR == 5 { print $2 }')
UMEM=$(swapinfo -tam | awk 'NR == 5 { print $3 }')
FMEM=$(swapinfo -tam | awk 'NR == 5 { print $4 }')
PMEM=$(echo $(($UMEM * 100 / $TMEM)))
if [ $PMEM -lt $1 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM OK|Uso(%)= $PMEM%"
exit 0
elif [ $PMEM -ge $1 ] && [ $PMEM -lt $2 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM Atencao!!!|Uso(%)= $PMEM% "
exit 1
elif [ $PMEM -ge $2 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM Critico!!!|Uso(%)= $PMEM%"
exit 2
fi
Espero ter ajudado e até a próxima!!!
Como não encontrei um plugin satisfatório na net que verifcasse a memória no HP-UX eu adaptei um plugin que eu criei para Linux. Abaixo o código para versão 11.31 (para a versão 11.23 mudar o "NR == 5" para "NR == 6"):
#!/sbin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
TMEM=$(swapinfo -tam | awk 'NR == 5 { print $2 }')
UMEM=$(swapinfo -tam | awk 'NR == 5 { print $3 }')
FMEM=$(swapinfo -tam | awk 'NR == 5 { print $4 }')
PMEM=$(echo $(($UMEM * 100 / $TMEM)))
if [ $PMEM -lt $1 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM OK|Uso(%)= $PMEM%"
exit 0
elif [ $PMEM -ge $1 ] && [ $PMEM -lt $2 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM Atencao!!!|Uso(%)= $PMEM% "
exit 1
elif [ $PMEM -ge $2 ]
then
echo "Total(MB)= $TMEM, Livre(MB)= $FMEM Uso(MB)= $UMEM Critico!!!|Uso(%)= $PMEM%"
exit 2
fi
Espero ter ajudado e até a próxima!!!
quarta-feira, 12 de junho de 2013
Comandos Úteis HP-UX para Administradores Linux
É muito comum acontecer (e aconteceu comigo também) de um administrador Linux pensar que é moleza administrar um sistema Unix HP-UX. Muitos comandos são os mesmos, às vezes muda uma sintaxe ou outra. Porém tem algumas coisas às vezes bem pequenas mas que podem irritar até os mais experientes. Esse pequeno artigo visa ajudar aos que estão habituados com o Linux a se ambientarem no HP-UX.
Para que o backspace funcione (o padrão do sistema é pressionar Esc e em seguida a tecla x para apagar os caracteres) basta digitar o comando:
"stty erase ^?"
E a partir daí já poderá usar o backspace. A dica aqui é incluir esse comando no arquivo .profile que fica na pasta home do usuário, para que sempre que esse usuário logar no sistema, a tecla backspace já fique automaticamente ativada.
O comando "df -h" no Linux nos mostra as partições, os tamanhos, espaço usado, espaço livre, a porcentagem de uso e o ponto de montagem. Esse mesmo comando no HP-UX traz uma saída parecida trazendo o ponto de montagem, a partição e o tamanho em blocos do disco. Para trazer a mesma saída do Linux o comando a ser utilizado é o:
"bdf"
Para mostrar o modelo e arquitetura do servidor, o comando é:
"model"
O HP-UX utiliza pacotes com extensão .depot, e para instalá-los o comando é:
"swinstall -s /caminho/completo/para/o/pacote.depot \*"
Para quem acha que não existe instaladores de pacotes como por exemplo o apt ou yum no HP-UX, eu indico a página http://hpux.connect.org.uk/hppd/packages.html e procure pelo pacote "depothelper" que faz exatamente esse trabalho. A instalação é feita com o comando acima e para executá-lo (como root) o comando é:
"/usr/local/bin/depothelper -h/?"
Quando precisamos desbloquear uma conta de usuário local, devemos executar:
"/usr/lbin/modprpw -k -l usuario"
A opção -k desbloqueia/habilita uma conta, e a opção -l informa ser uma conta local.
Usuários de Linux estão acostumados a iniciar e parar serviços acessando os scripts no diretório "/etc/init.d". Esse padrão não se aplica no HP-UX, mas sim:
"/sbin/init.d"
E os scripts rc (de inicialização) ficam em:
"sbin"
Para sabermos o runlevem do sistema, executamos o comando:
"who -r"
Para completar a nossa linha decomando no Linux usamos a tecla "Tab". No HP-UX utilizamos a tecla "Esc" duas vezes. De forma semelhante, para repetirmos os comandos anteriores no Linux utilizamos a tecla direcional para cima, no HP-UX utilizamos a combinação de teclas "Esc + k".
Para se adicionar um usuário no sistema, o comando é:
"useradd -m usuario"
Para adicionar um usuário a um grupo o comando é:
"usermod -G grupo usuario"
Para os preguiçosos de plantão ou em uma emergência onde não sabe-se os comandos certos, existe uma interface web de administração do sistema. Basta executar o comando:
"smh"
No navegador coloque o ip do servidor seguido da porta 2301:
"http://ip.do.seu.server:2301"
E logue normalmente.
Existe também uma central de administração via shell que é aberta através do comando:
"sam"
Por hoje é só, espero ter sido útil e até a próxima!!!
Fonte: http://www.spritian.com/2012/04/26/useful-hp-ux-commands-for-linux-administrator/
ATUALIZAÇÃO
No sistema Linux, quando precisamos ver a memória total, livre e usada, utilizamos o comando "free". No HP-UX o comando é:
"swapinfo -tam"
Para que o backspace funcione (o padrão do sistema é pressionar Esc e em seguida a tecla x para apagar os caracteres) basta digitar o comando:
"stty erase ^?"
E a partir daí já poderá usar o backspace. A dica aqui é incluir esse comando no arquivo .profile que fica na pasta home do usuário, para que sempre que esse usuário logar no sistema, a tecla backspace já fique automaticamente ativada.
O comando "df -h" no Linux nos mostra as partições, os tamanhos, espaço usado, espaço livre, a porcentagem de uso e o ponto de montagem. Esse mesmo comando no HP-UX traz uma saída parecida trazendo o ponto de montagem, a partição e o tamanho em blocos do disco. Para trazer a mesma saída do Linux o comando a ser utilizado é o:
"bdf"
Para mostrar o modelo e arquitetura do servidor, o comando é:
"model"
O HP-UX utiliza pacotes com extensão .depot, e para instalá-los o comando é:
"swinstall -s /caminho/completo/para/o/pacote.depot \*"
Para quem acha que não existe instaladores de pacotes como por exemplo o apt ou yum no HP-UX, eu indico a página http://hpux.connect.org.uk/hppd/packages.html e procure pelo pacote "depothelper" que faz exatamente esse trabalho. A instalação é feita com o comando acima e para executá-lo (como root) o comando é:
"/usr/local/bin/depothelper -h/?"
Quando precisamos desbloquear uma conta de usuário local, devemos executar:
"/usr/lbin/modprpw -k -l usuario"
A opção -k desbloqueia/habilita uma conta, e a opção -l informa ser uma conta local.
Usuários de Linux estão acostumados a iniciar e parar serviços acessando os scripts no diretório "/etc/init.d". Esse padrão não se aplica no HP-UX, mas sim:
"/sbin/init.d"
E os scripts rc (de inicialização) ficam em:
"sbin"
Para sabermos o runlevem do sistema, executamos o comando:
"who -r"
Para completar a nossa linha decomando no Linux usamos a tecla "Tab". No HP-UX utilizamos a tecla "Esc" duas vezes. De forma semelhante, para repetirmos os comandos anteriores no Linux utilizamos a tecla direcional para cima, no HP-UX utilizamos a combinação de teclas "Esc + k".
Para se adicionar um usuário no sistema, o comando é:
"useradd -m usuario"
Para adicionar um usuário a um grupo o comando é:
"usermod -G grupo usuario"
Para os preguiçosos de plantão ou em uma emergência onde não sabe-se os comandos certos, existe uma interface web de administração do sistema. Basta executar o comando:
"smh"
No navegador coloque o ip do servidor seguido da porta 2301:
"http://ip.do.seu.server:2301"
E logue normalmente.
Existe também uma central de administração via shell que é aberta através do comando:
"sam"
Por hoje é só, espero ter sido útil e até a próxima!!!
Fonte: http://www.spritian.com/2012/04/26/useful-hp-ux-commands-for-linux-administrator/
ATUALIZAÇÃO
No sistema Linux, quando precisamos ver a memória total, livre e usada, utilizamos o comando "free". No HP-UX o comando é:
"swapinfo -tam"
quinta-feira, 6 de junho de 2013
Poderes de Super Vaca
Olá a todos,
Muita gente já viu e me perguntou sobre o que significa a mensagem no final da ajuda do APT:
apt-get --help
"Este APT tem poderes de Super Vaca"
e do Aptitude
aptitude --help
"Este aptitude não contém poderes de Super Vaca"
o que pouca gente sabe é que essas mensagens fazem referência a easter eggs inseridos nos programas. Vamos ao easter egg do APT:
apt-get moo
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
E é só!
aptitude moo
"Não existem Ovos de Páscoa neste programa."
aptitude moo -v
"Realmente não existem Ovos de Páscoa neste programa."
aptitude moo -vv
"Eu já não lhe disse que não existem Ovos de Páscoa neste programa?"
aptitude moo -vvv
"Pare com isso!"
aptitude moo -vvvv
"Ok, ok, se eu lhe der um Ovo de Páscoa você irá embora?"
aptitude moo -vvvvv
"Tudo bem, você ganhou."
/----\
-------/ \
/ \
/ |
-----------------/ --------\
----------------------------------------------
aptitude moo -vvvvvv
"O que é isso? Isso é um elefante sendo comido por uma cobra, é claro."
E é isso!!! Agora todos sabem o que significa ter ou não poderes de Super Vaca !!!
Abraço e até a próxima!!!
Muita gente já viu e me perguntou sobre o que significa a mensagem no final da ajuda do APT:
apt-get --help
"Este APT tem poderes de Super Vaca"
e do Aptitude
aptitude --help
"Este aptitude não contém poderes de Super Vaca"
o que pouca gente sabe é que essas mensagens fazem referência a easter eggs inseridos nos programas. Vamos ao easter egg do APT:
apt-get moo
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
E é só!
aptitude moo
"Não existem Ovos de Páscoa neste programa."
aptitude moo -v
"Realmente não existem Ovos de Páscoa neste programa."
aptitude moo -vv
"Eu já não lhe disse que não existem Ovos de Páscoa neste programa?"
aptitude moo -vvv
"Pare com isso!"
aptitude moo -vvvv
"Ok, ok, se eu lhe der um Ovo de Páscoa você irá embora?"
aptitude moo -vvvvv
"Tudo bem, você ganhou."
/----\
-------/ \
/ \
/ |
-----------------/ --------\
----------------------------------------------
aptitude moo -vvvvvv
"O que é isso? Isso é um elefante sendo comido por uma cobra, é claro."
E é isso!!! Agora todos sabem o que significa ter ou não poderes de Super Vaca !!!
Abraço e até a próxima!!!
Assinar:
Postagens (Atom)

