Skip to content

Commit

Permalink
Update container evidence names and enumeration report
Browse files Browse the repository at this point in the history
  • Loading branch information
aarontp committed Nov 16, 2023
1 parent abb1bf9 commit d006957
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
13 changes: 10 additions & 3 deletions turbinia/evidence.py
Original file line number Diff line number Diff line change
Expand Up @@ -1274,11 +1274,15 @@ class ContainerdContainer(Evidence):
REQUIRED_ATTRIBUTES = ['namespace', 'container_id']
POSSIBLE_STATES = [EvidenceState.CONTAINER_MOUNTED]

def __init__(self, namespace=None, container_id=None, *args, **kwargs):
def __init__(
self, namespace=None, container_id=None, image_name=None,
pod_name=None, *args, **kwargs):
"""Initialization of containerd container."""
super(ContainerdContainer, self).__init__(*args, **kwargs)
self.namespace = namespace
self.container_id = container_id
self.image_name = image_name if image_name else 'UnknownImageName'
self.pod_name = pod_name if pod_name else 'UnknownPodName'
self._image_path = None
self._container_fs_path = None

Expand All @@ -1290,9 +1294,12 @@ def name(self):
return self._name

if self.parent_evidence:
return ':'.join((self.parent_evidence.name, self.container_id))
return ':'.join((
self.parent_evidence.name, self.image_name,
self.pod_name, self.container_id))
else:
return ':'.join((self.type, self.container_id))
return ':'.join((
self.type, self.image_name, self.pod_name, self.container_id))

def _preprocess(self, _, required_states):
if EvidenceState.CONTAINER_MOUNTED in required_states:
Expand Down
37 changes: 24 additions & 13 deletions turbinia/workers/containerd.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

CE_BINARY = '/opt/container-explorer/bin/ce'
CE_SUPPORT_FILE = '/opt/container-explorer/etc/supportcontainer.yaml'
POD_NAME_LABEL = 'io.kubernetes.pod.name'


class ContainerdEnumerationTask(TurbiniaTask):
Expand All @@ -45,7 +46,7 @@ class ContainerdEnumerationTask(TurbiniaTask):
#
# Which k8 namespaces to filter out by default
'filter_namespaces': ['kube-system'],
'filter_containers': ['sidecar', 'k8s-sidecar', 'konnectivity-agent'],
'filter_pod_names': ['sidecar', 'k8s-sidecar', 'konnectivity-agent'],
# Taken from
# https://github.com/google/container-explorer/blob/main/supportcontainer.yaml
'filter_images': [
Expand Down Expand Up @@ -164,7 +165,7 @@ def run(self, evidence, result):
success = False
report_data = []
filter_namespaces = self.task_config.get('filter_namespaces')
filter_containers = self.task_config.get('filter_containers')
filter_pod_names = self.task_config.get('filter_pod_names')
filter_images = self.task_config.get('filter_images')
filtered_container_list = []

Expand All @@ -191,9 +192,14 @@ def run(self, evidence, result):
for container in containers:
namespace = container.get('Namespace')
container_id = container.get('ID')
container_name = container.get('Name')
if container.get('Labels'):
pod_name = container.get('Labels').get(POD_NAME_LABEL, 'UnknownPodName')
else:
pod_name = 'UnknownPodName'
container_type = container.get('ContainerType') or None
image = container.get('Image')
image_short = image.split('@')[0]
image_short = image_short.split(':')[0]

if not namespace or not container_id:
message = (
Expand All @@ -203,7 +209,10 @@ def run(self, evidence, result):
report_data.append(message)
continue

# Filter out configured namespaces/containers/images
# Filter out configured namespaces/containers/images. Even though we
# could let container explorer filter these before we get them we want
# to do it here so that we can report on what was available and filtered
# out to give the analyst the option to reprocess these containers.
if filter_namespaces:
if namespace in filter_namespaces:
message = (
Expand All @@ -214,17 +223,15 @@ def run(self, evidence, result):
filtered_container_list.append(container_id)
continue
if filter_images:
image_short = image.split('@')[0]
image_short = image_short.split(':')[0]
if image_short in filter_images:
message = (
f'Filtering out image {image} because image matches filter')
result.log(message)
report_data.append(message)
filtered_container_list.append(container_id)
continue
if filter_containers:
if container_name in filter_containers:
if filter_pod_names:
if pod_name in filter_pod_names:
message = (
f'Filtering out container {container_id} because container '
f'name matches filter')
Expand All @@ -242,23 +249,27 @@ def run(self, evidence, result):
continue

container_evidence = ContainerdContainer(
namespace=namespace, container_id=container_id)
namespace=namespace, container_id=container_id,
image_name=image_short, pod_name=pod_name)

result.add_evidence(container_evidence, evidence.config)
result.log(
f'Adding container evidence: id {container_id} '
f'name {container_name} type {container_type} image {image}')
f'Adding container evidence {container_evidence.name} '
f'type {container_type}')

summary = (
f'Found {len(container_ids)} containers: {", ".join(container_ids)}')
f'Found {len(container_ids)} containers, added '
f'{len(filtered_container_list)} (filtered out '
f'{len(container_ids) - len(filtered_container_list)}): '
f'{", ".join(filtered_container_list)}')
success = True
if filtered_container_list:
report_data.append(
f'Filtered out {len(filtered_container_list)} containers: '
f'{", ".join(filtered_container_list)}')
report_data.append(
f'Container filter lists: Namespaces: {filter_namespaces}, Images: {filter_images}, '
f'Containers: {filter_containers}')
f'Pod Names: {filter_pod_names}')
report_data.append(
'To process filtered containers, adjust the ContainerEnumeration '
'Task config filter* parameters with a recipe')
Expand Down

0 comments on commit d006957

Please sign in to comment.