Compose: SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

Created on 27 Jan 2015  ·  182Comments  ·  Source: docker/compose

Got this error on both machines almost at the same time with docker-compose and lately with fig after rollback. A few search results points to python/openssl issue but i simple can't figure out where to dig to. Python/openssl comes from homebrew.

Boot2Docker-cli version: v1.4.1
Git commit: 43241cb

Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.4
Git commit (client): 5bc2ff8
OS/Arch (client): darwin/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8

arepackaging

Most helpful comment

I'm probably not the first one who may have brought this up, but isn't it counter intuitive that a curl environment variable have any effect what so ever on an unrelated Python application?

Thanks,
Jason Mills

  • sent from mobile.

On May 7, 2016, at 3:22 PM, Lorenzo Sicilia [email protected] wrote:

Rather than disable the CURL_CA_BUNDLE you can run using:
CURL_CA_BUNDLE=~/.docker/machine/machines/default/ca.pem docker-compose ps


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

All 182 comments

I think I'm experiencing the same thing trying to use the docker-compose release candidate...

$ docker-compose ps
SSL error: hostname '192.168.59.103' doesn't match 'boot2docker'

But fig works fine...

$ fig -f docker-compose.yml ps
Name   Command   State   Ports
------------------------------

I'm on OSX, running all the same versions as @gkostyanikov, except my Go client version is go1.3.3. My python/openssl is also installed via Homebrew. Might have something to do with it?

Edit: Actually it looks like Homebrew doesn't link openssl, so I'm using the default OSX version: OpenSSL 0.9.8za 5 Jun 2014.

The issue was Homebrew python.

docker-compose now works after uninstalling homebrew python/openssl, installing pip with easy_install, and reinstalling docker-composer using the system python.

@adambiggs Your solution works! Thanks!

This worked for me too, I'm using a brand new mac and set it up with homebrew python. Had this error with fig communicating with docker. Followed @adambiggs advice verbatim and got past my blocker, it could be a python version issue too but regardless I guess this machine will be using system python for awhile.

This is happening on me too. And I don't want to use the system's python, anyone have another workaround?

Have you tried using the binary? Do you get the same problem?

No I haven't tried the binary.
If you don't want to install it in your systems python, another workaround is to use virtualenv(wrapper).

mkvirtualenv --python=/usr/bin/python docker-compose
pip install docker-compose==1.1.0-rc2

Found a better solution using pyenv to roll back to python 2.7.8:

http://stackoverflow.com/a/28216459/1166293
https://github.com/yyuu/pyenv

Edit: Nevermind, pyenv introduced a bunch of it's own problems...

What caused this error for me was that the home-brew openssl was not linked to /usr/local/bin/openssl.

openssl version

returned OpenSSL 0.9.8zc 15 Oct 2014 not OpenSSL 1.0.1j 15 Oct 2014

Running

brew link --force openssl

and reinstalling fig resolved the issue.

Interesting, however my OpenSSL version is OpenSSL 1.0.1j 15 Oct 2014

@aanand in my case the binary does not have this problem.

I got this error when I had fig installed through pip, not homebrew. sudo pip uninstall fig and brew install fig fixed it for me.

+1 for @NotBobTheBuilder solution, also worked for me

:+1: for @NotBobTheBuilder

@NotBobTheBuilder nice solution for fig but docker-compose isn't available on homebrew yet unfortunately.

@ocasta what about this scary-sounding warning from homebrew about linking OpenSSL?

This formula is keg-only.
Mac OS X already provides this software and installing another version in
parallel can cause all kinds of trouble.

Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries

Thumbs up @NotBobTheBuilder - That fixed it with me as well.

anyone know the source of this problem? it's happening to me with fig. I prefer to stick to pip install fig like I have now. It all worked fine a couple of weeks ago, don't know what's changed on my system

My system OpenSSL is OpenSSL 0.9.8zc 15 Oct 2014, my homebrew openssl is newer but not linked.

...I am guessing it broke when I upgraded to Python 2.7.9, there seem some SSL related bugs with it... looks a lot like this:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=196431
http://bugs.python.org/issue23052

running brew link --force openssl and reinstalling fig did not do anything for me.

Does fig need updating to work around the SSL changes in Py 2.7.9?
https://www.python.org/dev/peps/pep-0476/#opting-out

I'm using boot2docker. I just upgraded to 1.5.0 but no change.

In [1]: from fig.cli.docker_client import docker_client

In [2]: client = docker_client()

In [3]: client.version()

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

In [4]: %debug
> /Users/anentropic/.virtualenvs/dpm/lib/python2.7/site-packages/requests/sessions.py(461)request()
    460         send_kwargs.update(settings)
--> 461         resp = self.send(prep, **send_kwargs)
    462

ipdb> p settings
{'verify': '/Users/anentropic/.boot2docker/certs/boot2docker-vm/ca.pem', 'cert': ('/Users/anentropic/.boot2docker/certs/boot2docker-vm/cert.pem', '/Users/anentropic/.boot2docker/certs/boot2docker-vm/key.pem'), 'proxies': {}, 'stream': False}

The fig code looks correct, it is attempting to use the certs installed by boot2docker... I assume these certs are ok because they always used to work and I just upgraded b2d so they shouldn't have expired.

Hmm, my Python (installed via homebrew) appears to be using the homebrew version of OpenSSL though:

$ python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.2 22 Jan 2015
$ brew info openssl
openssl: stable 1.0.2 (bottled)
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl/bin/c_rehash

...running /usr/local/opt/openssl/bin/c_rehash didn't help :)

I tried a previously installed version of python (2.7.8_2) via $ brew switch python 2.7.8_2 with the same problem (even if the error message was slightly different). So the python 2.7.9 version seems not to be the problem.

Then I tried switching to an older openssl version, from 1.0.2 to 1.0.1j_1 which seems to work.

$ python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.2 22 Jan 2015
$ docker-compose ps
SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
$ brew switch openssl 1.0.1j_1
$ python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.1j 15 Oct 2014
$ docker-compose ps
Name   Command   State   Ports 
------------------------------

For me I just get a different error, but maybe it helps narrow down what's wrong:

$ brew switch openssl 1.0.1j_1
Error: openssl does not have a version "1.0.1j_1" in the Cellar.
Versions available: 1.0.1e, 1.0.1f, 1.0.1g, 1.0.2
$ brew switch openssl 1.0.1g
Opt link created for /usr/local/Cellar/openssl/1.0.1g
$ fig up
SSL error: hostname '192.168.59.103' doesn't match 'boot2docker'

Switching back to OpenSSL 1.0.2 produces the previous CERTIFICATE_VERIFY_FAILED error so changing versions definitely has some effect

One workaround is to run docker-compose in a container:

git clone [email protected]:docker/fig.git
cd fig
docker build --tag docker-compose .

alias docker-compose='docker run --rm -e "DOCKER_TLS_VERIFY=$DOCKER_TLS_VERIFY" -e DOCKER_HOST=tcp://172.17.42.1:2376 -e DOCKER_CERT_PATH=/usr/local/certs -v "$DOCKER_CERT_PATH:/usr/local/certs" -v "$PWD:/code" docker-compose --project-name "${PWD##*/}"'

This requires exposing port 2376 in VirtualBox:

VBoxManage controlvm boot2docker-vm natpf1 "docker-s,tcp,127.0.0.1,2376,,2376"

@kretz's answer worked for me.

+1 @kretz brew switch openssl 1.0.1j_1
made the trick

brew switch openssl 1.0.1j works for me (note the lack of _1)

I don't like it, but uninstalling fig from my virtualenv and installing via homebrew fixed things for me

Thanks @kretz - your answer solved it for me!

It does not work for me because:

$ brew switch openssl 1.0.1j_1
Error: openssl does not have a version "1.0.1j_1" in the Cellar.
Versions available: 1.0.2

My workaround was to create a virtualenv with python 2.7.8, rather than the 2.7.9 that i got from brew.

various workarounds... does anyone have insight into the real problem?

what has App Engine got to do with anything?

On 11 March 2015 at 18:09, Ryan Small [email protected] wrote:

I'm pretty sure none of the app engine stuff works with python 2.7.9


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-78329652.

@anentropic You need to install the older openssl version before you can use (switch to) it.

# Find available older versions to install
$ brew search openssl
openssl
homebrew/versions/openssl098  homebrew/versions/openssl101

# Install older 1.0.1 version
$ brew install homebrew/versions/openssl101

# See what versions are installed locally
$ brew info openssl
...
/usr/local/Cellar/openssl/1.0.1f (429 files,  15M)
  Built from source
/usr/local/Cellar/openssl/1.0.1i (430 files,  15M)
  Poured from bottle
/usr/local/Cellar/openssl/1.0.1j (431 files,  15M)
  Poured from bottle
/usr/local/Cellar/openssl/1.0.1j_1 (431 files,  15M)
  Poured from bottle
/usr/local/Cellar/openssl/1.0.2 (459 files,  18M)
  Poured from bottle
...

# Switch to one of the 1.0.1 you got installed
$ brew switch openssl 1.0.1j_1

I did brew install openssl101 but it didn't give me the possibility to switch to 1.0.1j...it gave me a 1.0.1l and I worried it was going to confuse my system since they're separate brew packages and I already had 1.0.2 in parallel

didn't seem to help but maybe I didn't go far enough with it

Sorry I replied to the the wrong github issue (quickly deleted my comment)
On Wed, Mar 11, 2015 at 11:30 AM anentropic [email protected]
wrote:

I did brew install openssl101 but it didn't give me the possibility to
switch to 1.0.1j...it gave me a 1.0.1l and I worried it was going to
confuse my system since they're separate brew packages and I already had
1.0.2 in parallel

didn't seem to help but maybe I didn't go far enough with it


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-78340580.

So i seem to be getting this issue as well, running on Mac OSX. Using docker-compose this is my .yml file.

web:
    build: .
    links:
        - db
        - cache
        - worker
    ports:
        - "8080:8080"
db:
    image: mysql
cache:
    image: redis
worker:
    build: .
    command: celery -A application.extentions worker -l info

When running docker-compose pull I get the following output that failed.

$ docker-compose pull
Pulling db (mysql:latest)...
SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

Some things i checked.
which openssl; openssl version

/usr/local/bin/openssl
OpenSSL 1.0.2 22 Jan 2015

@psykzz Should be working if you install with brew

brew install docker-compose

@arvindtest what makes you think that is related to this issue?

FYI, after struggling a lot with this, it appears that this is a boot2docker issue.
What worked for me was to disable TLS. There isn't yet a user friendly way to do this, but the instructions are outlined here:
https://github.com/deis/deis/issues/2230

Basically, you need to:

boot2docker ssh
sudo echo 'DOCKER_TLS=no' > /var/lib/boot2docker/profile

then restart boot2docker, i.e.
boot2docker stop
boot2docker start

and something like this to your ~/.bashrc (make sure the ip is correct)

export DOCKER_HOST=tcp://192.168.59.103:2375
unset DOCKER_CERT_PATH
unset DOCKER_TLS_VERIFY

In your bashrc why not just have $(boot2docker shellinit)

Should help with everything right?

I mean you still have to do the TLS solution.
On 21 Mar 2015 23:05, "coderfi" [email protected] wrote:

FYI, after struggling a lot with this, it appears that this is a
boot2docker issue.
What worked for me was to disable TLS. There isn't yet a user friendly way
to do this, but the instructions are outlined here:
deis/deis#2230 https://github.com/deis/deis/issues/2230

Basically, you need to:

boot2docker ssh
sudo echo 'DOCKER_TLS=no' > /var/lib/boot2docker/profile

then restart boot2docker, i.e.
boot2docker stop
boot2docker start

and something like this to your ~/.bashrc
be sure the ip is correct

export DOCKER_HOST=tcp://192.168.59.103:2375
unset DOCKER_CERT_PATH
unset DOCKER_TLS_VERIFY


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-84468058.

@kretz it works! thanks.

@psykzz do you mean $(boot2docker shellinit) ?

yes I did, updated my comment. derp.

I can confirm that @coderfi 's solution to disable TLS works for me!

Glad it works for you. :)

@Matt yes, you are correct about the shell init shell expansion tip.
However, that may not work if boot2docker has not yet started, so I just
made the example explicit.

Fi
On Mar 26, 2015 10:18 AM, "anentropic" [email protected] wrote:

I can confirm that @coderfi https://github.com/coderfi 's solution to
disable TLS works for me!


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-86630313.

Maybe this is obvious, but those disabling TLS or downgrading OpenSSL just to get this working should tread carefully depending on what they're doing.

This won't relate to all, but I had a similar error pop up during pip installs using a Dockerfile pulling from gliderlabs/alpine:3.1 - the minimal Linux container from progrium & crew. The problem was that I had not installed the system certificates package, the issue was remedied by installing the package before install pip and running the requirements file:

RUN apk-install -X ca-certificates

The suggested sollutions didn't really work for me. Couldn't switch to any of the 1.0.1 OpenSSL versions. In the end I found that uninstalling all the pip-installed docker-compose versions and just doing brew install docker-compose somehow works.

The solutions above worked but were too cumbersome for me. A quick boot2docker upgrade fixed everything on my end.

I already have latest boot2docker version and it doesn't work for me without above fixes

Homebrew devs suggest docker-py and docker-compose should upgrade to using requests 2.6.0

https://github.com/Homebrew/homebrew/issues/38226#issuecomment-88083428

Hopefully this helps someone...not sure of a solution but if you're using Charles as a Mac OS X Proxy it will cause this message.

FWIW, installing docker-compose via pip got docker-compose itself working (installing through curl on OS X Mavericks resulted in an illegal operation error). I subsequently was also getting the SSL error. Running brew link --force openssl && brew switch openssl 1.0.1j seems to have fixed it for me.

@rseymour answer worked for me

For those who fails to find openssl-1.0.1j in brew -- you can grab older version of openssl recipe from github repo and make use of it:

» brew switch openssl 1.0.1j
Error: openssl does not have a version "1.0.1j" in the Cellar.
Versions available: 1.0.2a-1
» brew unlink openssl
Unlinking /usr/local/Cellar/openssl/1.0.2a-1... 1543 symlinks removed
» brew install https://raw.githubusercontent.com/Homebrew/homebrew/62fc2a1a65e83ba9dbb30b2e0a2b7355831c714b/Library/Formula/openssl.rb
...
🍺  /usr/local/Cellar/openssl/1.0.1j_1: 431 files, 14M, built in 4.2 minutes
» docker-compose up                                                                                                                   
Creating myservice...

I tried 1.0.1m but it didn't work.
So I tried @lazyval way, it works for me.
This is what I've done.

brew install https://raw.githubusercontent.com/Homebrew/homebrew/62fc2a1a65e83ba9dbb30b2e0a2b7355831c714b/Library/Formula/openssl.rb
brew switch openssl 1.0.1j_1
brew unlink openssl101 //Because I linked 1.0.1m before this
brew link openssl --force
docker-compose ps

Thank you!!

I'm currently investigating this, as we now need to build the binaries on Python 2.7.9+.

_Relocated from #1427_

Server:

  • CoreOS Stable
  • Docker 1.5.0

Client:

  • CentOS 6.6, 64-bit
  • kernel 2.6.32-042stab105.14
  • Docker client 1.5.0
  • docker-compose 1.2.0
  • SSL certificates placed at ~/.docker/{ca.pem,cert.pem,key.pem}
  • DOCKER_HOST=tcp://docker-builder:2376
  • DOCKER_TLS_VERIFY=1

Using the following Makefile to build the SSL certificates:

#!/bin/bash

SERVER=docker-builder

clean:
    rm ca.* server.* client.* *.key

all: ca.crt server.crt client.crt

%.key:
    openssl genrsa -out $@ 4096

ca.crt: ca.key
    openssl req -new -x509 -days 365 -key ca.key -sha256 -out ca.crt \
        -subj "/C=US/ST=Texas/L=Austin/O=Abc123/OU=Operations/CN=${SERVER}/[email protected]"

server.csr: server.key
    openssl req -new -key server.key -out server.csr \
        -subj "/C=US/ST=Texas/L=Austin/O=Abc123/OU=Operations/CN=${SERVER}/[email protected]"

server.crt: ca.key ca.crt server.csr
    openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \
        -CAcreateserial -out server.crt

client.csr: client.key
    openssl req -new -key client.key -out client.csr \
        -subj "/C=US/ST=Texas/L=Austin/O=Abc123/OU=Operations/CN=Docker Client/[email protected]"

client.ext.cnf:
    echo "extendedKeyUsage = clientAuth" > client.ext.cnf

client.crt: client.csr ca.crt ca.key client.ext.cnf
    openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key \
        -CAcreateserial -out client.crt -extfile client.ext.cnf

Here is the (admittedly less than ideal) user-data script to provision this machine:

#cloud-config

write_files:
    - path: /home/core/server.crt
      owner: core:core
      permissions: 0644
      content: |
        -----BEGIN CERTIFICATE-----
        <cert goes here>
        -----END CERTIFICATE-----


    - path: /home/core/server.key
      owner: core:core
      permissions: 0644
      content: |
        -----BEGIN RSA PRIVATE KEY-----
        <key goes here>
        -----END RSA PRIVATE KEY-----


    - path: /home/core/ca.crt
      owner: core:core
      permissions: 0644
      content: |
        -----BEGIN CERTIFICATE-----
        <ca cert goes here>
        -----END CERTIFICATE-----

coreos:
  update:
    reboot-strategy: reboot
  units:
  units:
    - name: var-lib-docker.mount
      command: start
      content: |
        [Unit]
        Description=Mount RAM to /var/lib/docker
        Before=docker.service
        [Mount]
        What=tmpfs
        Where=/var/lib/docker
        Type=tmpfs
        Options=size=200g
    - name: docker.service
      command: restart
      content: |
        [Unit]
        Description=Docker Application Container Engine
        Documentation=http://docs.docker.io
        After=network.target
        [Service]
        ExecStartPre=/bin/mount --make-rprivate /
        # Run docker but don't have docker automatically restart
        # containers. This is a job for systemd and unit files.
        ExecStart=/usr/bin/docker -d \
          --tlsverify \
          --tlscert=/home/core/server.crt \
          --tlscacert=/home/core/ca.crt \
          --tlskey=/home/core/server.key \
          -H 0.0.0.0:2376 -H unix:///var/run/docker.sock

        [Install]
        WantedBy=multi-user.target

Using the docker client I have good success accessing the remote docker server. We call the remote server up to a hundred thousand times a day with good success.

Attempting to use docker-compose, installed either via curl OR pip install --upgrade with python 2.7, we get an SSL error:

$ docker-compose up -d
SSL error: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

This is the case after manually specifying DOCKER_CERT_PATH=/home/user/.docker/ as well as REQUESTS_CA_BUNDLE=/home/user/.docker/ca.pem, individually and together.

To be clear: this setup works great with just docker daemon, but something about -compose is amiss.

Some notes:

  1. The Compose 1.3.0 RC1 binary for OSX has this bug. Probably not coincidentally, this is the first time it's been built against Python 2.7.9 - before, it was 2.7.6.
  2. Weirdly, I can reproduce against a boot2docker VM, but not against a Virtualbox VM provisioned by Machine. @ehazlett, @nathanleclaire, @tianon - any insights there?
  3. To anyone experiencing this when Compose is installed with Pip, please report the output of the following commands:

$ python -V $ python -c 'import ssl; print ssl.OPENSSL_VERSION'

On my local machine, where I can reproduce the error, I have Python 2.7.10 and OpenSSL 1.0.2a 19 Mar 2015.

  1. This has been reported to Homebrew, and some people say they've had success reinstalling Python and OpenSSL, but it hasn't worked for me. https://github.com/Homebrew/homebrew/issues/38226

Hmm that's really odd. What version of b2d are you using vs. the version
of machine? We both use b2d so I'm not sure what would be different
besides the version.

I will install via pip on my OS X machine and see what I get.

On Thu, May 28, 2015 at 9:19 AM, Aanand Prasad [email protected]
wrote:

Some notes:

1.

The Compose 1.3.0 RC1 binary for OSX has this bug. Probably not
coincidentally, this is the first time it's been built against Python 2.7.9

  • before, it was 2.7.6.
    2.

Weirdly, I can reproduce against a boot2docker VM, but not against a
Virtualbox VM provisioned by Machine. @ehazlett
https://github.com/ehazlett, @nathanleclaire
https://github.com/nathanleclaire, @tianon
https://github.com/tianon - any insights there?
3.

To anyone experiencing this when Compose is installed with Pip, please
report the output of the following commands:

$ python -V
$ python -c 'import ssl; print ssl.OPENSSL_VERSION'

On my local machine, where I can reproduce the error, I have Python
2.7.10 and OpenSSL 1.0.2a 19 Mar 2015.
4.

This has been reported to Homebrew, and some people say they've had
success reinstalling Python and OpenSSL, but it hasn't worked for me.
Homebrew/homebrew#38226
https://github.com/Homebrew/homebrew/issues/38226


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-106306690.

$ boot2docker version
Boot2Docker-cli version: v1.6.2
Git commit: cb2c3bc

$ docker-machine --version
docker-machine version 0.2.0 (8b9eaf2)

Is something different about cert generation, maybe? I seem to have more files in my machine cert dir than in my boot2docker one.

$ $(boot2docker shellinit)
$ ls -l $DOCKER_CERT_PATH/*.pem
-rw-r--r--  1 aanand  staff  1042 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/ca.pem
-rw-r--r--  1 aanand  staff  1070 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/cert.pem
-rw-r--r--  1 aanand  staff  1675 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/key.pem
$ eval "$(docker-machine env)"
$ ls -l $DOCKER_CERT_PATH/*.pem
-rw-r--r--  1 aanand  staff  1029 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/ca.pem
-rw-r--r--  1 aanand  staff  1054 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/cert.pem
-rw-r--r--  1 aanand  staff  1679 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/key.pem
-rw-------  1 aanand  staff  1679 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/server-key.pem
-rw-r--r--  1 aanand  staff  1086 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/server.pem

That is fine. The client will just use the ca.pem, cert.pem and key.pem
(server is just a local copy for the host in machine). I will create as
well and inspect the certs to see what the difference might be.

On Thu, May 28, 2015 at 9:30 AM, Aanand Prasad [email protected]
wrote:

$ boot2docker version
Boot2Docker-cli version: v1.6.2
Git commit: cb2c3bc

$ docker-machine --version
docker-machine version 0.2.0 (8b9eaf2)

Is something different about cert generation, maybe? I seem to have more
files in my machine cert dir than in my boot2docker one.

$ $(boot2docker shellinit)
$ ls -l $DOCKER_CERT_PATH/*.pem
-rw-r--r-- 1 aanand staff 1042 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/ca.pem
-rw-r--r-- 1 aanand staff 1070 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/cert.pem
-rw-r--r-- 1 aanand staff 1675 28 May 14:27 /Users/aanand/.boot2docker/certs/boot2docker-vm/key.pem

$ eval "$(docker-machine env)"
$ ls -l $DOCKER_CERT_PATH/*.pem
-rw-r--r-- 1 aanand staff 1029 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/ca.pem
-rw-r--r-- 1 aanand staff 1054 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/cert.pem
-rw-r--r-- 1 aanand staff 1679 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/key.pem
-rw------- 1 aanand staff 1679 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/server-key.pem
-rw-r--r-- 1 aanand staff 1086 11 May 12:15 /Users/aanand/.docker/machine/machines/dev/server.pem


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-106309885.

grahamc@snap$ python -V
Python 2.7.6

grahamc@snap$ python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.1e-fips 11 Feb 2013

See also https://github.com/docker/docker-py/issues/465. @garethr's test script there reproduces the error for me too, after making one modification to disable hostname checking:

from docker.client import Client
from docker.utils import kwargs_from_env

kwargs = kwargs_from_env()
kwargs['tls'].assert_hostname = False

client = Client(**kwargs)
print client.version()
$ eval "$(boot2docker shellinit)" && python test.py
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/key.pem
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    print client.version()
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 1108, in version
    return self._result(self._get(url), json=True)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 106, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 477, in get
    return self.request('GET', url, **kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

It still works with the Machine-provisioned VM, though:

$ eval "$(docker-machine env)" && python test.py
{u'KernelVersion': u'4.0.3-boot2docker', u'Arch': u'amd64', u'ApiVersion': u'1.18', u'Version': u'1.6.2', u'GitCommit': u'7c8fca2', u'Os': u'linux', u'GoVersion': u'go1.4.2'}

If I re-enable hostname checking (by commenting out the assert_hostname line in the test script), it fails with the same error against the boot2docker-cli VM, but a different error against the Machine VM, which may or may not be relevant:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    print client.version()
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 1108, in version
    return self._result(self._get(url), json=True)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 106, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 477, in get
    return self.request('GET', url, **kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: no appropriate commonName or subjectAltName fields were found

Additionally I tried using v1.3.0-rc1 via curl (the binary release, not through pip) and got the same error as before on a docker 1.6.2 daemon:

SSL error: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Yeah - the RC1 binary was built with Python 2.7.9 and OpenSSL 1.0.2a, which seems to be one of the problematic combinations.

This makes sense because I believe the cert generation in b2d is on the VM
whereas machine generates them in machine. We could detect and add the
machine name to the SANs if needed. Actually that probably would be good
especially for b2d VMs. The reason it works now I think is because you
access the engine using the IP which machine adds as an IP SAN. There is a
PR open to allow arbitrary additional SANs which would work too.

On Thursday, May 28, 2015, Aanand Prasad [email protected] wrote:

See also docker/docker-py#465
https://github.com/docker/docker-py/issues/465. @garethr
https://github.com/garethr's test script there reproduces the error for
me too, after making one modification to disable hostname checking:

from docker.client import Clientfrom docker.utils import kwargs_from_env

kwargs = kwargs_from_env()
kwargs['tls'].assert_hostname = False

client = Client(**kwargs)print client.version()

$ eval "$(boot2docker shellinit)" && python test.py
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/aanand/.boot2docker/certs/boot2docker-vm/key.pem
Traceback (most recent call last):
File "test.py", line 8, in
print client.version()
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 1108, in version
return self._result(self._get(url), json=True)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 106, in _get
return self.get(url, *_self._set_request_timeout(kwargs))
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 477, in get
return self.request('GET', url, *_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
resp = self.send(prep, *_send_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, *_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

It still works with the Machine-provisioned VM, though:

$ eval "$(docker-machine env)" && python test.py
{u'KernelVersion': u'4.0.3-boot2docker', u'Arch': u'amd64', u'ApiVersion': u'1.18', u'Version': u'1.6.2', u'GitCommit': u'7c8fca2', u'Os': u'linux', u'GoVersion': u'go1.4.2'}

If I re-enable hostname checking (by commenting out the assert_hostname
line in the test script), it fails with the _same error_ against the
boot2docker-cli VM, but a _different error_ against the Machine VM, which
may or may not be relevant:

Traceback (most recent call last):
File "test.py", line 8, in
print client.version()
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 1108, in version
return self._result(self._get(url), json=True)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/docker/client.py", line 106, in _get
return self.get(url, *_self._set_request_timeout(kwargs))
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 477, in get
return self.request('GET', url, *_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
resp = self.send(prep, *_send_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, *_kwargs)
File "/Users/aanand/.virtualenvs/docker-compose/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: no appropriate commonName or subjectAltName fields were found


Reply to this email directly or view it on GitHub
https://github.com/docker/compose/issues/890#issuecomment-106363305.

OK, I believe I've arrived at a fix for OS X: https://github.com/docker/compose/pull/1474

Fixing it for Linux will involve updating the Dockerfile to pin to Python 2.7.9 and OpenSSL 1.0.1, which will be a fun endeavour given it starts from debian:wheezy (which it does to ensure we're using a sufficiently old glibc - see https://github.com/docker/compose/pull/505).

Switching to 1.0.1k as described in @kretz's comment and installing 1.3.0 RC1 via pip did the trick for me.

Prior to switching python reported 1.0.2a:

❯ python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.2a 19 Mar 2015

After switching it reported 1.0.1k and docker-compose seems to work as expected:

❯ python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.1k 8 Jan 2015

a workaround that removed this error was to install the following packages in my virtualenv
pip install pyopenssl==0.14 ndg-httpsclient==0.4 pyasn1==0.1.7

In the environment described at https://github.com/docker/compose/issues/890#issuecomment-106289821 which provides Python 2.7.6 (via snap-ci.com, which you can get a free account at)

with the following script which uses @jsh2134's workaround in a pip install (https://github.com/docker/compose/issues/890#issuecomment-106806702):

#!/bin/bash

set -e
set -u
set -x


readonly DOCKER_VERSION=1.5.0
readonly TARGETFILE=$SNAP_CACHE_DIR/docker-$DOCKER_VERSION
[[ -f "$TARGETFILE" ]] || curl https://get.docker.io/builds/Linux/x86_64/docker-$DOCKER_VERSION > $TARGETFILE
cp $TARGETFILE ~/docker
chmod +x ~/docker


export DOCKER_HOST="tcp://docker-builds:2376" DOCKER_TLS_VERIFY=1

mkdir -p ~/.docker
cat > ~/.docker/ca.pem <<EOC
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

EOC
cat > ~/.docker/key.pem <<EOC
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

EOC
cat > ~/.docker/cert.pem <<EOC
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
EOC

function install_docker_compose {
  pip install --upgrade pip
  pip install --upgrade docker-compose
  pip install pyopenssl==0.14 ndg-httpsclient==0.4 pyasn1==0.1.7
  export COMPOSE=docker-compose
}

install_docker_compose

export COMPOSE_PROJECT_NAME=$(basename "$(pwd)")-${SNAP_COMMIT:-HEAD}

# Before running anything, setup the EXIT trap to always rm the container on
# exit of the script.
function cleanup {
  $COMPOSE kill
  $COMPOSE rm --force
}

trap cleanup EXIT

$COMPOSE --version
$COMPOSE build
$COMPOSE up -d

set +e
$COMPOSE run $@
exitcode=$?
set -e

set +x
echo ""
echo "Component Data:"
for id in `$COMPOSE ps -q`; do
  ~/docker inspect \
    -f 'Container {{ .Name }} exited with status {{ .State.ExitCode }}' $id
  ~/docker logs $id 2>&1 | sed -e "s/^/        /"
  echo "---"
done

exit $exitcode

I get the following output:

+ readonly DOCKER_VERSION=1.5.0
+ DOCKER_VERSION=1.5.0
+ readonly TARGETFILE=/var/go/docker-1.5.0
+ TARGETFILE=/var/go/docker-1.5.0
+ [[ -f /var/go/docker-1.5.0 ]]
+ cp /var/go/docker-1.5.0 /var/go/docker
+ chmod +x /var/go/docker
+ export DOCKER_HOST=tcp://docker-builds:2376 DOCKER_TLS_VERIFY=1
+ DOCKER_HOST=tcp://docker-builds:2376
+ DOCKER_TLS_VERIFY=1
+ mkdir -p /var/go/.docker
+ cat
+ cat
+ cat
+ install_docker_compose
+ /bin/true
+ pip install --upgrade pip
/var/go/py-virtualenv2.7/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Collecting pip
  Using cached pip-7.0.1-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 6.0.8
    Uninstalling pip-6.0.8:
      Successfully uninstalled pip-6.0.8
Successfully installed pip-7.0.1
+ pip install --upgrade docker-compose
/var/go/py-virtualenv2.7/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Requirement already up-to-date: docker-compose in /var/go/py-virtualenv2.7/lib/python2.7/site-packages
Requirement already up-to-date: docopt<0.7,>=0.6.1 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: PyYAML<4,>=3.10 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: requests<2.6,>=2.2.1 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: texttable<0.9,>=0.8.1 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: websocket-client<1.0,>=0.11.0 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: docker-py<1.2,>=1.0.0 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: dockerpty<0.4,>=0.3.2 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: six<2,>=1.3.0 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from docker-compose)
Requirement already up-to-date: backports.ssl-match-hostname in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from websocket-client<1.0,>=0.11.0->docker-compose)
+ pip install pyopenssl==0.14 ndg-httpsclient==0.4 pyasn1==0.1.7
Collecting pyopenssl==0.14
/var/go/py-virtualenv2.7/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading pyOpenSSL-0.14.tar.gz (128kB)
Collecting ndg-httpsclient==0.4
  Downloading ndg_httpsclient-0.4.0.tar.gz
Collecting pyasn1==0.1.7
  Downloading pyasn1-0.1.7.tar.gz (68kB)
Collecting cryptography>=0.2.1 (from pyopenssl==0.14)
  Downloading cryptography-0.9.tar.gz (302kB)
Requirement already satisfied (use --upgrade to upgrade): six>=1.5.2 in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from pyopenssl==0.14)
Collecting idna (from cryptography>=0.2.1->pyopenssl==0.14)
  Downloading idna-2.0.tar.gz (135kB)
Requirement already satisfied (use --upgrade to upgrade): setuptools in /var/go/py-virtualenv2.7/lib/python2.7/site-packages (from cryptography>=0.2.1->pyopenssl==0.14)
Collecting enum34 (from cryptography>=0.2.1->pyopenssl==0.14)
  Downloading enum34-1.0.4.tar.gz
Collecting ipaddress (from cryptography>=0.2.1->pyopenssl==0.14)
  Downloading ipaddress-1.0.7-py27-none-any.whl
Collecting cffi>=0.8 (from cryptography>=0.2.1->pyopenssl==0.14)
  Downloading cffi-1.0.3.tar.gz (317kB)
Collecting pycparser (from cffi>=0.8->cryptography>=0.2.1->pyopenssl==0.14)
  Downloading pycparser-2.13.tar.gz (299kB)
Installing collected packages: idna, pyasn1, enum34, ipaddress, pycparser, cffi, cryptography, pyopenssl, ndg-httpsclient
  Running setup.py install for idna
  Running setup.py install for pyasn1
  Running setup.py install for enum34
  Running setup.py install for pycparser
  Running setup.py install for cffi
  Running setup.py install for cryptography
  Running setup.py install for pyopenssl
  Running setup.py install for ndg-httpsclient
Successfully installed cffi-1.0.3 cryptography-0.9 enum34-1.0.4 idna-2.0 ipaddress-1.0.7 ndg-httpsclient-0.4.0 pyasn1-0.1.7 pycparser-2.13 pyopenssl-0.14
+ export COMPOSE=docker-compose
+ COMPOSE=docker-compose
+++ pwd
++ basename /var/snap-ci/repo/tests/composer
+ export COMPOSE_PROJECT_NAME=composer-a71ac4f39281a9571a2b5da1284ab1c05da40646
+ COMPOSE_PROJECT_NAME=composer-a71ac4f39281a9571a2b5da1284ab1c05da40646
+ trap cleanup EXIT
+ docker-compose --version
docker-compose 1.2.0
+ docker-compose build
test1 uses an image, skipping
test2 uses an image, skipping
test uses an image, skipping
+ docker-compose up -d
SSL error: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]
+ cleanup
+ docker-compose kill
SSL error: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]

Note especially the error (which seems new):

/var/go/py-virtualenv2.7/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.

Created https://github.com/docker/compose/issues/1484 to brain-dump my findings so far.

I've built some binaries with the fix in #1474. Please try them out if you've been experiencing SSL issues:

http://cl.ly/3W3a2S3t2c32/download/docker-compose-Linux-x86_64
http://cl.ly/0i00310l3x27/download/docker-compose-Darwin-x86_64

+ curl -L http://cl.ly/3W3a2S3t2c32/download/docker-compose-Linux-x86_64
+ /usr/bin/docker-compose --version
docker-compose version: 1.3.0rc1
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013

+ /var/go/docker-compose up -d
SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

@jsh2134 why exactly are you pinning pyOpenSSL to 0.14?

+1 for @kretz answer :)

+1 same issue :( seems like docker is completely broken on osx?

@coderfi solution worked for me: Windows 7 docker 1.7 Cygwin and docker-compose installed via pip in Cygwin

Dealing with one of the variant errors on a Centos7 VM, which is acting as a client to start containers on a docker-machine:

[root@xxxx cm]# docker-compose ps
SSL error: no appropriate commonName or subjectAltName fields were found

This used to be transient; I could log out, ssh back in, and not see the error for a while. Now seeing it always.

[root@xxxx cm]# python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.1e-fips 11 Feb 2013

[root@xxxx cm]# docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): ba1f6c3/1.6.2
OS/Arch (client): linux/amd64
Server version: swarm/0.2.0
Go version (server): go1.3.3
Git commit (server): 48fd993
OS/Arch (server): linux/amd64

[root@xxxx cm]# docker-compose --version
docker-compose 1.2.0

I'm not sure how to apply some of the fixes noted above in my environment. I'm not using boot2docker; dealing with docker 1.6.2 right on the bash command line.

Hello. I actually opened an issue for that cause I cant fix it. I tried lots of things i.e install compose with pip/brew/ newst versions. Same as openssl tried 0.x 1.0.2x versions etc and still not working.

PS: I don't use boot2docker. I have my own VM that I make via vagrant, generate the certs and launch the docker daemon with them. Apparently it works with docker so the issue does not come from my certifs.

>>> docker run hello-world
Hello from Docker.
[...]
>>> docker-compose up
SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
>>> docker-compose -v
docker-compose version: 1.3.1
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1j 15 Oct 2014
>>> docker -v
Docker version 1.6.2, build 7c8fca2

got this error as well at one time:

/usr/local/Cellar/fig/1.3.1/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
SSL error: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

After reading here and mucking with installing suggested packages:

https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning

The error message from docker-compose has changed:

[root@xxx cm]# docker-compose up -d
/usr/lib/python2.7/site-packages/requests/packages/urllib3/connection.py:251: SecurityWarning: Certificate has no subjectAltName, falling back to check for a commonName for now. This feature is being removed by major browsers and deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 for details.)
SecurityWarning
SSL error: hostname 'xx.xx.xx.xx' doesn't match None

(The dotted quad I xx'd out is of the swarm master / docker host).

Could this problem also be addressed by editing or regenerating the certificate?

Addendum: The certificates were created on these VM by "docker-machine create."

Could we be dealing with a bug in docker-machine that results in an insufficiently detailed certificate?

I'm only seeing this error with docker-machine created Docker hosts. I believe the SSL certs aren't getting created properly?

Does anyone have a work-around or a solutin to fix this? This is a bit of a blocker for me right now :/

@prologic Are you getting the error with the binary or with a Pip-installed Compose? If the latter, try installing requests[security] as well.

@aanand Thanks! I'll try that and report back if that works or not!

@prologic We want to package requests[security] instead of relying on Python's buggy SSL module; we're tracking the effort in #1530.

@aanand Thank you! THis worked perfectly :)

@coderfi your solution worked for me, thanks

@aanand the june 2 build works fine for me. best of luck squashing this painful bug.

@neilsarkar I happened to be running charles proxy, your comment saved me. :+1:

I'm using OS X 10.9.5, here is my selution:

# ➜  openssl version
# OpenSSL 1.0.2d 9 Jul 2015

➜  pyenv local system # switch to built-in python 2.7.5 for current directory
# ➜  python --version
# Python 2.7.5
# ➜  python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
# OpenSSL 0.9.8zd 8 Jan 2015

# ➜  docker-compose --version
# docker-compose version: 1.3.1
# CPython version: 2.7.5
# OpenSSL version: OpenSSL 0.9.8zd 8 Jan 2015

# ➜  docker-compose ps
# /usr/local/Cellar/fig/1.3.1/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
#   InsecurePlatformWarning
# Name   Command   State   Ports
# ------------------------------

My workaround:

comment out lines 246:253 in
/usr/local/Cellar/fig/1.3.1/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connection.py

this is the part that is throwing the Security Exception

The problem for me was that even thou I specified brew link --force openssl, fig/docker-compose still uses /usr/bin/openssl.

$ sudo mv /usr/bin/openssl /usr/bin/openssl_old
$ brew link --force openssl OR brew unlink openssl && brew link --force openssl

This worked for me. Now I don't get the annoying message anymore.

FYI, brew fig/docker-compose recipe uses system python, so even if you install python via pyenv or brew, brew install fig/docker-compose will still use the system openssl lib if available, otherwise, its installing some other version.

On my MAC at work I solved it with pyenv install 2.7.8, then easy_install pip, and pip install docker-compose.

but on my mac at home, "both running yosemite" I've done the same and still get the warning.

Will keep digging.

@dtunes - the root cause (as @aanand referenced above) is https://github.com/boot2docker/boot2docker/issues/808. The system-python/homebrew-python thing is a red herring, because it just depends on whether you're linked against new or old OpenSSL.

Yes, I saw that ticket. The thing that is bothering me, is that on my Mac at work, after trying the different approaches above none worked.
I then moved /usr/bin/openssl to /usr/bin/openssl_old, installed the latest openssl using home brew and forced linked it. only then I did the following:

~ $ brew install pyenv
~ $ pyenv install 2.7.8
~ $ pyenv global 2.7.8
~ $ easy_install pip
~ $ pip install docker-compose

This did the trick at work, on my Mac at home however, it didn't work. But I'll try again in case I made a mistake and report the results back.

@dtunes - In order to re-build all your dependencies you need to remove ~/Library/Caches/pip so that the cached binary wheel built against the wrong OpenSSL doesn't get re-used.

@glyph wrote:

the root cause (as @aanand referenced above) is boot2docker/boot2docker#808. The system-python/homebrew-python thing is a red herring, because it just depends on whether you're linked against new or old OpenSSL.

@glyph or @aanand, does that suggest that @aanand's fix (work-around) merged from #1474 merely accommodates a broken b2d? @aanand, if boot2docker/boot2docker#808 is addressed properly, should #1474 be backed out? Is placing hope in the next cryptography release (see this and this) also a red herring?

@aanand wrote:

Note that I cannot reproduce this error against a Boot2Docker VM provisioned with docker-machine - it only happens against a VM provisioned with the boot2docker command.

@ehazlett wrote:

This makes sense because I believe the cert generation in b2d is on the VM whereas machine generates them in machine.

I might have misunderstood, but there's a lot of chatter blaming various host-side Python/OpenSSL combinations for this and related issues. If the source of the problem is a broken OpenSSL distributed with b2d, I'm not sure the best approach is ensuring that Compose's host-side OpenSSL is similarly broken? For what it's worth, those types of host-side contortions are unlikely to solve this issue for those who run b2d via (e.g.) Vagrant, and access it outside of Compose (see, e.g., docker/docker-py#465).

If this comment is more appropriate in boot2docker/boot2docker#808, I can move it there.

I'm a Homebrew maintainer and I helped glyph run this down.

The Subject and Issuer DNs of the server certificate generated by boot2docker are identically set to /O=Boot2Docker. I believe the server certificate is actually signed by the CA cert, but AFAICT OpenSSL 1.0.2 uses this information (i.e. identical Subject and Issuer DNs) to reject the server certificate as self-signed instead of attempting to verify the server certificate against the provided CA cert. Versions of OpenSSL prior to 1.0.2 validate the server certificate against the provided CA cert, which succeeds.

I believe but have not tested that giving the server and CA certificates distinct Subject DNs (so that the server cert has distinct Subject and Issuer DNs) will allow the certificates to validate under all OpenSSL versions. I suspect (based on my reading of this X.509 survival guide but not any related specifications), but am not confident, that OpenSSL 1.0.2's behavior is reasonable and does not represent a regression that should be resolved by the OpenSSL developers.

1474 does two distinct things:

  • setting a minimum Python version at 2.7.9: this allows urllib3 to complete requests without issuing a InsecurePlatformWarning, which is issued while making HTTPS connections if both of two conditions are met: the Python version is prior to 2.7.9, and the PyOpenSSL module is not present. Bundling PyOpenSSL would be equally effective but I understand from the discussion that it's not compatible with PyInstaller. Either way, urllib3's InsecurePlatformWarning is not related to the boot2docker certificate issue, and fixing the certificates does not remove the need for this workaround.
  • setting a maximum OpenSSL version at 1.0.1j. I believe that this should be unnecessary once the boot2docker certificates are fixed.

If the source of the problem is a broken OpenSSL distributed with b2d

It is not; the boot2docker certificates (generated by this code) are invalid according to clients using OpenSSL ≥ 1.0.2; the OpenSSL library distributed with boot2docker is not implicated.

@glyph or @aanand, does that suggest that @aanand's fix (work-around) merged from #1474 merely accommodates a broken b2d? @aanand, if boot2docker/boot2docker#808 is addressed properly, should #1474 be backed out? Is placing hope in the next cryptography release (see this and this) also a red herring?

Yes, I think so. I believe the OpenSSL with the issue is 1.0.2, and by restricting it to 1.0.1, it would avoid whatever verification logic is causing the certificate to fail. I still don't know _what_ it is about the certificate it doesn't like, since the error messages are so obtuse.

Also, I think what #1474 is doing is far too specific; at least from my reading, it's not setting a _minimum_ python version, but specifying an _exact_ version. It also appears to fail its check you happen to have any 1.0.1 different from j, which means security updates won't be applied even to 1.0.1, which is _definitely_ a problem.

I believe but have not tested that giving the server and CA certificates distinct Subject DNs (so that the server cert has distinct Subject and Issuer DNs) will allow the certificates to validate under all OpenSSL versions. I suspect (based on my reading of this X.509 survival guide but not any related specifications), but am not confident, that OpenSSL 1.0.2's behavior is reasonable and does not represent a regression that should be resolved by the OpenSSL developers.

I will investigate the docker-machine-generated cert and see if it has this property. Why do you say this behavior would be acceptable / not a regression in OpenSSL? Trusting a self-signed certificate is perfectly fine, and there are no particular restrictions on what the subject or issuer may contain that I'm aware of. I skimmed a little of that guide and it seems to just be pointing out that self-signed certificates won't have CA-cartel trust, so your web browser won't trust them without additional configuration.

Looking at the certificate in my docker-machine VM, I see:

...
        Issuer: O=glyph
...
        Subject: O=dev
...

so you may be right about this...

I will investigate the docker-machine-generated cert and see if it has [matching Subject and Issuer DNs].

You can see that aanand's docker-machine certs also have distinct DNs: https://gist.github.com/aanand/3d865623481ba8ae66ee#file-docker-machine-log-L30-L32

Trusting a self-signed certificate is perfectly fine

But a self-signed certificate is not valid unless you trust the self-signed certificate. We do not instruct OpenSSL to trust the server certificate; we instruct OpenSSL to trust the CA that issued the server certificate.

Why do you say this behavior would be acceptable / not a regression in OpenSSL?

IANAL, but my reasoning is derived from the language "At a strict level [self-signing] means that the issuer and subject fields in the certificate are the same." That is the case for the boot2docker server certificate. When OpenSSL attempts to validate the boot2docker server certificate, it is possible to build a complete trust chain without considering the CA certificate since the server certificate appears to be signed by itself, but is not explicitly trusted, and therefore cannot be valid. I'm not confident that this is strictly correct or required behavior and I'm not qualified to decide but I think it seems "reasonable."

Thanks for the digging, folks.

Also, I think what #1474 is doing is far too specific; at least from my reading, it's not setting a minimum python version, but specifying an exact version. It also appears to fail its check you happen to have any 1.0.1 different from j, which means security updates won't be applied even to 1.0.1, which is definitely a problem.

Agreed. Assuming it's OpenSSL 1.0.2 that disagrees with boot2docker's certs, that part should at least be fixable - I'll look at getting an up-to-date OpenSSL 1.0.1 in.

@tdsmith, thanks for the explanation and apologies for the misunderstanding. @glyph, thanks for the clarification.

FWIW, I tried to test @tdsmith's theory and hacked generate_cert (it's ugly, forgive me) to create distinct values for Issuer and Subject. It _may_ appear to hold water (but see caveats below). Here's what I get when running b2d with certificates generated from the current generate_cert vs. my hacked up version:

0.9.8zd works with orig generate_cert (0.1)

% /usr/bin/openssl version
OpenSSL 0.9.8zd 8 Jan 2015
% /usr/bin/openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=1 /O=Boot2Docker
verify return:1
depth=0 /O=Boot2Docker
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2Docker
-----BEGIN CERTIFICATE-----
MIIC/TCCAeegAwIBAgIRAKt8Sy0ND8z8omBU0uhODVAwCwYJKoZIhvcNAQELMBYx
...
qKFg5oUO9wigoGlwnSjqC/5ZmFRf9B+nWeCUVi/vWl0skOIqCMlDamD8AOVtmtRg
tg==
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2Docker
---
Acceptable client certificate CA names
/O=Boot2Docker
---
SSL handshake has read 2554 bytes and written 2188 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 621C9DF6883DA1FAF273408D0C984AC6E1DA33BA44ADA0EBA88BE59490560CFC
    Session-ID-ctx: 
    Master-Key: 39A75DE8551C41241CDBF889A5EF32DC7F86A45C792218B7E380E90627C7D0691BC5FCCAB69154B84142171F866F36C2
    Key-Arg   : None
    TLS session ticket:
    0000 - 77 ca 24 b7 2e 33 6a fc-9d 6e d0 eb aa 0d d5 89   w.$..3j..n......
    ...
    0630 - db 49 35 a1 97                                    .I5..

    Start Time: 1438703085
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
DONE

1.0.2d (installed via MacPorts) does _not_ work with orig generate_cert (0.1)

% openssl version
OpenSSL 1.0.2d 9 Jul 2015
% openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=0 O = Boot2Docker
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Boot2Docker
verify error:num=21:unable to verify the first certificate
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2Docker
-----BEGIN CERTIFICATE-----
MIIC/TCCAeegAwIBAgIRAKt8Sy0ND8z8omBU0uhODVAwCwYJKoZIhvcNAQELMBYx
...
qKFg5oUO9wigoGlwnSjqC/5ZmFRf9B+nWeCUVi/vWl0skOIqCMlDamD8AOVtmtRg
tg==
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2Docker
---
Acceptable client certificate CA names
/O=Boot2Docker
Client Certificate Types: RSA sign, ECDSA sign
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2156 bytes and written 1373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: BAE02ACF63C2F4E28C46664CEB8E790DB0F00E8CB75913484BFE88CC215995D2
    Session-ID-ctx: 
    Master-Key: C7227519074A26A51D815655721F18C63932897D731D1BF077B8374F8A021D51EDF2E603386D249ED62127BD71A86048
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - 14 b0 7a 58 68 91 62 10-14 53 04 cf da 41 63 6e   ..zXh.b..S...Acn
    ...
    0350 - 5f 8e fe fd 9c b0 d0                              _......

    Start Time: 1438703297
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
DONE

0.9.8zd works with hacked generate_cert (0.1.1; not surprising)

% /usr/bin/openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=1 /O=Boot2DockerCA
verify return:1
depth=0 /O=Boot2Docker
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2DockerCA
-----BEGIN CERTIFICATE-----
MIIC/zCCAemgAwIBAgIRAMLl0tA00F2BDjyktFSD5aEwCwYJKoZIhvcNAQELMBgx
...
jhzP4aW3a8uAdpQXjf8nmJ5Qrq4Xb6yWAezXRdmPWfG1u4neBQKy1Zp64PiBd+0v
1UPu
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2DockerCA
---
Acceptable client certificate CA names
/O=Boot2DockerCA
---
SSL handshake has read 2563 bytes and written 2193 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 1E52C9982BE1F98559529B9E804D330ADD5EC8654EE9F3AFE6139B2AEAB24919
    Session-ID-ctx: 
    Master-Key: 0714B120A52F735C484BF0F6612909CEB5FAF27D5E66B3DDB76DCB32FFE506F70E4BC5EFC42BB19E5CBE6223ACEA5803
    Key-Arg   : None
    TLS session ticket:
    0000 - c4 54 e0 2f 90 68 f2 22-7a c9 ee 2f fb da 25 7a   .T./.h."z../..%z
    ...
    0630 - 5c 95 c6 0a e9 bd 21 70-fd                        \.....!p.
    063a - <SPACES/NULS>

    Start Time: 1438703534
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
DONE

1.0.2d _works(!)_ :tada: :see_no_evil: :hear_no_evil: :speak_no_evil: with hacked generate_cert (0.1.1)

% openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=1 O = Boot2DockerCA
verify return:1
depth=0 O = Boot2Docker
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2DockerCA
-----BEGIN CERTIFICATE-----
MIIC/zCCAemgAwIBAgIRAMLl0tA00F2BDjyktFSD5aEwCwYJKoZIhvcNAQELMBgx
...
jhzP4aW3a8uAdpQXjf8nmJ5Qrq4Xb6yWAezXRdmPWfG1u4neBQKy1Zp64PiBd+0v
1UPu
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2DockerCA
---
Acceptable client certificate CA names
/O=Boot2DockerCA
Client Certificate Types: RSA sign, ECDSA sign
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2899 bytes and written 2111 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 0F1A3A0AB7B1E7C1CFD43CED169E730745DEB935C4DBEDDC7CD8AB698ECB8896
    Session-ID-ctx: 
    Master-Key: A48F441FD8677E1602BFB96DC7E9B39D0E9A7241D1C4AF93F3022ACB621C73E16BD69F557FF4428B033B1C07DF5EB0FB
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - 30 e1 e9 1a 4d e0 48 78-14 22 e8 21 5d 84 e7 6f   0...M.Hx.".!]..o
    ...
    0630 - 27 15 8a 64 ff 2e 24 44-3d d8                     '..d..$D=.

    Start Time: 1438703550
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
DONE

Caveats

In the interest of trying to control for all changes, note that when the original generate_cert (0.1) was released, it was built when the golang:1.3-cross Docker image used to build it had access to a package called ssh. That package has since been replaced by openssh-client. The OpenSSL version used when building my hacked generate_cert is 1.0.1k. This appears to be statically linked:

% ldd generate_cert-0.1.1-linux-amd64
        linux-vdso.so.1 (0x00007ffd0936c000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007fddefe7f000)
        libc.so.6 => /lib/libc.so.6 (0x00007fddefb11000)
        /lib64/ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x00007fddf009a000)

So it looks like one of two things may be happening:

  • Either late versions of OpenSSL get confused when Issuer == Subject, as @tdsmith suggests; or
  • There is something else about certificate generation that changed in OpenSSL such that later versions of OpenSSL have trouble validating certificates generated by earlier ones

One way to test this is to rebuild generate_cert without my hack, but with an updated version of OpenSSL. I'll do that next.

So it looks like @tdsmith is right. After backing out my hack to ensure Issuer <> Subject, but rebuilding generate_cert with the newer version of OpenSSL from golang:1.3-cross, it goes back to failing with later OpenSSL versions on the client side:

0.9.8zd works with generate_cert (0.1.2) with updated OpenSSL

% /usr/bin/openssl version
OpenSSL 0.9.8zd 8 Jan 2015
% /usr/bin/openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=1 /O=Boot2Docker
verify return:1
depth=0 /O=Boot2Docker
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2Docker
-----BEGIN CERTIFICATE-----
MIIC/TCCAeegAwIBAgIRAIVQ9IAYtPQwnu/FHM8HNS0wCwYJKoZIhvcNAQELMBYx
...
xZ+XhXvepeJ/mBIui1qT3yAMum0Mj1zLAxqCY/qsEU4odsgU9N9DbUGngoIkBCrY
gw==
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2Docker
---
Acceptable client certificate CA names
/O=Boot2Docker
---
SSL handshake has read 2554 bytes and written 2188 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: FDE088ECF8D0EB2B36EC909B9A66C9C6770AE31355040761CB35150C5A56E92E
    Session-ID-ctx: 
    Master-Key: 86522F869CDE85C8171EEC3A7CF76FDF26F81AE6162DDDEA7D1C55FD5E49E4BDCA56D827C3BFECBFAD9AA2F71A5A94EE
    Key-Arg   : None
    TLS session ticket:
    0000 - 67 d0 60 8e 54 54 7c 7a-3e 5e 71 97 26 e0 06 2c   g.`.TT|z>^q.&..,
    ...
    0630 - cf 68 86 83 d7                                    .h...

    Start Time: 1438705996
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
DONE

1.0.2d (installed via MacPorts) does _not_ work with generate_cert (0.1.2) with updated OpenSSL

% openssl version
OpenSSL 1.0.2d 9 Jul 2015
% openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
depth=0 O = Boot2Docker
verify error:num=18:self signed certificate
verify return:1
depth=0 O = Boot2Docker
verify error:num=21:unable to verify the first certificate
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2Docker
-----BEGIN CERTIFICATE-----
MIIC/TCCAeegAwIBAgIRAIVQ9IAYtPQwnu/FHM8HNS0wCwYJKoZIhvcNAQELMBYx
...
xZ+XhXvepeJ/mBIui1qT3yAMum0Mj1zLAxqCY/qsEU4odsgU9N9DbUGngoIkBCrY
gw==
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Boot2Docker
issuer=/O=Boot2Docker
---
Acceptable client certificate CA names
/O=Boot2Docker
Client Certificate Types: RSA sign, ECDSA sign
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2156 bytes and written 1373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: C2A8BF01E9B754CBF48C69243091C54DAD19DCF52D285C9379B684A3B333AFDD
    Session-ID-ctx: 
    Master-Key: F8510162517AF4C115A13B7CA9E05E04868B4D78CBFA57B28A5B9616EE6FBED6B7B4FC52C2003EBC5D150FA8BDE95F4C
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - bc bc 2c 3e 2d b0 92 49-80 c2 c0 df 4f bd fb 84   ..,>-..I....O...
    ...
    0350 - 1e c7 c2 b2 e6 f5 74                              ......t

    Start Time: 1438705985
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
DONE

Needs SvenDowideit/generate_cert#10. By the way, if anyone wants to build b2d images that point to my hacked generate_certs, you can try these until an official fix is released.

If I understand correctly, this _should_ obviate the need to play OpenSSL/Python version games on the client side (at least with respect to this issue).

tagging @SvenDowideit

I've had a bit of a back-and-forth with the OpenSSL guys. Here's a summary from Steve Henson:

From: Stephen Henson via RT <[email protected]>
Subject: [openssl.org #3979] New OpenSSL issue: valid certificate fails validation where subject text == issuer text
Date: August 5, 2015 at 04:32:18 PDT
Cc: [email protected]
Reply-To: [email protected]

... The bug is that OpenSSL 1.0.2 is less strict about
what counts as a valid self signed certificate. Before 1.0.2 the certificate
had to have issuer and subject matching, if present AKID==SKID and
keyUsage (if present) had to include keyCertSign. For1.0.2 and later the
keyCertSign check is no longer present.

The attached patch should fix it. Let me know if it works for you.

A workaround (other than making subject != issuer) is to include SKID/AKID in
all certificates.

Regards, Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

Changing the way b2d generates its certificates in order to accommodate buggy OpenSSL clients seems far superior to patching and installing OpenSSL on the client side. I'm not sure which specific approach is more appropriate though (making subject != issuer vs. including SKID/ADID in all certificates). I'll pass that buck onto @SvenDowideit. :smirk:

For the curious (again I don't think we should take this route), here is the OpenSSL patch from Steve:

diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 1f9296a..7a0130a 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -63,6 +63,7 @@
 #include <openssl/x509_vfy.h>

 static void x509v3_cache_extensions(X509 *x);
+static int check_ca(const X509 *x);

 static int check_ssl_ca(const X509 *x);
 static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
@@ -493,7 +494,7 @@ static void x509v3_cache_extensions(X509 *x)
     if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
         x->ex_flags |= EXFLAG_SI;
         /* If SKID matches AKID also indicate self signed */
-        if (X509_check_akid(x, x->akid) == X509_V_OK)
+        if (X509_check_akid(x, x->akid) == X509_V_OK && check_ca(x) == 1)
             x->ex_flags |= EXFLAG_SS;
     }
     x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);

Full history: http://rt.openssl.org/Ticket/History.html?user=guest&pass=guest&id=3979.

Wait... _less_ strict? I'm confused how is a _less_ strict check failing where a more strict one passes?

Wait... _less_ strict? I'm confused how is a _less_ strict check failing where a more strict one passes?

Yeah, I had trouble with that choice of language as well. Looking at the diff, I think he means incorrectly sweeping in more certificates as self-signed by not performing as many checks (i.e., less strict in determining what _doesn't_ qualify as self-signed). But you're right. It's an odd turn of phrase.

I haven't spent that much time delving into OpenSSL sources, but I find them fairly impenetrable in many places. Perhaps it takes a "special" mindset to work on that project. :grin:

I haven't spent that much time delving into OpenSSL sources, but I find them fairly impenetrable in many places. Perhaps it takes a "special" mindset to work on that project.

An understatement, I think :wink: .

In any case, thanks for reaching out to the OpenSSL folks, glad to here it will be resolved over there. In the meanwhile, working around it in b2d seems like the right thing to do. I don't think that there's anything for compose to do here but wait.

As mentioned here, this fixes things for me:

pip install requests[security]

@iffy That's a red herring; it likely fixes it for you because you had a cached binary wheel which linked against a different OpenSSL.

FYI, PR with fix submitted as boot2docker/boot2docker#1029.

The fix for this (thanks @posita!) is out in the latest version of boot2docker. To upgrade:

$ boot2docker upgrade
$ boot2docker delete
$ boot2docker init
$ boot2docker up

That fixed the issue for me. Please try it and report back.

Alternatively, switch to Docker Machine, which now comes as standard as part of the new Docker Toolbox.

I am still having this issue...

❯ openssl version && docker-compose --version && docker-machine --version && python --version
OpenSSL 1.0.2d 9 Jul 2015
docker-compose version: 1.4.0
docker-machine version 0.4.1 (HEAD)
Python 2.7.10

❯ docker-compose ps
/usr/local/Cellar/fig/1.4.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Name   Command   State   Ports
------------------------------

@chiefy Your docker-compose call is succeeding; the warning you're seeing is harmless. You should upgrade to OS X 10.10.5 if you prefer to avoid seeing it.

@tdsmith not harmless to me, driving my OCD crazy :smile: thanks for the tip, will upgrade right now.

Uninstalling the python version installed via brew solved this problem for me. brew remove --force python

I have uninstalled the brew version, but still have Python 2.7.10 and still have the
SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581) error.

I have the next setup:

OpenSSL 0.9.8zg 14 July 2015
docker-compose version: 1.4.0
docker-machine version 0.4.1 (e2c88d6)
Python 2.7.10

@chiefy
have you solved your issue?

does anybode know if docker-compose guys are working to solve the issue, or it's basically not their issue?

Regards,

@PavelPolyakov
no. on both of my macs (10.9.x and 10.10.x), I have tried various things w/ no change. I don't think this is a docker-compose thing and more of Python thing FWIW.

@chiefy
I agree, but I haven't found any variant how to make it work :(

Seems like everyone has solved this issue already, but not me :)

I have installed python using brew once, and I think I have removed the system one, so I don't have an option to return to the old one.

I have tried to install docker by several variants:

  1. from binary (downloading the docker toolbox)
  2. from brew itself

however I still have:
image

does anyone have a comprehensive guide of how to overcome this behaviour?

Regards,

@PavelPolyakov - The bug is that boot2docker (and in some cases, I think, docker-machine) was building some certificates that were unusable by python's SSL support. If you have upgraded all your software but still have the bad old certificates, things will still be broken. So at this point I would recommend re-provisioning whatever dev VMs you've got, with a current version of docker-machine, so that new SSL certificates will be provisioned. This may involve moving aside ~/.docker on your host.

@PavelPolyakov and @chiefy, in addition to @glyph's advice, you can also try this (if you don't want to completely reprovision your boot2docker environment):

% mv ~/.docker ~/.docker.bak
% ssh docker@[boot2dockerip]
docker@[boot2dockerip]'s password: [typically "tcuser"]
...
Boot2Docker version 1.8.1, build master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015
Docker version 1.8.1, build d12ea79
docker@boot2docker:~$ rm -frv ~/.docker
...
docker@boot2docker:~$ sudo -s
root@boot2docker:/home/docker# rm -v /var/lib/boot2docker/tls/*
...
root@boot2docker:/home/docker# shutdown -h now
...

[boot2dockerip] is specific to your VM environment. There may be easier methods (e.g., vagrant ssh, if you're using Vagrant). Then restart your boot2docker instance and see if the SSL error still occurs.

@glyph

Thanks for the advice, for me it's not an issue to reprovision the docker-machine. However it doesn't help.

When I install docker & co with:
brew install docker docker-machine docker-compose

Then, default machine is not created. And I have no idea of how to create it using docker-machine create.

When I install docker-toolbelt using *.pkg file, then the machine is created, but I have SSL error.
I have even tried to do:

docker-machine regenerate-certs default

But it doesn't help.

@posita
Thanks for the advice as well.
In your guide, you suggest to mv ~/.docker ~/.docker-bak - for what reason? As soon as we do this, we can't start the machine again, because the files are moved.
Yes, I am able to login the machine and remove tls/*, then shut it down, but how to start it again?

How to reprovision it from the scratch?

@all
What is your way installing docker (with working docker-compose), is it via brew install or via toolbelt .pkg ?
How can I be sure, that the certificates, which are on my docker-machine are valid and useful by python, how can I upgrade python and openssl even more then brew can, etc?

Thanks for helping.

Regards,

@PavelPolyakov - docker-machine does not have a notion of a "default" machine. You can run docker-machine create --driver virtualbox my-docker-machine.

@PavelPolyakov Once you've done that you need to do eval "$(docker-machine env my-docker-machine)", or whatever you've chosen to call your local dev machine.

@glyph
Correct, that was the missing part of running everything from brew. I have successfully provisioned machine with the name default (the same that which is done while installing from *.pkg).

However, as usual, I end with:
image

:(

In your guide, you suggest to mv ~/.docker ~/.docker-bak - for what reason? As soon as we do this, we can't start the machine again, because the files are moved.

@PavelPolyakov, I'm not sure. I don't use docker-machine. I was guessing based on other environments. Please disregard if this doesn't work.

Yes, I am able to login the machine and remove tls/*, then shut it down, but how to start it again?

Does docker-machine restart not work?

My comment was based on my own experience with running boot2docker with Vagrant. It may not apply very well to docker-machine. It sounds like @glyph has more experience with that environment. I would try his suggestions.

What is your way installing docker (with working docker-compose), is it via brew install or via toolbelt .pkg ?

This is somewhat outside the scope of this issue (which deals specifically with a certificate problem with boot2docker as manifested in docker-compose), but on OS X, I use the binary builds.

@PavelPolyakov, what happens when you do the following?

docker-machine create --driver virtualbox shiny-new-machine-74d5a19e
eval $( docker-machine env shiny-new-machine-74d5a19e )
docker-compose build

What is the version for boot2docker that is displayed when you do the following?

docker-machine ssh shiny-new-machine-74d5a19e

Feel free to replace shiny-new-machine-74d5a19e with whatever you want, so long as it doesn't reference an existing instance (i.e., the name shouldn't already appear when you do docker-machine ls before executing the above commands.).

@posita
image
image

Hmmm.... :confused: @PavelPolyakov, what does this give you?

eval $( docker-machine env shiny-new-machine-74d5a19e ) # probably unnecessary if you're still in the same shell as above
which openssl
openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null

@posita
Thanks that you continue to help.
image

openssl s_client -showcerts -connect "${DOCKER_HOST#tcp:\/\/}" -key "${DOCKER_CERT_PATH}/key.pem" -cert "${DOCKER_CERT_PATH}/cert.pem" -CAfile "${DOCKER_CERT_PATH}/ca.pem" -tls1 </dev/null
http://pastebin.com/Y9ZqfTVG

Have tried to do the same on the different OSX machine.
With all the latest updates (os and brew packages), and faced the same issue with SSL.

image

@PavelPolyakov, I'm looking at this from your openssl s_client ... dump:

...
Certificate chain
 0 s:/O=shiny-new-machine-74d5a19e
   i:/O=PavelPolyakov
...

These aren't the boot2docker defaults, which (now) should be:

...
Certificate chain
 0 s:/O=Boot2Docker
   i:/O=Boot2Docker
...

Without knowing more, my guess is that docker-machine is overwriting the defaults (somehow) when it provisions the virtual machine. But the openssl call appears to have worked, so I'm not sure this is an issue, and I don't understand why docker-compose would fail. :confounded:

What is your output for the following?

(
set -x
eval $( docker-machine env shiny-new-machine-74d5a19e )
env | grep DOCKER
ls -al "${DOCKER_CERT_PATH}"
openssl x509 -in "${DOCKER_CERT_PATH}/cert.pem" -text
openssl x509 -in "${DOCKER_CERT_PATH}/ca.pem" -text
docker-compose --verbose version
docker-compose --verbose ps
DOCKER_TLS_VERIFY=0 docker-compose --verbose ps
) >"${HOME}/Desktop/docker-compose-890-outerr-$( date -u +%Y-%m-%dT%H:%M:%SZ ).txt" 2>&1

This should create a file like ~/Desktop/docker-compose-890-outerr-2015-09-18T14:45:29Z.txt suitable for pasting/uploading.

@posita
Here it is:
http://pastebin.com/vWqZgVKi

I'm pretty sure this has nothing to do with your issue, but your docker-compose and docker-py versions are behind. These are the latest releases:

...
 docker-compose version: 1.4.1
 docker-py version: 1.4.0
...

Also (and I might be misreading this), it looks like your ca.pem and cert.pem share the same Subject (which was the cause of the original boot2docker issue, but coming from the other direction). Since these certificates appear to be created/maintained by docker-machine, I suspect the issue is there? I found docker/machine#1335 and docker/machine#1767, which may be related, but neither appear to be directly on point.

FWIW, I'm using docker-compose (installed via pip in a virtualenv) with OpenSSL and Python 2.7 installed from MacPorts. That version of OpenSSL is subject to the problem identified in this issue (and worked around by the update to boot2docker). For me, this combination works without issue with boot2docker 1.8.1+ and Vagrant (my Vagrantfile handles copying the boot2docker certificates back to the host through some provisioning magic):

% cat /.../Vagrantfile
...
         # See <http://tinyurl.com/nz4tgy6>
         boot2docker.vm.provision :shell, inline: "set -e ; while ! docker >/dev/null ps --quiet ; do echo 'Waiting for Docker to come alive so we can kill it...' ; sleep 1 ; done ; sudo /etc/init.d/docker stop ; sudo rm -f /var/lib/boot2docker/tls/*.pem ~docker/.docker/*.pem ; sudo /etc/init.d/docker restart ; while ! docker >/dev/null ps --quiet ; do echo 'Waiting for Docker to come alive again so we can steal its keys...' ; sleep 1 ; done ; echo 'It lives!' ; [ -z \"$( find ~docker/.docker -name '*.pem' 2>/dev/null )\" ] || cp -Rv ~docker/.docker/*.pem '/vagrant/certs" , privileged: true
...
% env | grep DOCKER
DOCKER_HOST=tcp://w.x.y.z:2376
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/.../certs
% ls "${DOCKER_CERT_PATH}"
ca.pem
cert.pem
key.pem
% openssl x509 -in "${DOCKER_CERT_PATH}/cert.pem" -text
...
        Issuer: O=Boot2DockerCA
...
        Subject: O=Boot2Docker
...
% openssl x509 -in "${DOCKER_CERT_PATH}/ca.pem" -text
...
        Subject: O=Boot2DockerCA
...
% virtualenv --python=python2.7 .../venv
...
% .../venv/bin/pip install docker-compose
...
% .../venv/bin/docker-compose --verbose version
docker-compose version: 1.4.1
docker-py version: 1.4.0
CPython version: 2.7.10
OpenSSL version: OpenSSL 1.0.2d 9 Jul 2015
% .../venv/bin/docker-compose ps
Name   Command   State   Ports
------------------------------

I realize you may not have that option. I'm just posting it to help illuminate the differences, which may aid in diagnosing your issue. Compare the above with your docker-machine-created certs:

+-zsh:39> openssl x509 -in /.../.docker/machine/machines/shiny-new-machine-74d5a19e/cert.pem -text
...
        Issuer: O=PavelPolyakov
...
        Subject: O=PavelPolyakov
...
+-zsh:40> openssl x509 -in /.../.docker/machine/machines/shiny-new-machine-74d5a19e/ca.pem -text
...
        Subject: O=PavelPolyakov
...

Note that Subject of ca.pem is the same as the Subject of cert.pem.

I don't think your issue is a problem with docker-compose. (@aanand, perhaps you can comment?) Seeing as how this issue is quite cluttered, consider filing a new issue for docker/machine. I would reference this one, starting at your initial comment.

If you decide to file a new issue for docker/machine, consider adding where there is anything interesting in /var/log/docker.log or /var/log/boot2docker.log on your VM instance. For example, try this:

ssh docker@[machine-instance] grep generate_cert /var/log/boot2docker.log

Or:

docker-machine ssh grep generate_cert /var/log/boot2docker.log

Getting this on OSX el capitain,

docker-machine version 0.4.1 (HEAD)
Docker version 1.8.2, build 0a8c2e3
docker-compose version: 1.4.2

Hi @DaveBlooman ,

just curious, do you also have python and stuff installed using brew? Or the other way.
And do you have the exact error when doing docker-compose build ?

Via homebrew, Python 2.7.10

So definitely something takes places because of the brew :(

@DaveBlooman, see also docker/machine#1910. If you can reproduce @PavelPolyakov's issue, then maybe you two can collaborate on a diagnosis?

I had the same problem and it was due to the fact that I had a vpn connection open seated by another application (Astrill in my case) that was probably messing up something with the network configuration. Hope this can help someone else that gets the same problem.

I get errors on OSX 10.9.5

/usr/local/Cellar/docker-compose/1.5.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Starting compose_maven_1
/usr/local/Cellar/docker-compose/1.5.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Starting compose_ssh_1
/usr/local/Cellar/docker-compose/1.5.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning

Python 2.7.10
docker-machine version 0.5.0
docker-compose version: 1.5.0

all installed via Homebrew

@anthonygreen, that looks like a substantially different issue. I don't event see the same error message as what's being discussed here. It seems that Homebrew users are experience a substantial number of problems unrelated to this one. Please consider filing a new issue.

I haven't read through this entire post, but I saw the same error on a recent setup on OS X Yosemite using Docker Toolbox 1.9.1a.

$ docker-machine --version
docker-machine version 0.5.1 (7e8e38e)
$ docker-compose --version
docker-compose version: 1.5.1
$ docker --version
Docker version 1.9.1, build a34a1d5

Turns out I had a custom CURL_CA_BUNDLE environment variable set (with some custom internal certs), and unsetting this env var before running docker-compose allowed it to get past the [SSL: CERTIFICATE_VERIFY_FAILED] error.

$ (unset CURL_CA_BUNDLE; docker-compose up)
Starting ...

edit: oops, meant to comment over here https://github.com/docker/machine/issues/1880

@pmahoney, thanks for letting the rest of us know! I never would have guessed that. FYI, you can probably also do something like this (if you don't want the subshell):

$ CURL_CA_BUNDLE= docker-compose up

@posita Setting the env var to the empty string results in warnings:

$TMPDIR/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html

Though I do not get the SSL error.

@pmahoney, interesting. So it looks like a set-but-empty CURL_CA_BUNDLE has different semantics (i.e., a null override) than not setting it at all (which probably looks to some default location). I tried to find this in behavior in the docs, but wasn't successful. The closest thing I found was this.

@neilsarkar my problem was also Charles proxy running! Thank you!

oh god, I also have custom CURL_CA_BUNDLE on both machines where I was testing.

Thanks

erf nothing for me, no CURL_CA_BUNDLE variable :(
So I tried to set it to a value with no success at all but if I set a CURL_CA_BUNDLE to nothing (CURL_CA_BUNDLE=) then I have a warning as @pmahoney said and it works but my terminal il totally flod by warning messages.
I hope there is a better solution for me :)

If you know what is the good value for the CURL_CA_BUNDLE variable, i take it :)

Thx

I had the same issue with webkit-patch. From looking at the python docs on the SSL/TLS module, the ssl.get_default_verify_paths() shows us where Python/OpenSSL expects a CA certificate file. So if you run this in your terminal:

python3 -c "import ssl; [print(i) for i in ssl.get_default_verify_paths()]"

we should see that without SSL_CERT_FILE being set, Python's SSL module expects a CA certificate file at /usr/local/ssl/cert.pem (for those who installed OpenSSL to /usr/local/ssl). So either, you set SSL_CERT_FILE to a certificate file with Root CA certificates, or you place a file with Root CA certificates at /usr/local/ssl/cert.pem. If you need the Root CA certificates, download curl and in the source tree run lib/mk-ca-bundle.pl and a ca-bundle.crt file will be generated. I can confirm that setting SSL_CERT_FILE will work with OpenSSL 1.0.2d with Python 2.7.11 and Python 3.5.0.

@grahamc Did you happen to solve the issue? I have a similar set up as yours which it works great with remote docker daemon but fails with docker-compose

The error I get is ERROR: SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

No, I just had to abandon remote docker hosts, unfortunately :(

I've just had this issue where CURL_CA_BUNDLE caused docker-compose to fail with:

ERROR: SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

while docker was working fine. It would be good to have docker-compose ignore the environmental variable or at least log a warning that it won't be using the expected certificates.

@buckett, consider filing a new issue to add that as a feature request. Consider also filing a sister issue with docker-py and have them reference each other. I'm not sure which layer would be most appropriate.

edit: Created new issue #3114

Has everyone fixed this yet? I still get the same error. My docker-compose version is:

docker-compose version 1.6.2, build 4d72027
docker-py version: 1.7.2
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1j 15 Oct 2014

This is what i got from docker-compose --verbose build:

compose.config.config.find: Using configuration files: ./docker-compose.yml
docker.auth.auth.load_config: File doesn't exist
Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "compose/cli/main.py", line 56, in main
  File "compose/cli/docopt_command.py", line 23, in sys_dispatch
  File "compose/cli/docopt_command.py", line 26, in dispatch
  File "compose/cli/main.py", line 189, in perform_command
  File "compose/cli/command.py", line 52, in project_from_options
  File "compose/cli/command.py", line 85, in get_project
  File "compose/cli/command.py", line 68, in get_client
  File "site-packages/docker/api/daemon.py", line 78, in version
  File "site-packages/docker/utils/decorators.py", line 47, in inner
  File "site-packages/docker/client.py", line 112, in _get
  File "site-packages/requests/sessions.py", line 477, in get
  File "site-packages/requests/sessions.py", line 465, in request
  File "site-packages/requests/sessions.py", line 573, in send
  File "site-packages/requests/adapters.py", line 431, in send
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)

I installed docker, docker-mahine and docker-compose via Docker's toolbox.

I have tried all of the suggestion above but no luck. I have no experience in docker so I couldn't figure it out myself.

Does anyone have a root cause or a workaround on this? I'm seeing it in compose 1.7.0 with a newer openssl version.
This is all built and run from alpine, so the environment should be pure:

/usr/src/app # env | sed 's/DOCKER_HOST=.*/DOCKER_HOST=#redacted/' && docker version && docker ps && docker-compose version && docker-compose pull
HOSTNAME=aebfe81b5938
SHLVL=1
PYTHON_PIP_VERSION=8.1.1
HOME=/root
GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D
DOCKER_TLS_VERIFY=1
TERM=xterm
DOCKER_CERT_PATH=/certs
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=C.UTF-8
PYTHON_VERSION=3.5.1
DOCKER_HOST=#redacted
PWD=/usr/src/app
Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 21:49:11 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:39:25 2016
 OS/Arch:      linux/amd64
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
docker-compose version 1.7.0, build 0d7bf73
docker-py version: 1.8.0
CPython version: 3.5.1
OpenSSL version: OpenSSL 1.0.2g  1 Mar 2016
Pulling registry (registry:2)...
ERROR: SSL error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

@jmmills
in my case it was caused by the redefined CURL_CA_BUNDLE env variable. You should check if you have such case as well.

@PavelPolyakov check my env dump... no CURL_CA_BUNDLE

@PavelPolyakov okay this is odd, I explicitly unset that env variable and it worked, despite not being in my environment.

@jmmills huh… same here. Maybe python treats set-as-empty differently to unset?

Mac OS, homebrew docker-compose and docker-machine, using system python. Newly created machine with: docker-machine create --driver=vmwarefusion --vmwarefusion-memory-size 1536 dev

env | grep CURL returns nothing
docker-compose ps returns

ERROR: SSL error: hostname '172.16.129.133' doesn't match 'localhost'

CURL_CA_BUNDLE='' docker-compose ps returns:

/usr/local/Cellar/docker-compose/1.7.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/usr/local/Cellar/docker-compose/1.7.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
Name   Command   State   Ports 
------------------------------

I've had the exact same - CURL_CA_BUNDLE was not being set in my env, and setting it to an empty string gave me the same output as @inanimatt.

It definitely smells like an upstream bug, my guess would be some environment compatibility code for curl, in which "defined" and "empty" are being treated differently.

Thanks,
Jason Mills

  • sent from mobile.

On Apr 24, 2016, at 6:14 AM, Alex Wilson [email protected] wrote:

I've had the exact same - CURL_CA_BUNDLE was not being set in my env, and setting it to an empty string gave me the same output as @inanimatt.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

Only seems to affect the homebrew version - installing homebrew Python then installing docker-compose via pip solves all the errors.

On 24 Apr 2016, at 14:14, Alex Wilson [email protected] wrote:

I've had the exact same - CURL_CA_BUNDLE was not being set in my env, and setting it to an empty string gave me the same output as @inanimatt.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

I believe I pasted replication of the issue in Linux earlier. I can double check tomorrow when at a workstation

Thanks,
Jason Mills

  • sent from mobile.

On Apr 24, 2016, at 12:22 PM, Matt Robinson [email protected] wrote:

Only seems to affect the homebrew version - installing homebrew Python then installing docker-compose via pip solves all the errors.

On 24 Apr 2016, at 14:14, Alex Wilson [email protected] wrote:

I've had the exact same - CURL_CA_BUNDLE was not being set in my env, and setting it to an empty string gave me the same output as @inanimatt.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

Same problem here since i updated docker-compose to version 1.7 using brew.

$ docker-compose ps
ERROR: SSL error: hostname '192.168.99.100' doesn't match 'localhost'
$ docker-compose version
docker-compose version 1.7.0, build unknown
docker-py version: 1.8.0
CPython version: 2.7.10
OpenSSL version: OpenSSL 0.9.8zh 14 Jan 2016

Emptying the CURL_CA_BUNDLE env var kind of solves the problem :

CURL_CA_BUNDLE= docker-compose ps
/opt/boxen/homebrew/Cellar/docker-compose/1.7.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/opt/boxen/homebrew/Cellar/docker-compose/1.7.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/opt/boxen/homebrew/Cellar/docker-compose/1.7.0/libexec/vendor/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
   Name                 Command               State    Ports
------------------------------------------------------------

Downgrading to 1.6.2 also solves the problem.

$ brew switch docker-compose 1.6.2
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.4.2
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.5.1
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.5.2
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.6.0
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.6.2
Cleaning /opt/boxen/homebrew/Cellar/docker-compose/1.7.0
3 links created for /opt/boxen/homebrew/Cellar/docker-compose/1.6.2
$ docker-compose ps
   Name                 Command               State    Ports
------------------------------------------------------------

Rather than disable the CURL_CA_BUNDLE you can run using:
CURL_CA_BUNDLE=~/.docker/machine/machines/default/ca.pem docker-compose ps

I'm probably not the first one who may have brought this up, but isn't it counter intuitive that a curl environment variable have any effect what so ever on an unrelated Python application?

Thanks,
Jason Mills

  • sent from mobile.

On May 7, 2016, at 3:22 PM, Lorenzo Sicilia [email protected] wrote:

Rather than disable the CURL_CA_BUNDLE you can run using:
CURL_CA_BUNDLE=~/.docker/machine/machines/default/ca.pem docker-compose ps


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

I ran into this issue and the problem was with the environment variable REQUESTS_CA_BUNDLE pointing to a custom location for self-signed certs. Encase this helps anyone.

  • Michael Housh

@aboutlo This works - it did not work with other ca.pem file, only with this one. I am also on Windows so I have a more voodoo configuration, thank you!

Uninstalling ndg-httpsclient (with pip - was version 0.4.0) solved the issue for me, see my post here: https://github.com/docker/compose/issues/3365

I debugged docker-compose and docker-py and figured out that you should either use environment variables or options in command. You should not mix these . If you even specify --tls in command then you will have to specify all the options as the TLSConfig object, as now TLSConfig object is created completely from the command options and operide the TFSConfig object created from the environment variable.

@m-housh OMG thanks for that tip! Exact same thing happened to me! Removed REQUESTS_CA_BUNDLE from my environment and it resolved this issue for me.

I have encountered the same problem. First I though it is because the OpenSSL version differences (Pyhton had 1.0.2 but OS had 0.9.8) I made them both 1.0.2 but it still did not work.
I have solved my problem by simply ssh to docker and then check my certificate in authorized keys and update it. Interestingly somehow it was a wrong certificate there.

Follow these steps please:

boot2docker ssh
docker@boot2docker:~$ cat .ssh/authorized_keys

Check if this certificate is really the certificate from your computer. If not just copy yours in to this file and save it. Then just run:

docker-compose up

This worked for me and hope that it helps.

Issue grooming: There appears to be a variety of different failure modes and user error/misconfiguration scenarios (all largely historic) described here.

I'm not seeing anything which seems to point towards an active ongoing issue in compose, so I'm closing the issue. If you are still seeing a related error with modern versions then please open a fresh issue with full details of your scenario etc.

Was this page helpful?
0 / 5 - 0 ratings