Hey Donovan, I never used client certificates in haproxy, but have you tried the setup with a regular HTTP backend instead of the stats socket? That is something that should work and you could use to verify that your certs are working correctly...
Cheers, Conrad On 07/24/2014 09:36 PM, Meyers, Donovan wrote: > > Any ideas why "verify required" is allowing connections with no client > cert? > > Could this be an haproxy bug? > > I hate to even ask that, because it's so presumptuous and this software is > so well-written. It's one thousand times more likely that I'm doing > something wrong. > > But from where I sit it seems simple: > - I used "verify require" which should require a client cert > - I can connect without specifying a client cert > > > > So, am I > > > - misusing/misunderstanding "verify require"? > - screwing up some other piece of haproxy config? > - using the wrong socat/openssl syntax to send (or not) the client cert? > - thinking a client cert is valid with tcp when it isn't? > > I'm not sure what else to try, without spending money on a real client > cert, which doesn't seem like it should matter. Hopefully someone can tell > me what I'm doing wrong! > > > Also, sorry about the HTML email for my original post. > > Best, > Donovan > > > From: <Meyers>, Donovan Meyers <donovan_mey...@playstation.sony.com> > Date: Tuesday, July 22, 2014 3:33 PM > To: "haproxy@formilux.org" <haproxy@formilux.org> > Subject: Client certs on tcp and securing stats socket > > > Hi all, > > First of all, thanks again and always for the great work and an excellent > product. > > I'm looking for a secure way to communicate with the haproxy stats socket > for remote management of haproxy (without ssh), preferably without running > some extra API service or anything. > > I love that 1.5 can now listen on a socket instead of a file. My concern > is securing it. > > My current best idea is to have the stats socket on 127.0.0.1:7828, and to > have haproxy handle authentication before forwarding remote connections to > it. The only authentication I could think of would be client SSL > certificates. > > Having the socket on 127.0.0.1:7828 works great -- you can connect from > locally on the box but not from elsewhere. Having a TCP-mode proxy > listening and forwarding to there works great too, even with SSL. Haproxy > is proxying connections to its own stats > socket! > > Where I'm running into trouble is requiring a client cert -- even with > "verify required" on my frontend (or listen) bind line, I can connect with > no client cert. > > My intention is to use an ACL to check for specific information in the > client cert (using ssl_c_s_dn, ssl_c_serial, and/or ssl_c_sha1). I also > ran into trouble matching against that information, but then I discovered > that I wasn't even requiring a client > cert. > > I'm using all self-signed certs. Maybe there's an issue with the way I'm > generating certs that's causing this? Here's how I generated them: > > FILENAME=haproxy-server > openssl genrsa -out $FILENAME.key 1024 > openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt > cat $FILENAME.key $FILENAME.crt >$FILENAME.pem > > FILENAME=haproxy-client > openssl genrsa -out $FILENAME.key 1024 > openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt > cat $FILENAME.key $FILENAME.crt >$FILENAME.pem > > At first I didn't enter any info for the certs (just pressed Enter on each > line), but then I recreated the client cert with some valid info. > > Here's my config: > > global > daemon > pidfile /var/run/haproxy.pid > stats socket ipv4@127.0.0.1:7828 > log 127.0.0.1 local0 debug > > defaults > log global > option redispatch > retries 3 > timeout http-request 10s > timeout queue 1m > timeout connect 10s > timeout client 1m > timeout server 1m > timeout check 10s > > listen default_stats > bind 0.0.0.0:10800 > mode http > stats enable > > listen main-service > bind 0.0.0.0:80 > mode http > > frontend stats-socket > bind 10.108.0.166:7828 ssl crt /root/haproxy-ssl/haproxy-server.pem > verify required ca-file /root/haproxy-ssl/haproxy-client.crt > mode tcp > log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tw/%Tc/%Tt\ %B\ %ts\ > %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %{+Q}[ssl_c_s_dn] > default_backend local_socket > > backend local_socket > server localhost 127.0.0.1:7828 > > Here's my haproxy version and deets: > > HA-Proxy version 1.5.2 2014/07/12 > Copyright 2000-2014 Willy Tarreau <w...@1wt.eu> > > Build options : > TARGET = linux2628 > CPU = generic > CC = gcc > CFLAGS = -O2 -g -fno-strict-aliasing > OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_PCRE=1 > > Default settings : > maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200 > > Encrypted password support via crypt(3): yes > Built with zlib version : 1.2.3 > Compression algorithms supported : identity, deflate, gzip > Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > OpenSSL library supports TLS extensions : yes > OpenSSL library supports SNI : yes > OpenSSL library supports prefer-server-ciphers : yes > Built with PCRE version : 7.8 2008-09-05 > PCRE library supports JIT : no (USE_PCRE_JIT not set) > Built with transparent proxy support using: IP_TRANSPARENT > IPV6_TRANSPARENT IP_FREEBIND > > Available polling systems : > epoll : pref=300, test result OK > poll : pref=200, test result OK > select : pref=150, test result OK > Total: 3 (3 usable), will use epoll. > > Here's how I'm connecting with a client cert: > > socat stdio > openssl-connect:domeyers-haproxy-socket-test.gha.usw1.cld.scea.com:7828,cer > t=/root/haproxy-ssl/haproxy-client.pem,cafile=/root/haproxy-ssl/haproxy-ser > ver.crt > OR (less often - I tried openssl in case there was a problem with my socat) > openssl s_client -connect > domeyers-haproxy-socket-test.gha.usw1.cld.scea.com:7828 -cert > ./haproxy-client.crt -key ./haproxy-client.key > > And without: > > socat stdio > openssl-connect:domeyers-haproxy-socket-test.gha.usw1.cld.scea.com:7828,caf > ile=/root/haproxy-ssl/haproxy-server.crt > openssl s_client -connect > domeyers-haproxy-socket-test.gha.usw1.cld.scea.com:7828 > > Here is it allowing my connection, without a client cert, despite the > config above: > > [root@domeyers-haproxy-socket-test haproxy-ssl]# socat stdio > openssl-connect:domeyers-haproxy-socket-test.gha.usw1.cld.scea.com:7828,caf > ile=/root/haproxy-ssl/haproxy-server.crt > show stat > # > pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,e > resp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,ql > imit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_s > tatus,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5x > x,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_ > in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime, > ttime, > default_stats,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0 > ,0,0,,,,0,0,0,0,0,0,,0,0,0,,,0,0,0,0,,,,,,,, > default_stats,BACKEND,0,0,0,0,200,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,6304,0,,1, > 2,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,0,0,0,0,-1,,,0,0,0,0, > main-service,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,3,0,,,,0,0, > 0,0,,,,0,0,0,0,0,0,,0,0,0,,,0,0,0,0,,,,,,,, > main-service,BACKEND,0,0,0,0,200,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,6304,0,,1,3 > ,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,0,0,0,0,-1,,,0,0,0,0, > stats-socket,FRONTEND,,,1,1,2000,10,91,12588,0,0,0,,,,,OPEN,,,,,,,,,1,4,0,, > ,,0,0,0,1,,,,,,,,,,,0,0,0,,,0,0,0,0,,,,,,,, > local_socket,localhost,0,0,1,1,,10,91,12588,,0,,0,0,0,0,no > check,1,1,0,,,,,,1,5,1,,10,,2,0,,1,,,,,,,,,,0,,,,0,0,,,,,3,,,1,1,0,59, > local_socket,BACKEND,0,0,1,1,200,10,91,12588,0,0,,0,0,0,0,UP,1,1,0,,0,6304, > 0,,1,5,0,,10,,1,0,,1,,,,,,,,,,,,,,0,0,0,0,0,0,3,,,1,1,0,59, > > Log line: > 2014-07-22T15:03:10-07:00 localhost haproxy[21598]: 10.108.0.166:60116 > [22/Jul/2014:15:03:06.419] stats-socket~ local_socket/localhost 5/1/3890 > 1352 -- 0/0/0/0/0 0/0 "" > > I've never seen anything logged as ssl_c_s_dn (the last field) -- it's > always empty. At first I thought I wasn't using the client cert the right > way for haproxy to receive it, because I was having trouble matching ACLs > against it. But then I found that > I didn't even need a client cert to connect, so now I'm troubleshooting > that. > > Any help would be appreciated, including alternate options for securing > this traffic. > > For the record, here are some of the config lines I was trying to use to > validate fields in the client cert: > > tcp-request inspect-delay 30s > acl client_cert_cn_ok ssl_c_s_dn(CN) -m str my.host.name.com > tcp-request content accept if client_cert_cn_ok > tcp-request content reject > > > Thanks! > Donovan > > -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B