Skip to content

Commit 15abfc1

Browse files
committed
nginx-ssl-ja3: nginx variables for ja3 fingerprint
*) nginx modules *) config *) http_ssl_ja3_hash variable *) stream_ssl_ja3_hash variable *) docker *) dockerfiles *) compose *) travis
0 parents  commit 15abfc1

File tree

14 files changed

+1309
-0
lines changed

14 files changed

+1309
-0
lines changed

.travis.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
sudo: required
2+
dist: trusty
3+
4+
os: linux
5+
6+
language: c
7+
8+
compiler:
9+
- gcc
10+
11+
cache:
12+
apt: true
13+
directories:
14+
15+
env:
16+
global:
17+
- NGINX_PREFIX=/opt/nginx
18+
- JOBS=4
19+
- PATH=$PATH:$NGINX_PREFIX/sbin
20+
21+
before_install:
22+
- sudo apt-get install -qq -y software-properties-common
23+
- sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe"
24+
- sudo apt-get update -qq -y --fix-missing
25+
- sudo apt-get install -qq -y --fix-missing cpanminus mercurial build-essential make clang valgrind
26+
27+
install:
28+
- if [ ! -d /opt ]; then mkdir /opt; fi
29+
- git clone https://github.com/openresty/test-nginx.git
30+
- hg clone http://hg.nginx.org/nginx
31+
- git clone https://github.com/openssl/openssl
32+
33+
script:
34+
- ls -la
35+
- cd openssl
36+
- ./config -d
37+
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
38+
- sudo make install > build.log 2>&1 || (cat build.log && exit 1)
39+
- cd ..
40+
- cd test-nginx
41+
- sudo cpanm .
42+
- cd ..
43+
- export LD_LIBRARY_PATH=/usr/local/lib/
44+
- cp -v docker/debian-nginx-ssl-ja3/nginx.ssl.extensions.patch nginx/.
45+
- cd nginx
46+
- patch -p1 < nginx.ssl.extensions.patch
47+
- auto/configure --with-debug --with-stream --with-ld-opt="-Wl,-E" --prefix=$NGINX_PREFIX --with-http_ssl_module --with-stream_ssl_module --add-module=$PWD/.. > build.log 2>&1 || (cat build.log && exit 1)
48+
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
49+
- sudo make install > build.log 2>&1 || (cat build.log && exit 1)
50+
- cd ..
51+
- export PATH=$NGINX_PREFIX/sbin:$PATH
52+
- /opt/nginx/sbin/nginx -V
53+
- ldd /opt/nginx/sbin/nginx

CHANGES

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Changes with nginx-ssl-ja3 0.0.1 20 Aug 2017
2+
3+
*) nginx modules
4+
*) config
5+
*) http_ssl_ja3_hash variable
6+
*) stream_ssl_ja3_hash variable
7+
*) docker
8+
*) dockerfiles
9+
*) compose
10+
*) travis
11+

COPYRIGHT

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-----------------------------------------------------------------------------
2+
NGINX License
3+
4+
/*
5+
* Copyright (C) 2002-2016 Igor Sysoev
6+
* Copyright (C) 2011-2016 Nginx, Inc.
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions
11+
* are met:
12+
* 1. Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in the
16+
* documentation and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28+
* SUCH DAMAGE.
29+
*/
30+
-----------------------------------------------------------------------------

README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# nginx-ssl-ja3 [![Build Status](https://travis-ci.org/fooinha/nginx-ssl-ja3.svg?branch=master)](https://travis-ci.org/fooinha/nginx-ssl-ja3)
2+
3+
nginx module for SSL/TLS ja3 fingerprint.
4+
5+
## Description
6+
7+
This module adds to nginx the ability of new nginx variables for the TLS/SSL ja3 fingerprint.
8+
9+
For details about the ja3 fingerprint algorithm, check initial [project](https://github.com/salesforce/ja3).
10+
11+
## Configuration
12+
13+
### Directives
14+
15+
No directives yet.
16+
17+
### Variables
18+
19+
#### $http_ssl_ja3_hash
20+
21+
The ja3 fingerprint MD5 hash for a SSL connection for a HTTP server.
22+
23+
Example:
24+
25+
```
26+
http {
27+
server {
28+
listen 127.0.0.1:443 ssl;
29+
ssl_certificate cert.pem;
30+
ssl_certificate_key rsa.key;
31+
error_log /dev/stderr debug;
32+
return 200 "$time_iso8601-$http_ssl_ja3_hash\n";
33+
}
34+
}
35+
```
36+
37+
#### $stream_ssl_ja3_hash
38+
39+
The ja3 fingerprint MD5 hash for a SSL connection for a stream server.
40+
41+
Example:
42+
43+
```
44+
stream {
45+
server {
46+
listen 127.0.0.1:12345 ssl;
47+
ssl_certificate cert.pem;
48+
ssl_certificate_key rsa.key;
49+
error_log /dev/stderr debug;
50+
return "$time_iso8601-$stream_ssl_ja3_hash\n";
51+
}
52+
}
53+
```
54+
55+
## Build
56+
57+
### Dependencies
58+
59+
* [OpenSSL](https://github.com/openssl) - master dev version
60+
61+
The master version OpenSSL is required because this module fetches the
62+
extensions types declared at SSL/TLS Client Hello by using the new early
63+
callback [SSL_CTX_set_early_c](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_early_cb.html).
64+
65+
I was unable to find a way to get these values with the current versions of
66+
nginx and OpenSSL.
67+
68+
So, in order to, have the client extensions available for the fingerprint,
69+
we also need to apply a patch to the nginx code.
70+
71+
If you use, for development, the [docker](#docker) supplied in this repo,
72+
the patch is already applied. Check the Dockerfile of the dev image.
73+
74+
### Patches
75+
76+
- [save Client Hello extensions at nginx's SSL connection](docker/debian-nginx-ssl-ja3/nginx.ssl.extensions.patch)
77+
78+
79+
### Compilation and installation
80+
81+
Build as a common nginx module.
82+
83+
```bash
84+
$ ./configure --add-module=/build/ngx_ssl_ja3 --with-http_ssl_module --with-stream_ssl_module --with-debug --with-stream
85+
$ make && make install
86+
87+
```
88+
## Tests
89+
90+
Not available yet.
91+
92+
## Docker
93+
94+
Docker images and a docker compose file is available at the ./docker directory.
95+
96+
```
97+
$ docker-compose up --build -d
98+
99+
Creating nginx-ssl-ja3
100+
101+
```
102+
103+
## Fair Warning
104+
105+
**THIS IS NOT PRODUCTION** ready.
106+
107+
So there's no guarantee of success. It most probably blow up when running in real life scenarios.
108+

config

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
ngx_addon_name=ngx_ssl_ja3_module
2+
ngx_module_incs=$ngx_addon_dir/src
3+
4+
NGINX_VERSION=`grep version src/core/nginx.h | sed 's/#define nginx_version *//;'`
5+
6+
#TODO: To validate if correct OpenSSL version is available
7+
8+
if [ ! -z "${NGINX_VERSION}" ]
9+
then
10+
if [ $NGINX_VERSION -gt 1011002 ]
11+
then
12+
STREAM_MODULES="ngx_stream_ssl_ja3_preread_module $STREAM_MODULES"
13+
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
14+
$ngx_addon_dir/src/ngx_stream_ssl_ja3_preread_module.c"
15+
echo " + ngx_ssl_ja3: stream support"
16+
fi
17+
fi
18+
19+
HTTP_MODULES="$HTTP_MODULES ngx_http_ssl_ja3_module"
20+
21+
CORE_INCS="$CORE_INCS $ngx_module_incs"
22+
23+
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
24+
$ngx_addon_dir/src/ngx_ssl_ja3.c \
25+
$ngx_addon_dir/src/ngx_http_ssl_ja3_module.c
26+
"
27+
28+
CORE_LIBS="$CORE_LIBS"
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
FROM debian:sid
2+
3+
LABEL maintainer "fooinha@gmail.com"
4+
5+
# Build arguments
6+
ARG DEBIAN_REPO_HOST=httpredir.debian.org
7+
ARG GIT_LOCATION=https://github.com/fooinha/nginx-ssl-ja3.git
8+
ARG GIT_BRANCH=master
9+
10+
# Mirror to my location
11+
RUN echo "deb http://${DEBIAN_REPO_HOST}/debian sid main" > /etc/apt/sources.list
12+
RUN echo "deb-src http://${DEBIAN_REPO_HOST}/debian sid main" >> /etc/apt/sources.list
13+
14+
# Update
15+
RUN DEBIAN_FRONTEND=noninteractive apt-get update || true
16+
17+
# Install build dependencies
18+
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --fix-missing \
19+
apt-utils \
20+
autoconf \
21+
automake \
22+
bind9-host \
23+
build-essential \
24+
dh-autoreconf \
25+
cpanminus \
26+
curl \
27+
devscripts \
28+
exuberant-ctags \
29+
git-core \
30+
jq \
31+
llvm \
32+
libgeoip1 \
33+
libgeoip-dev \
34+
libpcre3 \
35+
libpcre3-dbg \
36+
libpcre3-dev \
37+
libperl-dev \
38+
libmagic-dev \
39+
libtool \
40+
lsof \
41+
make \
42+
mercurial \
43+
ngrep \
44+
procps \
45+
python \
46+
telnet \
47+
tcpflow \
48+
valgrind \
49+
vim \
50+
wget \
51+
zlib1g \
52+
zlib1g-dev
53+
54+
# Create build directory
55+
RUN mkdir -p /build
56+
57+
WORKDIR /build
58+
59+
# Fetches and clones from git location
60+
RUN git clone ${GIT_LOCATION}
61+
RUN cd nginx-ssl-ja3 && git checkout ${GIT_BRANCH}
62+
63+
WORKDIR /build
64+
65+
# Get openssl master from git
66+
RUN git clone https://github.com/openssl/openssl
67+
68+
# Build and install openssl
69+
WORKDIR /build/openssl
70+
RUN ./config -d
71+
RUN make
72+
RUN make install
73+
74+
# Clone from nginx
75+
WORKDIR /build
76+
RUN hg clone http://hg.nginx.org/nginx
77+
78+
# Patch nginx for fetching ssl client extensions
79+
WORKDIR /build/nginx
80+
COPY nginx.ssl.extensions.patch /build/nginx
81+
RUN cat nginx.ssl.extensions.patch
82+
RUN patch -p1 < nginx.ssl.extensions.patch
83+
84+
# Get test framework
85+
RUN git clone https://github.com/openresty/test-nginx.git
86+
87+
# Install test framework and dependencies
88+
RUN cd test-nginx/ && cpanm .
89+
90+
# Configure, make and install
91+
RUN export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
92+
RUN ./auto/configure --add-module=/build/nginx-ssl-ja3 --with-http_ssl_module --with-stream_ssl_module --with-debug --with-stream --with-cc-opt="-fsanitize=address -O -fno-omit-frame-pointer" --with-ld-opt="-Wl,-E -lasan"
93+
RUN make install
94+
95+
# Install files
96+
RUN mkdir -p /usr/local/nginx/conf/
97+
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
98+
99+
# Install self-signed certificate
100+
RUN LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib /usr/local/bin/openssl req -new -x509 -days 365 -nodes -out /usr/local/nginx/conf/cert.pem -keyout /usr/local/nginx/conf/rsa.key -subj "/C=PT/ST=Lisbon/L=Lisbon/O=Development/CN=foo.local"
101+
102+
# exuberant ctags
103+
RUN cd /build/nginx-ssl-ja3 && ctags -R src/ ../nginx/src/
104+
105+
# vim config
106+
COPY vimrc /etc/vim/vimrc
107+
108+
RUN echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib' | tee -a /root/.bashrc
109+
RUN echo 'export PATH=$PATH:/usr/local/bin:/usr/local/nginx/sbin' | tee -a /root/.bashrc
110+
RUN echo '' | tee -a /root/.bashrc
111+
RUN echo 'export ASAN_OPTIONS=symbolize=1' | tee -a /root/.bashrc
112+
RUN echo 'export export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer' | tee -a /root/.bashrc
113+
RUN echo '' | tee -a /root/.bashrc
114+
RUN echo 'TO TEST RUN:\n nginx &\n openssl s_client -connect 127.0.0.1:12345 -cipher "AES128-SHA" -curves secp521r1' | tee -a /build/TEST.README
115+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#user nobody;
2+
worker_processes 1;
3+
daemon off;
4+
5+
events {
6+
worker_connections 1024;
7+
}
8+
9+
http {
10+
server {
11+
listen 127.0.0.1:443 ssl;
12+
ssl_certificate cert.pem;
13+
ssl_certificate_key rsa.key;
14+
error_log /dev/stderr debug;
15+
return 200 "$time_iso8601-$http_ssl_ja3_hash\n";
16+
}
17+
}
18+
19+
stream {
20+
server {
21+
listen 127.0.0.1:12345 ssl;
22+
ssl_certificate cert.pem;
23+
ssl_certificate_key rsa.key;
24+
error_log /dev/stderr debug;
25+
return "$time_iso8601-$stream_ssl_ja3_hash\n";
26+
}
27+
}

0 commit comments

Comments
 (0)