Skip to content

Instantly share code, notes, and snippets.

@wsargent
Forked from tomdz/gist:5339163
Last active December 31, 2015 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wsargent/7906205 to your computer and use it in GitHub Desktop.
Save wsargent/7906205 to your computer and use it in GitHub Desktop.

Setup vagrant vm

vagrant box add precise64 http://files.vagrantup.com/precise64.box
vagrant init precise64
sed -i '.bak' 's/# config.vm.network :private_network/config.vm.network :private_network/' Vagrantfile
vagrant up
vagrant ssh

Install base software and apache (to have something to proxy)

sudo apt-get update
sudo apt-get install -y curl build-essential libpcre3-dev libssl-dev apache2

Install haproxy

export HAPROXY_VERSION=haproxy-1.5-dev18
curl -O http://haproxy.1wt.eu/download/1.5/src/devel/$HAPROXY_VERSION.tar.gz
tar zxf $HAPROXY_VERSION.tar.gz
cd $HAPROXY_VERSION
make PREFIX=/usr/local \
     IGNOREGIT=true \
     MANDIR=/usr/local/share/man \
     DOCDIR=/usr/local/share/doc/haproxy \
     TARGET=linux2628 \
     CPU=native \
     USE_PCRE=1 \
     USE_STATIC_PCRE=1 \
     USE_OPENSSL=1 \
     USE_ZLIB=1
sudo make install

Setup Ubuntu's official haproxy init.d script for 12.04

curl -O http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/precise/haproxy/precise/download/head:/haproxy.init-20090727115323-3c2mw7iu0du8tdiw-208/haproxy.init
sed -i 's/PATH=/PATH=\/usr\/local\/sbin:/' haproxy.init
sed -i 's/HAPROXY=\/usr\/sbin\/haproxy/HAPROXY=\/usr\/local\/sbin\/haproxy/' haproxy.init
sudo mv haproxy.init /etc/init.d/haproxy
sudo chmod +x /etc/init.d/haproxy

Setup chroot and haproxy configuration

sudo addgroup --system haproxy
sudo adduser --system --no-create-home --ingroup haproxy haproxy
sudo mkdir /opt/haproxy
sudo chown haproxy:haproxy /opt/haproxy/
sudo chmod a-w /opt/haproxy/
sudo mkdir /etc/haproxy
echo "ENABLED=1" | sudo tee /etc/default/haproxy
echo 'global
    daemon
    maxconn 256
    user haproxy
    group haproxy
    chroot /opt/haproxy

defaults
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option  http-server-close

frontend http-in
    mode http
    bind *:443 ssl crt /etc/haproxy/server.pem ca-file /etc/haproxy/ca.crt verify required
    default_backend servers
    reqadd X-Forwarded-Proto:\ https if { ssl_fc }
    option forwardfor

backend servers
    mode http
    server server1 localhost:80 maxconn 32' | sudo tee /etc/haproxy/haproxy.cfg

CA, server and client certificate setup. This is a slightly tweaked form of https://github.com/exceliance/haproxy/blob/master/blog/ssl_client_certificate_management_at_application_level/ca.sh for only the valid client certificate, which also makes use of the -subj commandline option to avoid re-typing those values.

export SUBJECT='/C=US/ST=California/L=San Francisco/CN=test@example.com'

# certificate authority creation
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "$SUBJECT"

# server certificate creation
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr -subj "$SUBJECT"
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

# client certificate creation
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr -subj "$SUBJECT"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt

cat server.crt server.key > server.pem
sudo cp server.pem /etc/haproxy/server.pem
sudo cp ca.crt /etc/haproxy/ca.crt

Start haproxy and test it:

sudo /etc/init.d/haproxy start
openssl s_client -connect localhost:443 -cert client.crt -key client.key

This gives me:

CONNECTED(00000003)
depth=0 C = US, ST = California, L = San Francisco, CN = test@example.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = California, L = San Francisco, CN = test@example.com
verify return:1
139701807867552:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1256:SSL alert number 48
139701807867552:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/CN=test@example.com
   i:/C=US/ST=California/L=San Francisco/CN=test@example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDmjCCAYICAQEwDQYJKoZIhvcNAQEFBQAwVTELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xGTAXBgNVBAMM
EHRlc3RAZXhhbXBsZS5jb20wHhcNMTMwNDA4MTgyMTQ1WhcNMTQwNDA4MTgyMTQ1
WjBVMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
U2FuIEZyYW5jaXNjbzEZMBcGA1UEAwwQdGVzdEBleGFtcGxlLmNvbTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEA672DeWWtseWeQnRa32Zhh9untI6F/gxRTvkv
vNZZgZqP1fgi/2+t6lmmZV5yM31A2wq54Qf00z+5uWwbOoxCeoyLiXQ7PDtWYdhP
zW+jyLWRzY4ndpI+dlA2HfLD9lbcoTMrcPJTab0TvhWSEaXSMCQWNIvhYPBsZ/HT
yy5WQNUCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEA8EWe7WgcBthvFI+9d15jkCX+
SuVn0rSTzKNcU3IAyktm8vVaamhfWqdeV/21ocwUMdQcGSPYJ2DEN8X5YaiCLGup
IT/3CHg1fmDLYrB732vZ0u1Vqz4O0rS3JpPRTQOryjvgDAHyR9V0oe0dP65oDtSA
TqAuaJC79YTB36XEWWgxZIfQCvKqpLYgP9cnlhdy8UOWW7e8a2mic9tw8JYro57/
d3q4l/WoOZ5UkYo4o3y7GviGUldW834nue0Tsdrb8csl0bqR+vqpCU2f6joh1VlF
pMOyrmWm6M4LeqFPTAY6U/S7LjUnYcC/AYvOUyIntNpf8kLRFsmbQapqG5q7jDjW
oWIqdhAzQIG1wS8TevQVHtg8MXKJcNPhcR4lT/xEqtcdiY6F3IFg95STnb41aQXm
7Trnw9j1gTa6cfuQcuTNh4Y9GPQdYhMeJiUUhpZOxOZx86VE5cfSxbY7awYZ+EO2
4NYUajdvyAvwV5WGfTbyJ3+qU5eoOfMKvntHhSYHeHU4jiQ/6q3p1u27b1LoQnr9
k8+CF04AK+V/qhGkeMjg7zcwA6zLdChGpP0sizV3kwcTk4SjNrfepLHgXoOvMQsK
uX00ZsEgZ7EMJqI1NX+Ma4WHUcNMA7eHsb+TuRYudsG2YGLLCsrwNK4Mni1swqKU
vneURb2jEpRn8t6kTv4=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Francisco/CN=test@example.com
issuer=/C=US/ST=California/L=San Francisco/CN=test@example.com
---
Acceptable client certificate CA names
/C=US/ST=California/L=San Francisco/CN=test@example.com
---
SSL handshake has read 1335 bytes and written 1230 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 14DAE59074B21C9AEB0ADB6B77D0833D8BF5FD9B03FF5E5F92EB697483313BFAAB0E028A56925ECBE4FF3AFE001201FA
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1365446671
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

Note the two error lines:

139701807867552:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1256:SSL alert number 48
139701807867552:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:

This

curl -vk --key client.key --cert client.crt https://localhost

gives me a similar error:

* About to connect() to localhost port 443 (#0)
*   Trying 127.0.0.1... connected
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS alert, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS alert, Server hello (2):
* error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
* Closing connection #0
curl: (35) error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment