Nginx – Configure SSL and HTTP in nginx with Rails 3.2

httpsnginxopensslruby-on-rails-3

I've looked at some examples but I really can't figure out why ssl wont work. My situation:

First of all I have a rails application with passenger, the normal application works with nginx, no problem there. I would like to add ssl support on some paths (for example /admin or /config). I've self signed my certificate because the url's will be used by a android application to send data secure to the server, this is the only reason why I need SSL support.

From what I understand is that I should enable both HTTP and HTTPS on nginx and let the rails application decide whether to use HTTP or HTTPS (correct me if I'm wrong). So how should my nginx configuration look like to allow both HTTPS and HTTP on the same IP/address? I've used the following command's to generate my certificates:

openssl req –new -x509 –keyout private/cakey.pem –out cacert.pem
openssl req –new –out newcert/webserver-cert/pem –keyout private/webserver-key.pem
echo '01' > serial
touch index.txt
openssl ca –cert cacert.pem –keyfile private/cakey.pem –out certs/webserver-cert.pem –in newcerts/webserver-cert.pem

Now I dont know if this is the right way to do it, any help on this would also be welcome 🙂

Thanks!

UPDATE

This is my current configuration, when I use https I get the following error: "SSL connection error"

root@event-backend:/opt# cat /opt/nginx/conf/nginx.conf

worker_processes 1;
error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    passenger_root /usr/local/rvm/gems/ruby-1.9.3-p194@rails32/gems/passenger-3.0.12;
    passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.3-p194@rails32/ruby;

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

    #access_log  logs/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

   server {
        listen 80;

        server_name 192.168.20.32;
        root /opt/bap-backend/public;

        location ~ .php$ {
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                fastcgi_pass 192.168.20.32:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /opt/www$fastcgi_script_name;
                include fastcgi_params;
        }

        passenger_enabled on;
   }

   server {
        listen 443 ssl;

        server_name 192.168.20.32;
        root /opt/bap-backend/public;

        #SSL options
        ssl_certificate         /opt/certificate/server.crt;
        ssl_certificate_key     /opt/certificate/server.key;

        location / {
                proxy_set_header X-FORWARDED_PROTO $scheme;
        }
        ssl_session_timeout 5m;
        ssl_protocols SSLv2 SSLv3 TLSv1;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

        passenger_enabled on;
   }

}

Is this normal or is this because I didnt change anything in my rails application?

LOGS

root@event-backend:/opt# netstat --tcp --listening --programs
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 localhost.localdom:smtp *:*                     LISTEN      392/sendmail: MTA:
tcp        0      0 *:https                 *:*                     LISTEN      8799/nginx
tcp        0      0 localhost.localdo:mysql *:*                     LISTEN      226/mysqld
tcp        0      0 localhost.lo:submission *:*                     LISTEN      392/sendmail: MTA:
tcp        0      0 *:www                   *:*                     LISTEN      8799/nginx
tcp        0      0 *:ssh                   *:*                     LISTEN      213/sshd
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN      213/sshd


root@event-backend:/opt# cat nginx/logs/error.log

2012/05/11 07:44:29 [notice] 1562#0: signal 15 (SIGTERM) received, exiting
2012/05/11 07:44:29 [notice] 1564#0: exiting
2012/05/11 07:44:29 [notice] 1564#0: exit
2012/05/11 07:44:29 [notice] 1562#0: signal 17 (SIGCHLD) received
2012/05/11 07:44:29 [notice] 1562#0: worker process 1564 exited with code 0
2012/05/11 07:44:29 [notice] 1562#0: exit
2012/05/11 07:44:29 [notice] 8756#0: using the "epoll" event method
2012/05/11 07:44:29 [notice] 8756#0: nginx/1.0.15
2012/05/11 07:44:29 [notice] 8756#0: built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
2012/05/11 07:44:29 [notice] 8756#0: OS: Linux 2.6.32-6-pve
2012/05/11 07:44:29 [notice] 8756#0: getrlimit(RLIMIT_NOFILE): 1024:1024
2012/05/11 07:44:29 [notice] 8799#0: start worker processes
2012/05/11 07:44:29 [notice] 8799#0: start worker process 8801

root@event-backend:/opt/nginx/sbin# ./nginx -V
nginx version: nginx/1.0.15
built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --with-http_ssl_module --with-http_gzip_static_module --with-cc-opt=-Wno-error --add-module=/usr/local/rvm/gems/ruby-1.9.3-p194@rails32/gems/passenger-3.0.12/ext/nginx --with-http_ssl_module

UPDATE 2

There was a firewall doing some crazy stuff, now I can use https but I find in my logs the following errors:

root@event-backend:/opt# cat nginx/logs/error.log

2012/05/11 12:48:15 [info] 14713#0: *229 client closed prematurely connection while SSL handshaking, client: 192.168.20.1, server: 192.168.20.32
2012/05/11 12:48:15 [info] 14713#0: *230 client closed prematurely connection while SSL handshaking, client: 192.168.20.1, server: 192.168.20.32
2012/05/11 12:48:15 [error] 14713#0: *231 directory index of "/opt/bap-backend/public/" is forbidden, client: 192.168.20.1, server: 192.168.20.32, request: "GET / HTTP/1.1", host: "192.168.20.32"

Best Answer

All you need is a second server { block that's configured for SSL on port 443.

You'll want a listen 443 ssl; directive and directives pointing to your public and private keys; ssl_certificate /path/to/webserver-cert.pem; and ssl_certificate_key /path/to/webserver-key.pem;.