summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-10-13 15:38:42 -0400
committerSimo Sorce <simo@redhat.com>2015-11-11 11:37:15 -0500
commit0abd2a6c4ac66b905430d3cad95c1b2a23bda40f (patch)
tree07d779127331e3e7b4dc8fa03ecc181845a3ff29
parentd944441d2a6d0c8619e61ba7ceff16d6b147a76b (diff)
downloadcustodia-0abd2a6c4ac66b905430d3cad95c1b2a23bda40f.tar.gz
custodia-0abd2a6c4ac66b905430d3cad95c1b2a23bda40f.tar.xz
custodia-0abd2a6c4ac66b905430d3cad95c1b2a23bda40f.zip
Add Authentication module for Kubernetes node
This authentication module connects to docker to figure out the pod name associated to the PID requesting the service by ay of discovering the container id via the process cgroup namespace. The pod name as set in the metadata label named 'io.kubernetes.pod.name' is then used as the 'remote_user' attribute on the request. Signed-off-by: Simo Sorce <simo@redhat.com>
-rw-r--r--custodia/kubernetes/__init__.py0
-rw-r--r--custodia/kubernetes/node.py73
-rwxr-xr-xsetup.py2
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
diff --git a/setup.py b/setup.py
index bda7db2..a24c8d7 100755
--- a/setup.py
+++ b/setup.py
@@ -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']),