ssl snippets

Compiling Ruby with OpenSSL, Zlib and Readline support on Debian

Tagged ruby, readline, ssl, zlib, debian  Languages ruby

DRAFT... From

Install pre-requisites

apt-get -y install build-essential libssl-dev libreadline5-dev zlib1g-dev

Download and install

cd /usr/local/src


tar zxvf ruby-1.8.6.tar.gz

cd ruby-1.8.6.tar.gz

./configure --prefix=/usr/local --with-openssl-dir=/usr --with-readline-dir=/usr --with-zlib-dir=/usr

make install

ruby -ropenssl -rzlib -rreadline -e "puts :success"

Hack for using OpenURI with SSL

Tagged openuri, ssl, http, hack  Languages ruby

This problem occurs with OpenURI and Ruby 1.8:

/usr/lib/ruby/1.8/net/http.rb:586:in connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: ce
rtificate verify failed (OpenSSL::SSL::SSLError)
        from /usr/lib/ruby/1.8/net/http.rb:586:in connect'
        from /usr/lib/ruby/1.8/net/http.rb:553:in do_start'
        from /usr/lib/ruby/1.8/net/http.rb:542:in start'
        from /usr/lib/ruby/1.8/open-uri.rb:242:in open_http'

With Ruby 1.9 you have an option to fix it like this:

open(uri,:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE)

For Ruby 1.8 you could do this:

require 'open-uri'
require 'openssl'

url = 'https://www....'
proxy = 'http://...'


puts open(url, :proxy => proxy).read

Code found here

Scroogle SSL search with vimperator.

Tagged scroogle, vimperator, ssl  Languages bash

A hack for using scroogle's SSL search as default search engine for :o, :p and :t commands of Vimperator.

:bmark -title="Scroogle SSL search" -keyword=scroogle
:set defsearch=scroogle

How to fix "PEM_read_bio:no start line error" nginx error

Tagged nginx, https, ssl  Languages bash

If nginx/OpenSSL gives you this error:

[emerg]: SSL_CTX_use_PrivateKey_file("/etc/ssl/cert.pem") failed (SSL:
error:0906D06C:PEM routines:PEM_read_bio:no start line error:140B0009:SSL
routines:SSL_CTX_use_PrivateKey_file:PEM lib)
configuration file /etc/nginx/nginx.conf test failed

It probably means your private key needs to be added to the certificate file (/etc/ssl/cert.pem). The file will then contain the following:


Remember to test your configuration and verify that nginx can read your certificate before restarting the server:

sudo /usr/sbin/nginx -c /etc/nginx/nginx.conf -t
the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful

If nginx asks you for a PEM password (Enter PEM pass phrase), strip out the password from the private key:

openssl rsa -in jebus.key -out jebus-stripped.key

How to use Ansible Vault to store SSL certificates

Tagged ssl, certificates, ansible, vault  Languages bash


In playbook.yml, list the file where we'll put the SSL certificates:

- hosts: servers
    - vault/certs/{{ domain }}.yml # Private SSL certificates

Ansible Vault

Next, create an encrypted Ansible vault (one per domain):

$ ansible-vault create vault/certs/

Put the following in the vault/certs/

  - name: ""
    content: |
      -----BEGIN CERTIFICATE-----
  - name: ""
    content: |
      -----BEGIN CERTIFICATE-----

The last thing we need to do is copy the certificates from the Ansible Vault to the server (roles/ssl_certs/tasks/main.yml):

- name: Copy private SSL certificates from Ansible Vault
  tags: ssl_certs
    content: "{{ item.content }}"
    dest: "/etc/ssl/private/{{ }}"
    owner: root
    group: root
    mode: "u=rw,g=r,o="
  sudo: yes
    # Certificates are stored encrypted in vault/certs/{{ domain }}.yml
    - "{{ certificates }}"


Use ask-vault-pass to specify the Ansible Vault's password at deployment:

$ ansible-playbook -i inventory/hosts --limit server1 --tags "ssl_certs" playbook.yml -v --ask-vault-pass

How to fix "SSL client CA chain cannot be verified" haproxy error

Tagged haproxy, ssl, openssl  Languages bash

Check which client certificates CA names the server accepts

$ openssl s_client -connect -servername

Acceptable client certificate CA names
/C=FI/ST=Finland/O=Vaestorekisterikeskus TEST/OU=Terveydenhuollon testiammattivarmenteet/CN=VRK TEST CA for Healthcare Professionals
/C=FI/ST=Finland/O=Vaestorekisterikeskus TEST/OU=Testivarmenteet/CN=VRK CA for Test Purposes

Export client certificate public key to a file

If needed, export the client certificate's public key to a file, e.g. xyz.pem.

Check who has issued the client certificate:

$ openssl x509 -in xyz.pem -text

Issuer: C=FI, ST=Finland, O=Vaestorekisterikeskus TEST, OU=Terveydenhuollon testiammattivarmenteet, CN=VRK TEST CA for Healthcare Professionals

Is the issuer one of the CAs listed in step #1?

Verify client certificate

If yes, verify the client certificate against haproxy's ca-file:

cat xyz.pem | openssl verify -CAfile /etc/ssl/certs/haproxy-ca-file.pem

If validation fails, you probably need to add some root or intermediate certificates to /etc/ssl/certs/haproxy-ca-file.pem.

Haproxy configuration template with SSL

Tagged haproxy, ssl, template  Languages 
# HAProxy documentation:
# Inspiration:
  # syslog
  log               /dev/log local0
  log      local1 notice
  # run as haproxy
  user              haproxy
  group             haproxy
  # total number of allowed open connections
  maxconn           50000
  pidfile           /var/run/
  # random health checks
  spread-checks     5
  # run in background
  # SSL certificates are found here
  ca-base           /etc/ssl/certs
  crt-base          /etc/ssl/private
  # SSL hardening, see
  tune.ssl.default-dh-param   2048
  ssl-default-bind-options    no-sslv3
  ssl-default-server-options  no-sslv3
  # uncomment to debug

# defaults apply to all servers
  log               global
  # requests use HTTP protocol
  mode              http
  # log HTTP requests
  option            httplog
  # keep alive connections between client and balancer. Close connections between balancer and backend
  option            http-server-close
  # X-Forwarded-For header
  option            forwardfor
  # Client closed connection, abort request
  option            abortonclose
  # if request fails, resend request to up to 2 servers
  retries           3
  # request can be handled by any server in case of failure
  option            redispatch
  # total number of allowed open connections per server
  maxconn           25000
  # health check fails it takes longer than this to respond
  timeout check     5s
  timeout client    30s
  timeout connect   30s
  timeout server    30s

# Define frontends (haproxy)
frontend http
  bind            *:80
  # redirect HTTP to HTTPS
  redirect scheme https if !{ ssl_fc }
  default_backend http-backend

frontend https
  bind            *:443 ssl crt
  default_backend http-backend

# Define backends (Rails, Go, Elixir, etc)
backend http-backend
  balance         roundrobin
  # health check is done by fetching /
  option          httpchk HEAD / HTTP/1.1
  # Define two backend servers
  server          http1 check #inter 5s rise 18 fall 2
  server          http2 check #inter 5s rise 18 fall 2
  # Set HTTP headers
  http-request    set-header X-Forwarded-Port %[dst_port]
  http-request    add-header X-Forwarded-Proto https if { ssl_fc }

How to view the client certificates accepted by a website

Tagged ca, certificates, client certificate, openssl, ssl  Languages bash

To view a list of acceptable client certificates, execute:

$ openssl s_client -connect

The output is a list of acceptable CA names:

Acceptable client certificate CA names
/C=FI/ST=Finland/O=Vaestorekisterikeskus CA/OU=XYZ/CN=ÅÄÖ

or, if no client certificates are accepted:

No client certificate CA names sent

To log client certificate information with haproxy:

  bind *:443 ssl crt ca-file vrk-ca.pem verify optional crt-ignore-err all crl-file vrk-revocation-list.pem
  # See
  http-request set-header X-SSL                  %[ssl_fc]
  http-request set-header X-SSL-Client-Verify    %[ssl_c_verify]
  http-request set-header X-SSL-Client-DN        %{+Q}[ssl_c_s_dn]
  http-request set-header X-SSL-Client-CN        %{+Q}[ssl_c_s_dn(cn)]
  http-request set-header X-SSL-Issuer           %{+Q}[ssl_c_i_dn]
  http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
  http-request set-header X-SSL-Client-NotAfter  %{+Q}[ssl_c_notafter]

  log-format "%ci:%cp [%t] %ft %b/%s %Tq/%Tw/%Tc/%Tr/%Tt %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs {%[ssl_c_verify],%{+Q}[ssl_c_s_dn],%{+Q}[ssl_c_i_dn]} %{+Q}r"

Also see

Ban invalid HTTP requests with fail2ban

Tagged fail2ban, hex, nginx, https, ssl  Languages bash

The goal is to use fail2ban to block invalid HTTP requests sent to nginx from Iran:

" - - [04/Jan/2021:02:46:12 +0000] "\x10\xD2\xE9\xA68\x8A\x98\xB3\x00\xB9mO\xD7\xC9\xAA]"

The request is a HEX encoded string instead of the normal “GET /“.

First, configure the jail:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Add the following at the end of the file:

enabled  = true
port     = http,https
filter   = nginx-idiots
logpath  = /var/log/nginx/access.log
# NOTE: Docker will override fail2ban's rules, so good luck with iptables:
# logpath = /var/lib/docker/containers/*/*.log
bantime  = 86400
findtime = 86400
maxretry = 2

Add a filter to block the idiots:

sudo vim /etc/fail2ban/filter.d/nginx-idiots.conf
failregex = ^.* <HOST> .*".*\\x.*".*$
ignoreregex =

Test the regex:

sudo fail2ban-regex -v --print-all-missed /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-idiots.conf

Restart fail2ban.

View banned IPs with:

sudo fail2ban-client status nginx-idiots

Note that this could also be a real idiot that is sending SSL traffic to the non-SSL port, or someone who has configured SSL traffic to be sent to the non-SSL port.