Desvendando o Nginx - Parte 2

Na primeira parte deste artigo mostrei como que é feita a configuração básica do Nginx explicando todas as diretivas padrão. Neste artigo vamos lidar com um dos casos de uso, o webserver:

Nginx como webserver

Geralmente quando não se cria o padrão Apache de configuração do Nginx, tudo pode ser declarado dentro do ngix.conf mesmo. Neste caso, o arquivo de configuração Nginx deve incluir pelo menos uma diretiva do servidor para definir um servidor virtual. Quando o Nginx processa uma solicitação, ele primeiro seleciona o servidor virtual que servirá o pedido. Um servidor virtual é definido por uma diretiva do servidor no contexto HTTP, por exemplo:

http {  
    server {
        # Configuração do servidor
    }
}

Mas como prefiro configurar os arquivos em separado, sugiro que se crie um arquivo base dentro da pasta sites-available como vimos no primeiro artigo. Por exemplo, vamos criar um arquivo de nome teste:

cd /etc/nginx/sites-available  
sudo touch teste  

Ainda dentro de sites-available vamos criar um index.html com o seguinte conteúdo:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">
    <title></title>
</head>  
<body>  
    <h3>Webserver básico!!!<h3>
</body>  
</html>  

Agora vamos editar as seguintes linhas dentro do arquivo teste que acabamos de criar:

server {  
        root /etc/nginx/sites-available/;
        index index.html index.htm;
        server_name localhost;
location / {  
        try_files $uri $uri/ /index.html;
}

Agora vá até a pasta sites-enabled, e crie um link simbólico para o arquivo teste que acabamos de criar:

# Entrando na pasta
cd /etc/nginx/sites-enabled  
# Criando o link simbólico
ln -s ../sites-available/teste  

Experimente agora reiniciar o nginx:

sudo systemctl restart nginx.service  
#ou
sudo service nginx restart  

Abra seu navegador preferido e acesse o seu http://localhost que irá aparecer o conteúdo do index.html que criamos.

Vamos a explicação do que acabamos de fazer:

  • A diretiva root define o diretório onde o conteúdo do site está localizado. Este é o local onde Nginx enxerga os arquivos que são solicitados pelo browser. O caminho padrão do nginx costuma ser /usr/share/nginx/html, mas pode ser /usr/share/nginx/www em outras distribuições também.

  • A diretiva index configura os formatos que irão servir para o domínio. Se a página foi solicitada, o bloco server irá procurar um arquivo chamado index.html e devolvê-lo. Se o servidor não conseguir encontrar esse arquivo, passará para o formato seguinte. Isto é, o index.htm.

  • A directiva server_name contém uma lista de nomes de domínio que será definido neste bloco. Você pode incluir tantos nomes como você gostaria, separados por espaços. Ou se preferir, poderá usar um coringa também. Isto é, o asterisco * no início ou fim da definição de nome de servidor.

  • A próxima parte é a configuração do bloco location. Este bloco é usado ​​para especificar a forma como certos pedidos são tratados dentro de um servidor. No caso do /, trata-se da raiz do endereço definido em server_name.

  • try_files $uri $uri/ /index.html; verifica a existência de arquivos na ordem especificada e usa o primeiro arquivo encontrado para o processar do pedido; o processamento é executado no contexto atual.

Podemos modificar o parâmetro em location / para proxy_pass:

location / {  
        proxy_pass http://www.google.com.br;
}

Agora ao acessar o localhost em seu navegador , o localhost irá redirecionar para o site do google.

  • A diretiva proxy_pass define o protocolo e endereço de um servidor proxy e um URI opcional para um local mapeado. Aqui o protocolo http ou https podem ser especificados. O endereço pode ser especificado como um nome de domínio ou endereço IP e uma porta opcional depois do :.

Aqui no LEMAF utilizamos muitos serviços rodando o Play Framework. Neste caso, uma configuração simples de serviço usando o Nginx seria algo neste formato:

upstream analise {  
        server localhost:porta;
}

server {  
        root /usr/share/nginx/www;
        index index.html index.htm;

        server_name teste.car.ti.lemaf.ufla.br;

        location / { 
                proxy_pass http://localhost:porta/;
                include /etc/nginx/proxy_params;
        }   

        location /ambiente/ {
                proxy_pass    http://localhost:porta/ambiente/;      
                include /etc/nginx/proxy_params;
        }  
}

Você deve estar se perguntando: Oras, mas o que são estas duas novas diretivas que apareceram? O que é upstream? E porque o include /etc/nginx/proxy_params;?

  • A diretiva upstream logo no cabeçalho, define um grupo de servidores que podem escutar em portas diferentes. Além disso, servidores escutam em sockets TCP e domínios misturados.

Observe que dentro das diretivas location / adicionamos o include /etc/nginx/proxy_params;. Este arquivo originalmente não existe na pasta raíz do Nginx. No Debian/Ubuntu, foram adicionados por padrão visto que os parâmetros de proxy são inapropriados se declarados todos na mesma linha da diretiva location. Este arquivo serve para adicionar funções de proxy ao nginx. Isto é, o nginx pode, opcionalmente, alterar a requisição do cliente ou a resposta do servidor e, algumas vezes, pode disponibilizar este recurso mesmo sem se conectar ao servidor especificado.

Pode também atuar como um servidor que armazena dados em forma de cache na rede. Através destas funções de proxy, é também possível agir como um firewall bloqueando portas, endereços IP, filtrando conteúdo, tipos de formatos de vídeo, docs, e diversos tipo de acessos. Vamos então entender a syntax básica do arquivo proxy_params em /etc/nginx/.

Nota: Nem sempre o arquivo proxy_params existirá na pasta raiz de configurações do nginx. E como não existe por padrão, logo, em distribuições baseadas em Redhat como Fedora/Centos entre outras como Arch Linux, por exemplo, também não existirá. Neste caso, precisamos criar o arquivo proxy_params com o conteúdo a baixo:

proxy_set_header Host $http_host;  
proxy_set_header X-Real-IP $remote_addr;  
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
proxy_set_header X-Forwarded-Proto $scheme;  

Para ajustar ou definir cabeçalhos para conexões de proxy, podemos usar a diretiva proxy_set_header. O pedido acima define o cabeçalho Host à variável $http_host, que deve conter informações sobre o host que está sendo solicitado.

  • A diretiva X-Real-IP é definido para o endereço IP do cliente para que o proxy possa tomar decisões corretamente ou gerar log com base nesta informação.

  • A diretiva X-Forwarded-For gera uma lista contendo os endereços IP de todos os servidores proxy. No exemplo acima, está definitido com a variável $proxy_add_x_forwarded_for. Esta variável assume o valor do cabeçalho X-Forwarded-Forafim de recuperar dados do cliente que está usando o Nginx.

  • A diretiva X-Forwarded-Proto transmite dá informações ao cabeçalho do servidor com proxy sobre o esquema do pedido original do cliente (se foi um http ou uma solicitação https).

Nota: Quando o serviço é estático, não é necessário usar proxy_params. Isto é, tudo depende de como a aplicação se comporta. Se a aplicação demanda procedimentos mais elaborados de transferências e gestão de dados, é recomendável usar o proxy_params. Os parâmetros usados aqui, são suficientes para um webserver. Iremos explorar mais do proxy_params para necessidades futuras.


Redirecionamento

Redirecionamento é uma técnica que aponta um domínio ou endereço para outro. Há muitos usos para redirecionamento, e há alguns diferentes tipos de redirecionamentos para considerar. Como você criar conteúdo e administrar servidores, muitas vezes vai encontrar a necessidade de redirecionar o tráfego de um lugar para outro. Existem algumas diferentes tipos de redirecionamentos de URL, cada um dos quais significam algo diferente para o navegador. Os dois tipos mais comuns são os redirecionamentos 302 temporários, e os redirecionamentos 301 permanentes.

  • Redirecionamentos temporários - são úteis se o conteúdo da Web para uma determinada URL precisa temporariamente ser redirecionado para outro local.

Por exemplo, se a sua aplicação estiver em manutenção, usar um redirecionamento temporário de todas as páginas do seu domínio a uma página para informar seus visitantes que você estará de volta em breve, usa-se o redirecionamento temporário. Ou seja, é informado ao navegador que o conteúdo está temporariamente em um local diferente, mas que eles devem continuar a tentar acessar a URL original.

  • Redirecionamentos permanentes - são úteis quando seu conteúdo foi transferido para um novo local permanentemente.

Isso é útil para quando você precisa alterar domínios ou quando o URL tem de mudar por outras razões e o local antigo não será mais usado. Este redirecionamento informa o navegador que os mesmos deixam de solicitar o antigo endereço e deve atualizar suas informações para apontar para o novo URL.

Redirecionamentos no Nginx são, em muitos aspectos muito mais simples de realizar do que no Apache. Na maioria das vezes, você pode redirecionar através do bloco server{} e com o conteúdo que você gostaria de redirecionar. Por exemplo, se você desejar redirecionar as solicitações do site www.ti.lemaf.ufla.br Para google.com, basta apenas criar um bloco server que se parecerá com isso:

server {  
    listen 80;
    server_name www.ti.lemaf.ufla.br;
    return 301 $scheme://www.google.com$request_uri;
}

A diretiva return executa a substituição da URL e, em seguida, retorna o status dado a ele, e a URL do redirecionamento. Neste caso,usa-se a variável $scheme para definir o protocolo http ou https. Em seguida, é retornado o código de redirecionamento permanente 301 e o URL. Existe também uma diretiva parecida com a diretiva usada em um módulo de redirecionamento usado no Apache Server. Isto é, o Apache usa a diretiva mod_alias para coisas simples e mod_rewrite para casos mais complexos. No Nginx, existe a diretiva rewrite. Por exemplo:

rewrite ^/images/(.*)$ http://images.example.com/$1 redirect;  

Neste exemplo a cima, esta diretiva quando colocada em um bloco de server{}, irá emitir um redirecionamento temporário para os pedidos dentro do diretório imagens para o subdomínio imagens.exemple.com.

  • Nota: Para um redirecionamento permanente, você poderá mudar o redirect por permanent no final da declaração.

Nos próximos artigos sobre Nginx iremos mais a fundo com algumas diretivas ainda abordando o proxy_params e diretivas interessantes de se trabalhar no nginx.conf.

Sugestão para estudo: