summaryrefslogtreecommitdiffstats
path: root/custodia/kubernetes/node.py
blob: 5d4f8635d9d4aae6e1e1822c04a65c2e076e4f93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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