mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-09-19 00:50:32 +00:00
Add tls tapper (#683)
* initial tls tapper commit * add tls flag to mizu cli * support ssl_read_ex/ssl_write_ex * use hostproc to find libssl * auto discover tls processes * support libssl1.0 * recompile ebpf with old clang/llvm * Update tap/passive_tapper.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * Update tap/tlstapper/tls_poller.go Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> * upgrade ebpf go lib * handling big tls messages * fixing max buffer size in ebpf * remove unused import * fix linter issues * minor pr fixes * compile with old clang * fix cgroup file format * pr fixes + cgroup extract enhance * fix linter * adding indirect ebpf dep to agent go.mod * adding ebpf docker builder * minor pr fixes * add req resp matcher to dissect * rename ssl hooks to ssl hooks structs * move to alpine, use local copy of mizu instead of git, add readme * use global req resp mather for tls Co-authored-by: M. Mert Yıldıran <mehmet@up9.com> Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com>
This commit is contained in:
143
tap/tlstapper/tls_process_discoverer.go
Normal file
143
tap/tlstapper/tls_process_discoverer.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package tlstapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/up9inc/mizu/shared/logger"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
var numberRegex = regexp.MustCompile("[0-9]+")
|
||||
|
||||
func UpdateTapTargets(tls *TlsTapper, pods *[]v1.Pod, procfs string) error {
|
||||
containerIds := buildContainerIdsMap(pods)
|
||||
containerPids, err := findContainerPids(procfs, containerIds)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pid := range containerPids {
|
||||
if err := tls.AddPid(procfs, pid); err != nil {
|
||||
LogError(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func findContainerPids(procfs string, containerIds map[string]bool) ([]uint32, error) {
|
||||
result := make([]uint32, 0)
|
||||
|
||||
pids, err := ioutil.ReadDir(procfs)
|
||||
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
logger.Log.Infof("Starting tls auto discoverer %v %v - scanning %v potential pids",
|
||||
procfs, containerIds, len(pids))
|
||||
|
||||
for _, pid := range pids {
|
||||
if !pid.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !numberRegex.MatchString(pid.Name()) {
|
||||
continue
|
||||
}
|
||||
|
||||
cgroup, err := getProcessCgroup(procfs, pid.Name())
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := containerIds[cgroup]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
pidNumber, err := strconv.Atoi(pid.Name())
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, uint32(pidNumber))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func buildContainerIdsMap(pods *[]v1.Pod) map[string]bool {
|
||||
result := make(map[string]bool)
|
||||
|
||||
for _, pod := range *pods {
|
||||
for _, container := range pod.Status.ContainerStatuses {
|
||||
url, err := url.Parse(container.ContainerID)
|
||||
|
||||
if err != nil {
|
||||
logger.Log.Warningf("Expecting URL like container ID %v", container.ContainerID)
|
||||
continue
|
||||
}
|
||||
|
||||
result[url.Host] = true
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func getProcessCgroup(procfs string, pid string) (string, error) {
|
||||
filePath := fmt.Sprintf("%s/%s/cgroup", procfs, pid)
|
||||
|
||||
bytes, err := ioutil.ReadFile(filePath)
|
||||
|
||||
if err != nil {
|
||||
logger.Log.Warningf("Error reading cgroup file %s - %v", filePath, err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(bytes), "\n")
|
||||
cgrouppath := extractCgroup(lines)
|
||||
|
||||
if cgrouppath == "" {
|
||||
return "", errors.Errorf("Cgroup path not found for %s, %s", pid, lines)
|
||||
}
|
||||
|
||||
return normalizeCgroup(cgrouppath), nil
|
||||
}
|
||||
|
||||
func extractCgroup(lines []string) string {
|
||||
if len(lines) == 1 {
|
||||
parts := strings.Split(lines[0], ":")
|
||||
return parts[len(parts)-1]
|
||||
} else {
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, ":pids:") {
|
||||
parts := strings.Split(line, ":")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func normalizeCgroup(cgrouppath string) string {
|
||||
basename := strings.TrimSpace(path.Base(cgrouppath))
|
||||
|
||||
if strings.Contains(basename, ".") {
|
||||
return strings.TrimSuffix(basename, filepath.Ext(basename))
|
||||
} else {
|
||||
return basename
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user