Nginx – OCSP stapling with nginx

certificatenginxopensslssl

I'm having trouble with OCSP stapling in nginx.
So I start up the openssl ocsp daemon, and then I visit my site. Then it says Invalid request. I am using a private PKI and CA. SSL key: 8192bit DH key 2048bit

root@wilhelm:/etc/ocsp# openssl ocsp -index index.txt -port 9999 -rsigner oscp.crt -rkey oscp.key -CA cacert.pem -text -out log.txt
Waiting for OCSP client connections...
Invalid request
root@wilhelm:/etc/ocsp# ls
cacert.pem  index.txt  index.txt.attr  index.txt.attr.old  index.txt.old  log.txt  ocsp.crt  ocsp.key  oscp.crt  oscp.key
root@wilhelm:/etc/ocsp# 

The server is working though, I tested it with openssl ocsp -CAfile ../cacert.pem -issuer ../cacert.pem -url http://* url *:9999 -resp_text -cert mycert.crt and it works fine.

Nginx config:

set_real_ip_from   199.27.128.0/21;
set_real_ip_from   173.245.48.0/20;
set_real_ip_from   103.21.244.0/22;
set_real_ip_from   103.22.200.0/22;
set_real_ip_from   103.31.4.0/22;
set_real_ip_from   141.101.64.0/18;
set_real_ip_from   108.162.192.0/18;
set_real_ip_from   190.93.240.0/20;
set_real_ip_from   188.114.96.0/20;
set_real_ip_from   197.234.240.0/22;
set_real_ip_from   198.41.128.0/17;  
set_real_ip_from   162.158.0.0/15;  
set_real_ip_from   104.16.0.0/12;
set_real_ip_from   172.64.0.0/13;
real_ip_header     X-Forwarded-For;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
limit_conn conn_limit_per_ip 5;
limit_req zone=req_limit_per_ip burst=10 nodelay;   

server_tokens off;

add_header X-Frame-Options SAMEORIGIN;

add_header X-Content-Type-Options nosniff;

add_header X-XSS-Protection "1; mode=block";


server {
  listen 80;
  server_name mail.wilhelm.co.za;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  ssl on;
  server_name mail.wilhelm.co.za;

  if ($http_referer ~* "(semalt|buttons-for|best-seo)") { return 444; }
  if ($http_host = '') { return 444; }
  if ($host !~* ^mail\.wilhelm\.co\.za$ ) { return 444; }
  if ($request_method !~ ^(GET|HEAD)$ ) { return 444; }

  ssl_certificate /etc/nginx/ssl/mail.wilhelm.co.za.key.crt;
  ssl_certificate_key /etc/nginx/ssl/mail.wilhelm.co.za.key;
  ssl_client_certificate /etc/nginx/ssl/cacert.pem;
  ssl_verify_client optional; 
  ssl_session_cache shared:SSL:50m;
  ssl_session_timeout 5m;

  ssl_dhparam /etc/nginx/ssl/dhparam.pem;

  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

  resolver 8.8.8.8 valid=300s;
  resolver_timeout 10s;
  ssl_stapling on;
  ssl_stapling_verify on;
  ssl_trusted_certificate /etc/nginx/ssl/mail.wilhelm.co.za.crt;

  add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
  root /var/www/mail.wilhelm.co.za/public_html;
  access_log /var/www/mail.wilhelm.co.za/logs/access.log;
  error_log /var/www/mail.wilhelm.co.za/logs/error.log;
  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_keep_conn on;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

  location ~ /\.ht {
    deny all;
  }

  location ^~ /data {
    deny all;
  }
}

Best Answer

For OCSP requests used for OCSP stapling nginx uses GET requests, as described in RFC 2560.

On the other hand, OpenSSL as of last released OpenSSL 1.0.2d only supports POST requests in the OCSP responder daemon available via openssl ocsp. It doesn't recognize GET requests and prints Invalid request for such requests.

To make this work, you may try OpenSSL from master branch - it seems to contain an attempt to improve OCSP responder code and should handle GET requests properly now. I've never tried though, and may be there are other problems. Please also keep in mind it's unreleased code.

You may also consider using another OCSP responder.