mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-09-27 05:23:06 +00:00
* 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>
178 lines
3.6 KiB
Go
178 lines
3.6 KiB
Go
package tlstapper
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
|
|
"github.com/cilium/ebpf/perf"
|
|
"github.com/cilium/ebpf/rlimit"
|
|
"github.com/go-errors/errors"
|
|
"github.com/up9inc/mizu/shared/logger"
|
|
)
|
|
|
|
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86
|
|
|
|
type TlsTapper struct {
|
|
bpfObjects tlsTapperObjects
|
|
syscallHooks syscallHooks
|
|
sslHooksStructs []sslHooks
|
|
reader *perf.Reader
|
|
}
|
|
|
|
func (t *TlsTapper) Init(bufferSize int) error {
|
|
logger.Log.Infof("Initializing tls tapper (bufferSize: %v)", bufferSize)
|
|
|
|
if err := setupRLimit(); err != nil {
|
|
return err
|
|
}
|
|
|
|
t.bpfObjects = tlsTapperObjects{}
|
|
|
|
if err := loadTlsTapperObjects(&t.bpfObjects, nil); err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
t.syscallHooks = syscallHooks{}
|
|
|
|
if err := t.syscallHooks.installSyscallHooks(&t.bpfObjects); err != nil {
|
|
return err
|
|
}
|
|
|
|
t.sslHooksStructs = make([]sslHooks, 0)
|
|
|
|
return t.initChunksReader(bufferSize)
|
|
}
|
|
|
|
func (t *TlsTapper) pollPerf(chunks chan<- *tlsChunk) {
|
|
logger.Log.Infof("Start polling for tls events")
|
|
|
|
for {
|
|
record, err := t.reader.Read()
|
|
|
|
if err != nil {
|
|
close(chunks)
|
|
|
|
if errors.Is(err, perf.ErrClosed) {
|
|
return
|
|
}
|
|
|
|
LogError(errors.Errorf("Error reading chunks from tls perf, aborting TLS! %v", err))
|
|
return
|
|
}
|
|
|
|
if record.LostSamples != 0 {
|
|
logger.Log.Infof("Buffer is full, dropped %d chunks", record.LostSamples)
|
|
continue
|
|
}
|
|
|
|
buffer := bytes.NewReader(record.RawSample)
|
|
|
|
var chunk tlsChunk
|
|
|
|
if err := binary.Read(buffer, binary.LittleEndian, &chunk); err != nil {
|
|
LogError(errors.Errorf("Error parsing chunk %v", err))
|
|
continue
|
|
}
|
|
|
|
chunks <- &chunk
|
|
}
|
|
}
|
|
|
|
func (t *TlsTapper) GlobalTap(sslLibrary string) error {
|
|
return t.tapPid(0, sslLibrary)
|
|
}
|
|
|
|
func (t *TlsTapper) AddPid(procfs string, pid uint32) error {
|
|
sslLibrary, err := findSsllib(procfs, pid)
|
|
|
|
if err != nil {
|
|
logger.Log.Infof("PID skipped no libssl.so found (pid: %d) %v", pid, err)
|
|
return nil // hide the error on purpose, its OK for a process to not use libssl.so
|
|
}
|
|
|
|
return t.tapPid(pid, sslLibrary)
|
|
}
|
|
|
|
func (t *TlsTapper) RemovePid(pid uint32) error {
|
|
logger.Log.Infof("Removing PID (pid: %v)", pid)
|
|
|
|
pids := t.bpfObjects.tlsTapperMaps.PidsMap
|
|
|
|
if err := pids.Delete(pid); err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (t *TlsTapper) Close() []error {
|
|
errors := make([]error, 0)
|
|
|
|
if err := t.bpfObjects.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
|
|
errors = append(errors, t.syscallHooks.close()...)
|
|
|
|
for _, sslHooks := range t.sslHooksStructs {
|
|
errors = append(errors, sslHooks.close()...)
|
|
}
|
|
|
|
if err := t.reader.Close(); err != nil {
|
|
errors = append(errors, err)
|
|
}
|
|
|
|
return errors
|
|
}
|
|
|
|
func setupRLimit() error {
|
|
err := rlimit.RemoveMemlock()
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (t *TlsTapper) initChunksReader(bufferSize int) error {
|
|
var err error
|
|
|
|
t.reader, err = perf.NewReader(t.bpfObjects.ChunksBuffer, bufferSize)
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (t *TlsTapper) tapPid(pid uint32, sslLibrary string) error {
|
|
logger.Log.Infof("Tapping TLS (pid: %v) (sslLibrary: %v)", pid, sslLibrary)
|
|
|
|
newSsl := sslHooks{}
|
|
|
|
if err := newSsl.installUprobes(&t.bpfObjects, sslLibrary); err != nil {
|
|
return err
|
|
}
|
|
|
|
t.sslHooksStructs = append(t.sslHooksStructs, newSsl)
|
|
|
|
pids := t.bpfObjects.tlsTapperMaps.PidsMap
|
|
|
|
if err := pids.Put(pid, uint32(1)); err != nil {
|
|
return errors.Wrap(err, 0)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func LogError(err error) {
|
|
var e *errors.Error
|
|
if errors.As(err, &e) {
|
|
logger.Log.Errorf("Error: %v", e.ErrorStack())
|
|
} else {
|
|
logger.Log.Errorf("Error: %v", err)
|
|
}
|
|
}
|