Português do Brasil English
Devin no Facebook  Devin no Twitter  RSS do Site 
Servidores    

Proxy para ambientes mistos


Comentários  8
Visualizações  
440.636

Introdução

Ainda me lembro, de uns 10 anos atrás, quando comecei a mexer com programação para Web. Me diverti bastante com o assunto, mas como minha área era realmente Redes e Infraestrutura, acabei rumando para um misto dos dois: Redes e Infraestrutura para sistemas de Internet. Ao longo de minha experiência, trabalhei com gente que fazia pequenos sites, até gente que fazia grandes blogs e portais.

Em quase todos os casos, sempre havia ambientes mistos para o desenvolvimento e testes das aplicações. Geralmente são esses três ambientes:

  • Desenvolvimento – Onde realmente os desenvolvedores trabalham, onde o código está sempre cutting-edge e as coisas quebram o tempo todo, consertando-se num passe de mágica. Muitas vezes está localizado na própria máquina do desenvolvedor, dependendo do tamanho do projeto e da equipe.
  • Homologação – Ambiente onde depois de um freeze do site, que a equipe acha que está estável, põe-se o produto para funcionar e fazer vários testes. Este ambiente deve ser fiel ao de produção, pois a validação (como o nome diz) tem que ser feita nele antes de qualquer tipo de lançamento.
  • Produção – Depois de tudo desenvolvido e testado, o ambiente de produção é justamente aquele em que o site vai funcionar para o “mundo”. Depois de se certificar que tudo está certo, coloca-se em produção e só se altera se for validado tudo em homologação antes.

O cenário perfeito seria esse, mas falar é fácil demais, né? Os problemas já começam no Desenvolvimento, quando o ambiente já é diferente da homologação. O desenvolvedor constrói um código que funciona às maravilhas, mas na hora de colocar em homologação, nada funciona. E então na produção, nem se fala…

O desenvolvedor tem que estar ciente sobre o que faz no código: bons programadores sempre pensam macro – e assim conseguem prever diferenças entre ambientes. Essa característica do perfeccionismo é uma boa qualidade quando os prazos não estão já estourados, mas não podemos sempre contar com isso ao nosso lado, pois há diversas variáveis em jogo que podem não garantir muito bem isso.

Então é aí que entra a parte da galera de Redes e Infraestrutura: ajudar os desenvolvedores a trabalhar. No caso dos ambientes, isso significa deixar os 3 ambientes iguais. E quem trabalha com isso sabe muito bem que é bastante difícil… Mas de vez em quando vou dar algumas dicas baseadas em experiências e sugestões que vou obtendo no trabalho.

O problema com as URLs

O primeiro problema que podemos enfrentar são as benditas URLs. Cada servidor Web pode estar configurado para responder por domínios diferentes. Por exemplo, um mesmo site de uma empresa Mega Radical Enterprise tem os três ambientes que citei acima, mas configurados da seguinte forma:

  • Desenvolvimento: http://devel.intranet.megaradicalenterprises.com.br (IP interno: 192.168.0.20)
  • Homologação: http://homol.intranet.megaradicalenterprises.com.br (IP interno: 192.168.1.20)
  • Produção: http://www.megaradicalenterprises.com.br (IP Externo: 200.xxx.xxx.xxx)

E ainda por cima, o site utiliza segregação de domínios para imagens e scripts (o que é recomendável para sites grandes), utilizando sub-domínios img e js para cada um desses sites. Imagine o terror que é para administrar tudo isso na aplicação, fica muito mais complicado. Então entra a parte em que falei que o desenvolvedor sempre que estar ciente dessas mudanças e programar ‘macro’… ou não…

Este problema poderia ser facilmente resolvido editando o arquivo hosts do Linux (ou Windows) em cada uma das máquinas. Mas em um ambiente com mais de 10 desenvolvedores e muitos sites e sistemas sendo desenvolvidos, fica meio inviável ficar administrando isso em cada máquina. Então descartando essa idéia, temos…

Uma solução com Proxies

Uma das soluções para unificar essas URLs apareceu com uma sugestão dos colegas de trabalho Denis Almeida Vieira (@davieira) e Rainer Alves (@rainer_alves), que seria usar Proxies para cada ambiente. Quando um usuário precisar acessar um ambiente, ele muda a configuração do proxy no navegador e o proxy se encarrega de direcionar os domínios pro lugar correto. Aliando essa facilidade com algum plugin que troca proxies de forma fácil no navegador, os desenvolvedores e usuários conseguem acessar os ambientes muito mais facilmente.

Para não ter que ficar criando uma máquina para cada Proxy e ambiente diferente, utilizei a seguinte topologia:

Diagrama de Proxies para Ambientes Mistos

Diagrama de Proxies para Ambientes Mistos

Como o DNS está usando Views, dependendo do IP do cliente, um domínio vai ter uma resposta diferente. Por exemplo:

  • Cliente 192.168.0.1 consulta www.megaradicalenterprises.com.br, recebe resposta: 192.168.0.20
  • Cliente 192.168.0.2 consulta www.megaradicalenterprises.com.br, recebe resposta:192.168.1.20
  • Cliente 192.168.0.3 consulta www.megaradicalenterprises.com.br, recebe resposta:200.xxx.xxx.xxx

Ou seja, o mesmo domínio agora pode ter três tipos de resposta, exatamente o que a gente precisa. Do jeito que vamos fazer, como cada squid está atrelado a um IP da máquina, o cliente DNS dele terá sempre uma reposta de acordo com a view.

A única desvantagem que vejo neste modelo é que para cada domínio que você quiser usar nos três ambientes, terá que configurar as views do BIND para responder corretamente, ou seja, mais um ponto de administração de DNS, independente do DNS autoritário pro domínio. Mesmo assim, acredito que isso é pouco trabalho em compensação à vantagem.

Configuração da máquina DNS

Não vou entrar no mérito de configurar passo a passo todo o BIND, porque ao escrever esse tutorial, acho que quem o lê já tem boas noções sobre o assunto. Se não tiver, recomendo dar uma lida antes em outros materiais para aprender… :) Neste nosso método, vamos usar uma funcionalidade do BIND que vi poucas pessoas usarem por aí: views. Uma view funciona respondendo com configurações específicas, dependendo de qual cliente requisitar.

Agora lá vai uma configuração de exemplo para o BIND com três views (desenvolvimento, homologação e produção) para um mesmo domínio (megaradicalenterprises.com.br). Versão do BIND utilizada: 9.3.6. Como distribuição base para este tutorial, estou usando o RHEL/CentOS 5.x.

acl "proxy-dev" {
        192.168.0.1;
};

acl "proxy-homol" {
        192.168.0.2;
};

acl "proxy-prod" {
        192.168.0.3;
};

acl "ourselves" {
        192.168.0.1;
        192.168.0.2;
        192.168.0.3;
        192.168.0.10;
};

options {
        listen-on port 53 { localhost; 192.168.0.10; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";

        allow-query     { ourselves; };
        allow-query-cache { ourselves; };
};
logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

view localhost_resolver {
        match-clients      { localhost; };
        match-destinations { localhost; };
        recursion yes;
        include "/etc/named.rfc1912.zones";
};

view dev {
        match-clients { proxy-dev; };
        recursion yes;
        notify no;
        include "/etc/named.rfc1912.zones";

        zone "megaradicalenterprises.com.br" {
                type master;
                file "data/dev-db.megaradicalenterprises.com.br.zone";
        };
};

view homol {
        match-clients { proxy-homol; };
        recursion yes;
        notify no;
        include "/etc/named.rfc1912.zones";

        zone "megaradicalenterprises.com.br" {
                type master;
                file "data/homol-db.megaradicalenterprises.com.br.zone";
        };

};

view prod {
        match-clients { proxy-prod; };
        recursion yes;
        notify no;
        include "/etc/named.rfc1912.zones";
};

Na configuração acima, podemos ressaltar:

  • Criamos três ACLs para os nossos IPs do servidor de Proxy. As ACLs são usadas no match-clients de cada view. É assim que ele vai diferenciar que configuração vai usar pro domínio.
  • O arquivo /etc/named.rfc1912.zones contém configurações das zonas padrões, como o localhost, 127, além do servidores raízes. (zona “.”). É um arquivo que vem padrão na instalação do RHEL/CentOS 5.x e pode ser que não exista em outras distribuições.
  • Temos três zonas: dev, homol e prod. As zonas dev e homol têm diferentes arquivos de configuração de zona.
  • A zona prod não tem nenhum arquivo de configuração. Isso porque se é produção, tem que usar mesmo é o DNS real :-) Então ele ao invés de buscar a zona no BIND, faz o caminho normal pelo /etc/resolv.conf.

Agora vamos pros dois arquivos de configuração de zona:

  • /var/named/data/dev-db.megaradicalenterprises.com.br.zone
$TTL    60
@               IN SOA  @       master.megaradicalenterprises.com.br. (
                                        2010061700      ; serial
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum

@               IN NS           @

www        IN A            192.168.0.20
  • /var/named/data/homol-db.megaradicalenterprises.com.br.zone
$TTL    60
@               IN SOA  @       master.megaradicalenterprises.com.br. (
                                        2010061700      ; serial
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum

@               IN NS           @

www        IN A            192.168.1.20

Pronto. O BIND e suas views estão configuradas. Agora é só iniciar o serviço:

# /etc/init.d/named start

Ou no Debian/Ubuntu:

# /etc/init.d/bind9 start

E agora é hora de configurar o servidor Squid…

Configuração da máquina de Squid

Como vimos no diagrama, teremos três Squids, um para cada ambiente: desenvolvimento, homologação e produção. Aqui neste tutorial, decidi fazer os 3 squids funcionarem na mesma máquina. Mas nada impede que esta configuração fosse simplificada utilizando três máquinas diferentes. Neste caso, basta fazer alguns passos bem simples.

Configurando três proxies em três máquinas diferentes

Configure três máquinas com três IPs que estamos usando no exemplo deste tutorial:

  • Máquina com nome proxy-dev, IP 192.168.0.1
  • Máquina com nome proxy-homol, IP 192.168.0.2
  • Máquina com nome proxy-prod, IP 192.168.0.3

Não esqueça também de configurar o cliente DNS do sistema, deixando somente a seguinte linha no arquivo /etc/resolv.conf:

nameserver 192.168.0.10

Assim ele só vai consultar o DNS que configuramos antes e mais nada.

Depois instale o squid em cada das máquinas:

# yum install squid

Ou no Debian/Ubuntu:

# apt-get install squid

Depois é só iniciar o squid. Para cada máquina que você usar como proxy no navegador, o squid vai retornar um IP diferente para os domínios que você pedir a ele, exemplo:

[usuario@proxy-dev ~$] host www.megaradicalenterprises.com.br
www.megaradicalenterprises.com.br has address 192.168.0.20

[usuario@proxy-homol ~$] host www.megaradicalenterprises.com.br
www.megaradicalenterprises.com.br has address 192.168.1.20

[usuario@proxy-prod ~$] host www.megaradicalenterprises.com.br
www.megaradicalenterprises.com.br has address 200.xxx.xxx.xxx

Configurando três proxies em uma máquina

Pra economizar máquina, resolvi então criar os três proxies numa mesma máquina. Essa máquina, chamada proxy, é configurada com três interfaces de rede:

  • Desenvolvimento: eth0 – 192.168.0.1
  • Homologação: eth0:1 – 192.168.o.2 (IP alias)
  • Produção: eth0:2 – 192.168.0.3 (IP alias)

E então:

  • A configuração abaixo é muito específica para RHEL/CentOS 5.x.
  • Na configuração de cada squid, ele estará escutando apenas em um dos 3 IPs, de acordo com sua função.
  • Cada squid terá seus diretório de log e seu diretório de cache separados.
  • Cada processo do squid será executado por um usuário diferente no sistema.
  • O iptables se encarregará de forçar o usuário de cada squid a sair pelo IP correto para o DNS.

Então pra começar, instale o squid:

# yum install squid

Ou no Debian/Ubuntu:

# apt-get install squid

Agora crie os usuários adicionais para cada ambiente:

# adduser squid-dev
# adduser squid-homol
# adduser squid-prod

Pode deixar com a senha bloqueada mesmo. Agora crie os diretórios necessários de logs e cache e dê as devidas permissões:

# mkdir -p /var/log/squid-{dev,homol,prod} /var/spool/squid-{dev,homol,prod}
# chown -R squid-dev:squid-dev /var/log/squid-dev /var/spool/squid-dev
# chown -R squid-homol:squid-homol /var/log/squid-homol /var/spool/squid-homol
# chown -R squid-prod:squid-prod /var/log/squid-prod /var/spool/squid-prod

Agora um exemplo de arquivo de configuração padrão do squid, no nosso caso para o ambiente de desenvolvimento.

  • /etc/squid-dev.conf
pid_filename /var/run/squid-dev.pid

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl nois src 192.168.0.0/255.255.255.0
acl to_localhost dst 127.0.0.0/8

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT

http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

http_access allow localhost
http_access allow nois
http_access deny all

icp_access allow all

http_port 192.168.0.1:3128

hierarchy_stoplist cgi-bin ?

access_log /var/log/squid-dev/access.log squid
cache_log /var/log/squid-dev/cache.log
cache_store_log /var/log/squid-dev/store.log

acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY

refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .               0       20%     4320

acl apache rep_header Server ^Apache
broken_vary_encoding allow apache

coredump_dir /var/spool/squid-dev

visible_hostname proxy-dev.localdomain
cache_effective_user squid-dev
cache_effective_group squid-dev
cache_dir ufs /var/spool/squid-dev 100 16 256

Agora crie outros dois arquivos, substituindo apenas as linhas apresentadas abaixo:

  • /etc/squid/squid-homol.conf
pid_filename /var/run/squid-homol.pid
http_port 192.168.0.2:3128
access_log /var/log/squid-homol/access.log squid
cache_log /var/log/squid-homol/cache.log
cache_store_log /var/log/squid-homol/store.log
coredump_dir /var/spool/squid-homol
visible_hostname proxy-homol.localdomain
cache_effective_user squid-homol
cache_effective_group squid-homol
cache_dir ufs /var/spool/squid-homol 100 16 256
  • /etc/squid/squid-prod.conf
pid_filename /var/run/squid-prod.pid
http_port 192.168.0.3:3128
access_log /var/log/squid-prod/access.log squid
cache_log /var/log/squid-prod/cache.log
cache_store_log /var/log/squid-prod/store.log
coredump_dir /var/spool/squid-prod
visible_hostname proxy-prod.localdomain
cache_effective_user squid-prod
cache_effective_group squid-prod
cache_dir ufs /var/spool/squid-prod 100 16 256

Ou seja:

  • Cada arquivo de configuração usa o http_port para escutar em um IP específico, na porta 3128.
  • Cada um grava seus arquivos de log nos seus respectivos diretórios no /var/log.
  • Cada um grava seus arquivos de cache nos seus respectivos diretórios no /var/spool.
  • Os parâmetros cache_effective_user e cache_effective_group forçam o squid a ser executado como cada um desses usuários.

Inicialize os diretórios de cache:

# squid -f /etc/squid/squid-dev.conf -z -F -D
# squid -f /etc/squid/squid-homol.conf -z -F -D
# squid -f /etc/squid/squid-prod.conf -z -F -D

Então para executar o squid, basta fazer:

# squid -f /etc/squid/squid-dev.conf -D
# squid -f /etc/squid/squid-homol.conf -D
# squid -f /etc/squid/squid-prod.conf -D

Para facilitar a vida, modifiquei o initscript do RHEL/CentOS para fazer essas tarefas de forma padrão da distribuição. Se quiser usar dessa forma, primeiro crie os arquivos no /etc/sysconfig:

  • /etc/sysconfig/squid-dev
SQUID_OPTS="-f /etc/squid/squid-dev.conf -D"
SQUID_SHUTDOWN_TIMEOUT=100
  • /etc/sysconfig/squid-homol
SQUID_OPTS="-f /etc/squid/squid-homol.conf -D"
SQUID_SHUTDOWN_TIMEOUT=100
  • /etc/sysconfig/squid-prod
SQUID_OPTS="-f /etc/squid/squid-prod.conf -D"
SQUID_SHUTDOWN_TIMEOUT=100

Coloque os scripts em anexo abaixo no diretório /etc/init.d.

Depois:

# chmod 755 /etc/init.d/squid-{dev,homol,prod}
# chkconfig --add squid-dev
# chkconfig --add squid-homol
# chkconfig --add squid-prod
# chkconfig squid-dev on
# chkconfig squid-homol on
# chkconfig squid-prod on

E então é só iniciar (ou parar, ou reiniciar, etc…) o serviço:

# /etc/init.d/squid-dev start
# /etc/init.d/squid-homol start
# /etc/init.d/squid-prod start

Agora para finalizar, vamos usar o iptables para forçar a saída dos diferentes squids para os diferentes IPs:

# iptables -t nat -A POSTROUTING -m owner --uid-owner squid-dev -j SNAT --to-source 192.168.0.1
# iptables -t nat -A POSTROUTING -m owner --uid-owner squid-homol -j SNAT --to-source 192.168.0.2
# iptables -t nat -A POSTROUTING -m owner --uid-owner squid-prod -j SNAT --to-source 192.168.0.3

Os comandos do iptables podem ser colocados nos scripts de iniciação do sistema.

Agora façamos o teste do DNS!

[root@proxy ~#] su squid-dev -c "host www.megaradicalenterprises.com.br"
www.megaradicalenterprises.com.br has address 192.168.0.20

[root@proxy ~#] su squid-homol -c "host www.megaradicalenterprises.com.br"
www.megaradicalenterprises.com.br has address 192.168.1.20

[root@proxy ~#] su squid-prod -c "host www.megaradicalenterprises.com.br"
www.megaradicalenterprises.com.br has address 200.xxx.xxx.xxx

Pronto, agora a máquina do Proxy está configurada! Agora é hora dos clientes…

Configurando os clientes

Nos navegadores dos clientes, só precisamos agora configurar o proxy de acordo com o que queremos:

  • Ambiente Desenvolvimento: 192.168.0.1, porta 3128.
  • Ambiente Homologação: 192.168.0.2, porta 3128.
  • Ambiente Produção: 192.168.0.3, porta 3128.

Outra dica legal é utilizar um plugin de troca rápida de proxies. Por exemplo, o Firefox tem um plugin muito bom chamado FoxyProxy que com dois cliques você muda de uma configuração de proxy para outra, veja estes screenshots:

Tela de Configuração do FoxyProxy

Tela de Configuração do FoxyProxy

FoxyProxy e sua integração na barra de status

FoxyProxy e sua integração na barra de status

E com certeza tem outras extensões para outros navegadores que também facilitem a vida dessa troca de proxies no navegador. Só espero que você não esteja usando muito Internet Explorer pra desenvolver, porque sinceramente ele é uma droga :)

Conclusão

Este é apenas um passo em direção a um ambiente mais transparente para o desenvolvedor. Se você chegou até aqui, é porque realmente se interessou pelo assunto e trabalha nesse meio. Então se tiver alguma dúvida ou sugestão de outros problemas que enfrentamos no dia-a-dia de trabalho, não deixe de comentar sobre isso! Bom proveito.

440.636

Comentários  8
Visualizações  
440.636


TagsLeia também

Apaixonado por Linux e administração de sistemas. Viciado em Internet, servidores, e em passar conhecimento. Idealizador do Devin, tem como meta aprender e ensinar muito Linux, o que ele vem fazendo desde 1997 :-)


Leia também



Comentários

8 respostas para “Proxy para ambientes mistos”

  1. Danilo Hawila disse:

    Parabéns pelo artigo.

  2. disse:

    É você que é o Hugo?

  3. Filosofus disse:

    Eitch!

    Achei muito legal e didático.

    Como aprendizado é muito válido, mas ainda restam algumas coisas a serem pensadas. Será que não é muito trabalho para resolver um problema que ( nem sei se é um problema).

    Notei que é uma briga muito grande pra resolver um problema de 3 URL's

    Prefiro as 3 URL's independentes e usar cada uma como quiser e ao mesmo tempo, coisa que a solução sugerida não permite.

    Pensando como um desenvolvedor: Quero ter 3 browsers abertos, um em homologação, um em desenvolvimento e um em produção.

    Como fazer ?

    Isso é só para enriquecer o artigo.

    Abração meu amigão!!

    • @Filosofus:

      Em um ambiente com muito desenvolvimento Web (e consequentemente muitos desenvolvedores) isso é um problema bem grande. Isso não há dúvidas. Conteúdos e chamadas internas as vezes podem estar referenciando links de produção, então é muito mais fácil você trabalhar com uma URL para os três ambientes do que ficar transformando essas URLs toda hora que quiser migrar dados e sistema de um ambiente para o outro. Em larga escala, facilita muito.

      Quanto a ter 3 navegadores ao mesmo tempo, basta utilizar 3 perfis diferentes de, por exemplo, Firefox :) Ou utilizar um perfil mesmo, junto com o plugin de troca de proxy que indiquei no artigo, assim essa troca fica bem mais fácil, apenas com dois clicks.

  4. Filosofus disse:

    Eitch!

    É sim, entretanto se os desenvolvedores ficarem programando com URLs absolutas ( ESTE É O ERRO ) devem usar sempre URLs relativas. Daí não vai existir problemas no desenvolvimento.

    :-)

  5. @Filosofus:

    Infelizmente esse mundo ideal não existe… Também existem questões de ambientes, como sistemas que utilizam proxy, chamadas externas para outros sistemas (web services), URLs de conteúdo (e não na programação), migrações entre bases, essas coisas… :)

  6. Paulo disse:

    Boa Tarde.

    Muito boa essas explicações.

    Preciso de uma ajuda extra.

    Preciso ter 2 ip no mesmo PC. Atualmente estou utilizando Máquina Virtual no ambiente do Windows XP e configurei um proxy para a Máquina Virtual para conseguir isto.

    Agora preciso utilizar 2 ip sem precisar rodar uma Máquina Virtual.

    Isto é possivel?

    Agradeço a sua atenção.

    Paulo.

  7. Renato disse:

    Bom dia.

    Gostei do artigo, porém não seria mais fácil fazer pelo iptables?

    algo assim, iptables -t nat -I PREROUTING 1 -p tcp -s 192.168.0.0/24 -d 192.168.0.1 –dport 80 -j DNAT 192.168.0.1:80

    e nas outras classes..

    sou novo na area, não sei seria correto.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *