Compare commits

..

10 Commits

Author SHA1 Message Date
Alon Girmonsky
62912d248d for mac os compatibility 2025-02-10 13:53:42 -08:00
Alon Girmonsky
be8136687b 🔖 Bump the Helm chart version to 52.4.0 2025-02-05 12:15:19 -08:00
Volodymyr Stoiko
3d4606d439 Worker component security context refactoring (#1707)
* Add new security context config

* Fine-grained template for securityContext

---------

Co-authored-by: Alon Girmonsky <1990761+alongir@users.noreply.github.com>
2025-02-03 13:38:41 -08:00
Ilya Gavrilov
46ca7e3ad7 Remove init container; remove -disable-ebpf option (#1706)
* Remove init container; remove -disable-ebpf option

* Remove init container; remove -disable-ebpf option
2025-02-03 08:58:32 -08:00
Alon Girmonsky
e9796bfb24 Readme updated (#1705)
* Update README.md

* Update README.md
2025-01-29 14:05:00 -08:00
Volodymyr Stoiko
ce7913ce2e Fix pull secret aligning (#1703)
* Fix pull secret aligning

* align
2025-01-29 08:34:43 -08:00
bogdanvbalan
8f6ef686de Refactor and simplify pcapdump logic (#1701)
* Fix spammy logs

* Fix err related to value missing from pcap config

* Test target dir only when provided

* Improve consistency of error handling

* Remove obsolete code

---------

Co-authored-by: bogdan.balan1 <bogdanvalentin.balan@1nce.com>
2025-01-27 13:42:59 -08:00
M. Mert Yildiran
f2e60cdee1 Add PortMapping to TapConfig for port number based dissector prioritization (#1700) 2025-01-25 12:10:53 -08:00
Alon Girmonsky
67aa1dac39 Automatic patch updates
Update Makefile to include the Minor version in the Chart.yaml
in support for automatic patch updates.
2025-01-24 14:54:19 -08:00
Alon Girmonsky
818a9e2bec Moving to eBPF as a default packet capture method.
Making default packet capture method eBPF, defaulting to AF_PACKET in case eBPF is not available
2025-01-24 14:24:02 -08:00
13 changed files with 531 additions and 416 deletions

View File

@@ -182,24 +182,21 @@ release:
@cd ../tracer && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../hub && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../front && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../kubeshark && git checkout master && git pull && sed -i 's/^version:.*/version: "$(VERSION)"/' helm-chart/Chart.yaml && make && make generate-helm-values && make generate-manifests
@cd ../kubeshark && git checkout master && git pull && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make
@if [ "$(shell uname)" = "Darwin" ]; then \
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
fi
@make generate-helm-values && make generate-manifests
@git add -A . && git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)" && git push
@git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd helm-chart && cp -r . ../../kubeshark.github.io/charts/chart
@cd helm-chart && rm -r ../../kubeshark.github.io/charts/chart/* && cp -r . ../../kubeshark.github.io/charts/chart
@cd ../../kubeshark.github.io/ && git add -A . && git commit -m ":sparkles: Update the Helm chart" && git push
@cd ../kubeshark
soft-release:
@cd ../worker && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../tracer && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../hub && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../front && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../kubeshark && git checkout master && git pull && sed -i 's/^version:.*/version: "$(VERSION)"/' helm-chart/Chart.yaml && make && make generate-helm-values && make generate-manifests
@git add -A . && git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)" && git push
# @git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
# @cd helm-chart && cp -r . ../../kubeshark.github.io/charts/chart
# @cd ../../kubeshark.github.io/ && git add -A . && git commit -m ":sparkles: Update the Helm chart" && git push
# @cd ../kubeshark
release-dry-run:
@cd ../kubeshark && git checkout master && git pull && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make && make generate-helm-values && make generate-manifests
@cd helm-chart && rm -r ../../kubeshark.github.io/charts/chart/* && cp -r . ../../kubeshark.github.io/charts/chart
@cd ../kubeshark
branch:
@cd ../worker && git checkout master && git pull && git checkout -b $(name); git push --set-upstream origin $(name)

View File

@@ -12,7 +12,7 @@
<a href="https://hub.docker.com/r/kubeshark/worker">
<img alt="Image size" src="https://img.shields.io/docker/image-size/kubeshark/kubeshark/latest?logo=Docker&style=flat-square">
</a>
<a href="https://discord.gg/WkvRGMUcx7">
<a href="https://discord.gg/WkvRGMUcx7">
<img alt="Discord" src="https://img.shields.io/discord/1042559155224973352?logo=Discord&style=flat-square&label=discord">
</a>
<a href="https://join.slack.com/t/kubeshark/shared_invite/zt-1m90td3n7-VHxN_~V5kVp80SfQW3SfpA">
@@ -22,60 +22,75 @@
<p align="center">
<b>
Want to see Kubeshark in action, right now? Visit this
<a href="https://demo.kubeshark.co/">live demo deployment</a> of Kubeshark.
Want to see Kubeshark in action right now? Visit this
<a href="https://demo.kubeshark.co/">live demo deployment</a> of Kubeshark.
</b>
</p>
**Kubeshark** is an API Traffic Analyzer for [**Kubernetes**](https://kubernetes.io/) providing real-time, protocol-level visibility into Kubernetes internal network, capturing and monitoring all traffic and payloads going in, out and across containers, pods, nodes and clusters.
**Kubeshark** is a network observability platform for [**Kubernetes**](https://kubernetes.io/), providing real-time, protocol-level visibility into Kubernetes network. It enables users to inspect all internal and external cluster connections, API calls, and data in transit. Additionally, Kubeshark detects suspicious network behaviors, triggers automated actions, and provides deep insights into the network.
![Simple UI](https://github.com/kubeshark/assets/raw/master/png/kubeshark-ui.png)
Think [TCPDump](https://en.wikipedia.org/wiki/Tcpdump) and [Wireshark](https://www.wireshark.org/) re-invented for Kubernetes
Think [TCPDump](https://en.wikipedia.org/wiki/Tcpdump) and [Wireshark](https://www.wireshark.org/) reimagined for Kubernetes.
## Getting Started
Download **Kubeshark**'s binary distribution [latest release](https://github.com/kubeshark/kubeshark/releases/latest) and run following one of these examples:
```shell
kubeshark tap
```
```shell
kubeshark tap -n sock-shop "(catalo*|front-end*)"
```
Running any of the :point_up: above commands will open the [Web UI](https://docs.kubeshark.co/en/ui) in your browser which streams the traffic in your Kubernetes cluster in real-time.
Download **Kubeshark**'s binary distribution [latest release](https://github.com/kubeshark/kubeshark/releases/latest) or use one of the following methods to deploy **Kubeshark**. The [web-based dashboard](https://docs.kubeshark.co/en/ui) should open in your browser, showing a real-time view of your cluster's traffic.
### Homebrew
[Homebrew](https://brew.sh/) :beer: users install Kubeshark CLI with:
[Homebrew](https://brew.sh/) :beer: users can install the Kubeshark CLI with:
```shell
brew install kubeshark
kubeshark tap
```
To clean up:
```shell
kubeshark clean
```
### Helm
Add the helm repository and install the chart:
Add the Helm repository and install the chart:
```shell
helm repo add kubeshark https://helm.kubeshark.co
helm install kubeshark kubeshark/kubeshark
helm install kubeshark kubeshark/kubeshark
```
Follow the on-screen instructions how to connect to the dashboard.
To clean up:
```shell
helm uninstall kubeshark
```
## Building From Source
Clone this repository and run `make` command to build it. After the build is complete, the executable can be found at `./bin/kubeshark__`.
Clone this repository and run the `make` command to build it. After the build is complete, the executable can be found at `./bin/kubeshark`.
## Documentation
To learn more, read the [documentation](https://docs.kubeshark.co).
## Additional Use Cases
### Dump All Cluster-wide Traffic into a Single PCAP File
Record **all** cluster traffic and consolidate it into a single PCAP file (tcpdump-style).
Run Kubeshark to start capturing traffic:
```shell
kubeshark tap --set headless=true
```
> You can press `^C` to stop the command. Kubeshark will continue running in the background.
Take a snapshot of traffic (e.g., from the past 5 minutes):
```shell
kubeshark pcapdump --time 5m
```
> Read more [here](https://docs.kubeshark.co/en/pcapdump).
## Contributing
We :heart: pull requests! See [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution guide.
## Code of Conduct
This project is for everyone. We ask that our users and contributors take a few minutes to review our [Code of Conduct](CODE_OF_CONDUCT.md).

View File

@@ -2,11 +2,14 @@ package cmd
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
@@ -31,17 +34,23 @@ var pcapDumpCmd = &cobra.Command{
}
}
debugEnabled, _ := cmd.Flags().GetBool("debug")
if debugEnabled {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
log.Debug().Msg("Debug logging enabled")
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
// Use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
log.Error().Err(err).Msg("Error building kubeconfig")
return err
return fmt.Errorf("Error building kubeconfig: %w", err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Error().Err(err).Msg("Error creating Kubernetes client")
return err
return fmt.Errorf("Error creating Kubernetes client: %w", err)
}
// Parse the `--time` flag
@@ -50,19 +59,35 @@ var pcapDumpCmd = &cobra.Command{
if timeIntervalStr != "" {
duration, err := time.ParseDuration(timeIntervalStr)
if err != nil {
log.Error().Err(err).Msg("Invalid time interval")
return err
return fmt.Errorf("Invalid format %w", err)
}
tempCutoffTime := time.Now().Add(-duration)
cutoffTime = &tempCutoffTime
}
// Handle copy operation if the copy string is provided
// Test the dest dir if provided
destDir, _ := cmd.Flags().GetString(configStructs.PcapDest)
if destDir != "" {
info, err := os.Stat(destDir)
if os.IsNotExist(err) {
return fmt.Errorf("Directory does not exist: %s", destDir)
}
if err != nil {
return fmt.Errorf("Error checking dest directory: %w", err)
}
if !info.IsDir() {
return fmt.Errorf("Dest path is not a directory: %s", destDir)
}
tempFile, err := os.CreateTemp(destDir, "write-test-*")
if err != nil {
return fmt.Errorf("Directory %s is not writable", destDir)
}
_ = os.Remove(tempFile.Name())
}
log.Info().Msg("Copying PCAP files")
err = copyPcapFiles(clientset, config, destDir, cutoffTime)
if err != nil {
log.Error().Err(err).Msg("Error copying PCAP files")
return err
}
@@ -81,4 +106,5 @@ func init() {
pcapDumpCmd.Flags().String(configStructs.PcapTime, "", "Time interval (e.g., 10m, 1h) in the past for which the pcaps are copied")
pcapDumpCmd.Flags().String(configStructs.PcapDest, "", "Local destination path for copied PCAP files (can not be used together with --enabled)")
pcapDumpCmd.Flags().String(configStructs.PcapKubeconfig, "", "Path for kubeconfig (if not provided the default location will be checked)")
pcapDumpCmd.Flags().Bool("debug", false, "Enable debug logging")
}

View File

@@ -10,6 +10,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/kubeshark/gopacket/pcapgo"
@@ -23,20 +24,24 @@ import (
)
const (
label = "app.kubeshark.co/app=worker"
srcDir = "pcapdump"
label = "app.kubeshark.co/app=worker"
srcDir = "pcapdump"
maxSnaplen uint32 = 262144
maxTimePerFile = time.Minute * 5
)
// NamespaceFiles represents the namespace and the files found in that namespace.
type NamespaceFiles struct {
Namespace string // The namespace in which the files were found
SrcDir string // The source directory from which the files were listed
Files []string // List of files found in the namespace
// PodFileInfo represents information about a pod, its namespace, and associated files
type PodFileInfo struct {
Pod corev1.Pod
SrcDir string
Files []string
CopiedFiles []string
}
// listWorkerPods fetches all worker pods from multiple namespaces
func listWorkerPods(ctx context.Context, clientset *clientk8s.Clientset, namespaces []string) ([]corev1.Pod, error) {
var allPods []corev1.Pod
func listWorkerPods(ctx context.Context, clientset *clientk8s.Clientset, namespaces []string) ([]*PodFileInfo, error) {
var podFileInfos []*PodFileInfo
var errs []error
labelSelector := label
for _, namespace := range namespaces {
@@ -45,128 +50,30 @@ func listWorkerPods(ctx context.Context, clientset *clientk8s.Clientset, namespa
LabelSelector: labelSelector,
})
if err != nil {
return nil, fmt.Errorf("failed to list worker pods in namespace %s: %w", namespace, err)
}
// Accumulate the pods
allPods = append(allPods, pods.Items...)
}
return allPods, nil
}
// listFilesInPodDir lists all files in the specified directory inside the pod across multiple namespaces
func listFilesInPodDir(ctx context.Context, clientset *clientk8s.Clientset, config *rest.Config, podName string, namespaces []string, cutoffTime *time.Time) ([]NamespaceFiles, error) {
var namespaceFilesList []NamespaceFiles
for _, namespace := range namespaces {
// Attempt to get the pod in the current namespace
pod, err := clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})
if err != nil {
errs = append(errs, fmt.Errorf("failed to list worker pods in namespace %s: %w", namespace, err))
continue
}
nodeName := pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir)
cmd := []string{"ls", srcFilePath}
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(podName).
Namespace(namespace).
SubResource("exec").
Param("container", "sniffer").
Param("stdout", "true").
Param("stderr", "true").
Param("command", cmd[0]).
Param("command", cmd[1])
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
log.Error().Err(err).Msgf("failed to initialize executor for pod %s in namespace %s", podName, namespace)
continue
}
var stdoutBuf bytes.Buffer
var stderrBuf bytes.Buffer
// Execute the command to list files
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdout: &stdoutBuf,
Stderr: &stderrBuf,
})
if err != nil {
log.Error().Err(err).Msgf("error listing files in pod %s in namespace %s: %s", podName, namespace, stderrBuf.String())
continue
}
// Split the output (file names) into a list
files := strings.Split(strings.TrimSpace(stdoutBuf.String()), "\n")
if len(files) == 0 {
log.Info().Msgf("No files found in directory %s in pod %s", srcFilePath, podName)
continue
}
var filteredFiles []string
// Filter files based on cutoff time if provided
for _, file := range files {
if cutoffTime != nil {
parts := strings.Split(file, "-")
if len(parts) < 2 {
log.Warn().Msgf("Skipping file with invalid format: %s", file)
continue
}
timestampStr := parts[len(parts)-2] + parts[len(parts)-1][:6] // Extract YYYYMMDDHHMMSS
fileTime, err := time.Parse("20060102150405", timestampStr)
if err != nil {
log.Warn().Err(err).Msgf("Skipping file with unparsable timestamp: %s", file)
continue
}
if fileTime.Before(*cutoffTime) {
continue
}
}
// Add file to filtered list
filteredFiles = append(filteredFiles, file)
}
if len(filteredFiles) > 0 {
namespaceFilesList = append(namespaceFilesList, NamespaceFiles{
Namespace: namespace,
SrcDir: srcDir,
Files: filteredFiles,
for _, pod := range pods.Items {
podFileInfos = append(podFileInfos, &PodFileInfo{
Pod: pod,
})
}
}
if len(namespaceFilesList) == 0 {
return nil, fmt.Errorf("no files found in pod %s across the provided namespaces", podName)
}
return namespaceFilesList, nil
return podFileInfos, errors.Join(errs...)
}
// copyFileFromPod copies a single file from a pod to a local destination
func copyFileFromPod(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, podName, namespace, srcDir, srcFile, destFile string) error {
// Get the pod to retrieve its node name
pod, err := clientset.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("failed to get pod %s in namespace %s: %w", podName, namespace, err)
}
// listFilesInPodDir lists all files in the specified directory inside the pod across multiple namespaces
func listFilesInPodDir(ctx context.Context, clientset *clientk8s.Clientset, config *rest.Config, pod *PodFileInfo, cutoffTime *time.Time) error {
nodeName := pod.Pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir)
// Construct the complete path using /data, the node name, srcDir, and srcFile
nodeName := pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir, srcFile)
// Execute the `cat` command to read the file at the srcFilePath
cmd := []string{"cat", srcFilePath}
cmd := []string{"ls", srcFilePath}
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(podName).
Namespace(namespace).
Name(pod.Pod.Name).
Namespace(pod.Pod.Namespace).
SubResource("exec").
Param("container", "sniffer").
Param("stdout", "true").
@@ -176,7 +83,81 @@ func copyFileFromPod(ctx context.Context, clientset *kubernetes.Clientset, confi
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return fmt.Errorf("failed to initialize executor for pod %s in namespace %s: %w", podName, namespace, err)
return err
}
var stdoutBuf bytes.Buffer
var stderrBuf bytes.Buffer
// Execute the command to list files
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdout: &stdoutBuf,
Stderr: &stderrBuf,
})
if err != nil {
return err
}
// Split the output (file names) into a list
files := strings.Split(strings.TrimSpace(stdoutBuf.String()), "\n")
if len(files) == 0 {
// No files were found in the target dir for this pod
return nil
}
var filteredFiles []string
var fileProcessingErrs []error
// Filter files based on cutoff time if provided
for _, file := range files {
if cutoffTime != nil {
parts := strings.Split(file, "-")
if len(parts) < 2 {
continue
}
timestampStr := parts[len(parts)-2] + parts[len(parts)-1][:6] // Extract YYYYMMDDHHMMSS
fileTime, err := time.Parse("20060102150405", timestampStr)
if err != nil {
fileProcessingErrs = append(fileProcessingErrs, fmt.Errorf("failed parse file timestamp %s: %w", file, err))
continue
}
if fileTime.Before(*cutoffTime) {
continue
}
}
// Add file to filtered list
filteredFiles = append(filteredFiles, file)
}
pod.SrcDir = srcDir
pod.Files = filteredFiles
return errors.Join(fileProcessingErrs...)
}
// copyFileFromPod copies a single file from a pod to a local destination
func copyFileFromPod(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, pod *PodFileInfo, srcFile, destFile string) error {
// Construct the complete path using /data, the node name, srcDir, and srcFile
nodeName := pod.Pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir, srcFile)
// Execute the `cat` command to read the file at the srcFilePath
cmd := []string{"cat", srcFilePath}
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(pod.Pod.Name).
Namespace(pod.Pod.Namespace).
SubResource("exec").
Param("container", "sniffer").
Param("stdout", "true").
Param("stderr", "true").
Param("command", cmd[0]).
Param("command", cmd[1])
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return fmt.Errorf("failed to initialize executor for pod %s in namespace %s: %w", pod.Pod.Name, pod.Pod.Namespace, err)
}
// Create the local file to write the content to
@@ -195,7 +176,7 @@ func copyFileFromPod(ctx context.Context, clientset *kubernetes.Clientset, confi
Stderr: &stderrBuf,
})
if err != nil {
return fmt.Errorf("error copying file from pod %s in namespace %s: %s", podName, namespace, stderrBuf.String())
return err
}
return nil
@@ -209,29 +190,45 @@ func mergePCAPs(outputFile string, inputFiles []string) error {
}
defer f.Close()
bufWriter := bufio.NewWriter(f)
bufWriter := bufio.NewWriterSize(f, 4*1024*1024)
defer bufWriter.Flush()
// Create the PCAP writer
writer := pcapgo.NewWriter(bufWriter)
err = writer.WriteFileHeader(65536, 1)
err = writer.WriteFileHeader(maxSnaplen, 1)
if err != nil {
return fmt.Errorf("failed to write PCAP file header: %w", err)
}
var mergingErrs []error
for _, inputFile := range inputFiles {
// Open the input file
file, err := os.Open(inputFile)
if err != nil {
log.Error().Err(err).Msgf("Failed to open %v", inputFile)
mergingErrs = append(mergingErrs, fmt.Errorf("failed to open %s: %w", inputFile, err))
continue
}
fileInfo, err := file.Stat()
if err != nil {
mergingErrs = append(mergingErrs, fmt.Errorf("failed to stat file %s: %w", inputFile, err))
file.Close()
continue
}
if fileInfo.Size() == 0 {
// Skip empty files
log.Debug().Msgf("Skipped empty file: %s", inputFile)
file.Close()
continue
}
defer file.Close()
// Create the PCAP reader for the input file
reader, err := pcapgo.NewReader(file)
if err != nil {
log.Error().Err(err).Msgf("Failed to create pcapng reader for %v", file.Name())
mergingErrs = append(mergingErrs, fmt.Errorf("failed to create pcapng reader for %v: %w", file.Name(), err))
file.Close()
continue
}
@@ -242,7 +239,7 @@ func mergePCAPs(outputFile string, inputFiles []string) error {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
break
}
log.Error().Err(err).Msgf("Error reading packet from file %s", inputFile)
mergingErrs = append(mergingErrs, fmt.Errorf("error reading packet from file %s: %w", file.Name(), err))
break
}
@@ -250,19 +247,23 @@ func mergePCAPs(outputFile string, inputFiles []string) error {
err = writer.WritePacket(ci, data)
if err != nil {
log.Error().Err(err).Msgf("Error writing packet to output file")
mergingErrs = append(mergingErrs, fmt.Errorf("error writing packet to output file: %w", err))
break
}
}
file.Close()
}
log.Debug().Err(errors.Join(mergingErrs...))
return nil
}
// copyPcapFiles function for copying the PCAP files from the worker pods
func copyPcapFiles(clientset *kubernetes.Clientset, config *rest.Config, destDir string, cutoffTime *time.Time) error {
// List all namespaces
namespaceList, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Error().Err(err).Msg("Error listing namespaces")
return err
}
@@ -271,76 +272,87 @@ func copyPcapFiles(clientset *kubernetes.Clientset, config *rest.Config, destDir
targetNamespaces = append(targetNamespaces, ns.Name)
}
// List worker pods
// List all worker pods
workerPods, err := listWorkerPods(context.Background(), clientset, targetNamespaces)
if err != nil {
log.Warn().Err(err).Msg("Error listing worker pods")
return err
}
var currentFiles []string
// Iterate over each pod to get the PCAP directory from config and copy files
for _, pod := range workerPods {
// Get the list of NamespaceFiles (files per namespace) and their source directories
namespaceFiles, err := listFilesInPodDir(context.Background(), clientset, config, pod.Name, targetNamespaces, cutoffTime)
if err != nil {
log.Warn().Err(err).Send()
continue
if len(workerPods) == 0 {
return err
}
log.Debug().Err(err).Msg("error while listing worker pods")
}
// Copy each file from the pod to the local destination for each namespace
for _, nsFiles := range namespaceFiles {
for _, file := range nsFiles.Files {
var wg sync.WaitGroup
// Launch a goroutine for each pod
for _, pod := range workerPods {
wg.Add(1)
go func(pod *PodFileInfo) {
defer wg.Done()
// List files for the current pod
err := listFilesInPodDir(context.Background(), clientset, config, pod, cutoffTime)
if err != nil {
log.Debug().Err(err).Msgf("error listing files in pod %s", pod.Pod.Name)
return
}
// Copy files from the pod
for _, file := range pod.Files {
destFile := filepath.Join(destDir, file)
// Pass the correct namespace and related details to the function
err = copyFileFromPod(context.Background(), clientset, config, pod.Name, nsFiles.Namespace, nsFiles.SrcDir, file, destFile)
// Add a timeout context for file copy
ctx, cancel := context.WithTimeout(context.Background(), maxTimePerFile)
err := copyFileFromPod(ctx, clientset, config, pod, file, destFile)
cancel()
if err != nil {
log.Error().Err(err).Msgf("Error copying file from pod %s in namespace %s", pod.Name, nsFiles.Namespace)
} else {
log.Info().Msgf("Copied %s from %s to %s", file, pod.Name, destFile)
log.Debug().Err(err).Msgf("error copying file %s from pod %s in namespace %s", file, pod.Pod.Name, pod.Pod.Namespace)
continue
}
currentFiles = append(currentFiles, destFile)
log.Info().Msgf("Copied file %s from pod %s to %s", file, pod.Pod.Name, destFile)
pod.CopiedFiles = append(pod.CopiedFiles, destFile)
}
}
}(pod)
}
if len(currentFiles) == 0 {
log.Error().Msgf("No files to merge")
// Wait for all goroutines to complete
wg.Wait()
var copiedFiles []string
for _, pod := range workerPods {
copiedFiles = append(copiedFiles, pod.CopiedFiles...)
}
if len(copiedFiles) == 0 {
log.Info().Msg("No pcaps available to copy on the workers")
return nil
// continue
}
// Generate a temporary filename based on the first file
tempMergedFile := currentFiles[0] + "_temp"
// Generate a temporary filename for the merged file
tempMergedFile := copiedFiles[0] + "_temp"
// Merge the PCAPs into the temporary file
err = mergePCAPs(tempMergedFile, currentFiles)
// Merge PCAP files
err = mergePCAPs(tempMergedFile, copiedFiles)
if err != nil {
log.Error().Err(err).Msgf("Error merging files")
return err
// continue
os.Remove(tempMergedFile)
return fmt.Errorf("error merging files: %w", err)
}
// Remove the original files after merging
for _, file := range currentFiles {
err := os.Remove(file)
if err != nil {
log.Error().Err(err).Msgf("Error removing file %s", file)
for _, file := range copiedFiles {
if err := os.Remove(file); err != nil {
log.Debug().Err(err).Msgf("error removing file %s", file)
}
}
// Rename the temp file to the final name (removing "_temp")
// Rename the temp file to the final name
finalMergedFile := strings.TrimSuffix(tempMergedFile, "_temp")
err = os.Rename(tempMergedFile, finalMergedFile)
if err != nil {
log.Error().Err(err).Msgf("Error renaming merged file %s", tempMergedFile)
// continue
return err
}
log.Info().Msgf("Merged file created: %s", finalMergedFile)
return nil
}

View File

@@ -51,31 +51,35 @@ func CreateDefaultConfig() ConfigStruct {
},
},
},
Capabilities: configStructs.CapabilitiesConfig{
NetworkCapture: []string{
// NET_RAW is required to listen the network traffic
"NET_RAW",
// NET_ADMIN is required to listen the network traffic
"NET_ADMIN",
},
ServiceMeshCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// DAC_OVERRIDE is required to read /proc/PID/environ
"DAC_OVERRIDE",
},
EBPFCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// SYS_RESOURCE is required to change rlimits for eBPF
"SYS_RESOURCE",
// IPC_LOCK is required for ebpf perf buffers allocations after some amount of size buffer size:
// https://github.com/kubeshark/tracer/blob/13e24725ba8b98216dd0e553262e6d9c56dce5fa/main.go#L82)
"IPC_LOCK",
SecurityContext: configStructs.SecurityContextConfig{
Privileged: true,
// Capabilities used only when running in unprivileged mode
Capabilities: configStructs.CapabilitiesConfig{
NetworkCapture: []string{
// NET_RAW is required to listen the network traffic
"NET_RAW",
// NET_ADMIN is required to listen the network traffic
"NET_ADMIN",
},
ServiceMeshCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// DAC_OVERRIDE is required to read /proc/PID/environ
"DAC_OVERRIDE",
},
EBPFCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// SYS_RESOURCE is required to change rlimits for eBPF
"SYS_RESOURCE",
// IPC_LOCK is required for ebpf perf buffers allocations after some amount of size buffer size:
// https://github.com/kubeshark/tracer/blob/13e24725ba8b98216dd0e553262e6d9c56dce5fa/main.go#L82)
"IPC_LOCK",
},
},
},
Auth: configStructs.AuthConfig{
@@ -115,6 +119,14 @@ func CreateDefaultConfig() ConfigStruct {
"radius",
"diameter",
},
PortMapping: configStructs.PortMapping{
HTTP: []uint16{80, 443, 8080},
AMQP: []uint16{5671, 5672},
KAFKA: []uint16{9092},
REDIS: []uint16{6379},
LDAP: []uint16{389},
DIAMETER: []uint16{3868},
},
},
}
}

View File

@@ -238,6 +238,36 @@ type PcapDumpConfig struct {
PcapMaxTime string `yaml:"maxTime" json:"maxTime" default:"1h"`
PcapMaxSize string `yaml:"maxSize" json:"maxSize" default:"500MB"`
PcapTime string `yaml:"time" json:"time" default:"time"`
PcapDebug bool `yaml:"debug" json:"debug" default:"false"`
PcapDest string `yaml:"dest" json:"dest" default:""`
}
type PortMapping struct {
HTTP []uint16 `yaml:"http" json:"http"`
AMQP []uint16 `yaml:"amqp" json:"amqp"`
KAFKA []uint16 `yaml:"kafka" json:"kafka"`
REDIS []uint16 `yaml:"redis" json:"redis"`
LDAP []uint16 `yaml:"ldap" json:"ldap"`
DIAMETER []uint16 `yaml:"diameter" json:"diameter"`
}
type SecurityContextConfig struct {
Privileged bool `yaml:"privileged" json:"privileged" default:"true"`
AppArmorProfile AppArmorProfileConfig `yaml:"appArmorProfile" json:"appArmorProfile"`
SeLinuxOptions SeLinuxOptionsConfig `yaml:"seLinuxOptions" json:"seLinuxOptions"`
Capabilities CapabilitiesConfig `yaml:"capabilities" json:"capabilities"`
}
type AppArmorProfileConfig struct {
Type string `yaml:"type" json:"type"`
LocalhostProfile string `yaml:"localhostProfile" json:"localhostProfile"`
}
type SeLinuxOptionsConfig struct {
Level string `yaml:"level" json:"level"`
Role string `yaml:"role" json:"role"`
Type string `yaml:"type" json:"type"`
User string `yaml:"user" json:"user"`
}
type TapConfig struct {
@@ -275,13 +305,14 @@ type TapConfig struct {
Sentry SentryConfig `yaml:"sentry" json:"sentry"`
DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter" default:"!dns and !error"`
LiveConfigMapChangesDisabled bool `yaml:"liveConfigMapChangesDisabled" json:"liveConfigMapChangesDisabled" default:"false"`
Capabilities CapabilitiesConfig `yaml:"capabilities" json:"capabilities"`
GlobalFilter string `yaml:"globalFilter" json:"globalFilter" default:""`
EnabledDissectors []string `yaml:"enabledDissectors" json:"enabledDissectors"`
PortMapping PortMapping `yaml:"portMapping" json:"portMapping"`
CustomMacros map[string]string `yaml:"customMacros" json:"customMacros" default:"{\"https\":\"tls and (http or http2)\"}"`
Metrics MetricsConfig `yaml:"metrics" json:"metrics"`
Pprof PprofConfig `yaml:"pprof" json:"pprof"`
Misc MiscConfig `yaml:"misc" json:"misc"`
SecurityContext SecurityContextConfig `yaml:"securityContext" json:"securityContext"`
}
func (config *TapConfig) PodRegex() *regexp.Regexp {

View File

@@ -1,6 +1,6 @@
apiVersion: v2
name: kubeshark
version: "52.3.96"
version: "52.4"
description: The API Traffic Analyzer for Kubernetes
home: https://kubeshark.co
keywords:

View File

@@ -58,12 +58,6 @@ spec:
image: '{{ .Values.tap.docker.registry }}/hub:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
readinessProbe:
periodSeconds: {{ .Values.tap.probes.hub.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.hub.failureThreshold }}
@@ -97,6 +91,12 @@ spec:
- name: saml-x509-volume
mountPath: "/etc/saml/x509"
readOnly: true
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- if gt (len .Values.tap.nodeSelectorTerms.hub) 0}}
affinity:
nodeAffinity:

View File

@@ -74,12 +74,6 @@ spec:
image: '{{ .Values.tap.docker.registry }}/front:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
name: kubeshark-front
livenessProbe:
periodSeconds: 1
@@ -108,6 +102,12 @@ spec:
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
readOnly: true
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- if gt (len .Values.tap.nodeSelectorTerms.front) 0}}
affinity:
nodeAffinity:

View File

@@ -25,39 +25,26 @@ spec:
name: kubeshark-worker-daemon-set
namespace: kubeshark
spec:
{{- if .Values.tap.mountBpf }}
initContainers:
- command:
- /bin/sh
- -c
- mkdir -p /sys/fs/bpf && mount | grep -q '/sys/fs/bpf' || mount -t bpf bpf /sys/fs/bpf
{{- if .Values.tap.docker.overrideTag.worker }}
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: check-bpf
name: mount-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
mountPropagation: Bidirectional
- command:
- ./tracer
- -init-bpf
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: init-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
{{- end }}
containers:
- command:
- ./worker
@@ -71,9 +58,7 @@ spec:
- '{{ .Values.tap.packetCapture }}'
- -loglevel
- '{{ .Values.logLevel | default "warning" }}'
{{- if .Values.tap.tls }}
- -unixsocket
{{- else }}
{{- if not .Values.tap.tls }}
- -disable-tracer
{{- end }}
{{- if .Values.tap.serviceMesh }}
@@ -81,9 +66,6 @@ spec:
{{- end }}
- -procfs
- /hostproc
{{- if ne .Values.tap.packetCapture "ebpf" }}
- -disable-ebpf
{{- end }}
{{- if .Values.tap.resourceGuard.enabled }}
- -enable-resource-guard
{{- end }}
@@ -147,23 +129,52 @@ spec:
memory: {{ .Values.tap.resources.sniffer.requests.memory }}
{{ end }}
securityContext:
privileged: {{ .Values.tap.securityContext.privileged }}
{{- if not .Values.tap.securityContext.privileged }}
{{- $aaProfile := .Values.tap.securityContext.appArmorProfile }}
{{- $selinuxOpts := .Values.tap.securityContext.seLinuxOptions }}
{{- if or (ne $aaProfile.type "") (ne $aaProfile.localhostProfile "") }}
appArmorProfile:
{{- if ne $aaProfile.type "" }}
type: {{ $aaProfile.type }}
{{- end }}
{{- if ne $aaProfile.localhostProfile "" }}
localhostProfile: {{ $aaProfile.localhostProfile }}
{{- end }}
{{- end }}
{{- if or (ne $selinuxOpts.level "") (ne $selinuxOpts.role "") (ne $selinuxOpts.type "") (ne $selinuxOpts.user "") }}
seLinuxOptions:
{{- if ne $selinuxOpts.level "" }}
level: {{ $selinuxOpts.level }}
{{- end }}
{{- if ne $selinuxOpts.role "" }}
role: {{ $selinuxOpts.role }}
{{- end }}
{{- if ne $selinuxOpts.type "" }}
type: {{ $selinuxOpts.type }}
{{- end }}
{{- if ne $selinuxOpts.user "" }}
user: {{ $selinuxOpts.user }}
{{- end }}
{{- end }}
capabilities:
add:
{{- range .Values.tap.capabilities.networkCapture }}
{{- range .Values.tap.securityContext.capabilities.networkCapture }}
{{ print "- " . }}
{{- end }}
{{- if .Values.tap.serviceMesh }}
{{- range .Values.tap.capabilities.serviceMeshCapture }}
{{- range .Values.tap.securityContext.capabilities.serviceMeshCapture }}
{{ print "- " . }}
{{- end }}
{{- end }}
{{- if .Values.tap.capabilities.ebpfCapture }}
{{- range .Values.tap.capabilities.ebpfCapture }}
{{- if .Values.tap.securityContext.capabilities.ebpfCapture }}
{{- range .Values.tap.securityContext.capabilities.ebpfCapture }}
{{ print "- " . }}
{{- end }}
{{- end }}
drop:
- ALL
{{- end }}
readinessProbe:
periodSeconds: {{ .Values.tap.probes.sniffer.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.sniffer.failureThreshold }}
@@ -185,6 +196,7 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
{{- if .Values.tap.tls }}
@@ -192,9 +204,6 @@ spec:
- ./tracer
- -procfs
- /hostproc
{{- if ne .Values.tap.packetCapture "ebpf" }}
- -disable-ebpf
{{- end }}
{{- if .Values.tap.disableTlsLog }}
- -disable-tls-log
{{- end }}
@@ -202,20 +211,14 @@ spec:
- -port
- '{{ add .Values.tap.proxy.worker.srvPort 1 }}'
{{- end }}
# - -loglevel
# - '{{ .Values.logLevel | default "warning" }}'
- -loglevel
- '{{ .Values.logLevel | default "warning" }}'
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
name: tracer
env:
- name: POD_NAME
@@ -248,16 +251,45 @@ spec:
memory: {{ .Values.tap.resources.tracer.requests.memory }}
{{ end }}
securityContext:
privileged: {{ .Values.tap.securityContext.privileged }}
{{- if not .Values.tap.securityContext.privileged }}
{{- $aaProfile := .Values.tap.securityContext.appArmorProfile }}
{{- $selinuxOpts := .Values.tap.securityContext.seLinuxOptions }}
{{- if or (ne $aaProfile.type "") (ne $aaProfile.localhostProfile "") }}
appArmorProfile:
{{- if ne $aaProfile.type "" }}
type: {{ $aaProfile.type }}
{{- end }}
{{- if ne $aaProfile.localhostProfile "" }}
localhostProfile: {{ $aaProfile.localhostProfile }}
{{- end }}
{{- end }}
{{- if or (ne $selinuxOpts.level "") (ne $selinuxOpts.role "") (ne $selinuxOpts.type "") (ne $selinuxOpts.user "") }}
seLinuxOptions:
{{- if ne $selinuxOpts.level "" }}
level: {{ $selinuxOpts.level }}
{{- end }}
{{- if ne $selinuxOpts.role "" }}
role: {{ $selinuxOpts.role }}
{{- end }}
{{- if ne $selinuxOpts.type "" }}
type: {{ $selinuxOpts.type }}
{{- end }}
{{- if ne $selinuxOpts.user "" }}
user: {{ $selinuxOpts.user }}
{{- end }}
{{- end }}
capabilities:
add:
{{- range .Values.tap.capabilities.ebpfCapture }}
{{- range .Values.tap.securityContext.capabilities.ebpfCapture }}
{{ print "- " . }}
{{- end }}
{{- range .Values.tap.capabilities.networkCapture }}
{{- range .Values.tap.securityContext.capabilities.networkCapture }}
{{ print "- " . }}
{{- end }}
drop:
- ALL
{{- end }}
volumeMounts:
- mountPath: /hostproc
name: proc
@@ -265,6 +297,7 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- mountPath: /etc/os-release
@@ -286,6 +319,12 @@ spec:
- effect: NoSchedule
operator: Exists
{{- end }}
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- if gt (len .Values.tap.nodeSelectorTerms.workers) 0}}
affinity:
nodeAffinity:

View File

@@ -56,4 +56,5 @@ data:
PCAP_DUMP_ENABLE: '{{ .Values.pcapdump.enabled }}'
PCAP_TIME_INTERVAL: '{{ .Values.pcapdump.timeInterval }}'
PCAP_MAX_TIME: '{{ .Values.pcapdump.maxTime }}'
PCAP_MAX_SIZE: '{{ .Values.pcapdump.maxSize }}'
PCAP_MAX_SIZE: '{{ .Values.pcapdump.maxSize }}'
PORT_MAPPING: '{{ toJson .Values.tap.portMapping }}'

View File

@@ -137,19 +137,6 @@ tap:
environment: production
defaultFilter: "!dns and !error"
liveConfigMapChangesDisabled: false
capabilities:
networkCapture:
- NET_RAW
- NET_ADMIN
serviceMeshCapture:
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
ebpfCapture:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
globalFilter: ""
enabledDissectors:
- amqp
@@ -164,6 +151,22 @@ tap:
- ldap
- radius
- diameter
portMapping:
http:
- 80
- 443
- 8080
amqp:
- 5671
- 5672
kafka:
- 9092
redis:
- 6379
ldap:
- 389
diameter:
- 3868
customMacros:
https: tls and (http or http2)
metrics:
@@ -183,6 +186,29 @@ tap:
duplicateTimeframe: 200ms
detectDuplicates: false
staleTimeoutSeconds: 30
securityContext:
privileged: true
appArmorProfile:
type: ""
localhostProfile: ""
seLinuxOptions:
level: ""
role: ""
type: ""
user: ""
capabilities:
networkCapture:
- NET_RAW
- NET_ADMIN
serviceMeshCapture:
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
ebpfCapture:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
logs:
file: ""
grep: ""
@@ -192,6 +218,8 @@ pcapdump:
maxTime: 1h
maxSize: 500MB
time: time
debug: false
dest: ""
kube:
configPath: ""
context: ""

View File

@@ -4,10 +4,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub-network-policy
@@ -34,10 +34,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front-network-policy
@@ -61,10 +61,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-worker-network-policy
@@ -90,10 +90,10 @@ apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-service-account
@@ -107,10 +107,10 @@ metadata:
namespace: default
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
stringData:
LICENSE: ''
@@ -124,10 +124,10 @@ metadata:
namespace: default
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_CRT: |
@@ -140,10 +140,10 @@ metadata:
namespace: default
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_KEY: |
@@ -155,10 +155,10 @@ metadata:
name: kubeshark-nginx-config-map
namespace: default
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
data:
default.conf: |
@@ -219,10 +219,10 @@ metadata:
namespace: default
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
data:
POD_REGEX: '.*'
@@ -263,16 +263,17 @@ data:
PCAP_TIME_INTERVAL: '1m'
PCAP_MAX_TIME: '1h'
PCAP_MAX_SIZE: '500MB'
PORT_MAPPING: '{"amqp":[5671,5672],"diameter":[3868],"http":[80,443,8080],"kafka":[9092],"ldap":[389],"redis":[6379]}'
---
# Source: kubeshark/templates/02-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-cluster-role-default
@@ -317,10 +318,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-cluster-role-binding-default
@@ -339,10 +340,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role
@@ -369,10 +370,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role-binding
@@ -392,10 +393,10 @@ kind: Service
metadata:
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub
@@ -414,10 +415,10 @@ apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front
@@ -436,10 +437,10 @@ kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
@@ -449,10 +450,10 @@ metadata:
spec:
selector:
app.kubeshark.co/app: worker
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
@@ -465,10 +466,10 @@ kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
@@ -478,10 +479,10 @@ metadata:
spec:
selector:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
@@ -496,10 +497,10 @@ metadata:
labels:
app.kubeshark.co/app: worker
sidecar.istio.io/inject: "false"
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-worker-daemon-set
@@ -514,39 +515,14 @@ spec:
metadata:
labels:
app.kubeshark.co/app: worker
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
name: kubeshark-worker-daemon-set
namespace: kubeshark
spec:
initContainers:
- command:
- /bin/sh
- -c
- mkdir -p /sys/fs/bpf && mount | grep -q '/sys/fs/bpf' || mount -t bpf bpf /sys/fs/bpf
image: 'docker.io/kubeshark/worker:v52.3.96'
imagePullPolicy: Always
name: check-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
mountPropagation: Bidirectional
- command:
- ./tracer
- -init-bpf
image: 'docker.io/kubeshark/worker:v52.3.96'
imagePullPolicy: Always
name: init-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
containers:
- command:
- ./worker
@@ -560,16 +536,14 @@ spec:
- 'best'
- -loglevel
- 'warning'
- -unixsocket
- -servicemesh
- -procfs
- /hostproc
- -disable-ebpf
- -resolution-strategy
- 'auto'
- -staletimeout
- '30'
image: 'docker.io/kubeshark/worker:v52.3.96'
image: 'docker.io/kubeshark/worker:v52.4'
imagePullPolicy: Always
name: sniffer
ports:
@@ -611,19 +585,7 @@ spec:
memory: 50Mi
securityContext:
capabilities:
add:
- NET_RAW
- NET_ADMIN
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
drop:
- ALL
privileged: true
readinessProbe:
periodSeconds: 10
failureThreshold: 3
@@ -645,17 +607,17 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- command:
- ./tracer
- -procfs
- /hostproc
- -disable-ebpf
- -disable-tls-log
# - -loglevel
# - 'warning'
image: 'docker.io/kubeshark/worker:v52.3.96'
- -loglevel
- 'warning'
image: 'docker.io/kubeshark/worker:v52.4'
imagePullPolicy: Always
name: tracer
env:
@@ -687,16 +649,7 @@ spec:
memory: 50Mi
securityContext:
capabilities:
add:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
- NET_RAW
- NET_ADMIN
drop:
- ALL
privileged: true
volumeMounts:
- mountPath: /hostproc
name: proc
@@ -704,6 +657,7 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- mountPath: /etc/os-release
@@ -757,10 +711,10 @@ kind: Deployment
metadata:
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub
@@ -776,10 +730,10 @@ spec:
metadata:
labels:
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
spec:
dnsPolicy: ClusterFirstWithHostNet
@@ -809,7 +763,7 @@ spec:
value: 'https://api.kubeshark.co'
- name: PROFILING_ENABLED
value: 'false'
image: 'docker.io/kubeshark/hub:v52.3.96'
image: 'docker.io/kubeshark/hub:v52.4'
imagePullPolicy: Always
readinessProbe:
periodSeconds: 10
@@ -872,10 +826,10 @@ kind: Deployment
metadata:
labels:
app.kubeshark.co/app: front
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front
@@ -891,10 +845,10 @@ spec:
metadata:
labels:
app.kubeshark.co/app: front
helm.sh/chart: kubeshark-52.3.96
helm.sh/chart: kubeshark-52.4
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.3.96"
app.kubernetes.io/version: "52.4"
app.kubernetes.io/managed-by: Helm
spec:
containers:
@@ -929,7 +883,7 @@ spec:
value: 'false'
- name: REACT_APP_SENTRY_ENVIRONMENT
value: 'production'
image: 'docker.io/kubeshark/front:v52.3.96'
image: 'docker.io/kubeshark/front:v52.4'
imagePullPolicy: Always
name: kubeshark-front
livenessProbe: