Rotinas SSL: SSL23_WRITE: falha de handshake SSL, nginx no CentOS 7

5

Primeiro de tudo, o que eu tenho:

OpenSSL 1.0.1e-fips 11 Feb 2013
nginx version: nginx/1.6.2
CentOS Linux release 7.0.1406 (Core)

e, para fins de teste, um certificado autoassinado:

openssl req -x509 -sha256 -newkey rsa:2048 -keyout private_key.pem -out certificate.pem -days 365
openssl rsa -in private_key.pem -out certificate_key.pem
openssl dhparam -out dhparam.pem 4096

Então, o problema está ocorrendo - quando abro test.example.com no navegador, recebo ERR_CONNECTION_RESET. No log de erros do nginx, vejo o seguinte:

2015/02/07 03:18:34 [error] 27951#0: *17 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: my.computers.ip.address, server: 0.0.0.0:443

Meu /etc/nginx/nginx.conf -

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user  nginx;
worker_processes  1;

error_log  /path/error_log.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

pid        /run/nginx.pid;


events {
    worker_connections  1024;
}


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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /path/access_log.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    index index.php index.html index.htm;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       443 default ssl;
        server_name  localhost;
        root         /usr/share/nginx/html;

        #charset koi8-r;

        #access_log  /var/log/nginx/host.access.log  main;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        # redirect server error pages to the static page /40x.html
        #
        error_page  404              /404.html;
        location = /40x.html {
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        }
    }
}

Meu /etc/nginx/conf.d/test.example.com.conf -

upstream php-handler {
  server 127.0.0.1:9000;
  #server unix:/var/run/php5-fpm.sock;
  }

server {
  listen 80;
  server_name test.example.com;
  # enforce https
  return 301 https://$server_name$request_uri;
  }

server {
  listen 443 ssl;
  server_name test.example.com;

  ssl on;
  ssl_certificate_key /path/certificate_key.pem;
  ssl_certificate /path/certificate.pem;

  ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_session_cache shared:SSL:10m;

  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.4.4 8.8.8.8 valid=300s;
  resolver_timeout 10s;

  ssl_prefer_server_ciphers on;
  ssl_dhparam /path/dhparam.pem;

  add_header Strict-Transport-Security max-age=63072000;
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;

  # Path to the root of your installation
  root /usr/share/owncloud/;
  # set max upload size
  client_max_body_size 10G;
  fastcgi_buffers 64 4K;

  rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
  rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
  rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;

  error_page 403 /core/templates/403.php;
  error_page 404 /core/templates/404.php;

  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
    }

  location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README){
    deny all;
    }

  location / {
   # The following 2 rules are only needed with webfinger
   rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
   rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

   rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
   rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;

   rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;

   try_files $uri $uri/ /index.php;
   }

   location ~ \.php(?:$|/) {
   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   fastcgi_param PATH_INFO $fastcgi_path_info;
   fastcgi_param HTTPS on;
   fastcgi_pass php-handler;
   }

   # Optional: set long EXPIRES header on static assets
   location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
       expires 30d;
       # Optional: Don't log access to assets
         access_log off;
   }

  }

Se eu comentar todos os assuntos relacionados ao SSL do segundo server block, comentar todo o primeiro server block e colocar listen 80; no segundo bloco, então ele funciona e, portanto, concluo que o problema está relacionado ao SSL.

Assim, comecei a procurar por casos semelhantes. Entre dúzias de perguntas que eu verifiquei aqui, o seguinte par pareceu ser particularmente relevante:

  1. Rotinas SSL: SSL23_WRITE: falha de handshake ssl
  2. falha no handshake do OpenSSL

Desde a primeira pergunta, descobri que deveria tentar executar openssl s_client -connect test.example.com:443 e openssl s_client -tls1 -connect test.example.com:443 .

Para o primeiro, o resultado é:

[user@server nginx]# openssl s_client -connect test.example.com:443
CONNECTED(00000003)
140140897699744:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 249 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

Para o último, o resultado é:

[user@server nginx]# openssl s_client -tls1 -connect test.example.com.com:443
CONNECTED(00000003)
140133453146016:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1423271541
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

Dadas essas respostas, bem como as informações das duas listadas, e algumas outras perguntas, bem como algumas questões mencionadas em outros lugares, concluí que:

  • Eu posso ter uma versão do OpenSSL com bug.
  • Eu posso ter configurado mal meu SSL. Em particular, eu posso ter feito algo errado com cyphers.
  • posso ter encontrado alguma forma de incompatibilidade.

A partir daí, como a migração para outro servidor ou a limpeza do servidor para reconstruí-lo com outro sistema operacional não é viável, acho que tenho estas opções:

  • De alguma forma, atualize o OpenSSL no meu servidor para, por exemplo, recentemente lançado 1.0.2. A questão é compatibilidade e como fazer isso - eu parece ter a versão mais recente do OpenSSL para ser encontrado em repos eu sou ciente de.
  • De alguma forma, instale a segunda instância do OpenSSL, se for possível, ou alguma alternativa OpenSSL, se tal existir.
  • Desativar criptografia, que não é uma solução de produção viável em longo prazo.

O que eu, espero, perdi? Espero que, desde que eu prefiro evitar qualquer solução bastante radical que eu tenha feito.

    
por Community 07.02.2015 / 02:28

2 respostas

1

Resolvido comentando linhas

    listen       80 default_server;
    listen       443 default ssl;

em nginx.conf , para que eles se tornem

    #listen       80 default_server;
    #listen       443 default ssl;
    
por 07.02.2015 / 04:03
0

Eu estava recebendo "não ssl_certificate é definido no servidor de escuta na porta SSL, enquanto handshaking SSL", também. No meu caso, a explicação era muito mais simples: eu estava fazendo "serviço nginx start" em vez de "service nginx restart". Doh!

    
por 28.04.2015 / 01:09