mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-05-21 00:23:41 +00:00
* Show pod name and namespace (#61) * WIP * Update main.go, consts.go, and 2 more files... * Update messageSensitiveDataCleaner.go * Update consts.go and messageSensitiveDataCleaner.go * Update messageSensitiveDataCleaner.go * Update main.go, consts.go, and 3 more files... * WIP * Update main.go, messageSensitiveDataCleaner.go, and 6 more files... * Update main.go, messageSensitiveDataCleaner.go, and 3 more files... * Update consts.go, messageSensitiveDataCleaner.go, and tap.go * Update provider.go * Update serializableRegexp.go * Update tap.go * TRA-3234 fetch with _source + no hard limit (#64) * remove the HARD limit of 5000 * TRA-3299 Reduce footprint and Add Tolerances(#65) * Use lib const for DNSClusterFirstWithHostNet. * Whitespace. * Break lines. * Added affinity to pod names. * Added tolerations to NoExecute and NoSchedule taints. * Implementation of Mizu view command * . * . * Update main.go and messageSensitiveDataCleaner.go * Update main.go * String and not pointers (#68) * TRA-3318 - Cookies not null and fix har file names (#69) * no message * TRA-3212 Passive-Tapper and Mizu share code (#70) * Use log in tap package instead of fmt. * Moved api/pkg/tap to root. * Added go.mod and go.sum for tap. * Added replace for shared. * api uses tap module instead of tap package. * Removed dependency of tap in shared by moving env var out of tap. * Fixed compilation bugs. * Fixed: Forgot to export struct field HostMode. * Removed unused flag. * Close har output channel when done. * Moved websocket out of mizu and into passive-tapper. * Send connection details over har output channel. * Fixed compilation errors. * Removed unused info from request response cache. * Renamed connection -> connectionID. * Fixed rename bug. * Export setters and getters for filter ips and ports. * Added tap dependency to Dockerfile. * Uncomment error messages. * Renamed `filterIpAddresses` -> `filterAuthorities`. * Renamed ConnectionID -> ConnectionInfo. * Fixed: Missed one replace. * TRA-3342 Mizu/tap dump to har directory fails on Linux (#71) * Instead of saving incomplete temp har files in a temp dir, save them in the output dir with a *.har.tmp suffix. * API only loads har from *.har files (by extension). * Add export entries endpoint for better up9 connect funcionality (#72) * no message * no message * no message * Filter 'cookie' header * Release action (#73) * Create main.yml * Update main.yml * Update main.yml * Update main.yml * Update main.yml * trying new approach * no message * yaml error * no message * no message * no message * missing ) * no message * no message * remove main.yml and fix branches * Create tag-temp.yaml * Update tag-temp.yaml * Update tag-temp.yaml * no message * no message * no message * no message * no message * no message * no message * #minor * no message * no message * added checksum calc to CLI makefile * fixed build error - created bin directory upfront * using markdown for release text * use separate checksum files * fixed release readme * #minor * readme updated Co-authored-by: Alex Haiut <alex@up9.com> * TRA-3360 Fix: Mizu ignores -n namespace flag and records traffic from all pods (#75) Do not tap pods in namespaces which were not requested. * added apple/m1 binary, updated readme (#77) Co-authored-by: Alex Haiut <alex@up9.com> * Update README.md (#78) Co-authored-by: lirazyehezkel <61656597+lirazyehezkel@users.noreply.github.com> Co-authored-by: RamiBerm <rami.berman@up9.com> Co-authored-by: RamiBerm <54766858+RamiBerm@users.noreply.github.com> Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com> Co-authored-by: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Co-authored-by: Igor Gov <igor.govorov1@gmail.com> Co-authored-by: Alex Haiut <alex@up9.com>
169 lines
5.0 KiB
Go
169 lines
5.0 KiB
Go
package tap
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/google/gopacket"
|
|
"github.com/google/gopacket/layers" // pulls in all layers decoders
|
|
"github.com/google/gopacket/reassembly"
|
|
)
|
|
|
|
/* It's a connection (bidirectional)
|
|
* Implements gopacket.reassembly.Stream interface (Accept, ReassembledSG, ReassemblyComplete)
|
|
* ReassembledSG gets called when new reassembled data is ready (i.e. bytes in order, no duplicates, complete)
|
|
* In our implementation, we pass information from ReassembledSG to the httpReader through a shared channel.
|
|
*/
|
|
type tcpStream struct {
|
|
tcpstate *reassembly.TCPSimpleFSM
|
|
fsmerr bool
|
|
optchecker reassembly.TCPOptionCheck
|
|
net, transport gopacket.Flow
|
|
isDNS bool
|
|
isHTTP bool
|
|
reversed bool
|
|
client httpReader
|
|
server httpReader
|
|
urls []string
|
|
ident string
|
|
sync.Mutex
|
|
}
|
|
|
|
func (t *tcpStream) Accept(tcp *layers.TCP, ci gopacket.CaptureInfo, dir reassembly.TCPFlowDirection, nextSeq reassembly.Sequence, start *bool, ac reassembly.AssemblerContext) bool {
|
|
// FSM
|
|
if !t.tcpstate.CheckState(tcp, dir) {
|
|
SilentError("FSM-rejection", "%s: Packet rejected by FSM (state:%s)", t.ident, t.tcpstate.String())
|
|
stats.rejectFsm++
|
|
if !t.fsmerr {
|
|
t.fsmerr = true
|
|
stats.rejectConnFsm++
|
|
}
|
|
if !*ignorefsmerr {
|
|
return false
|
|
}
|
|
}
|
|
// Options
|
|
err := t.optchecker.Accept(tcp, ci, dir, nextSeq, start)
|
|
if err != nil {
|
|
SilentError("OptionChecker-rejection", "%s: Packet rejected by OptionChecker: %s", t.ident, err)
|
|
stats.rejectOpt++
|
|
if !*nooptcheck {
|
|
return false
|
|
}
|
|
}
|
|
// Checksum
|
|
accept := true
|
|
if *checksum {
|
|
c, err := tcp.ComputeChecksum()
|
|
if err != nil {
|
|
SilentError("ChecksumCompute", "%s: Got error computing checksum: %s", t.ident, err)
|
|
accept = false
|
|
} else if c != 0x0 {
|
|
SilentError("Checksum", "%s: Invalid checksum: 0x%x", t.ident, c)
|
|
accept = false
|
|
}
|
|
}
|
|
if !accept {
|
|
stats.rejectOpt++
|
|
}
|
|
return accept
|
|
}
|
|
|
|
func (t *tcpStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.AssemblerContext) {
|
|
dir, start, end, skip := sg.Info()
|
|
length, saved := sg.Lengths()
|
|
// update stats
|
|
sgStats := sg.Stats()
|
|
if skip > 0 {
|
|
stats.missedBytes += skip
|
|
}
|
|
stats.sz += length - saved
|
|
stats.pkt += sgStats.Packets
|
|
if sgStats.Chunks > 1 {
|
|
stats.reassembled++
|
|
}
|
|
stats.outOfOrderPackets += sgStats.QueuedPackets
|
|
stats.outOfOrderBytes += sgStats.QueuedBytes
|
|
if length > stats.biggestChunkBytes {
|
|
stats.biggestChunkBytes = length
|
|
}
|
|
if sgStats.Packets > stats.biggestChunkPackets {
|
|
stats.biggestChunkPackets = sgStats.Packets
|
|
}
|
|
if sgStats.OverlapBytes != 0 && sgStats.OverlapPackets == 0 {
|
|
// In the original example this was handled with panic().
|
|
// I don't know what this error means or how to handle it properly.
|
|
SilentError("Invalid-Overlap", "bytes:%d, pkts:%d", sgStats.OverlapBytes, sgStats.OverlapPackets)
|
|
}
|
|
stats.overlapBytes += sgStats.OverlapBytes
|
|
stats.overlapPackets += sgStats.OverlapPackets
|
|
|
|
var ident string
|
|
if dir == reassembly.TCPDirClientToServer {
|
|
ident = fmt.Sprintf("%v %v(%s): ", t.net, t.transport, dir)
|
|
} else {
|
|
ident = fmt.Sprintf("%v %v(%s): ", t.net.Reverse(), t.transport.Reverse(), dir)
|
|
}
|
|
Debug("%s: SG reassembled packet with %d bytes (start:%v,end:%v,skip:%d,saved:%d,nb:%d,%d,overlap:%d,%d)", ident, length, start, end, skip, saved, sgStats.Packets, sgStats.Chunks, sgStats.OverlapBytes, sgStats.OverlapPackets)
|
|
if skip == -1 && *allowmissinginit {
|
|
// this is allowed
|
|
} else if skip != 0 {
|
|
// Missing bytes in stream: do not even try to parse it
|
|
return
|
|
}
|
|
data := sg.Fetch(length)
|
|
if t.isDNS {
|
|
dns := &layers.DNS{}
|
|
var decoded []gopacket.LayerType
|
|
if len(data) < 2 {
|
|
if len(data) > 0 {
|
|
sg.KeepFrom(0)
|
|
}
|
|
return
|
|
}
|
|
dnsSize := binary.BigEndian.Uint16(data[:2])
|
|
missing := int(dnsSize) - len(data[2:])
|
|
Debug("dnsSize: %d, missing: %d", dnsSize, missing)
|
|
if missing > 0 {
|
|
Info("Missing some bytes: %d", missing)
|
|
sg.KeepFrom(0)
|
|
return
|
|
}
|
|
p := gopacket.NewDecodingLayerParser(layers.LayerTypeDNS, dns)
|
|
err := p.DecodeLayers(data[2:], &decoded)
|
|
if err != nil {
|
|
SilentError("DNS-parser", "Failed to decode DNS: %v", err)
|
|
} else {
|
|
Debug("DNS: %s", gopacket.LayerDump(dns))
|
|
}
|
|
if len(data) > 2+int(dnsSize) {
|
|
sg.KeepFrom(2 + int(dnsSize))
|
|
}
|
|
} else if t.isHTTP {
|
|
if length > 0 {
|
|
if *hexdump {
|
|
Debug("Feeding http with:%s", hex.Dump(data))
|
|
}
|
|
// This is where we pass the reassembled information onwards
|
|
// This channel is read by an httpReader object
|
|
if dir == reassembly.TCPDirClientToServer && !t.reversed {
|
|
t.client.msgQueue <- httpReaderDataMsg{data, ac.GetCaptureInfo().Timestamp}
|
|
} else {
|
|
t.server.msgQueue <- httpReaderDataMsg{data, ac.GetCaptureInfo().Timestamp}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *tcpStream) ReassemblyComplete(ac reassembly.AssemblerContext) bool {
|
|
Debug("%s: Connection closed", t.ident)
|
|
if t.isHTTP {
|
|
close(t.client.msgQueue)
|
|
close(t.server.msgQueue)
|
|
}
|
|
// do not remove the connection to allow last ACK
|
|
return false
|
|
}
|