Nginx – Enable SSL compression in nginx server

deflatenginxopensslssl

I've been trying to do a demo of the CRIME attack, which requires both a browser and server with SSL compression enabled. I've procured such a browser, and I've set up an nginx HTTPS server on localhost with options that I thought would enable compression (DEFLATE).

Here is my nginx.conf:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # victim's bank server - HTTPS
    server {
        listen       443 ssl;
        #listen       81; # used to observe GET requests
        server_name  www.thebank.com thebank.com;
        ssl_certificate path/to/bank.crt;
        ssl_certificate_key path/to/bank.key;
        ssl_protocols SSLv2 SSLv3 TLSv1; #TLSv1.1 TLSv1.2;

        gzip         on;
        #gzip_types   *;
        #gzip_min_length 0;
        #gzip_comp_level 9;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   path/to/bank;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

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

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # evil server
    server {
        listen       80;
        server_name  evil.com www.evil.com;

        location / {
            root   path/to/evil;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }
# ...
    include servers/*;
}

(Disclaimer: I've never worked much with nginx so I apologize if this violates some conventions, I basically just copied the provided conf file and modified it as necessary. That's why there's a lot of extra comments.)

It's been hard to find information on enabling something insecure, but I thought the gzip on; line enabled SSL compression. Yet when I listen in on the loopback traffic with Wireshark, I see DEFLATE listed as a compression method in the client hello but only null in the server hello's compression methods.

I've been using an old version of nginx (1.1.6) and OpenSSL (0.9.8zb) in the hopes that this would work. Also tried nginx 1.0.6, but still no luck.

Can anyone help me out? I feel like I've tried everything.

Edit: Even with OpenSSL 0.9.7 and nginx 1.0.6 the Server Hello still shows no compression methods.

Edit: At @Steffen Ullrich's request, and to provide more detail on the compilations of OpenSSL and nginx, here is output from my latest attempt:

# install OpenSSL from source in /path/to/Downloads
wget https://www.openssl.org/source/old/0.9.x/openssl-0.9.8zb.tar.gz
tar xvf openssl-0.9.8zb.tar.gz
cd openssl-0.9.8zb
./config zlib
make
sudo make install

# check for zlib support
openssl version -a
# OpenSSL 0.9.8zb 6 Aug 2014
# built on: Fri Sep 27 01:59:42 EDT 2019
# platform: linux-x86_64
# options:  bn(64,64) md2(int) rc4(1x,char) des(idx,cisc,16,int) idea(int) blowfish(idx) 
# compiler: gcc -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM
# OPENSSLDIR: "/usr/local/ssl"

# install nginx 1.0.6 from source with custom OpenSSL source
wget http://nginx.org/download/nginx-1.0.6.tar.gz
tar xvfz nginx-1.0.6.tar.gz
cd nginx-1.0.6
./configure --with-http_ssl_module --without-http_rewrite_module --with-openssl=/path/to/Downloads/openssl-0.9.8zb
sudo make
sudo make install

# check for zlib support
openssl version -a
# OpenSSL 0.9.8zb 6 Aug 2014
# built on: Fri Sep 27 02:57:12 EDT 2019
# platform: linux-x86_64
# options:  bn(64,64) md2(int) rc4(1x,char) des(idx,cisc,16,int) idea(int) blowfish(idx) 
# compiler: gcc -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM
# OPENSSLDIR: "/path/to/Downloads/openssl-0.9.8zb/.openssl/ssl"

Best Answer

According to this information you need an old nginx and and old OpenSSL - much older than the one you've used:

The CRIME attack uses SSL Compression to do its magic. SSL compression is turned off by default in nginx 1.1.6+/1.0.9+ (if OpenSSL 1.0.0+ used) and nginx 1.3.2+/1.2.2+ (if older versions of OpenSSL are used).

Thus, using nginx 1.1.5 or nginx 1.0.8 should work but only if you also use OpenSSL 0.9.8. Newer versions of OpenSSL has TLS compression disabled by default. Note that there is no support for TLS 1.1 or TLS 1.2 with this old version of OpenSSL.