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 <ikaryd...@gmail.com> 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 <ikaryd...@gmail.com> 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 <ikaryd...@gmail.com> 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 <ikaryd...@gmail.com> 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 <ikaryd...@gmail.com> Date: 2017-06-02T12:05:19Z pass the real version and not a default one commit e15e4a8346a121eb437c45b9f9c3c8812afd5ce5 Author: johnnyWalnut <ikaryd...@gmail.com> 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 infrastruct...@apache.org or file a JIRA ticket with INFRA. ---