GitHub user johnnyWalnut opened a pull request:
https://github.com/apache/libcloud/pull/1067
Fix docker tls
## Fix Docker driver tls connection
### Description
I tried to connect a Docker daemonâs host machine with tls key_file &
cert_file,
through libcloud's docker driver and it fails under all circumstances.
I used this info for securing my Docker daemonâs host machine:
https://docs.docker.com/engine/security/https/
First scenario: tls with key_file and cert_file:
My environment:
- server side
root@cloudLining:~# ps aux | grep docker
root 4330 0.2 4.9 350520 24996 ? Sl Jun01 1:45 dockerd
--tls --tlscert=server-cert.pem --tlskey=server-key.pem -H=tcp://0.0.0.0:4243 -D
root 4333 0.1 1.0 209380 5188 ? Ssl Jun01 1:04
docker-containerd -l
unix:///var/run/docker/libcontainerd/docker-containerd.sock
--metrics-interval=0 --start-timeout 2m --state-dir /var/run/doc$
root 5755 0.0 0.4 12000 2100 pts/0 S+ 08:32 0:00 grep
--color=auto docker
- client side
root@cloudLining:~# docker --tls --tlscacert=ca.pem
--tlscert=server-cert.pem --tlskey=server-key.pem -H=tcp://127.0.0.1:4243 images
REPOSITORY TAG IMAGE ID CREATED
SIZE
tomcat latest d71978506e58 5 weeks ago
367 MB
ubuntu latest 6a2f32de169d 7 weeks ago
117 MB
ubuntu 12.04 5b117edd0b76 7 weeks ago
104 MB
debian 7.11 69e388a5985c 2 months ago
85.3 MB
According to libcloud's docs:
conn = driver(host='https://198.61.239.128', port=4243, key_file='key.pem',
cert_file='cert.pem')
``` In [20]: from libcloud.container.providers import get_driver
...: from libcloud import security
...: security.VERIFY_SSL_CERT=False
...: driver = get_driver('docker')
...: key = '/home/johnny/Documents/kleidia/key.pem'
...: cert = '/home/johnny/Documents/kleidia/cert.pem'
...: d = driver(host='199.226.146.250', port=4243, key_file=key,
cert_file=cert,secure=True)
...: d.list_images()
----> 1 d.list_images()
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/libcloud/libcloud/container/drivers/docker.py
in list_images(self)
250 """
251 result = self.connection.request('/v%s/images/json' %
--> 252 (self.version)).object
253 images = []
254 for image in result:
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/libcloud/libcloud/common/base.pyc
in request(self, action, params, data, headers, method, raw, stream)
601 else:
602 self.connection.request(method=method, url=url,
body=data,
--> 603 headers=headers,
stream=stream)
604 except socket.gaierror:
605 e = sys.exc_info()[1]
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/libcloud/libcloud/http.pyc
in request(self, method, url, body, headers, raw, stream)
208 import ipdb
209 ipdb.set_trace()
--> 210 self.response = self.session.request(
211 method=method.lower(),
212 url=url,
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/local/lib/python2.7/site-packages/requests/sessions.pyc
in request(self, method, url, params, data, headers, cookies, files, auth,
timeout, allow_red$
486 }
487 send_kwargs.update(settings)
--> 488 resp = self.send(prep, **send_kwargs)
489
490 return resp
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/local/lib/python2.7/site-packages/requests/sessions.pyc
in send(self, request, **kwargs)
607
608 # Send the request
--> 609 r = adapter.send(request, **kwargs)
610
611 # Total elapsed time of the request (approximately)
/home/johnny/Documents/mylibcloud/libcloudfine/fork_libcloud/local/lib/python2.7/site-packages/requests/adapters.pyc
in send(self, request, stream, timeout, verify, cert, proxies)
485 raise ProxyError(e, request=request)
486
--> 487 raise ConnectionError(e, request=request)
488
489 except ClosedPoolError as e:
ConnectionError: HTTPSConnectionPool(host='4243', port=443): Max retries
exceeded with url: /v1.24/images/json (Caused by
NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection
object$
```
It's obvious at this point that variables are messed up!
I attached a more extensive debugging explanation here:
[docker_tls.txt](https://github.com/apache/libcloud/files/1047835/docker_tls.txt)
* With this pr I propose to add a new class DockertlsConnection in
DockerContainerDriver, which
handles the tls connection and is a subclass of class
KeyCertificateConnection (added in
libcloud/common/base.py).
* I replaced key,secret default values with empty strings( previous None)
otherwise it's not possible to call
driver(host='https://198.61.239.128', port=4243, key_file='key.pem',
cert_file='cert.pem')
* I added ca_cert variable in DockerContainerDriver, in case of a user
doesn't want to change
the environment's variables through libcloud.security.CA_CERTS_PATH
commit d5af021a92ef04ff42439f0e5ff7bd007de05015
commit e15e4a8346a121eb437c45b9f9c3c8812afd5ce5
* I passed the real version and not a default one
I have done seperated commits if you want to exclude anything.
I tested this pr against all scenarios:
- http
- http basic authentication
- tls
- tls key_file & cert_file
- tls verified key_file, cert_file, ca_cert
### Status
- done, ready for review
### Checklist (tick everything that applies)
- [X] [Code
linting](http://libcloud.readthedocs.org/en/latest/development.html#code-style-guide)
(required, can be done after the PR checks)
- [X] Documentation
- [X] [Tests](http://libcloud.readthedocs.org/en/latest/testing.html)
You can merge this pull request into a Git repository by running:
$ git pull https://github.com/johnnyWalnut/libcloud fix_docker_tls
Alternatively you can review and apply these changes as the patch at:
https://github.com/apache/libcloud/pull/1067.patch
To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:
This closes #1067
----
commit 2567025cdefe5eae4acc98fb38f7ed6557d0d63e
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T11:21:44Z
add class KeyCertificateConnection
which accepts both key_file and cert_file.
It can be used for tls connection.
commit 80156e393c02fe15df9879f21e849e88ae928c53
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T11:54:10Z
add DockertlsConnection, a subclass of KeyCertificateConnection
fix DockerContainerDriver connect either with http or tls
pass key_file, cert_file through function _ex_connection_class_kwargs
commit cc54341a1d8a54542348d2d7ef8c9ce2f4380759
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T11:59:38Z
change key,secret default values from None to ''
otherwise you cannot call
driver(host='https://198.61.239.128',
port=4243, key_file='key.pem', cert_file='cert.pem')
commit d5af021a92ef04ff42439f0e5ff7bd007de05015
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T12:02:45Z
pass ca_cert at DockerContainerDriver
if a user wants to not change the environmental variables
commit 445db65c124ca47ad6002f9c8a26a4f7330c098a
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T12:05:19Z
pass the real version and not a default one
commit e15e4a8346a121eb437c45b9f9c3c8812afd5ce5
Author: johnnyWalnut <[email protected]>
Date: 2017-06-02T13:29:32Z
in case of ca_cert has been already set by
libcloud.security.CA_CERT_PATH
----
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---