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!!!
quarta-feira, 17 de julho de 2013
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!!!
sexta-feira, 24 de maio de 2013
Script de Backup de Arquivos
Olá a todos!!!
Mais uma vez eu trago um script desenvolvido por mim para fazer backup de arquivos de um servidor, compactando-os e salvando-os em um ponto de montagem (de preferência de rede), ele guarda os arquivos de backup por 1 mês e então vai removendo pelo mais antigo. Originalmente esse script possuía 6 linhas (versão 1.0), mas como sempre eu me empolgo e tento fazer o mais completo possível. Eis o script:
#!/bin/bash
##########################################################################
# Script de backup 2.1 (23/05/2013)
# Desenvolvido por Rodrigo Garcia em 19/10/2012
##########################################################################
PATH=/sbin:/usr/sbin:/bin:/usr/bin
##########################################################################
# Informe os arquivos a serem copiados no campo BACKUP="" separados por espaços
##########################################################################
BACKUP=""
##########################################################################
# Informe o ponto de montagem Windows a ser utilizado no backup, ex: "//192.168.0.254/compartilhamento"
##########################################################################
MOUNT=""
##########################################################################
# Informe o username e a senha nos campos abaixo
##########################################################################
USER=""
PASSWD=""
##########################################################################
FN_INS()
{
echo "Deseja realmente instalar o script de backup (s/n)?"
read RESPOSTA
case $RESPOSTA in
"s")
echo "Criando ponto de montagem de rede..."
echo "$MOUNT cifs username=$USER,password=$PASSWD,user,dir_mode=0777,file_mode=0777 0 0 # Backup" >> /etc/fstab
mkdir /mnt/bkp
echo "Montando diretório de backup..."
mount -a
echo "Script de backup instalado com sucesso!!!"
;;
"n")
exit
;;
*)
echo "Opção Inválida!!!"
exit
;;
esac
}
FN_UNS()
{
echo "Deseja realmente desinstalar o script de backup (s/n)?"
read RESPOSTA
case $RESPOSTA in
"s")
echo "Excluindo ponto de montagem de rede..."
sed -i '/# Backup/d' /etc/fstab
echo "Desmontando diretório de backup..."
umount /mnt/bkp
rm -rf /mnt/bkp
echo "Script de backup desinstalado com sucesso!!!"
;;
"n")
exit
;;
*)
echo "Opção Inválida!!!"
exit
;;
esac
}
FN_HLP()
{
echo "Script de Backup de Arquivos 2.1"
echo "Desenvolvido por Rodrigo Garcia"
echo "Opções:"
echo "install instala automaticamente o ponto de montagem"
echo "uninstall remove automaticamente o ponto de montagem"
echo "run executa a rotina de backup"
echo "help mostra essa mensagem"
}
FN_TAR()
{
echo "Compactando os arquivos $BACKUP..."
for BKP in $BACKUP
do
tar -Pczf $(hostname)-$(date +%Y-%m-%d).tar.gz $BACKUP
done
}
FN_CP()
{
test -d /mnt/bkp/$(hostname)
if [ $? == 1 ]
then
echo "Criando diretorio /mnt/bkp/$(hostname)..."
mkdir /mnt/bkp/$(hostname)
fi
echo "Copiando o backup para a pasta /mnt/bkp/$(hostname)..."
cp $(hostname)-$(date +%Y-%m-%d).tar.gz /mnt/bkp/$(hostname)
}
FN_RM()
{
echo "Excluindo arquivo local..."
rm -rf $(hostname)-$(date +%Y-%m-%d).tar.gz
echo "Excluindo backups antigos..."
find /mnt/bkp/$(hostname) -maxdepth 1 -ctime +1 -exec rm -Rf {} \;
}
case $1 in
"install")
FN_INS
exit
;;
"uninstall")
FN_UNS
exit
;;
"run")
FN_TAR
FN_CP
FN_RM
echo "Backup Executado Com Sucesso!!!"
exit
;;
"help")
FN_HLP
exit
;;
*)
echo "Use $0 {install|uninstall|run|help}"
exit
;;
esac
Espero que seja útil, e até a próxima!!!
Mais uma vez eu trago um script desenvolvido por mim para fazer backup de arquivos de um servidor, compactando-os e salvando-os em um ponto de montagem (de preferência de rede), ele guarda os arquivos de backup por 1 mês e então vai removendo pelo mais antigo. Originalmente esse script possuía 6 linhas (versão 1.0), mas como sempre eu me empolgo e tento fazer o mais completo possível. Eis o script:
#!/bin/bash
##########################################################################
# Script de backup 2.1 (23/05/2013)
# Desenvolvido por Rodrigo Garcia em 19/10/2012
##########################################################################
PATH=/sbin:/usr/sbin:/bin:/usr/bin
##########################################################################
# Informe os arquivos a serem copiados no campo BACKUP="" separados por espaços
##########################################################################
BACKUP=""
##########################################################################
# Informe o ponto de montagem Windows a ser utilizado no backup, ex: "//192.168.0.254/compartilhamento"
##########################################################################
MOUNT=""
##########################################################################
# Informe o username e a senha nos campos abaixo
##########################################################################
USER=""
PASSWD=""
##########################################################################
FN_INS()
{
echo "Deseja realmente instalar o script de backup (s/n)?"
read RESPOSTA
case $RESPOSTA in
"s")
echo "Criando ponto de montagem de rede..."
echo "$MOUNT cifs username=$USER,password=$PASSWD,user,dir_mode=0777,file_mode=0777 0 0 # Backup" >> /etc/fstab
mkdir /mnt/bkp
echo "Montando diretório de backup..."
mount -a
echo "Script de backup instalado com sucesso!!!"
;;
"n")
exit
;;
*)
echo "Opção Inválida!!!"
exit
;;
esac
}
FN_UNS()
{
echo "Deseja realmente desinstalar o script de backup (s/n)?"
read RESPOSTA
case $RESPOSTA in
"s")
echo "Excluindo ponto de montagem de rede..."
sed -i '/# Backup/d' /etc/fstab
echo "Desmontando diretório de backup..."
umount /mnt/bkp
rm -rf /mnt/bkp
echo "Script de backup desinstalado com sucesso!!!"
;;
"n")
exit
;;
*)
echo "Opção Inválida!!!"
exit
;;
esac
}
FN_HLP()
{
echo "Script de Backup de Arquivos 2.1"
echo "Desenvolvido por Rodrigo Garcia"
echo "Opções:"
echo "install instala automaticamente o ponto de montagem"
echo "uninstall remove automaticamente o ponto de montagem"
echo "run executa a rotina de backup"
echo "help mostra essa mensagem"
}
FN_TAR()
{
echo "Compactando os arquivos $BACKUP..."
for BKP in $BACKUP
do
tar -Pczf $(hostname)-$(date +%Y-%m-%d).tar.gz $BACKUP
done
}
FN_CP()
{
test -d /mnt/bkp/$(hostname)
if [ $? == 1 ]
then
echo "Criando diretorio /mnt/bkp/$(hostname)..."
mkdir /mnt/bkp/$(hostname)
fi
echo "Copiando o backup para a pasta /mnt/bkp/$(hostname)..."
cp $(hostname)-$(date +%Y-%m-%d).tar.gz /mnt/bkp/$(hostname)
}
FN_RM()
{
echo "Excluindo arquivo local..."
rm -rf $(hostname)-$(date +%Y-%m-%d).tar.gz
echo "Excluindo backups antigos..."
find /mnt/bkp/$(hostname) -maxdepth 1 -ctime +1 -exec rm -Rf {} \;
}
case $1 in
"install")
FN_INS
exit
;;
"uninstall")
FN_UNS
exit
;;
"run")
FN_TAR
FN_CP
FN_RM
echo "Backup Executado Com Sucesso!!!"
exit
;;
"help")
FN_HLP
exit
;;
*)
echo "Use $0 {install|uninstall|run|help}"
exit
;;
esac
Espero que seja útil, e até a próxima!!!
segunda-feira, 22 de abril de 2013
Firewall Corporativo com IPtables
Como prometido, nesse post eu vou colocar um script para firewall corporativo. Obviamente que eu vou explicar a estrutura do script e o porquê de fazer algumas coisas e não fazer outras. Em primeiro lugar eu quero explicar que nesse script eu não coloquei comandos para carregar módulos, nem para setar opções no kernel, etc, por pensar que essas configurações se tratam do sistema operacional em si e não do firewall como eu vejo muitos fazendo. O firewall foi criado com pequenas particularidades pensando no Debian, mas no geral funciona em qualquer outra distribuição.
1ª Parte:
#!/bin/bash
#
# ## BEGIN INIT INFO
# Provides : Firewall
# Required - Start : networking
# Required - Stop :
# Should - Start : S
# Should - Stop :
# Default - Start : 2 3 4 5
# Default - Stop :
# Short - Description : Firewall - Rodrigo Garcia
# Description : Firewall - Rodrigo Garcia
#
# ## END INIT INFO
################################################################################################
# 1- VARIAVEIS
################################################################################################
IPT=$(which iptables)
HIPRT="1024:65535"
################################################################################################
# 1.1- EXTERNO - Informe a placa de rede externa em IFEXT="" e o IP externo em IPEXT=""
################################################################################################
IFEXT=""
IPEXT=""
################################################################################################
# 1.2- INTERNO - Informe a placa de rede interna em IFINT="" e o ip interno em IPINT=""
################################################################################################
IFINT=""
IPINT=""
################################################################################################
# 1.3- Redes - Informe o IP da WAN (geralmente 0/0) em IPWAN="" e o IP da rede interna (CIDR) em IPLAN=""
################################################################################################
IPWAN=""
IPLAN=""
################################################################################################
# 1.4- Informe em OPENP="" as portas abertas no firewall no formato "porta:protocolo:origem", ex: 22:tcp:192.168.0.2
# e as portas encaminhadas em FRWDP="" como "porta:protocolo:destino:porta", ex: 80:tcp:192.168.0.3:80
# As portas de saída devem ser informadas em OUTPT="" no formato porta:protocolo:destino, ex: 53:udp:0/0 ou 53:udp:$IPWAN
# As portas que devem ser priorizadas, devem ser informadas em TOSPT="" apenas com o numero ex: TOSPT="22 80 443"
################################################################################################
OPENP=""
FRWDP=""
OUTPT=""
TOSPT=""
################################################################################################
No bloco acima, as linhas de 3 a 14 são tags usadas para configurar o script para subir com o sistema operacional. Deve-se colocar o script (já com permissão de execução) em /etc/init.d/ e executar o comando insserv -d firewall . Isso adicionará a sua execução nos runlevels de inicialização.
A primeira seção (1- VARIAVEIS) estão as variáveis globais que serão usadas no script. Começamos com a variável $IPT que já foi explicada no post anterior sobre firewall pessoal. O diferencial está na seção 1.4 que traz as portas que você quer abrir no firewall e as que quer encaminhar para dentro de sua rede, e as portas de saída do firewall e as portas cujos pacotes devem ser priorizados.
################################################################################################
# 2- POLITICA DROP
################################################################################################
FN_DROP()
{
for CHAIN in INPUT OUTPUT FORWARD
do
$IPT -P $CHAIN DROP
done
}
################################################################################################
# 3- POLITICA ACCEPT
################################################################################################
FN_ACCEPT()
{
for CHAIN in INPUT OUTPUT FORWARD
do
$IPT -P $CHAIN ACCEPT
done
}
################################################################################################
# 4- LIMPAR FIREWALL
################################################################################################
FN_LIMPA()
{
for TABLE in filter nat mangle
do
$IPT -t $TABLE -X
$IPT -t $TABLE -F
done
}
################################################################################################
# 5- LIBERAR LOCALHOST
################################################################################################
FN_LOCAL()
{
$IPT -I INPUT -i lo -d 127.0.0.1 -j ACCEPT
$IPT -I OUTPUT -o lo -s 127.0.0.1 -j ACCEPT
}
################################################################################################
# 6- LIBERAR CONEXOES
################################################################################################
FN_CONN()
{
for CHAIN in INPUT OUTPUT FORWARD
do
$IPT -A $CHAIN -m state --state ESTABLISHED,RELATED -j ACCEPT
done
}
################################################################################################
# 7- ENCAMINHAR REDES
################################################################################################
FN_FRWD()
{
for FROM in -s -d
do
$IPT -A FORWARD $FROM $IPLAN -j ACCEPT
done
}
################################################################################################
# 8- PING
################################################################################################
FN_PING()
{
for TYPE in "0" "8"
do
$IPT -A INPUT -i $IFINT -p icmp -s $IPLAN -d $IPINT --icmp-type $TYPE -j ACCEPT
$IPT -A OUTPUT -o $IFINT -p icmp -s $IPINT -d $IPLAN --icmp-type $TYPE -j ACCEPT
done
$IPT -A INPUT -i $IFEXT -p icmp -s $IPWAN -d $IPEXT --icmp-type 0 -j ACCEPT
$IPT -A OUTPUT -o $IFEXT -p icmp -s $IPEXT -d $IPWAN --icmp-type 8 -j ACCEPT
}
################################################################################################
O bloco de comandos acima foi feito todo no formato de funções. Por que? Fica muito mais fácil de manupular a estrutura do firewall dessa forma, e podemos facilmente alterar a ordem de execução das funções além de servir para complementarmos com parâmetros de execução do script na parte final. Os comandos acima são os mais básicos para qualquer firewall como liberar comunicação com localhost, permitir entrada de ping só da rede interna, e resposta de ping de todos, encaminhar os pacotes para as redes, etc. Deve ser notado que os comandos utilizam as variáveis locais para facilitar a criação das regras e posteriormente a alteração de IPs, interfaces, etc sem precisar mudar em cada regra.
################################################################################################
# 9- PORTAS DE SAIDA
################################################################################################
FN_OUTPT()
{
for PORTA in $OUTPT
do
PORT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $1 }')
PROT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $2 }')
DEST=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $3 }')
if [ -z $PROT ]
then
PROT="tcp"
fi
if [ -z $DEST ]
then
DEST="$IPWAN"
fi
NET=$(echo "$IPLAN" | awk 'BEGIN { FS = "." } ; { print $1 FS $2 FS $3 FS "*"}')
case $DEST in
$NET)
IF=$(echo $IFINT)
IP=$(echo $IPINT)
;;
*)
IF=$(echo $IFEXT)
IP=$(echo $IPEXT)
;;
esac
$IPT -A INPUT -i $IF -p $PROT -s $DEST --sport $PORT -d $IP --dport $HIPRT -j ACCEPT
$IPT -A OUTPUT -o $IF -p $PROT -s $IP --sport $HIPRT -d $DEST --dport $PORT -j ACCEPT
done
}
################################################################################################
A função acima abre portas para saída do firewall para serviços externos como cosultar um DNS ou instalar pacotes por repositórios, etc.
################################################################################################
# 10- ABRIR PORTAS
################################################################################################
FN_OPENP()
{
for PORTA in $OPENP
do
PORT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $1 }')
PROT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $2 }')
FROM=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $3 }')
if [ -z $PROT ]
then
PROT="tcp"
fi
if [ -z $FROM ]
then
FROM="$IPINT"
fi
NET=$(echo "$IPLAN" | awk 'BEGIN { FS = "." } ; { print $1 FS $2 FS $3 FS "*"}')
case $FROM in
$NET)
IF=$(echo $IFINT)
IP=$(echo $IPINT)
;;
*)
IF=$(echo $IFEXT)
IP=$(echo $IPEXT)
;;
esac
$IPT -A INPUT -i $IF -p $PROT -s $FROM --sport $HIPRT -d $IP --dport $PORT -j ACCEPT
$IPT -A OUTPUT -o $IF -p $PROT -s $IP --sport $PORT -d $FROM --dport $HIPRT -j ACCEPT
done
}
################################################################################################
A função acima é a responsável pela abertura das portas no firewall, definindo o protocolo e a origem caso nao sejam especificados na variável, e decidindo qual interface de rede utilizar de acordo com a origem da comunicação.
################################################################################################
# 11- ENCAMINHAR PORTAS
################################################################################################
FN_FWDP()
{
for PORTA in $FRWDP
do
PORT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $1 }')
PROT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $2 }')
FWSV=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $3 }')
FWPT=$(echo $PORTA | awk 'BEGIN { FS = ":" } ; { print $4 }')
if [ -z $PROT ]
then
PROT="tcp"
fi
if [ -z $FWPT ]
then
FWPT=$(echo $PORT)
fi
$IPT -t nat -A PREROUTING -i $IFEXT -p $PROT -s $IPWAN --sport $HIPRT -d $IPEXT --dport $PORT -j DNAT --to $FWSV:$FWPT
done
}
################################################################################################
Acima temos a função de encaminhamento das portas para a rede interna, e assim como a função de abertura de portas, ela também define o protocolo caso não seja especificado nq variável. Em ambas as funções eu fiz uso do AWK, uma linguagem de edição de textos muito útil e versátil que pode facilitar em muito a vida de um Sysadmin.
################################################################################################
# 12- TOS - PRIORIZACAO DE PACOTES
################################################################################################
FN_TOS()
{
for PORTA in $TOSPT
do
$IPT -t mangle -A PREROUTING -i $IFEXT -p tcp -s $IPWAN -d $IPEXT --sport $PORTA -j TOS --set-tos 16
$IPT -t mangle -A OUTPUT -o $IFEXT -p tcp -s $IPEXT -d $IPWAN --dport $PORTA -j TOS --set-tos 16
done
}
################################################################################################
O bloco acima faz a parte de priorização dos pacotes.
################################################################################################
# 13- COMPARTILHAR INTERNET
################################################################################################
FN_SNAT()
{
$IPT -t nat -A POSTROUTING -o $IFEXT -s $IPLAN -j SNAT --to $IPEXT
}
################################################################################################
Aqui nós temos uma função de compartilhamento da Internet usando SNAT ao invés do MASQUERADE (que é recomendado para IPs dinâmicos).
################################################################################################
# 14- LOG
################################################################################################
FN_LOG()
{
echo "$0 $1 Executado em $(date +%d-%m-%Y-%H:%M:%S)" 2>&1 >> /var/log/firewall.log
}
################################################################################################
Acima temos a criação de logs de execução em /var/log/firewall.log
################################################################################################
# 15- EXECUCAO DO FIREWALL
################################################################################################
case $1 in
start)
FN_DROP
FN_LIMPA
FN_LOCAL
FN_CONN
FN_FRWD
FN_PING
FN_OUTPT
FN_OPENP
FN_FWDP
FN_TOS
FN_SNAT
FN_LOG "start"
echo "Starting IPTables Firewall Rules: firewall."
;;
stop)
FN_ACCEPT
FN_LIMPA
FN_LOG "stop"
echo "Stopping IPTables Firewall Rules: firewall."
;;
restart)
$0 stop
$0 start
;;
*)
echo "Use $0 {start|stop|restart}"
;;
esac
################################################################################################
Acima temos toda a ordem de execução de cada função, e a forma de execução do firewall através dos parâmetros start, stop ou restart.
Espero ter sido útil, e até a próxima!!!
sábado, 6 de abril de 2013
Firewall Pessoal
Olá a todos!!!
Nesse post eu vou mostrar algo muito simples e útil, que é um firewall pessoal através do IPTables. O IPTables é um front-end para o módulo Netfilter do kernel do Linux.
Ele possui 4 tabelas, a Filter, que é a padrão (controla o tráfego básico de entrada, saída e encaminhamento do firewall), a tabela NAT (responsável por tradução de endereços de redes), a tabela Mangle (que é responsável por regras de ações especiais a serem tomadas pelo firewall) e a tabela RAW (controle de pacotes).
Neste firewall, usaremos apenas a tabela Filter, conforme veremos a seguir. Geralmente (nos sistemas baseados em Debian), o IPTables não contém nenhuma regra e a política do firewall é a ACCEPT, que aceita todos os pacotes de entrada, saída e encaminhamento. Entretando, nos sistemas baseados em Red Hat por exemplo, o firewall possui já algumas regras criadas na instalação do SO. Vamos trabalhar como se já houvessem regras preexistentes.
A primeira ação a ser tomada é limpar todas as regras de todas as tabelas do firewall:
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
A opção "-F" é a mesma de "--flush" e vai limpar todas as tabelas, e a opção "-X" vai excluir todas as chains personalizadas préexistentes. A seguir, vamos aplicar a política "DROP" no firewall, que vai negar qualquer conexão por padrão:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
O que foi feito acima foi bloquear qualquer conexão de entrada e de encaminhamento no firewall, e permitir todas as conexões de saída. Nesse momento você não conseguirá estabelecer conexão nenhuma, pois conseguirá enviar pacotes de saída, mas não conseguirá receber respostas.
A primeira coisa que devemos liberar no firewall é o localhost:
iptables -A INPUT -i lo -j ACCEPT
Em seguida, devemos liberar as conexões que você estabeleceu, para que haja entrada de respostas de pacotes:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Agora o próximo passo é liberar a entrada de respostas de ping, e solicitações de ping da rede interna (opcional)
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A INPUT -p icmp -s ip.da.rede.interna/máscara --icmp-type 8 -j ACCEPT
O que vamos fazer agora, é liberar as respostas de servidores de DNS externos:
iptables -A INPUT -p udp -s 0/0 --sport 53 -j ACCEPT
Vimos que agora o comando teve algumas novidades:
-s 0/0 = Significa qualquer origem com qualquer máscara de rede
--sport = Significa uma conexão que tem como origem a porta 53 (DNS)
A partir desse momento, você já conseguirá executar com sucesso ping nas pelo nome do endereço que você quiser. Então vamos agora liberar a navegação web:
iptables -A INPUT -p tcp -s 0/0 --sport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 0/0 --sport 443 -j ACCEPT
Pronto! Você já consegue também navegar na internet! Esses são os passos da criação de um firewall pessoal básico, que você mesmo pode personalizar de acordo com suas necessidades. Por exemplo, se quiser acessar algum serviço externo, deverá criar uma regra assim:
iptables -A INPUT -p tcp -s 0/0 --sport "porta do serviço" -j ACCEPT
E se quiser liberar na sua máquina o acesso a um serviço SSh de dentro da rede, deverá criar uma regra como essa:
iptables -A INPUT -p tcp -s ip.da.rede.interna/máscara --dport 22 -j ACCEPT
Para facilitar, eu gosto de criar scripts que aplicam todas essas regras automaticamente e facilitam na adição de novas regras com o uso de variáveis. Por exemplo:
#!/bin/bash
# Script de Firewall criado por Rodrigo Garcia - www.unix4life.blogspot.com
##############################################################
# 1 - VARIÁVEIS
##############################################################
IPT=$(which iptables) # Isso diminui a sua digitação, e traz maior segurança
IF_INT="eth0" # Colocar aqui o nome da placa de rede interna
IP_INT="`ifconfig $IF_INT | awk 'NR == 2{ print $3 }'`"
NET_INT="192.168.0.0/24" # IP da rede interna
##############################################################
# 2 - LIMPAR FIREWALL
##############################################################
for TABLE in filter nat mangle raw
do
$IPT -t $TABLE -F
$IPT -t $TABLE -X
done
##############################################################
# 3 - APLICAR POLITICAS
##############################################################
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
##############################################################
# 4 - LIBERAR LOCALHOST
##############################################################
$IPT -A INPUT -i lo -j ACCEPT
##############################################################
# 5 - LIBERAR CONEXÕES ESTABELECIDAS
##############################################################
$IPT -A INPUT -i $IF_INT -m state --state ESTABLISHED,RELATED -j ACCEPT
##############################################################
# 6 - ECHO REPLY E ECHO REQUEST VINDO DA REDE INTERNA
##############################################################
$IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT
$IPT -A INPUT -i $IF_INT -p icmp -s $NET_INT --icmp-type 8 -j ACCEPT
##############################################################
# 7 - LIBERAR RESPOSTAS DE DNS
##############################################################
$IPT -A INPUT -i $IF_INT -p udp -s 0/0 --sport 53 -j ACCEPT
##############################################################
# 8 - LIBERAR NAVEGAÇÃO WEB
##############################################################
$IPT -A INPUT -i $IF_INT -p tcp --sport 80 -j ACCEPT
$IPT -A INPUT -i $IF_INT -p tcp --sport 443 -j ACCEPT
##############################################################
E assim terminamos nosso script! Podemos adicioná-lo na inicialização do sistema editando arquivo /etc/rc.local e adicionando o caminho absoluto para o script.
No próximo post vou colocar um script de firewall para redes corporativas. Até a próxima!!!
Nesse post eu vou mostrar algo muito simples e útil, que é um firewall pessoal através do IPTables. O IPTables é um front-end para o módulo Netfilter do kernel do Linux.
Ele possui 4 tabelas, a Filter, que é a padrão (controla o tráfego básico de entrada, saída e encaminhamento do firewall), a tabela NAT (responsável por tradução de endereços de redes), a tabela Mangle (que é responsável por regras de ações especiais a serem tomadas pelo firewall) e a tabela RAW (controle de pacotes).
Neste firewall, usaremos apenas a tabela Filter, conforme veremos a seguir. Geralmente (nos sistemas baseados em Debian), o IPTables não contém nenhuma regra e a política do firewall é a ACCEPT, que aceita todos os pacotes de entrada, saída e encaminhamento. Entretando, nos sistemas baseados em Red Hat por exemplo, o firewall possui já algumas regras criadas na instalação do SO. Vamos trabalhar como se já houvessem regras preexistentes.
A primeira ação a ser tomada é limpar todas as regras de todas as tabelas do firewall:
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
A opção "-F" é a mesma de "--flush" e vai limpar todas as tabelas, e a opção "-X" vai excluir todas as chains personalizadas préexistentes. A seguir, vamos aplicar a política "DROP" no firewall, que vai negar qualquer conexão por padrão:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
O que foi feito acima foi bloquear qualquer conexão de entrada e de encaminhamento no firewall, e permitir todas as conexões de saída. Nesse momento você não conseguirá estabelecer conexão nenhuma, pois conseguirá enviar pacotes de saída, mas não conseguirá receber respostas.
A primeira coisa que devemos liberar no firewall é o localhost:
iptables -A INPUT -i lo -j ACCEPT
Em seguida, devemos liberar as conexões que você estabeleceu, para que haja entrada de respostas de pacotes:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Agora o próximo passo é liberar a entrada de respostas de ping, e solicitações de ping da rede interna (opcional)
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A INPUT -p icmp -s ip.da.rede.interna/máscara --icmp-type 8 -j ACCEPT
O que vamos fazer agora, é liberar as respostas de servidores de DNS externos:
iptables -A INPUT -p udp -s 0/0 --sport 53 -j ACCEPT
Vimos que agora o comando teve algumas novidades:
-s 0/0 = Significa qualquer origem com qualquer máscara de rede
--sport = Significa uma conexão que tem como origem a porta 53 (DNS)
A partir desse momento, você já conseguirá executar com sucesso ping nas pelo nome do endereço que você quiser. Então vamos agora liberar a navegação web:
iptables -A INPUT -p tcp -s 0/0 --sport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 0/0 --sport 443 -j ACCEPT
Pronto! Você já consegue também navegar na internet! Esses são os passos da criação de um firewall pessoal básico, que você mesmo pode personalizar de acordo com suas necessidades. Por exemplo, se quiser acessar algum serviço externo, deverá criar uma regra assim:
iptables -A INPUT -p tcp -s 0/0 --sport "porta do serviço" -j ACCEPT
E se quiser liberar na sua máquina o acesso a um serviço SSh de dentro da rede, deverá criar uma regra como essa:
iptables -A INPUT -p tcp -s ip.da.rede.interna/máscara --dport 22 -j ACCEPT
Para facilitar, eu gosto de criar scripts que aplicam todas essas regras automaticamente e facilitam na adição de novas regras com o uso de variáveis. Por exemplo:
#!/bin/bash
# Script de Firewall criado por Rodrigo Garcia - www.unix4life.blogspot.com
##############################################################
# 1 - VARIÁVEIS
##############################################################
IPT=$(which iptables) # Isso diminui a sua digitação, e traz maior segurança
IF_INT="eth0" # Colocar aqui o nome da placa de rede interna
IP_INT="`ifconfig $IF_INT | awk 'NR == 2{ print $3 }'`"
NET_INT="192.168.0.0/24" # IP da rede interna
##############################################################
# 2 - LIMPAR FIREWALL
##############################################################
for TABLE in filter nat mangle raw
do
$IPT -t $TABLE -F
$IPT -t $TABLE -X
done
##############################################################
# 3 - APLICAR POLITICAS
##############################################################
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
##############################################################
# 4 - LIBERAR LOCALHOST
##############################################################
$IPT -A INPUT -i lo -j ACCEPT
##############################################################
# 5 - LIBERAR CONEXÕES ESTABELECIDAS
##############################################################
$IPT -A INPUT -i $IF_INT -m state --state ESTABLISHED,RELATED -j ACCEPT
##############################################################
# 6 - ECHO REPLY E ECHO REQUEST VINDO DA REDE INTERNA
##############################################################
$IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT
$IPT -A INPUT -i $IF_INT -p icmp -s $NET_INT --icmp-type 8 -j ACCEPT
##############################################################
# 7 - LIBERAR RESPOSTAS DE DNS
##############################################################
$IPT -A INPUT -i $IF_INT -p udp -s 0/0 --sport 53 -j ACCEPT
##############################################################
# 8 - LIBERAR NAVEGAÇÃO WEB
##############################################################
$IPT -A INPUT -i $IF_INT -p tcp --sport 80 -j ACCEPT
$IPT -A INPUT -i $IF_INT -p tcp --sport 443 -j ACCEPT
##############################################################
E assim terminamos nosso script! Podemos adicioná-lo na inicialização do sistema editando arquivo /etc/rc.local e adicionando o caminho absoluto para o script.
No próximo post vou colocar um script de firewall para redes corporativas. Até a próxima!!!
quinta-feira, 21 de fevereiro de 2013
IPSec
Olá a todos,
Meu último desafio (nem foi tão grande assim) foi conectar uma unidade do litoral à nossa sede. Os usuários se conectavam via PPTP, mas não estava muito legal dessa forma. A solução encontrada por mim era criar um tunel site-to-site através de IPSec.
Para a unidade, foi utilizado um roteador Cisco RV042 pelo fato de ser uma unidade bem pequena não tendo muito espaço para comportar equipamentos maiores (como é de minha preferência). Na sede eu utilizei uma máquina com Ubuntu Server.
Na ponta da sede o que eu fiz foi instalar o pacote "OpenSwan":
apt-get install openswan
E editar os seguintes arquivos:
/etc/ipsec.conf
config setup
plutodebug=all
#nat_traversal=on # Caso a máquina que conectará esteja atrás de um firewall
oe=off
protostack=netkey
interfaces=%none
conn Unidade # Trocar o nome "Unidade" para qualquer outro que desejar
left=0.0.0.0 # IP público local
leftsourceip=1.1.1.1 # IP da máquina que fará a conexão
leftsubnet=1.1.1.0/24 # IP da rede que a outra ponta deverá enxergar
leftnexthop=0.0.0.1 # gateway do IP público local
right=2.2.2.2 # IP público da unidade
rightsourceip=3.3.3.3 # IP da máquina da unidade que fará a conexão
rightsubnet=3.3.3.0/24 # IP da rede da unidade
rightnexthop=2.2.2.1 # Gateway do IP público da unidade
authby=secret
auto=start
auth=esp
rekey=yes
keyingtries=0
keyexchange=ike
ike=3des-md5;modp1024
ikelifetime=3600s
esp=3des-md5;modp1024
keylife=28800s
pfs=no
Em seguida devemos configurar o arquivo /etc/ipsec.secrets (no ubuntu, o arquivo é /var/lib/openswan/ipsec.secrets.inc)
0.0.0.0 %any : PSK "chavequevocequiser"
A configuração acima permite que qualquer máquina que tenha as configurações adequadas e a mesma chave configurada acima se conecte no tunel. Caso não queira essa configuração basta alterar "%any" para o IP público da outra ponta.
Caso o tunel esteja configurado no firewall, é necessário adicionar a seguinte regra:
iptables -A INPUT -p udp --dport 500 -j accept
Caso esteja em uma máquina atrás do firewall, a regra muda para:
iptables -t nat -A PREROUTING -p udp -d ip_publico --dport 500 -j DNAT --to ip_da_máquina
E também essa:
iptables -t nat -A PREROUTING -p udp -d ip_publico --dport 4500 -j DNAT --to ip_da_máquina
Agora é só configurar a outra ponta que pode ser outra máquina linux ou um equipamento como o Cisco RV042, utilizando as mesmas configurações porém não esquecendo de fazer as devidas alterações de IPs.
Lembrando que essa é uma VPN básica, existem muito mais recursos de segurança a serem explorados, e cabe a cada um decidir o que é necessário para cada caso.
Espero que tenha sido útil,
Até a próxima!!!
Meu último desafio (nem foi tão grande assim) foi conectar uma unidade do litoral à nossa sede. Os usuários se conectavam via PPTP, mas não estava muito legal dessa forma. A solução encontrada por mim era criar um tunel site-to-site através de IPSec.
Para a unidade, foi utilizado um roteador Cisco RV042 pelo fato de ser uma unidade bem pequena não tendo muito espaço para comportar equipamentos maiores (como é de minha preferência). Na sede eu utilizei uma máquina com Ubuntu Server.
Na ponta da sede o que eu fiz foi instalar o pacote "OpenSwan":
apt-get install openswan
E editar os seguintes arquivos:
/etc/ipsec.conf
config setup
plutodebug=all
#nat_traversal=on # Caso a máquina que conectará esteja atrás de um firewall
oe=off
protostack=netkey
interfaces=%none
conn Unidade # Trocar o nome "Unidade" para qualquer outro que desejar
left=0.0.0.0 # IP público local
leftsourceip=1.1.1.1 # IP da máquina que fará a conexão
leftsubnet=1.1.1.0/24 # IP da rede que a outra ponta deverá enxergar
leftnexthop=0.0.0.1 # gateway do IP público local
right=2.2.2.2 # IP público da unidade
rightsourceip=3.3.3.3 # IP da máquina da unidade que fará a conexão
rightsubnet=3.3.3.0/24 # IP da rede da unidade
rightnexthop=2.2.2.1 # Gateway do IP público da unidade
authby=secret
auto=start
auth=esp
rekey=yes
keyingtries=0
keyexchange=ike
ike=3des-md5;modp1024
ikelifetime=3600s
esp=3des-md5;modp1024
keylife=28800s
pfs=no
Em seguida devemos configurar o arquivo /etc/ipsec.secrets (no ubuntu, o arquivo é /var/lib/openswan/ipsec.secrets.inc)
0.0.0.0 %any : PSK "chavequevocequiser"
A configuração acima permite que qualquer máquina que tenha as configurações adequadas e a mesma chave configurada acima se conecte no tunel. Caso não queira essa configuração basta alterar "%any" para o IP público da outra ponta.
Caso o tunel esteja configurado no firewall, é necessário adicionar a seguinte regra:
iptables -A INPUT -p udp --dport 500 -j accept
Caso esteja em uma máquina atrás do firewall, a regra muda para:
iptables -t nat -A PREROUTING -p udp -d ip_publico --dport 500 -j DNAT --to ip_da_máquina
E também essa:
iptables -t nat -A PREROUTING -p udp -d ip_publico --dport 4500 -j DNAT --to ip_da_máquina
Agora é só configurar a outra ponta que pode ser outra máquina linux ou um equipamento como o Cisco RV042, utilizando as mesmas configurações porém não esquecendo de fazer as devidas alterações de IPs.
Lembrando que essa é uma VPN básica, existem muito mais recursos de segurança a serem explorados, e cabe a cada um decidir o que é necessário para cada caso.
Espero que tenha sido útil,
Até a próxima!!!
quarta-feira, 9 de janeiro de 2013
Script Para Redundancia Atualizado
Olá a todos!!!
Criei uma versão melhor do script de redundância de links dedicados, e a diferença agora é que ele testa apenas o link principal e caso esteja offline, ele muda para o link secundário. Quando o link principal volta, o script retorna para ele.
#!/bin/bash
# Script de redundancia de links dedicados
# Desenvolvido por Rodrigo Manzzato Alves Garcia em 08/10/2012
# Atualizado em 20/12/2012
PATH=/sbin:/usr/sbin:/bin:/usr/bin
# Informe abaixo o gateway principal
GW_PRIMARIO=""
# Informe abaixo os IPs primários de teste
IP_TESTE_PRIMARIO1=""
IP_TESTE_PRIMARIO2=""
# Informe abaixo o IP do link primario
IP_PRIMARIO_ROUTER=""
# Informe abaixo o gateway do link secundario
GW_SECUNDARIO=""
# Informe abaixo o IP do link secundario
IP_SECUNDARIO_ROUTER=""
# Armazenar gateway padrao na variavel GW_ATUAL
GW_ATUAL=`netstat -nr | awk '$1 ~ /^[0.0.0.0]/ {print $2}'`
# ATENCAO!!! A secao abaixo so deve ser alterada com absoluta certeza de que sabe o que esta fazendo!!!
# Funcao para troca do gateway
function GATEWAY()
{
netstat -nr | awk -v gw2="$GW2" -v gw="$GW" 'NR > 1 {if ($2 == gw2) print "route add -net " $1 FS "netmask " $3 " gw " gw > "/etc/network/gateway";}'
netstat -nr | awk -v gw2="$GW2" 'NR > 2 {if ($2 == gw2) print "route del -net " $1 FS "netmask " $3 " gw " gw2 > "/etc/network/gateway_del";}'
while read ROTA2
do
echo -e "`$ROTA2`"
done < /etc/network/gateway_del
while read ROTA
do
echo -e "`$ROTA`"
done < /etc/network/gateway
}
# Backup das rotas existentes
echo "#!/bin/bash" > /etc/network/rotas.sh
netstat -nr | awk 'length($2) > 7' | awk 'NR > 1 {print "route add -net " $1 FS "netmask " $3 " gw " $2}' >> /etc/network/rotas.sh
# Teste das redes
ping -c4 $IP_TESTE_PRIMARIO1 -I $IP_PRIMARIO_ROUTER >> /dev/null
if [ $? = "0" ]
then
if [ $GW_ATUAL = "$GW_PRINCIPAL" ]
then
exit
else # Troca de Gateway caso o link atual não for o principal
GW=$GW_PRIMARIO
GW2=$GW_SECUNDARIO
GATEWAY
echo `date` "Rede Principal Ativada" >> /etc/network/gateway.log
exit
fi
else
ping -c4 $IP_TESTE_PRIMARIO2 -I $IP_PRIMARIO_ROUTER >> /dev/null
if [ $? = "0" ]
then
exit
else # Troca de Gateway caso o link atual não estiver respondendo
GW=$GW_SECUNDARIO
GW2=$GW_PRIMARIO
GATEWAY
echo `date` "Rede Secundaria Ativada" >> /etc/network/gateway.log
exit
fi
fi
Espero que seja útil!!!
Até a próxima!!!
Criei uma versão melhor do script de redundância de links dedicados, e a diferença agora é que ele testa apenas o link principal e caso esteja offline, ele muda para o link secundário. Quando o link principal volta, o script retorna para ele.
#!/bin/bash
# Script de redundancia de links dedicados
# Desenvolvido por Rodrigo Manzzato Alves Garcia em 08/10/2012
# Atualizado em 20/12/2012
PATH=/sbin:/usr/sbin:/bin:/usr/bin
# Informe abaixo o gateway principal
GW_PRIMARIO=""
# Informe abaixo os IPs primários de teste
IP_TESTE_PRIMARIO1=""
IP_TESTE_PRIMARIO2=""
# Informe abaixo o IP do link primario
IP_PRIMARIO_ROUTER=""
# Informe abaixo o gateway do link secundario
GW_SECUNDARIO=""
# Informe abaixo o IP do link secundario
IP_SECUNDARIO_ROUTER=""
# Armazenar gateway padrao na variavel GW_ATUAL
GW_ATUAL=`netstat -nr | awk '$1 ~ /^[0.0.0.0]/ {print $2}'`
# ATENCAO!!! A secao abaixo so deve ser alterada com absoluta certeza de que sabe o que esta fazendo!!!
# Funcao para troca do gateway
function GATEWAY()
{
netstat -nr | awk -v gw2="$GW2" -v gw="$GW" 'NR > 1 {if ($2 == gw2) print "route add -net " $1 FS "netmask " $3 " gw " gw > "/etc/network/gateway";}'
netstat -nr | awk -v gw2="$GW2" 'NR > 2 {if ($2 == gw2) print "route del -net " $1 FS "netmask " $3 " gw " gw2 > "/etc/network/gateway_del";}'
while read ROTA2
do
echo -e "`$ROTA2`"
done < /etc/network/gateway_del
while read ROTA
do
echo -e "`$ROTA`"
done < /etc/network/gateway
}
# Backup das rotas existentes
echo "#!/bin/bash" > /etc/network/rotas.sh
netstat -nr | awk 'length($2) > 7' | awk 'NR > 1 {print "route add -net " $1 FS "netmask " $3 " gw " $2}' >> /etc/network/rotas.sh
# Teste das redes
ping -c4 $IP_TESTE_PRIMARIO1 -I $IP_PRIMARIO_ROUTER >> /dev/null
if [ $? = "0" ]
then
if [ $GW_ATUAL = "$GW_PRINCIPAL" ]
then
exit
else # Troca de Gateway caso o link atual não for o principal
GW=$GW_PRIMARIO
GW2=$GW_SECUNDARIO
GATEWAY
echo `date` "Rede Principal Ativada" >> /etc/network/gateway.log
exit
fi
else
ping -c4 $IP_TESTE_PRIMARIO2 -I $IP_PRIMARIO_ROUTER >> /dev/null
if [ $? = "0" ]
then
exit
else # Troca de Gateway caso o link atual não estiver respondendo
GW=$GW_SECUNDARIO
GW2=$GW_PRIMARIO
GATEWAY
echo `date` "Rede Secundaria Ativada" >> /etc/network/gateway.log
exit
fi
fi
Espero que seja útil!!!
Até a próxima!!!
quarta-feira, 2 de janeiro de 2013
Plugin para Nagios
Olá a Todos!!!
Recentemente instalei o Nagios a fim de monitorar meus servidores e roteadores. Senti falta porém de um plugin que checasse a memória ram. Desenvolvi então um plugin em shell script chamado "check_ram":
#!/bin/bash
# Desenvolvido por Rodrigo Garcia em 16/01/2013
# Sobrevivi ao fim do mundo!!!
PATH=/sbin:/usr/sbin:/bin:/usr/bin
TMEM=`free -m | awk 'NR == 2 {print $2}'`
UMEM=`free -m | awk 'NR == 3 {print $3}'`
FMEM=`free -m | awk 'NR == 3 {print $4}'`
PMEM=`echo $((UMEM * 100 / $TMEM))`
if [ $PMEM -lt $1 ]
then
echo "Total(MB)= $TMEM, Uso(MB)= $PMEM%, Livre(MB)= $FMEM OK"
exit 0
elif [ $PMEM -ge $1 ] && [ $PMEM -lt $2 ]
then
echo "Total(MB)= $TMEM, Uso= $PMEM% , Livre(MB)= $FMEM Atencao!!!"
exit 1
elif [ $PMEM -ge $1 ]
then
echo "Total(MB)= $TMEM, Uso(MB)= $PMEM%, Livre(MB)= $FMEM Critico!!!"
exit 2
fi
Sua execução deve conter como parâmetro os níveis de warning e critical pelo valor da porcentagem, por exemplo:
./check_ram 80 90
É isso aí, espero que seja útil!!!
Até a próxima!!!
Recentemente instalei o Nagios a fim de monitorar meus servidores e roteadores. Senti falta porém de um plugin que checasse a memória ram. Desenvolvi então um plugin em shell script chamado "check_ram":
#!/bin/bash
# Desenvolvido por Rodrigo Garcia em 16/01/2013
# Sobrevivi ao fim do mundo!!!
PATH=/sbin:/usr/sbin:/bin:/usr/bin
TMEM=`free -m | awk 'NR == 2 {print $2}'`
UMEM=`free -m | awk 'NR == 3 {print $3}'`
FMEM=`free -m | awk 'NR == 3 {print $4}'`
PMEM=`echo $((UMEM * 100 / $TMEM))`
if [ $PMEM -lt $1 ]
then
echo "Total(MB)= $TMEM, Uso(MB)= $PMEM%, Livre(MB)= $FMEM OK"
exit 0
elif [ $PMEM -ge $1 ] && [ $PMEM -lt $2 ]
then
echo "Total(MB)= $TMEM, Uso= $PMEM% , Livre(MB)= $FMEM Atencao!!!"
exit 1
elif [ $PMEM -ge $1 ]
then
echo "Total(MB)= $TMEM, Uso(MB)= $PMEM%, Livre(MB)= $FMEM Critico!!!"
exit 2
fi
Sua execução deve conter como parâmetro os níveis de warning e critical pelo valor da porcentagem, por exemplo:
./check_ram 80 90
É isso aí, espero que seja útil!!!
Até a próxima!!!
Assinar:
Postagens (Atom)