After importing the Boot2Docker certificate and setting it to "Always Trust", API requests such as "https://192.168.59.103:2376/images/json" fail with the following error code:
ERR_BAD_SSL_CLIENT_AUTH_CERT
As a workaround you can reach Docker on port 2375 via plain http
$(docker run sequenceiq/socat)
This starts a socat in a container which proxy /var/run/docker.sock on port 2375. So you can use: http://192.168.59.103:2375/images/json
@lalyos I'm not sure what kind of wizardry this is but _it works_! I spend alot of time getting my http client to work with boot2dockers generated certs with little to show for the effort. your example works with one line. Thanks so much for posting!
Thanks for the workaround, @lalyos. However, I'd still like to get certificate authentication working.
Using the example given at https://docs.docker.com/reference/api/docker_remote_api/ , I sent an API request via curl as such:
curl --insecure --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem https://192.168.59.103:2376/images/json
curl spits out the following error info:
2014-10-17 14:56:24.798 curl[1162:32239] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8f66864c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8d66e6de objc_exception_throw + 43
2 CoreFoundation 0x00007fff8f50c068 -[__NSPlaceholderArray initWithObjects:count:] + 360
3 CoreFoundation 0x00007fff8f50ba2d CFArrayCreate + 141
4 libcurl.4.dylib 0x00007fff8c25369e darwinssl_connect_common + 2089
5 libcurl.4.dylib 0x00007fff8c25273a Curl_ssl_connect_nonblocking + 36
6 libcurl.4.dylib 0x00007fff8c21b673 Curl_http_connect + 77
7 libcurl.4.dylib 0x00007fff8c229977 Curl_protocol_connect + 129
8 libcurl.4.dylib 0x00007fff8c23bcef multi_runsingle + 799
9 libcurl.4.dylib 0x00007fff8c23b93d curl_multi_perform + 170
10 libcurl.4.dylib 0x00007fff8c234d25 curl_easy_perform + 352
11 curl 0x0000000109546a87 curl + 47751
12 curl 0x00000001095431f4 curl + 33268
13 curl 0x0000000109542c00 curl + 31744
14 libdyld.dylib 0x00007fff91fd25c9 start + 1
15 ??? 0x0000000000000007 0x0 + 7
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
If I try the same command again, curl returns the following error:
curl: (58) SSL: Can't load the certificate "$DOCKER_CERT_PATH/cert.pem" and its private key: OSStatus -25299
Is there anything wrong with my request? If not, what's wrong with the certificate or how it's being handled?
Thanks.
It looks like it is a bug in the OSX specific curl. If you run the exact same command inside of boot2docker, it works just fine.
$curl -sS --insecure --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem https://192.168.59.103:2376/_ping
curl: (35) Unknown SSL protocol error in connection to 192.168.59.103:-9825
by simple adding a boot2docker ssh prefix suddenly it works fine
$boot2docker ssh curl -sS --insecure --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem https://192.168.59.103:2376/_ping
OK$
Yes, I also noticed I was able to use curl via boot2docker ssh and read about the problems with the OSX specific curl at http://curl.haxx.se/mail/archive-2014-10/0053.html . Thanks for verifying the curl error, by the way.
However, this doesn't explain the ERR_BAD_SSL_CLIENT_AUTH_CERT error when making requests from a browser. There is something wrong with the certificate and the trust between client and server.
Thanks.
@ghoffer As the error message states the CLIENT side certification is missing.
When tls is enbled Docker uses client and serverside certificates. You can see 3 pem files in $DOCKER_CERT_PATH:
So when you choose "Always Trust", you were deciding about the server-side cert (ca.pem).
cert.pem and key.pem files are used by the client side. With the docker command you specify the --cert and --key options. But browsers and some other application needs them in a combined form. That format called PKCS #12
openssl pkcs12 -export \
-inkey key.pem \
-in cert.pem \
-name b2d-client-side \
-out b2d-client-side.p12 \
-password pass:tcuser
Now you need to import this p12 certificate. The import password is tcuser.
Next time you try to connect to https://192.168.59.103:2376/images/json the browser will provide you a gray dialog (similar to basic auth) to select which client side certificate to use. You choose the just imported _Boot2Docker_ and voila ...
Thank you cert master. I spent hours searching the interwebz and still couldn't figure out how to properly import the client-side cert.
I'm going to reopen this to help others find it, and to remind me to write some more docs for Docker :)
@SvenDowideit so this is on the 1.3.1 milestone to keep it on your own radar for writing docs upstream? :smile:
(ie, what's actionable for boot2docker here?)
Just came across this issue from a Google search, looks like OSStatus -25299 is a broad issue with OS X Yosemite and curl.
@lalyos , Importing in PKCS #12 format worked. But having trouble wrapping head around this. Thank You!.
Hey all, I can confirm that OS X El Capitan 10.11.1 still has a bug in its curl implementation of https. Great.
I'm getting the same OSStatus -25299. Does someone want to let Cupertino know? haha.
OS X El Capitan 10.11.6 has this bug too
the OSX curl can be replacing the stock curl:
brew install curl --with-openssl
brew link curl --force
hash -r
Most helpful comment
the OSX curl can be replacing the stock curl: