O proxy Nginx retorna dados binários

2

Eu tenho o nginx como proxy na frente do meu aplicativo para encerrar o TLS. Eu tenho que definir para ouvir a porta 80 e redirecionar para 443.

Originalmente, o Chromium faria download de um arquivo chamado "download" em vez de redirecionar, mas, por algum motivo, ele não está mais fazendo isso (tentei o que foi sugerido em esta pergunta mas não ajudou). Enquanto o Chromium redireciona corretamente, embora o problema ainda exista, o Firefox ainda reage a isso, presumindo que seja um download de arquivo:

Oproblemaémaisvisívelcomocurl:

curl-vhttp://example.com*RebuiltURLto:http://example.com/*Trying54.213.157.146...*Connectedtoexample.com(54.213.157.146)port80(#0)>GET/HTTP/1.1>Host:example.com>User-Agent:curl/7.50.0>Accept:*/*>*Connection#0tohostexample.comleftintact����

Emvezderetornaroscabeçalhos/status/etcusuais.pareceestarenviandodevoltadadosbinários.Enquantoisso,aversãohttpsparecefuncionarcorretamente:

curl-vhttps://example.com*RebuiltURLto:https://example.com/*Trying54.213.157.146...*Connectedtoexample.com(54.213.157.146)port443(#0)*ALPN,offeringhttp/1.1*Cipherselection:ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH*successfullysetcertificateverifylocations:*CAfile:/etc/ssl/certs/ca-certificates.crtCApath:none*TLSv1.2(OUT),TLSheader,CertificateStatus(22):*TLSv1.2(OUT),TLShandshake,Clienthello(1):*TLSv1.2(IN),TLShandshake,Serverhello(2):*TLSv1.2(IN),TLShandshake,Certificate(11):*TLSv1.2(IN),TLShandshake,Serverkeyexchange(12):*TLSv1.2(IN),TLShandshake,Serverfinished(14):*TLSv1.2(OUT),TLShandshake,Clientkeyexchange(16):*TLSv1.2(OUT),TLSchangecipher,Clienthello(1):*TLSv1.2(OUT),TLShandshake,Finished(20):*TLSv1.2(IN),TLSchangecipher,Clienthello(1):*TLSv1.2(IN),TLShandshake,Finished(20):*SSLconnectionusingTLSv1.2/ECDHE-RSA-AES128-GCM-SHA256*ALPN,serveracceptedtousehttp/1.1*Servercertificate:*subject:CN=example.com*startdate:Jul2918:50:002016GMT*expiredate:Oct2718:50:002016GMT*subjectAltName:host"example.com" matched cert's "example.com"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok. 
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.50.0
> Accept: */* 
> 
< HTTP/1.1 200 OK
< Server: nginx/1.11.1
< Date: Fri, 29 Jul 2016 22:53:33 GMT 
< Content-Type: text/html; charset=utf-8
< Content-Length: 1121
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"461-VBuWbiWQQ/3ptwQjG8pM3w"
< Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
< X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
< 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
...

É evidente que o meu nginx está mal configurado, mas não está claro para mim como.

Meu nginx.conf:

user nginx;
worker_processes 2;

events {
    worker_connections  8096;
    multi_accept        on;
    use                 epoll;
}

http {
  include mime.types;
  default_type application/octet-stream;

  proxy_cache_path /var/cache/nginx keys_zone=anonymous:10m;
  proxy_temp_path /var/tmp/nginx;

  sendfile on;
  client_max_body_size 20M;
  tcp_nodelay off;
  tcp_nopush on;
  keepalive_timeout 65;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
  }

  #Include the vhost files.
  include vhosts/*.conf;
}

E o arquivo vhosts:

server {
  listen 80 http2;
  server_name ${DOMAIN};
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2;
  server_name ${DOMAIN};

  ssl_certificate /etc/letsencrypt/live/${PATH}/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/${PATH}/privkey.pem;
  ssl_dhparam /etc/ssl/dhparams.pem;

  ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;
  add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
  add_header X-Frame-Options SAMEORIGIN;
  add_header X-Content-Type-Options nosniff;
  ssl_session_tickets off;
  ssl_stapling on;
  ssl_stapling_verify on;

  root /etc/letsencrypt/webrootauth;

  location / {
    proxy_pass http://${UPSTREAM};
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_cache   anonymous;
    proxy_cache_valid 200 301 302 30m;
    expires 30m;
    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;      
  }

  location ~* \.(html|css|jpg|gif|ico|js)$ {
    proxy_cache          cache;
    proxy_cache_key      $host$uri$is_args$args;
    proxy_cache_valid    200 301 302 30m;
    expires              30m;
    proxy_pass  http://backend;
  }

  location /.well-known/acme-challenge {
    alias /etc/letsencrypt/webrootauth/.well-known/acme-challenge;
    location ~ /.well-known/acme-challenge/(.*) {
      add_header Content-Type application/jose+json;
    }
  }
}

Alguém vê o que poderia estar causando isso?

    
por mikewilliamson 30.07.2016 / 01:10

1 resposta

4

A diretiva http2 que você está usando implica que a porta tem suporte a SSL (ela não funciona sem SSL), portanto os dados binários que você vê são na verdade nginx tentando se comunicar com segurança pela porta 80 sem nenhum certificado.

Você pode verificar isso com:

curl --tlsv1.2 https://your-domain-name.is:80

que você recebe:

curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

enquanto qualquer outro servidor lhe dará um

curl: (35) Unknown SSL protocol error in connection to example.com:80

remova a diretiva http2 da porta 80 (e coloque-a na porta 443)

Se você insistir em manter a diretiva http2 na porta 80, pelo menos adicione todos os parâmetros relacionados a ssl nessa seção, assim você poderá se comunicar via ssl usando https://your-domain-name.is:80 (brincadeira ...)

    
por 30.07.2016 / 10:47

Tags