Nginx como proxy reverso sem cache

1

Estou tentando configurar o Nginx como um proxy reverso de armazenamento em cache. O servidor de origem é o Apache e hospeda uma instância do WordPress, se isso for importante.

A funcionalidade de proxy reverso está funcionando como esperado, mas o cache parece não funcionar. Se eu obtiver o mesmo recurso estático duas vezes seguidas, receberei x-proxy-cache: MISS duas vezes.

assodigitale.it é o domínio, 138.201.87.123 o endereço IP do servidor de origem e 138.201.87.124 o endereço IP do proxy Nginx.

O servidor de origem parece responder permitindo que o proxy armazene em cache o recurso:

$ curl --connect-to ::138.201.87.123:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
date: Sun, 11 Mar 2018 20:59:39 GMT
server: Apache/2.4.25 (Debian)
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
accept-ranges: bytes
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
content-type: image/jpeg

A primeira solicitação para o servidor proxy resulta em uma MISS, como esperado:

$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:04:00 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes

A segunda requisição para o proxy Nginx resulta em um HIT, mas resulta em outra MISS:

$ curl --connect-to ::138.201.87.124:443 --http2 -I https://assodigitale.it/wp-content/uploads/2018/03/aereo.jpg
HTTP/2 200 
server: nginx/1.13.9
date: Sun, 11 Mar 2018 21:05:52 GMT
content-type: image/jpeg
content-length: 32989
strict-transport-security: max-age=31536000; includeSubdomains; preload
last-modified: Wed, 07 Mar 2018 09:34:41 GMT
etag: "80dd-566cf44ca2952"
vary: Accept-Encoding
cache-control: max-age=1209600, public
x-content-type-options: nosniff
x-proxy-cache: MISS
strict-transport-security: max-age=4838400; includeSubDomains; preload
accept-ranges: bytes

Aqui está a parte relevante da minha configuração do nginx:

proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;

server {
    listen 443 ssl http2;
    ssl on;
    server_name assodigitale.it;

    ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    location / {
        proxy_cache revproxy;
        add_header X-Proxy-Cache $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=4838400; includeSubDomains; preload";

        proxy_pass  https://138.201.87.123;
        proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
        proxy_cache_bypass $http_x_forceflushcacheurl;
        proxy_cache_lock on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_hide_header Upgrade;
        proxy_buffering off;
        proxy_connect_timeout       600;
        proxy_send_timeout          600;
        proxy_read_timeout          600;
        send_timeout                600;
        proxy_ignore_headers Set-Cookie;

        http2_push_preload on;
        client_max_body_size 64M;
    }
}

O diretório /srv/cache/nginx tem 755 permissões e www-data owner, e o Nginx é executado como www-data . Na verdade, o Nginx escreve suas pastas lá, ou seja, 0 1 2 3 4 5 6 7 8 9 a b c d e f , mas o espaço total ocupado agora é de 344 KB, para um site que é bem grande e que tem muito mais do que um tráfego casual.

Tentar os mesmos comandos curl acima, mas com páginas em vez de imagens, apenas o mesmo resultado, é sempre uma MISS.

Por que o Nginx se recusa a armazenar recursos em cache?

    
por Lucio Crusca 11.03.2018 / 22:24

3 respostas

1

você deve definir proxy_buffering on , caso contrário o nginx não armazenará a resposta em cache!

o documento oficial disse:

Quando o armazenamento em buffer está desativado, a resposta é passada para um cliente de forma síncrona, imediatamente à medida que é recebida. nginx will not try to read the whole response from the proxied server. O tamanho máximo dos dados que o nginx pode receber do servidor por vez é definido pela diretiva proxy_buffer_size.

    
por 05.06.2018 / 10:24
0

Eu copiei a configuração de outro proxy Nginx similar que executei, adaptei-a ao site e agora funciona.

Esta é a configuração que estou usando atualmente:

proxy_cache_path /srv/cache/nginx levels=1:2 keys_zone=revproxy:2000m inactive=2880m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_methods GET HEAD;
proxy_cache_valid any 1m;
proxy_cache_valid 200 1440m;    
server {
    listen 443 ssl http2;
    ssl on;
    server_name assodigitale.it;

    ssl_certificate /etc/letsencrypt/live/assodigitale.it/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/assodigitale.it/privkey.pem;

        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;    
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    60;
        ssl_session_timeout  10m;

    location / {
            proxy_cache revproxy;
            add_header X-Proxy-Cache $upstream_cache_status;

            proxy_pass  https://138.201.87.123;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
            proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
            proxy_cache_lock on;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_hide_header      Upgrade;
            proxy_buffering on;
            proxy_connect_timeout       600;
            proxy_send_timeout          600;
            proxy_read_timeout          600;
            send_timeout                600;
            client_max_body_size 64M;
    }
}
Embora isso possa ser uma resposta porque resolve o problema, não entendo por que isso funciona (ou, mais precisamente, por que a configuração anterior não funcionou), então não vou aceitar minha própria resposta.

Talvez alguém consiga identificar a diferença específica nas duas configurações que fazem o cache funcionar: essa seria uma resposta aceitável.

    
por 20.03.2018 / 12:03
0

Tivemos um problema semelhante. Estávamos usando o nginx como um cache de proxy para um bucket s3 (para que pudéssemos oferecer suporte à lista de permissões de IP). Percebemos que não fornecíamos um endpoint https, embora nosso proxy estivesse sendo exibido em https. Parece que o nginx não gostou disso. Depois que mudamos de http para https , não há problemas.

    
por 06.12.2018 / 14:56