diff options
-rw-r--r-- | custodia/kubernetes/__init__.py | 0 | ||||
-rw-r--r-- | custodia/kubernetes/node.py | 73 | ||||
-rwxr-xr-x | setup.py | 2 |
3 files changed, 74 insertions, 1 deletions
diff --git a/custodia/kubernetes/__init__.py b/custodia/kubernetes/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/custodia/kubernetes/__init__.py diff --git a/custodia/kubernetes/node.py b/custodia/kubernetes/node.py new file mode 100644 index 0000000..5d4f863 --- /dev/null +++ b/custodia/kubernetes/node.py @@ -0,0 +1,73 @@ +# Copyright (C) 2015 Custodia Project Contributors - see LICENSE file + +import re + +from docker import Client + +from custodia import log +from custodia.httpd.authenticators import HTTPAuthenticator + +DEFAULT_REGEX = r'/docker-([0-9a-f]{64})\.scope' +DEFUALT_DOCKER_URI = 'unix://var/run/docker.sock' + + +class NodeAuth(HTTPAuthenticator): + + def __init__(self, config=None): + super(NodeAuth, self).__init__(config) + if self.config is not None: + regex = self.config.get('docker_regex', DEFAULT_REGEX) + self.docker_uri = self.config.get('docker_uri', DEFUALT_DOCKER_URI) + else: + regex = DEFAULT_REGEX + self.docker_uri = DEFUALT_DOCKER_URI + self.id_filter = re.compile(regex) + + def _pid2dockerid(self, pid): + with open('/proc/%i/cgroup' % pid) as f: + for line in f: + mo = self.id_filter.search(line) + if mo is not None: + return mo.group(1) + return None + + def handle(self, request): + creds = request.get('creds') + if creds is None: + self.logger.debug('Missing "creds" on request') + return None + dockerid = self._pid2dockerid(int(creds['pid'])) + if dockerid is None: + self.logger.debug("Didn't find docker ID for pid %s", creds['pid']) + return None + + try: + dc = Client(base_url=self.docker_uri) + data = dc.inspect_container(dockerid) + data_id = data['Id'] + data_labels = dict(data['Config']['Labels']) + except Exception as err: # pylint: disable=broad-except + self.logger.debug("Failed to query docker for [%s:%s]: %s", + creds['pid'], dockerid, err) + self.audit_svc_access(log.AUDIT_SVC_AUTH_FAIL, + request['client_id'], dockerid) + return False + + if data_id != dockerid: + self.logger.debug("Docker ID %s not found!", dockerid) + self.audit_svc_access(log.AUDIT_SVC_AUTH_FAIL, + request['client_id'], dockerid) + return False + + podname = data_labels.get('io.kubernetes.pod.name') + if podname is None: + self.logger.debug("Pod Name not found for Docker ID %s", dockerid) + self.audit_svc_access(log.AUDIT_SVC_AUTH_FAIL, + request['client_id'], dockerid) + return False + + self.audit_svc_access(log.AUDIT_SVC_AUTH_PASS, + request['client_id'], dockerid) + request['client_id'] = dockerid + request['remote_user'] = podname + return True @@ -12,7 +12,7 @@ setup( maintainer_email='simo@redhat.com', url='https://github.com/simo5/custodia', packages=['custodia', 'custodia.httpd', 'custodia.store', - 'custodia.message'], + 'custodia.message', 'custodia.kubernetes'], data_files=[('share/man/man7', ["man/custodia.7"]), ('share/doc/custodia', ['LICENSE', 'README', 'API.md']), ('share/doc/custodia/examples', ['custodia.conf']), |