Skip to main content

SslTerminating

The duty of this module is to offload HTTPS connections, and help our CaptchaHttp and WAF module to work properly with HTTPS requests. If you enable SslTerminating it will try to download and install bitninja-ssl-termination package to /opt/bitninja-ssl-termination, which is basically a HAProxy 1.9.13. We decided to build and publish our self-built HAProxy, because it will not depend on official repositories, and it will not interfere with other HAProxy installations and configurations. After installation succeeds, it will try to find currently active virtual hosts using HTTPS and extract any information which can be used to generate a valid haproxy.cfg. The module is responsible for collecting and generating pem files every 5 minutes, which can be used by bitninja-ssl-termination to offload HTTPS requests.

The module works with CaptchaHttp and WAF 2.0 modules. When a challenge listed IP tries to connect to your server on 443 it will be redirected to bitninja-ssl-termination's frontend. The CAPTCHA will appear, and the innocent visitor can solve it.

caution

SslTerminating (HAProxy 1.9.13) will be replaced shortly by Caddy Server (along with Nginx) for better performance.

Certificate miners

To gather certificate information, SSL Terminating module currently uses three certificate miner implementations. These miners are: ApacheCertMiner, NginxCertMiner, LiteSpeedCertMiner.

A certificate miner implementation should consist of the following steps:

  • Collect the public key, the private key and the chain file for the SSL Certificate and put them in a pem file.
  • Put the newly created pem file location in /opt/bitninja-ssl-termination/etc/haproxy/cert-list-lst file, with every domain that belongs to this certificate, separated with spaces. Like this: /opt/bitninja-ssl-termination/etc/haproxy/certs/example.com-ssl.pem example.com www.example.com \*.example.com

An example bash implementation for DirectAdmin:

echo > /opt/bitninja-ssl-termination/etc/haproxy/cert-list.lst
for i in `ls /usr/local/directadmin/data/users/*/domains/* | grep ".key" | awk -F "/" {'print $9'} | sed 's/\.[^.]*$//'` ;

do

cat /usr/local/directadmin/data/users/*/domains/"$i".key /usr/local/directadmin/data/users/*/domains/"$i".cert > /opt/bitninja-ssl-termination/etc/haproxy/certs/"$i".pem
echo "/opt/bitninja-ssl-termination/etc/haproxy/certs/$i.pem $i www.$i *.$i" >> /opt/bitninja-ssl-termination/etc/haproxy/cert-list.lst

done

You can make your custom cert miner as default. To use your custom certificate miner instead of the ConfigParser module:

  • Disable the useConfigParserModule variable and enable the allowCertListFileEdition option.
  • Move your certificate miner to the /etc/bitninja/SslTerminating/cert_miners/ directory.
  • Currently only BASH scripts are supported.
  • The script has to be a .sh file.
  • The owner of the script has to be ROOT

The cert miner will run automatically when the SslTerminating module is started or restarted.

Web Server CertMiners

You may adjust the path for each web server binary on the Dashboard Configuration -> Advanced Modules (ConfigParser). This ensures that the ConfigParser can find the virtualhosts for your domains and locate the certificates and private keys.

Option to edit the ConfigParser module configuration is still available locally on the server.

/etc/bitninja/ConfigParser/config.ini

warning

Don't forget to sync your local configuration to the cloud with bitninjacli --syncconfigs

Custom CertMiner

You may also create your very own certificate miner to collect them automatically.

Example and visual practises are available on our knowledgebase.

Manual certificate mapping

Since version 3.7.7 you can manually add each domain's SSL cert's location if neccesary.

warning

Wildcard SSL Certificates like *.example.com are not supported yet.

  1. Turn off the ConfigParser module from our Dashboard -> Configuration - Advanced Modules (Protection on HTTPS)

  2. Map the certificate's location to the domain with this command:
    bitninjacli --module=SslTerminating --add-cert --domain=<domain> --certFile=<certFile> --keyFile=<keyFile>

  3. Finally run our recollect command:
    bitninjacli --module=SslTerminating --force-recollect

(Chained certificates can be also added with the following parameter --chainFile=<chainFile>)

CLI options

You can use CLI to enable and disable SslTerminating module with:

   bitninjacli --module=SslTerminating --enabled
bitninjacli --module=SslTerminating --disabled

HAProxy configuration can be reloaded, if they were manually edited with:

   bitninjacli --module=SslTerminating --reload

HAProxy configuration can be regenerated, if module configurations were edited:

   bitninjacli --module=SslTerminating --regenerate

Custom Certmapping options

   bitninjacli --module=SslTerminating --add-cert --domain=<domain> --certFile=<certFile> --keyFile=<keyFile> | optional --chainFile=<chainFile>
bitninjacli --module=SslTerminating --del-cert --domain=<domain>

Configuration

The module can be configured in /etc/bitninja/SslTerminating/config.ini. This config file contains 9 config sections. The first two are for HAProxy and Apache binary settings. The other seven sections are for configuring different sections of the haproxy.cfg, if needed.

;
;
; Bitninja [SslTerminating] Module configuration file
;
;

;
; SslTerminating module uses HAProxy 1.5.8. This section define basic configurations.
;

[certificateMiner]
;useConfigParserModule=0
;
; Allow edition of the cert-list.lst file, when Certificate miners found any certificate.
; When Certificate miners fail to find any valid certificate, manually creation and mantaining the list file
; are not changed.
;
;allowCertListFileEdition=0

;
; Allow run of the Certificate finder cron, which runs every 5 minutes.
;
;allowCertificateFinderCron=1

; Certiicate miner need to read the webserver's configuration file which can be huge.
; We need to increase the module memory limit to avoid out of memory fatal errors.
; Memory limit value is in Mega bytes default. Default value is 2024 Mega byte (2Gb).
; The minimum value is 100 Mb.
;memoryLimit='2024'

[domainratelimit]
; Maximum requests per domain every 'perDomainRateLimitInterval' seconds (see below)
; If set to 0, rate limiting is disabled
; perDomainRateLimit = 0
; How many seconds should take before resetting the rate limit counter
; perDomainRateLimitInterval = 0

[general]
; Always generate haproxy configuration based on config.ini setting.
;generate_config_on_startup = 1

[haproxy]
;; where is the haproxy binary
;binaryLocation='/opt/bitninja-ssl-termination/sbin/haproxy'
;; where should we look for haproxy config file
;configLocation='/opt/bitninja-ssl-termination/etc/haproxy/haproxy.cfg'
;; where could haproxy work
;workingDirectory='/var/lib/bitninja/SslTerminating'
;; where could SslTerminating put collected cert files
;certDir = '/opt/bitninja-ssl-termination/etc/haproxy/certs'
;; where is the cert list file
;certListFile = '/opt/bitninja-ssl-termination/etc/haproxy/cert-list.lst'
;; user for haproxy
;haproxyUser='bitninja-ssl-termination'
;; Https Captcha backend port
;haproxyPort = 60413
;; front end port
;httpsPort = 443
;; Captcha front and backend settings
;CaptchaFrontEndSettings[name]= 'Captcha-https'
;CaptchaFrontEndSettings[iface]= '*'
;CaptchaFrontEndSettings[port]= 60413
;CaptchaBackEndSettings[name]= 'Captcha-https-backend'
;; WAF front and backend setting
;; not used for now
;WafFrontEndSettings[name]= 'waf-https'
;WafFrontEndSettings[iface]= '*'
;WafFrontEndSettings[port]= '60414'
;WafBackEndSettings[name]= 'waf-https-backend'

;
; Web server settings
;
[webserver]
;; if binary location not set SslTerminating module tries to find where is apache.
;apachectlBinaryLocation = '/usr/sbin/apache2ctl'
;apachectlBinaryLocation = '/usr/sbin/httpd'
;apachectlBinaryLocation = '/opt/sp/apache/bin/apachectl'
;listVirtualHostParameter= '-S'

;
; Haproxy global settings. Every ini key value will be converted to a haproxy configuration.
; E.g.: chroot = '/var/lib/bitninja/SslTerminating'
; Will be converted to:
; chroot = /var/lib/bitninja/SslTerminating
; If you whan to add multiple values use ini arrays.
; E.g.: log[] = '/dev/log local0'
; log[] = '/dev/log local1 notice'
; This will be converted to:
; log = /dev/log local0
; log = /dev/log local1 notice
; See more about haproxy configuration at: https://cbonte.github.io/haproxy-dconv/1.5/configuration.html
;
[haproxyGlobalSettings]
;log[] = '/dev/log local0'
;log[] = '/dev/log local1 notice'
;chroot = '/var/lib/bitninja/SslTerminating'
;stats[] = 'socket /var/lib/bitninja/SslTerminating/admin.sock mode 660 level admin'
;stats[] = 'timeout 30s'
;user = 'bitninja-ssl-termination'
;group = 'bitninja-ssl-termination'
;; Default SSL material locations
;ca-base = '/etc/ssl/certs'
;crt-base = '/etc/ssl/private'

;; Default ciphers to use on SSL-enabled listening sockets.
;; For more information, see ciphers(1SSL). This list is from:
;; https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
;; An alternative list with additional directives can be obtained from
;; https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
;ssl-default-bind-ciphers = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'
;ssl-default-server-ciphers = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'
;ssl-default-bind-options = 'no-sslv3 no-tlsv10'
;tune.ssl.default-dh-param = 2048

;
; Haproxy default Settings
;
[haproxyDefaultSettings]
;log = 'global'
;mode = 'http'
;option[] = 'httplog'
;option[] = 'dontlognull'
;option[] = 'forwardfor'
;timeout[] = 'connect 5000'
;timeout[] = 'client 50000'
;timeout[] = 'server 50000'
;errorfile[] = '400 /opt/bitninja-ssl-termination/etc/haproxy/errors/400.http'
;errorfile[] = '403 /opt/bitninja-ssl-termination/etc/haproxy/errors/403.http'
;errorfile[] = '408 /opt/bitninja-ssl-termination/etc/haproxy/errors/408.http'
;errorfile[] = '500 /opt/bitninja-ssl-termination/etc/haproxy/errors/500.http'
;errorfile[] = '502 /opt/bitninja-ssl-termination/etc/haproxy/errors/502.http'
;errorfile[] = '503 /opt/bitninja-ssl-termination/etc/haproxy/errors/503.http'
;errorfile[] = '504 /opt/bitninja-ssl-termination/etc/haproxy/errors/504.http'

;
; Stat page setting. For security reason please Change uri, auth
;
[statPageSettings]
;bind = '*:1936'
;mode = 'http'
;log = 'global'
;maxconn = 10
;timeout queue = '100s'
;stats[] = 'enable'
;stats[] = 'hide-version'
;stats[] = 'refresh 30s'
;stats[] = 'show-node'
; Haproxy stat page auth setting. Change it before enabling stat page.
;stats[] = 'auth user:password'
; Haproxy stat page uri setting. Change it before enabling stat page.
;stats[] = 'uri /haproxy?stats'

;
; Haproxy Captcha frontend settings.
; Don't use Haproxy bind configuration in thes section.
;
[CaptchaFrontEndSettings]
;option[]= "httpclose"
;reqadd = 'X-Forwarded-Proto:\ https'

;
; Haproxy Captcha backend settings
;
[CaptchaBackEndSettings]
;redirect = 'scheme https if !{ ssl_fc }'
;server= 'captcha-1 *:60412 check'

;
; Haproxy WAF frontend settings.
; Not used yet.
;
[WafFrontEndSettings]
;reqadd = 'X-Forwarded-Proto:\ https'
;default_backend = 'waf-https-backend'

;
; Haproxy WAF backend settings.
; Not used yet.
;
[WafBackEndSettings]
;redirect = 'scheme https if !{ ssl_fc }'
;server 'waf-1 *:60045 check'

Regenerating certificate information

If the SslTerminating is using expired certificate information on your server for some reason, you can regenerate the certificate information by running the following command:

bitninjacli --module=SslTerminating --force-recollect

This command does the same as below, which you can also run manually, one after the other, if needed:

rm -f /opt/bitninja-ssl-termination/etc/haproxy/certs/*
rm -f /opt/bitninja-ssl-termination/etc/haproxy/cert-list.lst
rm -f /opt/bitninja-ssl-termination/etc/haproxy/haproxy.cfg
bitninjacli --module=SslTerminating --regenerate
bitninjacli --module=SslTerminating --reload

Enhance Control Panel

BitNinja has been compatible with Enhance Control Panel since version 3.3.0. The Config Parser module can now parse and find the corresponding configuration files. The WAF, captcha, and TrustedProxy modules work seamlessly with the control panel.

However, there are still some limitations, unfortunately, that require further development.

  • The LogAnalysis and Defense Robot modules cannot process back-end web server logs with Enhance Control Panel.
  • The PortHoneypot module will not start in a dockerized environment. Therefore, it is not enabled in this case either.
info

In order to ensure complete protection for the entire cluster, it is necessary to install BitNinja on all servers within the setup. Merely installing it on the control panel node will not suffice.