Search code examples
pythonrubysslwsgirest-client

OpenSSL error - RestClient Gem - Python WSGI


Issue :

I'm struggling on a SSL issue. I'm trying to connect to a Web server for a Python application but each time I execute a request, I have this error :

RestClient::SSLCertificateNotVerified: SSL_connect returned=1 errno=0 state=error: certificate verify failed:

Details :

  • I use the RestClient gem (v1.8.0) and am trying a simple GET request
  • The python code to launch the server is as so :

    http_server = WSGIServer(('', int(port)), app, log=nylas_logger, handler_class=NylasWSGIHandler,
    keyfile='/vagrant/server.key', certfile='/vagrant/server.crt')

  • I use the same certificates (wildcard certificate COMODO) on another subdomain on another server (Nginx Passenger) and I can successfully launch my requests

What I tried :

  • I tried reinstalling Openssl using Brew
  • I successfully launched my request passing the verify_ssl: false flag to the restclient gem (but I want to find a solution that does not use this workaround)
  • I tried reinstalling Ruby (I'm using RVM) with the --disable-bynary flag
  • I launched rvm osx-ssl-certs update all

The most surprising is that I actually can perform requests on another type of server using the same certificates so it seems the issue may be with the Python web server.


Solution

  • It turns out the gevent.pywsgi server did not handle the SSL certificate correctly. I installed Nginx and did a reverse proxy on the localhost Python gevent.pywsgi server and did the SSL handling on the Nginx part and it worked instantly.

    For information, my nginx conf :

    server{
            listen 80;
            return 301 https://$host$request_uri;
    }
    
    server{
            listen 443;
            server_name subdomain.domain.com;
            ssl on;
            ssl_certificate /etc/nginx/ssl/cert.pem;
            ssl_certificate_key /etc/nginx/ssl/cert.key;
    
            location / {
                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_set_header X-Forwarded-Proro $scheme;
    
                proxy_pass http://localhost:5555;
                proxy_read_timeout 90;
                proxy_pass_request_headers on;
    
                proxy_redirect http://localhost:5555 https://subdomain.domain.com;
            }
    }
    

    And I restricted the python server to listen only to localhost requests.