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:
David Levanon
2022-02-16 15:34:51 +02:00
committed by GitHub
parent 72df652f6b
commit 87ef469e25
36 changed files with 2166 additions and 14 deletions

View 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
}
}