NGINX with LibreSSL build script

Works with (at least) Ubuntu Xenial 16.04.

For updates see here.

Or just replace the version numbers ūüôā


# names of latest versions of each package
export NGINX_VERSION=1.15.7
export VERSION_PCRE=pcre-8.42
export VERSION_LIBRESSL=libressl-2.9.0
export SPNEGO_VERSION=1.1.0
export GEOIP2_VERSION=3.2

# URLs to the source directories

# clean out any files from previous runs of this script
rm -rf build
mkdir build

# ensure that we have the required software to compile our own nginx
sudo apt-get -y install curl wget build-essential libgd-dev libgeoip-dev checkinstall git krb5-user uuid-dev

# grab the source files
echo "Download sources"
wget -P ./build $SOURCE_PCRE$VERSION_PCRE.tar.gz
wget -P ./build $SOURCE_NGINX$VERSION_NGINX.tar.gz
wget -P ./build $SOURCE_SPNEGO$VERSION_SPNEGO.tar.gz
wget -P ./build $SOURCE_GEOIP2$VERSION_GEOIP2.tar.gz
git clone $SOURCE_RTMP ./build/rtmp

# expand the source files
echo "Extract Packages"
cd build
tar xzf $VERSION_NGINX.tar.gz
tar xzf $VERSION_LIBRESSL.tar.gz
tar xzf $VERSION_PCRE.tar.gz
tar xzf $VERSION_SPNEGO.tar.gz
tar xzf $VERSION_GEOIP2.tar.gz
cd ../
# set where LibreSSL and nginx will be built
export BPATH=$(pwd)/build

# build static LibreSSL
echo "Configure & Build LibreSSL"
./configure LDFLAGS=-lrt --prefix=${STATICLIBSSL}/.openssl/ && make install-strip

# build nginx, with various modules included/excluded
echo "Configure & Build Nginx"
#echo "Download and apply path"
#wget -q -O - $NGINX_PATH | patch -p0
mkdir -p $BPATH/nginx
./configure --with-openssl=$STATICLIBSSL \
--with-ld-opt="-lrt" \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-pcre=$BPATH/$VERSION_PCRE \
--with-http_ssl_module \
--with-http_v2_module \
--with-file-aio \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--without-mail_pop3_module \
--without-mail_smtp_module \
--without-mail_imap_module \
--with-http_image_filter_module \
 --lock-path=/var/lock/nginx.lock \
 --pid-path=/run/ \
 --http-client-body-temp-path=/var/lib/nginx/body \
 --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
 --http-proxy-temp-path=/var/lib/nginx/proxy \
 --http-scgi-temp-path=/var/lib/nginx/scgi \
 --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
 --with-debug \
 --with-pcre-jit \
 --with-http_stub_status_module \
 --with-http_realip_module \
 --with-http_auth_request_module \
 --with-http_addition_module \
 --with-http_geoip_module \
 --with-http_gzip_static_module \
 --add-module=$BPATH/rtmp \
 --add-module=$BPATH/spnego-http-auth-nginx-module-${SPNEGO_VERSION} \
 --add-module=$BPATH/ngx_http_geoip2_module-${GEOIP2_VERSION} \
 --build="nginx with ${VERSION_LIBRESSL}"

touch $STATICLIBSSL/.openssl/include/openssl/ssl.h
make && sudo checkinstall --pkgname="nginx-libressl" --pkgversion="$NGINX_VERSION" \
--provides="nginx" --requires="libc6, libpcre3, zlib1g" --strip=yes \
--stripso=yes --backup=yes -y --install=yes

echo "All done.";
echo "This build has not edited your existing /etc/nginx directory.";
echo "If things aren't working now you may need to refer to the";
echo "configuration files the new nginx ships with as defaults,";
echo "which are available at /etc/nginx-default";

a patch for IRSSI to prevent errors when compiling with LibreSSL 2.7.0/2.7.1

Also here, submitted upstream as a pull request now merged upstream.

Grabbed from here.

Works with irssi 1.1.1 and git master:

--- a/src/core/network-openssl.c
+++ b/src/core/network-openssl.c
@@ -35,7 +35,8 @@
 #include <openssl/err.h>
 /* OpenSSL 1.1.0 introduced some backward-incompatible changes to the api */
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL) /* The two functions below could be already defined if OPENSSL_API_COMPAT is * below the 1.1.0 version so let's do a clean start */ #undef X509_get_notBefore @@ -47,7 +48,8 @@ /* OpenSSL 1.1.0 also introduced some useful additions to the api */ #if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
 static int X509_STORE_up_ref(X509_STORE *vfy)
     int n;

a patch for OpenVPN 2.4.5 to prevent errors when compiling with LibreSSL 2.6.4

Here is a patch for OpenVPN 2.4.5 to prevent errors when compiling with LibreSSL 2.6.4:

diff --git a/ b/
index 88d1e09..7db5c79 100644
--- a/
+++ b/
@@ -935,6 +935,18 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
+		[
+			SSL_CTX_get_min_proto_version,
+			SSL_CTX_get_max_proto_version,
+			SSL_CTX_set_min_proto_version,
+			SSL_CTX_set_max_proto_version,
+		],
+		,
+		,
+		[[#include <openssl/ssl.h>]]
+	)
diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h
index d375fab..340d452 100644
--- a/src/openvpn/openssl_compat.h
+++ b/src/openvpn/openssl_compat.h
@@ -661,7 +661,7 @@ EC_GROUP_order_bits(const EC_GROUP *group)
-#ifndef SSL_CTX_get_min_proto_version
 /** Return the min SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -684,7 +684,7 @@ SSL_CTX_get_min_proto_version(SSL_CTX *ctx)
 #endif /* SSL_CTX_get_min_proto_version */
-#ifndef SSL_CTX_get_max_proto_version
 /** Return the max SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -707,7 +707,7 @@ SSL_CTX_get_max_proto_version(SSL_CTX *ctx)
 #endif /* SSL_CTX_get_max_proto_version */
-#ifndef SSL_CTX_set_min_proto_version
 /** Mimics SSL_CTX_set_min_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
@@ -736,7 +736,7 @@ SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
 #endif /* SSL_CTX_set_min_proto_version */
-#ifndef SSL_CTX_set_max_proto_version
 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)

Source here, I altered it to work with OpenVPN 2.4.5.

But it only works when autoconf is actually called (so it doesn’t work for openvpn-build).

OpenVPN built with LibreSSL – Windows binaries

Sometimes, when you cannot find something on the web, you have to build it yourself. Eventually this resulted in some working executables for OpenVPN, built with LibreSSL, to be ran on Windows.

To use these, first grab the regular setup from the OpenVPN website’s download section, install it, and afterwards replace the files in the bin subdirectory with the ones from the correct ZIP file below. Now you can delete libeay32.dll and ssleay32.dll – they came with the original installer and will not be used by the new executables.

Last updated:

I’ll try to keep up with new releases and post new builds over time.

The instructions I followed for building are described here.
Also see:

Apache with LibreSSL

We are going to build Apache with LibreSSL.

We will also attempt to score an A+ with 100/100/100/100 points on the Qualys SSL Labs Server Test.

We assume we have
1.   Ubuntu Server 14.04 with httpd-2.4.12 from ppa:ondrej/apache2.
2.   A working, running Apache configuration.
3.   At least one SSL-enabled VirtualHost with a valid SSL certificate.

DISCLAIMER:¬†I’m not in any way responsible for any damage to your system and/or configuration which may result from following this text. It it assumed that you have the knowledge how to restore things back to their original state and that you make backups.

Getting the files

Let’s grab all the necessary files and¬†unpack them in our homedir :

$ cd ~
$ wget
$ tar zxvf httpd-2.4.12.tar.gz
$ cd httpd-2.4.12/srclib
$ wget
$ wget
$ tar zxvf apr-1.5.1.tar.gz
$ tar zxvf apr-util-1.5.4.tar.gz
$ ln -s apr-1.5.1 apr
$ ln -s apt-util-1.5.4 apr-util
$ cd ~ && wget
$ tar zxvf libressl-2.1.6.tar.gz

Installing LibreSSL

We will not replace the system’s default OpenSSL.
We will just install it in /opt/libressl-2.1.6 :

$ cd ~
$ cd libressl-2.1.6
$ ./configure --prefix=/opt/libressl-2.1.6 --exec-prefix=/opt/libressl-2.1.6
$ make -j3
$ sudo make install

Patching Apache for LibreSSL

Now¬†we partly apply the following patch to Apache’s mod_ssl source :

--- a/modules/ssl/ssl_engine_init.c 2014-07-15 18:48:00.382044224 +0200
+++ b/modules/ssl/ssl_engine_init.c 2015-03-28 18:48:35.452335112 +0100
@@ -275,9 +275,11 @@ apr_status_t ssl_init_Engine(server_rec
             return ssl_die(s);
         if (strEQ(mc->szCryptoDevice, "chil")) {
             ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
         if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01889)
--- a/modules/ssl/ssl_engine_rand.c 2014-07-15 18:49:13.853653603 +0200
+++ b/modules/ssl/ssl_engine_rand.c 2015-03-28 18:49:49.180946663 +0100
@@ -86,9 +86,11 @@ int ssl_rand_seed(server_rec *s, apr_poo
                  * seed in contents provided by the external
                  * Entropy Gathering Daemon (EGD)
                 if ((n = RAND_egd(pRandSeed->cpPath)) == -1)
                 nDone += n;
             else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) {
                 struct {

Now we apply this patch to fix a small memory leak. We adjust it slightly, to change the default EC curve from prime256v1 to brainpoolP384t1 :

--- a/modules/ssl/ssl_engine_init.c Fri Mar 13 07:32:46 2015
+++ b/modules/ssl/ssl_engine_init.c Fri Mar 29 13:32:46 2015
@@ -982,7 +982,7 @@ static apr_status_t ssl_init_server_cert
 #ifdef HAVE_ECC
     EC_GROUP *ecparams;
     int nid;
-    EC_KEY *eckey;
+    EC_KEY *eckey = NULL;
     SSL *ssl;
@@ -1151,10 +1151,11 @@ static apr_status_t ssl_init_server_cert
 #if defined(SSL_CTX_set_ecdh_auto)
         SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1);
-        SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx,
-                             EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+        eckey = EC_KEY_new_by_curve_name(NID_brainpoolP384t1);
+        SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
+    EC_KEY_free(eckey);
     return APR_SUCCESS;

Also – not at all necessary but it does look nicer – let’s change the string for SSL_LIBRARY_NAME to LibreSSL :

--- a/modules/ssl/ssl_util_ssl.h 2015-03-28 13:55:14.518443044 +0200
+++ b/modules/ssl/ssl_util_ssl.h 2015-03-29 13:02:08.450443044 +0100
@@ -39,7 +39,7 @@
+#define SSL_LIBRARY_NAME "LibreSSL"

Building Apache

WARNING:¬†In this example¬†we are replacing¬†the system’s default Apache !!!

If you do not want this, use¬†–prefix=/opt/httpd¬†(or some other path) in the ./configure¬†line. I like it this way,¬†because it allows me to¬†continue using the regular service start/stop scripts without changing anything.

For any additional modules you want to use,¬†you generally have to extract¬†them to your¬†Apache¬†source directory¬†manually and add –enable-modname¬†(like for example¬†–enable-fcgid) to the configure line. See the Apache documentation for more info.

Now we build Apache :

$ cd ~
$ cd httpd-2.4.12
$ ./configure --with-included-apr --enable-ssl --with-ssl=/opt/libressl-2.1.6 --with-crypto --enable-mpms-shared
$ make -j3
$ sudo service apache2 stop
$ sudo make install

In Ubuntu Server 14.04, Apache’s modules live in /usr/lib/apache2/modules. The *.load files in /etc/apache2/mods-available still link to the module files in that default directory.¬†Let’s change all of these *.load files, to link them to the¬†newly installed ones in /usr/local/apache2/modules¬†:

$ cd /etc/apache2/mods-available
$ sudo sed -i 's|/usr/lib/apache2/modules|/usr/local/apache2/modules|g' *.load

If Apache complains about missing modules later when you start it, you could¬†copy the missing modules¬†over manually (but they were built against the system’s default Apache, it’s not a good idea) or compile them during the above procedure.

Now start Apache :

sudo service apache2 start

If all went well, you’ll find something similar to¬†this in your log :

[mpm_prefork:notice] [pid 19325] AH00163: Apache/2.4.12 (Ubuntu) mod_fcgid/2.3.9 LibreSSL/2.1.6 configured -- resuming normal operations

Apache configuration

We will only use TLS 1.2 with 256-bit ciphersuites and either ECDHE or DHE.¬†We explicitly disable the stuff we don’t want or need.

/etc/apache2/mods-enabled/ssl.conf :

<IfModule mod_ssl.c>
   # Other stuff
   # ...
   SSLProtocol -All +TLSv1.2
   SSLHonorCipherOrder on
   # LibreSSL can't do SSL compression by default.
   #SSLCompression Off
   # ...
   # Other stuff

/etc/apache2/conf-enabled/security.conf :

# Other stuff
# ...
ServerTokens Prod
ServerSignature Off
Header set X-Content-Type-Options: "nosniff"
Header set X-Frame-Options: "sameorigin"
Header set X-XSS-Protection: "1; mode=block"
# ...
# Other stuff

If you don’t want to hide version numbers replace the first line above with :

ServerTokens Full

Use these tutorials to set up HPKP, HSTS and OSCP Stapling :


OSCP Stapling—enable-ocsp-stapling


Testing the server

Now let’s test our Apache server with the Qualys¬ģ¬†SSL Labs Server Test¬†:

SSL Report:

If you’re using¬†ServerTokens Full it will mention that¬†LibreSSL is being used :

HTTP server signature

This text was originally posted here.