Servidor Linux Com Proxy e Controle de Banda
Servidor Linux Com Proxy e Controle de Banda
Servidor Linux Com Proxy e Controle de Banda
Vou mostrar como configurar um servidor Linux para compartilhar a internet de maneira mais segura com
firewall bloqueando máquinas não cadastradas, proxy Squid fazendo cache full e controle de banda com
CBQ.
Um servidor desse tipo é uma excelente opção custo/benefício para pequenas e médias empresas, para
pequenos provedores de internet (ISP) ou mesmo para quem deseja apenas compartilhar a internet entre
vizinhos.
Dessa vez é um artigo mais prático e menos teórico. Não vou entrar em explicações sobre o que é um
proxy, como funciona o controle de banda ou tabelas do iptables.
O artigo foi divido em 3 partes:
Introdução
O uso do GNU/Linux em servidores vem crescendo a cada ano. Não só pelo custo zero com licenças mas
também por sua superior vantagem em desempenho, segurança e estabilidade em relação à outros sistemas
operacionais.
Graças ao Linux e aos softwares open source descritos nesse artigo é possível criar uma solução
economicamente viável para empresas que ainda não dispõem de uma estrutura adequada para
compartilhar a internet.
Nesse exemplo vamos instalar o proxy Squid na mesma máquina que funciona como gateway. Com o
crescimento da rede, é aconselhável separar um ou mais servidores apenas para proxy e definindo as rotas
manualmente no gateway.
A distribuição utilizada foi Ubuntu Server 9.04 mas nada impede que seja aplicada à outras distros.
Primeiro foi feito o download do patch ZPH usando o software wget. Depois foi baixado o source do
squid3 diretamente dos repositórios do Ubuntu e então, usando o apt-get build-dep squid3, foi criado
o diretório squid3-3.0.STABLE8 e instaladas as dependências necessárias para compilar o squid. Após
isso, entrei no diretório contendo o source do Squid, apliquei o patch ZPH (comando patch -p1) e com
isso foram criados os pacotes no formato deb para instalação. Para instalar basta usar o dpkg -i em cada
pacote no formato deb.
root@localhost:~/squid3-3.0.STABLE8# cd ..
root@localhost:~# dpkg -i squid3_3.0.STABLE8-3+lenny2build0.9.04.1_i386.deb
root@localhost:~# dpkg -i squid3-common_3.0.STABLE8-3+lenny2build0.9.04.1_all.deb
root@localhost:~# dpkg -i squid3-cgi_3.0.STABLE8-3+lenny2build0.9.04.1_i386.deb
root@localhost:~# dpkg -i squidclient_3.0.STABLE8-3+lenny2build0.9.04.1_i386.deb
Configurando o squid.conf
A localização do arquivo deve ser /etc/squid3/squid.conf.
Inciando o Squid
Criando a estrutura de diretórios e iniciando o serviço:
root@localhost:~# squid -z
root@localhost:~# /etc/init.d/squid3 start
Para testar o funcionamento basta configurar o browser para acessar via proxy usando o IP 127.0.0.1 e
porta 3128. Se navegar na internet significa que funcionou, se não, leia os arquivos de log para tentar
identificar o problema.
Conclusão
É possível que ocorra algum problema seguindo os passos descritos nesse artigo. O motivo se deve ao fato
de que tive que simplificar bastante os passos para servir como um exemplo genérico.
Problemas ou dúvidas ficarei feliz em poder ajudar.
Feliz natal à todos!
Servidor Linux com Proxy e Controle de Banda – Parte 2
Introdução
Nessa segunda parte do artigo vou mostrar como criar um shell script usando o iptables para filtragem de
pacotes e CBQ para controle de banda.
O script está fácil de entender e sua utilização é bem simples. É necessário criar um arquivo texto contento
informações sobre cada máquina cliente que possui acesso à internet. Informações como IP, MAC,
Download, Upload, se vai passar pelo Squid e se está bloqueado o acesso. Com base nestas informações, o
script cria as regras no firewall bloqueando ou liberando acessos, amarrando IP ao endereço MAC, faz
proxy transparente e determina qual a velocidade de download e upload para cada um. Fora isso, é criado o
arquivo /etc/dhcpd.con usado pelo servidor DHCP associando o IP ao seu MAC, fazendo com que um
cliente obtenha sempre o mesmo IP.
#!/bin/bash
ARQUIVO="/var/www/bandcontrol/scripts/pontosderede.txt" # Contem os pontos de rede
cadastrados
MOD=$(which modprobe) # Comando para carregar modulos do kernel
IPT=$(which iptables) # Caminho do iptables
TC=$(which tc) # tc (pacote iproute2)
I_WAN="eth0" # Interface internet
I_LAN1="eth1" # Interface Rede local
GATEWAY_IP="192.168.254.254"
NETMASK="255.255.255.0"
CLASSE_LAN1="192.168.254" # Classe de IP utilizada na rede local.
Ex.: 10.0
PROXY_SERVER="$GATEWAY_IP:3128" # O proprio gateway tambem roda o Squid
na porta 3128
DHCPD_DAEMON="/etc/init.d/dhcp3-server" # Executavel do dhcpd server
DHCPDCONF="/etc/dhcp3/dhcpd.conf" # Arquivo de configuracao do dhcpd
DOMINIO="gustavohenrique.net" # Dominio ao qual a rede faz parte
DNS_SERVERS="$GATEWAY_IP, 8.8.8.8, 4.2.2.2" # Servidores DNS. O primeiro é o próprio
gateway
# Remove o controle de banda
function parar_controle_de_banda {
$TC qdisc del dev $I_LAN1 root
$TC qdisc del dev $I_WAN root
}
# Cria as regras iniciais para controle de banda
function iniciar_controle_de_banda {
# Remove as regras do controle de banda
parar_controle_de_banda
# Download
$TC qdisc add dev $I_LAN1 root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8
$TC class change dev $I_LAN1 root cbq weight 10Mbit allot 1514
# Upload
$TC qdisc add dev $I_WAN root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8
$TC class change dev $I_WAN root cbq weight 10Mbit allot 1514
# Cache Full. Pacotes marcados com TOS 60 vao para a classe 1:9999 cuja banda é
100 Mbit (rede ethernet)
$TC class add dev $I_LAN1 parent 1: classid 1:9999 cbq bandwidth 100Mbit rate
100Mbit weight 10Mbit prio 4 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded
$TC filter add dev $I_LAN1 parent 1:0 protocol ip prio 3 u32 match ip protocol 0x6
0xff match ip tos 60 0xff classid 1:9999
}
# Limpa o firewall
function parar_firewall() {
# Configura a politca padrao para aceitar tudo
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
# Limpa a tabela netfilter
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
}
# Cria as regras de firewall
function iniciar_firewall() {
# Finaliza o script se nao existir o arquivo contendo os pontos de rede
if [ ! -f $ARQUIVO ]; then
echo "Arquivo contendo os pontos de rede ($ARQUIVO) nao existe.";
exit 0
fi
# Carrega modulos do iptables
$MOD ip_tables
$MOD iptable_nat
$MOD ipt_MASQUERADE
$MOD ipt_LOG
$MOD ipt_REJECT
$MOD ip_conntrack_ftp
$MOD ip_nat_ftp
# Limpa todas as regras do firewall
parar_firewall
# Recria as regras para controle de banda
iniciar_controle_de_banda
# Por padrao bloqueia tudo que for entrar no firewall
$IPT -P INPUT DROP
$IPT -t nat -P PREROUTING DROP
# Habilita redirecionamento de pacotes para compartilhar internet
echo 1 > /proc/sys/net/ipv4/ip_forward
# Aumenta o limite do nf_conntrack_max
echo 99999 > /proc/sys/net/netfilter/nf_conntrack_max
# Libera acesso para pacotes vindos da internet (CUIDADO)
$IPT -t nat -A PREROUTING -s 0/0 -i $I_WAN -p all -j ACCEPT
$IPT -A INPUT -i $I_WAN -j ACCEPT
# Cria uma nova chain para tratar do proxy transparente
$IPT -t nat -N proxy
# O software conectividade social da Caixa Economica nao funciona se
# estiver passando pelo proxy. Tudo que for destinado ao IP da Caixa
# nao vai passar pelo proxy
$IPT -t nat -A proxy -p tcp -d 200.201.174.0/16 --dport 80 -j ACCEPT
$IPT -t nat -A proxy -p tcp -d 200.201.173.0/16 --dport 80 -j ACCEPT
$IPT -t nat -A proxy -p tcp -d 200.201.0.0/16 --dport 80 -j ACCEPT
$IPT -t nat -A proxy -p tcp -d 200.201.174.207 --dport 80 -j ACCEPT
# Internet Caixa nao passa pelo proxy
$IPT -t nat -A proxy -p tcp -d 200.201.169.0/8 --dport 80 -j ACCEPT
$IPT -t nat -A proxy -p tcp -d 200.201.169.69 --dport 80 -j ACCEPT
# Esse servidor tambem roda o Apache na port 80. Nao quero que as
# paginas locais passem pelo proxy, pois assim posso controlar a banda
# de pacotes vindos do apache definindo a velocidade máxima da rede
$IPT -t nat -A proxy -p tcp -d $GATEWAY_IP --dport 80 -j ACCEPT
# Proxy transparente redirecionando os pacotes para a porta do Squid
$IPT -t nat -A proxy -s 0/0 -p tcp --dport 80 -j DNAT --to-dest $PROXY_SERVER
# Se o pacote nao for pra porta 80 (não é navegação), deixa passar
$IPT -t nat -A proxy -i $I_LAN1 -j ACCEPT
# Libera o IP abaixo sem amarrar com MAC e sem passar pelo proxy
#$IPT -t nat -A PREROUTING -i $I_LAN1 -s 192.168.254.2 -j ACCEPT
# Configuracao inicial do dhcpd.conf. Distribuicao de IPs na faixa 192.168.254.80
a 192.168.254.90
echo "# Arquivo dhcpd.conf criado pelo BandControl" > $DHCPDCONF
echo "ddns-update-style none;" >> $DHCPDCONF
echo "option domain-name \"$DOMINIO\";" >> $DHCPDCONF
echo "option domain-name-servers $DNS_SERVERS;" >> $DHCPDCONF
echo "default-lease-time 600;" >> $DHCPDCONF
echo "max-lease-time 7200;" >> $DHCPDCONF
echo "authoritative;" >> $DHCPDCONF
echo "shared-network 0-2 {" >> $DHCPDCONF
echo " subnet $CLASSE_LAN1"."0 netmask $NETMASK { range $CLASSE_LAN1.80
$CLASSE_LAN1.90; }" >> $DHCPDCONF
echo "}" >> $DHCPDCONF
# Inicio do loop para liberacao e bloqueio de clientes.
# O formato do arquivo é: codigo_identificador-descricao-ip-mac-download-upload-
liberado-proxy
# Ex.: 1-gustavo_henrique_notebook-192.168.254.10-512-256-S-S
# Acesso liberado e uso do proxy sao valores que devem ser True ou False
for i in `cat $ARQUIVO`; do
CODIGO=$(echo $i | awk -F "-" {'print $1'}) # Numero usado
como identificador no controle de banda
IP=$(echo $i | awk -F "-" {'print $3'}) # IP
MAC=$(echo $i | awk -F "-" {'print $4'}) # MAC em letras
minusculas e separado por dois pontos (:)
DOWNLOAD=$(echo $i | awk -F "-" {'print $5'}) # Numero
correspondente a velocidade de download em Kbit
UPLOAD=$(echo $i | awk -F "-" {'print $6'}) # Numero
correspondente a velocidade de upload em Kbit
POSSUI_ACESSO_LIBERADO=$(echo $i | awk -F "-" {'print $7'}) # True para sim,
False para bloquear o acesso
VAI_USAR_PROXY=$(echo $i | awk -F "-" {'print $8'}) # True para usar
o proxy, False para não usar
# Configurar dhcpd para associar IP ao MAC
if [ "$MAC" != "" ]; then
LINHA="host $CODIGO { hardware ethernet $MAC; fixed-address $IP; option
subnet-mask $NETMASK; option routers $GATEWAY_IP; option domain-name-servers
$DNS_SERVERS; }"
echo $LINHA >> $DHCPDCONF
fi
# Se o IP nao esta liberado, bloqueia no firewall
if [ "$POSSUI_ACESSO_LIBERADO" == "False" ]; then
EXECUTAR_REGRA="$IPT -t nat -A PREROUTING -p tcp -i $I_LAN1 -s $IP -j
DROP"
else
if [ "$VAI_USAR_PROXY" == "True" ]; then
EXECUTAR_REGRA="$IPT -t nat -A PREROUTING -i $I_LAN1 -s $IP -m mac
--mac-source $MAC -j proxy"
else
EXECUTAR_REGRA="$IPT -t nat -A PREROUTING -i $I_LAN1 -s $IP -j ACCEPT"
fi
fi
# Executa a regra referente ao IP dentro do loop
$EXECUTAR_REGRA
# Aplica o controle de banda ao IP. Para cada IP é criada uma classe de
download e upload.
WEIGHT_DOWN=$(expr $DOWNLOAD / 10)
ID_DOWN=1"$CODIGO"
$TC class add dev $I_LAN1 parent 1: classid 1:$ID_DOWN cbq bandwidth 10Mbit
rate "$DOWNLOAD"Kbit weight "$WEIGHT_DOWN"Kbit prio 5 allot 1514 cell 8 maxburst 20
avpkt 1000 bounded
$TC filter add dev $I_LAN1 parent 1:0 protocol ip prio 100 u32 match ip dst
$IP classid 1:$ID_DOWN
WEIGHT_UP=$(expr $UPLOAD / 10)
ID_UP=2"$CODIGO"
$TC class add dev $I_WAN parent 1: classid 1:$ID_UP cbq bandwidth 10Mbit rate
"$UPLOAD"Kbit weight "$WEIGHT_UP"Kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000
bounded
$TC qdisc add dev $I_WAN parent 1:$ID_UP handle $ID_UP tbf rate "$UPLOAD"Kbit
buffer 10Kb/8 limit 15Kb mtu 1500
$TC filter add dev $I_WAN parent 1:0 protocol ip prio 100 u32 match ip src $IP
classid 1:$ID_UP
done
# Aplica o TOS 60 nas portas utilizadas por outros serviços. Assim é usado a
velocidade total da rede
# para acesso ao SSH, Apache e Samba
$IPT -t mangle -A OUTPUT -p tcp --sport 22 -j TOS --set-tos 60
$IPT -t mangle -A OUTPUT -p tcp --sport 80 -j TOS --set-tos 60
$IPT -t mangle -A OUTPUT -p tcp --sport 137:139 -j TOS --set-tos 60
$IPT -t mangle -A OUTPUT -p udp --sport 137:139 -j TOS --set-tos 60
$IPT -t mangle -A INPUT -p tcp --dport 137:139 -j TOS --set-tos 60
$IPT -t mangle -A INPUT -p udp --dport 137:139 -j TOS --set-tos 60
# Compartilha a internet
$IPT -t nat -A POSTROUTING -o $I_WAN -j MASQUERADE
# Bloqueio contra Scanners Ocultos (Shealt Scan)
$IPT -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j DROP
# Libera ping (CUIDADO com ataques ddos)
$IPT -A INPUT -i $I_LAN1 -p icmp -j ACCEPT
$IPT -A INPUT -i $I_WAN -p icmp -j ACCEPT
# Libera acesso para o proprio gateway
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A FORWARD -i lo -j ACCEPT
# Libera acesso ao Apache
$IPT -A INPUT -p tcp --dport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT
# Libera acesso ao Squid
$IPT -A INPUT -p tcp --dport 3128 -j ACCEPT
# Libera acesso ao SSH
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
# Libera acesso ao DNS
$IPT -A INPUT -p udp --dport 53 -j ACCEPT
# Libera acesso aos compartilhamentos do Samba
$IPT -A INPUT -p tcp --dport 137:139 -j ACCEPT
$IPT -A INPUT -p udp --dport 137:139 -j ACCEPT
# Libera acesso ao SNMP
#$IPT -A INPUT -p udp --dport 160:162 -j ACCEPT
# Tratamento de conexoes TCP
$IPT -A INPUT -p tcp --syn -j DROP
$IPT -A INPUT -p tcp -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
$IPT -A INPUT -m limit --limit 3/minute --limit-burst 3 -j DROP
# Bloqueando pacotes estranhos
$IPT -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL FIN -j DROP
$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
echo "Firewall iniciado"
}
case $1 in
# Inicia o firewall e o dhcpd
start) iniciar_firewall; $DHCPD_DAEMON stop; $DHCPD_DAEMON start; exit ;;
# Finaliza o firewall sem parar o dhcp
stop) parar_firewall; exit ;;
# Inicia o firewall sem reiniciar o dhcpd
only) iniciar_firewall; exit ;;
# Finaliza o controle de banda
fast) parar_controle_de_banda; exit ;;
# Se nenhum parametro for passado, mostra a ajuda abaixo
*) echo "Use assim: $0 start|stop|only|fast"; exit 1;;
esac
Conclusão
Com o término da segunda parte do artigo é possível colocar um servidor Linux funcionando com
eficiência, segurança e estabilidade para compartilhar uma conexão de internet. É uma ótima solução
custo/benefício para micro e pequenas empresas.
Na próxima parte vou mostrar como desenvolver uma interface web para gerenciar melhor os pontos de
rede. Isso dá mais agilidade ao trabalhar com muitas máquinas na rede.
Algumas considerações:
Tomem cuidado na configuração do firewall. Esse é um script simples que serve não deve ser
tomado como solução definitiva.
Há outra alternativa para controle de banda chamada HTB. Pessoalmente prefiro o CBQ, o mesmo
utilizado nesse script, mas vale a pena dar uma estudada.
Usar um arquivo texto contendo os dados dos pontos de rede para ser lido pelo shell script foi a
idéia mais simples e não a de melhor desempenho. Também fiz o script fazer consultas ao MySQL
mas não senti diferença na velocidade comparado com a leitura de um arquivo de texto.
Bom, a parte 3 do artigo só em 2010. Nesse momento já estou em algum lugar sem internet e talvez sem
celular.
Feliz ano novo à todos!
Instalação
Há diversas maneiras de se instalar um sistema feito em django. Vou mostrar como fazer o deploy usando
Apache2 com o módulo mod_wsgi.
O ambiente completo usa Apache2, sqlite3, python-2.6 e Django-1.1.
O diretório web padrão do Apache no Ubuntu é o /var/www. Vamos manter assim. Faça o download do
Bandcontrol pelo site github.com (no site, clique no botão Download Source), descompacte no /var/www,
renomeie o diretório para bandcontrol e altere o dono/grupo de acordo com o usuário do apache.
Os shell scripts usam o Iptables para firewall e TC para controle de banda. É necessário permissão de
super usuário para executar esses comandos. Vamos configurar o sudo para que o usuário do Apache possa
executar tais comandos como root.
WSGIRestrictStdout Off
NameVirtualHost bandcontrol
<VirtualHost bandcontrol>
ServerAdmin webmaster@localhost
LimitInternalRecursion 1000
ServerName bandcontrol
<Directory /var/www/bandcontrol>
Options ExecCGI FollowSymLinks MultiViews
AllowOverride FileInfo
MultiviewsMatch Handlers
Order deny,allow
Allow from all
</Directory>
ErrorLog /var/log/apache2/bandcontrol_error.log
CustomLog /var/log/apache2/bandcontrol_access.log combined
WSGIScriptAlias / "/var/www/bandcontrol/config.wsgi"
Alias /admin_media/ "/usr/lib/pymodules/python2.6/django/contrib/admin/media/"
Alias /media/ "/var/www/bandcontrol/media/"
</VirtualHost>
127.0.0.2 bandcontrol
Configuracao do Bandcontrol
Por padrão é utilizado o banco de dados sqlite3. Você pode escolher usar o MySQL ou PostgreSQL
editando o arquivo /var/www/bandcontrol/settings.py.
Para criar o BD, entre no diretório do bandcontrol e execute o comando manage.py syncdb. Digite yes
para confirmar a criação do super usuário. Forneça um login, e-mail e senha:
Utilização
Abra o browser e acesse http://bandcontrol/.
Reparem que no campo de endereço da URL e os nomes de usuário utilizados não condizem com o que foi
exemplificado nesse artigo. Bom... estou com preguiça para alterar as imagens, então vamos desconsiderar
esse "bug".
Volte à tela inicial, clique em Pontos de Rede. No menu superior há opção para executar o firewall, parar o
controle de banda e exibir os IPs conectados ao servidor. Sempre que fizer alguma alteração no sistema
deve executar o firewall para ativar as mudanças.
Em exibir IPs conectados, para adicionar um IP no sistema forneça uma descrição única, escolha o plano e
clique em [+].
O bandcontrol permite criar outros usuários com acesso ao sistema. Trabalha com permissões e grupos.
Cortesia do Django \o/
Conclusão
Bandcontrol foi uma daquelas coisas "pra ontem". Foi feito em uma tarde de terça-feira. Tal velocidade se
deve ao framework Django.
Esse artigo foi escrito um pouco de cada vez, por isso há grandes chances de algo sair errado. Há muito
material disponível na web sobre deploy de projetos em Django. Em caso de dúvidas estarei disposto a
ajudar.
1. Rogerpgu disse:
Oi, estou executando esse procedimento para utilizar numa lan com 10 pcs. Ocorre o seguinte:
O comando patch -p1 ../squid-3.0.STABLE8-zph.patch quando executado o pc para, tipo fica
ligado, cursor piscando e não volta ao prompt.
Ele demora mesmo pra executar esse passo ou estou com um problema de instalação?
O Hardware utilizado (pra teste apenas) é um k6-II 300Mhz em uma pcchips 5598 (sis530), com
256mb de ram pc133.
Alguma idéia?
Responder
2. Beto disse:
valew
Responder
3. Beto disse:
olá so eu dinovo..
parçeiro o comando ai tava foltando um detalhe era pra ser assim
entar no diretorio:
cd squid3-3.0.STABLE8
depois:
valew
Responder
o Rogerpgu disse:
Isso mesmo. Aqui enfim deu certo. Faltava o “<" para funcionar.
Depois disso funcionou 100%
Valeu Beto
Responder
4. Rogerpgu disse:
1. Rodrigo disse:
Responder
2. william disse:
como posso instala esse sistema no fedora 8,pois estou tentando e não estou conseguindo
Responder