Um dos recursos mais poderosos do Apache (e aquele que me motivou a escrever este guia) é a possibilidade de termos um proxy reverso. Este conceito – proxy reverso – não é muito conhecido pela maioria dos desenvolvedores, mas uma vez estabelecido o contato inicial, poderá mudar profundamente sua visão a respeito do modo como sua infraestrutura pode ser configurada.

Como quase todo capítulo deste guia vamos começar expondo os problemas para, na sequência, tratarmos do conceitual e irmos para a prática.

Os problemas

Você quer disponibilizar um serviço presente em um servidor que não deve ser totalmente exposto

Imagine que você tem um servidor no qual existam os seguintes serviços instalados:

  • Seu ERP super poderoso com dados de altíssima confidencialidade – o que você não quer expor.
  • A API de um sistema que será consumida pelo seu lindo frontend – o que você quer desesperadamente expor. 

O diagrama a seguir expõe bem a situação (espero):

O computador no qual sua API está em execução não deve ser diretamente exposto na internet. Então o frontend irá interagir apenas com o Apache (disponibilizado na Internet) que, por sua vez, direcionará o tráfego apenas para o módulo API, deixando o ERP isolado.

O serviço a ser disponibilizado está usando uma porta diferente (ou você quer centralizar a configuração de TLS/HTTPS em um único ponto (o Apache))

Sabe o problema anterior? Talvez esteja tudo até mesmo no servidor, só que o serviço está usando uma porta diferente daquela que você deseja disponibilizar ao frontend.

Ou então, melhor ainda, dado que gerenciar certificados TLS/SSL pode ser um saco, você quer centralizar toda a gestão dos seus certificados digitais em um único ponto, o Apache.

O diagrama a seguir expõe esta situação: temos nossa API sendo servida internamente usando a porta 9090, mas a gestão dos certificados SSL/TLS está centralizada no Apache: as requisições chegarão ao Apache e este, por sua vez, realizará o meio de campo entre o frontend e a API. Você não precisará configurar certificados para o módulo API (imagine que está hospedado em algo como um Apache Tomcat, por exemplo), apenas no Apache HTTP.

Mas o que é um proxy?

Conceitualmente, proxy é algo que se faz passar por outra entidade. Voltando ao nosso exemplo, o frontend acredita estar lidando com nossa API. Entretanto ele interage diretamente com um substituto: alguém que se faz passar por algo que não é.

Mas não basta simplesmente se passar pelo que não é, pois caso contrário teríamos simplesmente um mock. O proxy, para ser um proxy, obrigatóriamente deve intermediar a interação entre o cliente (aquele que inicia a interação) e o servidor (aquele com o qual o cliente deseja interagir).

E durante esta intermediação o proxy pode, para não se tornar um objeto inútil, enriquecer este processamento executando ações tais como:

  • Comprimir a resposta enviada ao cliente usando gzip.
  • Ao invés de consultar o servidor, obter uma resposta cacheada, minimizando com isto o consumo computacional.
  • Criptografia – o proxy pode, por exemplo, aplicar a criptografia SSL sem que o objeto alvo da interação sequer saiba (e veremos isto em um outro post).
  • Controlar o acesso ao serviço com o qual desejamos interagir.
  • E, para o mal, pode te fazer achar que está usando um serviço e na realidade, estar usando outro (e isto dá muito medo só de pensar).

O proxy é portanto um intermediário que tem como principal objetivo ocultar o objeto de interação ao mesmo tempo que enriquece o modo como interagimos com o serviço ocultado.

Então por que este proxy se chama proxy reverso? Por que aqui estamos fazendo o contrário: estamos expondo algo com nosso proxy (só que de forma indireta e modificando a interação com este).

Pondo em prática

Habilitando alguns módulos

Se você está seguindo sequencialmente este guia, até este momento o Apache não faz mais que servir conteúdo estático e definir alguns virtual hosts. Módulos são o que realmente dão graça ao Apache, sendo assim vamos começar a habilitar alguns.

Se você possui uma instalação virgem do Apache, é hora de conhecer um importante comando: a2enmod. Como usuário root, digite-o na sua interface de linha de comando, você verá uma saída similar à exposta a seguir:

Que loucura é esta?

A saída obtida são todos os módulos que vieram na instalação padrão do Apache (pode variar de acordo com a sua distribuição). O comando a2enmod é usado para que possamos habilitar estes módulos. É importante que você saiba neste momento quais habilitar:

  • proxy
  • proxy_http
  • proxy_ajp
  • rewrite
  • deflate
  • headers
  • proxy_balancer (usaremos este aqui num post futuro)
  • proxy_connect
  • proxy_html

Notou que no comando acima ele pede que você digite o nome dos módulos que desjea habilitar? Então, basta digitar esta lista que acabei de passar separando cada um por espaço, tal como no comando a seguir:

Assim, olha:

a2enmod proxy proxy_http proxy_ajp rewrite deflate headers proxy_balancer proxy_connect proxy_html

Claro, após habilitar todos estes módulos você deverá reiniciar o Apache. Como fazer isto?

service apache2 restart

Configurando o proxy reverso

Configurar o Proxy reverso requer apenas três linhas de configuração. Para tal, vamos editar um dos sites habilitados na sua instalação do Apache. Se a sua for uma instalação virgem, muito provávelmente este arquivo será o /etc/apache2/sites-enabled/000-default.conf.

Releia o primeiro capítulo deste guia no qual falamos a respeito dos arquivos de configuração do Apache.

Edite-o para que fique similar ao exemplo a seguir:

<VirtualHost *:80>
# Da raíz ao servidor destino na porta 9444
ProxyPass / http://172.17.0.3:9444/
# E do servidor destino, na raíz, para a raíz deste Virtual Host
ProxyPassReverse / http://172.17.0.0.3:9444/
# E nós vamos preservar o host em todas as requisições
ProxyPreserveHost On
</VirtualHost>

Observe que na realidade estamos aqui editando um host virtual que recebe todas as requisições do servidor Apache na porta 80.

A primeira diretriz, ProxyPass, mapeia o contexto do host corrente (“/” neste caso) para um servidor de destino. Em nosso exemplo, este servidor consistirá no http://172.17.0.3:9444 (que 9444 é este? Estou usando o S3 Ninja como exemplo).

Agora precisamos realizar o caminho reverso. Entra em cena a diretiva ProxyPassReverse. Ela essencialmente obtém a resposta do serviço oculto (o segundo parâmetro) e mapeia para a resposta a ser enviada para o servidor proxy.

Finalmente, temos a terceira diretiva: ProxyPreserveHost, que apenas serve para repassar o mesmo host recebido na requisição de origem para o serviço que está sendo “proxiado”. Se o parâmetro for On, o host será passado para o serviço alvo, caso contrário, será usado o mesmo endereço definido em ProxyPassReverse no segundo parâmetro.

Lembre-se de reiniciar o Apache após ter alterado estas configurações.

Notou que não há um DocumentRoot nesta configuração? É por que não estamos transmitindo o conteúdo do Apache para o nosso cliente, apenas o conteúdo gerado pelo serviço que estamos proxiando.

E como você testa isto? Simples: acesse o seu servidor Apache. Se tudo estiver bem configurado, uma página proveniente do sistema proxiado será o retorno apresentado pelo browser!

Proxy reverso com virtual hosts

Voltando ao /dev/All, vamos imaginar que a API, acima mencionada, seja aquela usada para alimentar o nosso frontend e que esta estaria disponibilizada em outro servidor, usando outra porta. Como você configuraria o arquivo deste host virtual?

Segue um exemplo rápido:

<VirtualHost *:80>
# A mesma coisa, você só vai mudar o nome do domínio :)
ServerName api.devall.com.br

ProxyPass / http://172.17.0.15:9090/
ProxyPassReverse / http://172.17.0.0.15:9090/
ProxyPreserveHost On
</VirtualHost>

Resumindo

Este foi o nosso primeiro contato com o conceito de proxy reverso no Apache, mas creio que já deu pra entender a ideia e sentir o poder que ele pode nos trazer.

Você agora sabe como expor parte dos seus servidores na web e, mais importante: viu que é um processo relativamente fácil (relativamente não, é bem fácil mesmo).

De propósito apenas mencionei que podemos centralizar toda a gestão de certificados SSL no Apache, o que tornará sua vida muito mais fácil ao lidar com esta que, sabemos, é uma tarefa que pode ser bem chata.

Por que isto? Para no próximo capítulo você aprender a lidar com este tipo de gestão de forma bem simples e barata usando o Certbot e o projeto Let’s Encrypt!

Desenvolvedor e co-fundador da itexto, do /dev/All, Groovy e Grails Brasil, Spring Brasil e JavaScript Brasil.
Desenvolvendo software desde o século passado e escrevendo a respeito no /dev/Kico

Leave comment

Your email address will not be published. Required fields are marked with *.

%d blogueiros gostam disto: