mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-06-16 13:17:45 +00:00
Compare commits
5 Commits
31.0-dev50
...
31.0-dev55
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30986c3b22 | ||
|
|
1e167f2757 | ||
|
|
149e86d050 | ||
|
|
1213162b85 | ||
|
|
189c158150 |
38
.github/workflows/acceptance_tests_on_pr.yml
vendored
Normal file
38
.github/workflows/acceptance_tests_on_pr.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Acceptance tests on PR
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: acceptance-tests-on-pr-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-tests:
|
||||||
|
name: Run tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ contains(github.event.head_commit.message, '#run_acceptance_tests') }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up Go 1.17
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '^1.17'
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup acceptance test
|
||||||
|
run: ./acceptanceTests/setup.sh
|
||||||
|
|
||||||
|
- name: Create k8s users and change context
|
||||||
|
env:
|
||||||
|
USERNAME_UNRESTRICTED: user-with-clusterwide-access
|
||||||
|
USERNAME_RESTRICTED: user-with-restricted-access
|
||||||
|
run: |
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_UNRESTRICTED}"
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_RESTRICTED}"
|
||||||
|
kubectl apply -f cli/cmd/permissionFiles/permissions-all-namespaces-tap.yaml
|
||||||
|
kubectl config use-context ${USERNAME_UNRESTRICTED}
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: make acceptance-test
|
||||||
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check extensions modified files
|
- name: Check extensions modified files
|
||||||
id: ext_modified_files
|
id: ext_modified_files
|
||||||
run: devops/check_modified_files.sh tap/extensions/
|
run: devops/check_modified_files.sh tap/extensions/ tap/api/
|
||||||
|
|
||||||
- name: Extensions Test
|
- name: Extensions Test
|
||||||
if: github.event_name == 'push' || steps.ext_modified_files.outputs.matched == 'true'
|
if: github.event_name == 'push' || steps.ext_modified_files.outputs.matched == 'true'
|
||||||
@@ -64,4 +64,3 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,11 @@ BasenineReconnect:
|
|||||||
for item := range outputItems {
|
for item := range outputItems {
|
||||||
extension := extensionsMap[item.Protocol.Name]
|
extension := extensionsMap[item.Protocol.Name]
|
||||||
resolvedSource, resolvedDestionation, namespace := resolveIP(item.ConnectionInfo)
|
resolvedSource, resolvedDestionation, namespace := resolveIP(item.ConnectionInfo)
|
||||||
|
|
||||||
|
if namespace == "" && item.Namespace != tapApi.UNKNOWN_NAMESPACE {
|
||||||
|
namespace = item.Namespace
|
||||||
|
}
|
||||||
|
|
||||||
mizuEntry := extension.Dissector.Analyze(item, resolvedSource, resolvedDestionation, namespace)
|
mizuEntry := extension.Dissector.Analyze(item, resolvedSource, resolvedDestionation, namespace)
|
||||||
if extension.Protocol.Name == "http" {
|
if extension.Protocol.Name == "http" {
|
||||||
if !disableOASValidation {
|
if !disableOASValidation {
|
||||||
|
|||||||
@@ -4,18 +4,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
"github.com/up9inc/mizu/agent/pkg/models"
|
"github.com/up9inc/mizu/agent/pkg/models"
|
||||||
"github.com/up9inc/mizu/shared"
|
"github.com/up9inc/mizu/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tlsLinkRetainmentTime = time.Minute * 15
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
authStatus *models.AuthStatus
|
authStatus *models.AuthStatus
|
||||||
RecentTLSLinks = cache.New(tlsLinkRetainmentTime, tlsLinkRetainmentTime)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetAuthStatus() (*models.AuthStatus, error) {
|
func GetAuthStatus() (*models.AuthStatus, error) {
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ func GetNodeHostToTappedPodsMap(tappedPods []core.Pod) shared.NodeToPodsMap {
|
|||||||
func getMinimizedPod(fullPod core.Pod) core.Pod {
|
func getMinimizedPod(fullPod core.Pod) core.Pod {
|
||||||
return core.Pod{
|
return core.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: fullPod.Name,
|
Name: fullPod.Name,
|
||||||
|
Namespace: fullPod.Namespace,
|
||||||
},
|
},
|
||||||
Status: core.PodStatus{
|
Status: core.PodStatus{
|
||||||
PodIP: fullPod.Status.PodIP,
|
PodIP: fullPod.Status.PodIP,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const mizuTestEnvVar = "MIZU_TEST"
|
const mizuTestEnvVar = "MIZU_TEST"
|
||||||
|
const UNKNOWN_NAMESPACE = ""
|
||||||
|
|
||||||
var UnknownIp net.IP = net.IP{0, 0, 0, 0}
|
var UnknownIp net.IP = net.IP{0, 0, 0, 0}
|
||||||
var UnknownPort uint16 = 0
|
var UnknownPort uint16 = 0
|
||||||
@@ -92,14 +93,15 @@ type RequestResponsePair struct {
|
|||||||
Response GenericMessage `json:"response"`
|
Response GenericMessage `json:"response"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Protocol` is modified in the later stages of data propagation. Therefore it's not a pointer.
|
|
||||||
type OutputChannelItem struct {
|
type OutputChannelItem struct {
|
||||||
|
// `Protocol` is modified in later stages of data propagation. Therefore, it's not a pointer.
|
||||||
Protocol Protocol
|
Protocol Protocol
|
||||||
Capture Capture
|
Capture Capture
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
ConnectionInfo *ConnectionInfo
|
ConnectionInfo *ConnectionInfo
|
||||||
Pair *RequestResponsePair
|
Pair *RequestResponsePair
|
||||||
Summary *BaseEntry
|
Summary *BaseEntry
|
||||||
|
Namespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SuperTimer struct {
|
type SuperTimer struct {
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/amqp/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/amqp/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/http/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/http/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/kafka/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/kafka/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/redis/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/redis/\* expect
|
||||||
|
|||||||
13
tap/tlstapper/tls_emitter.go
Normal file
13
tap/tlstapper/tls_emitter.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package tlstapper
|
||||||
|
|
||||||
|
import "github.com/up9inc/mizu/tap/api"
|
||||||
|
|
||||||
|
type tlsEmitter struct {
|
||||||
|
delegate api.Emitter
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *tlsEmitter) Emit(item *api.OutputChannelItem) {
|
||||||
|
item.Namespace = e.namespace
|
||||||
|
e.delegate.Emit(item)
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@@ -19,13 +20,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type tlsPoller struct {
|
type tlsPoller struct {
|
||||||
tls *TlsTapper
|
tls *TlsTapper
|
||||||
readers map[string]*tlsReader
|
readers map[string]*tlsReader
|
||||||
closedReaders chan string
|
closedReaders chan string
|
||||||
reqResMatcher api.RequestResponseMatcher
|
reqResMatcher api.RequestResponseMatcher
|
||||||
chunksReader *perf.Reader
|
chunksReader *perf.Reader
|
||||||
extension *api.Extension
|
extension *api.Extension
|
||||||
procfs string
|
procfs string
|
||||||
|
pidToNamespace sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTlsPoller(tls *TlsTapper, extension *api.Extension, procfs string) *tlsPoller {
|
func newTlsPoller(tls *TlsTapper, extension *api.Extension, procfs string) *tlsPoller {
|
||||||
@@ -151,16 +153,21 @@ func (p *tlsPoller) startNewTlsReader(chunk *tlsChunk, ip net.IP, port uint16, k
|
|||||||
|
|
||||||
tcpid := p.buildTcpId(chunk, ip, port)
|
tcpid := p.buildTcpId(chunk, ip, port)
|
||||||
|
|
||||||
go dissect(extension, reader, chunk.isRequest(), &tcpid, emitter, options, p.reqResMatcher)
|
tlsEmitter := &tlsEmitter{
|
||||||
|
delegate: emitter,
|
||||||
|
namespace: p.getNamespace(chunk.Pid),
|
||||||
|
}
|
||||||
|
|
||||||
|
go dissect(extension, reader, chunk.isRequest(), &tcpid, tlsEmitter, options, p.reqResMatcher)
|
||||||
return reader
|
return reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func dissect(extension *api.Extension, reader *tlsReader, isRequest bool, tcpid *api.TcpID,
|
func dissect(extension *api.Extension, reader *tlsReader, isRequest bool, tcpid *api.TcpID,
|
||||||
emitter api.Emitter, options *api.TrafficFilteringOptions, reqResMatcher api.RequestResponseMatcher) {
|
tlsEmitter *tlsEmitter, options *api.TrafficFilteringOptions, reqResMatcher api.RequestResponseMatcher) {
|
||||||
b := bufio.NewReader(reader)
|
b := bufio.NewReader(reader)
|
||||||
|
|
||||||
err := extension.Dissector.Dissect(b, reader.progress, api.Ebpf, isRequest, tcpid, &api.CounterPair{},
|
err := extension.Dissector.Dissect(b, reader.progress, api.Ebpf, isRequest, tcpid, &api.CounterPair{},
|
||||||
&api.SuperTimer{}, &api.SuperIdentifier{}, emitter, options, reqResMatcher)
|
&api.SuperTimer{}, &api.SuperIdentifier{}, tlsEmitter, options, reqResMatcher)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Warningf("Error dissecting TLS %v - %v", tcpid, err)
|
logger.Log.Warningf("Error dissecting TLS %v - %v", tcpid, err)
|
||||||
@@ -205,6 +212,33 @@ func (p *tlsPoller) buildTcpId(chunk *tlsChunk, ip net.IP, port uint16) api.TcpI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *tlsPoller) addPid(pid uint32, namespace string) {
|
||||||
|
p.pidToNamespace.Store(pid, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *tlsPoller) getNamespace(pid uint32) string {
|
||||||
|
namespaceIfc, ok := p.pidToNamespace.Load(pid)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return api.UNKNOWN_NAMESPACE
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace, ok := namespaceIfc.(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return api.UNKNOWN_NAMESPACE
|
||||||
|
}
|
||||||
|
|
||||||
|
return namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *tlsPoller) clearPids() {
|
||||||
|
p.pidToNamespace.Range(func(key, v interface{}) bool {
|
||||||
|
p.pidToNamespace.Delete(key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (p *tlsPoller) logTls(chunk *tlsChunk, ip net.IP, port uint16) {
|
func (p *tlsPoller) logTls(chunk *tlsChunk, ip net.IP, port uint16) {
|
||||||
var flagsStr string
|
var flagsStr string
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ func UpdateTapTargets(tls *TlsTapper, pods *[]v1.Pod, procfs string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tls.ClearPids()
|
tls.ClearPids()
|
||||||
|
|
||||||
for _, pid := range containerPids {
|
for pid, pod := range containerPids {
|
||||||
if err := tls.AddPid(procfs, pid); err != nil {
|
if err := tls.AddPid(procfs, pid, pod.Namespace); err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,8 @@ func UpdateTapTargets(tls *TlsTapper, pods *[]v1.Pod, procfs string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func findContainerPids(procfs string, containerIds map[string]bool) ([]uint32, error) {
|
func findContainerPids(procfs string, containerIds map[string]v1.Pod) (map[uint32]v1.Pod, error) {
|
||||||
result := make([]uint32, 0)
|
result := make(map[uint32]v1.Pod)
|
||||||
|
|
||||||
pids, err := ioutil.ReadDir(procfs)
|
pids, err := ioutil.ReadDir(procfs)
|
||||||
|
|
||||||
@@ -63,7 +63,9 @@ func findContainerPids(procfs string, containerIds map[string]bool) ([]uint32, e
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := containerIds[cgroup]; !ok {
|
pod, ok := containerIds[cgroup]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,14 +75,14 @@ func findContainerPids(procfs string, containerIds map[string]bool) ([]uint32, e
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, uint32(pidNumber))
|
result[uint32(pidNumber)] = pod
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildContainerIdsMap(pods *[]v1.Pod) map[string]bool {
|
func buildContainerIdsMap(pods *[]v1.Pod) map[string]v1.Pod {
|
||||||
result := make(map[string]bool)
|
result := make(map[string]v1.Pod)
|
||||||
|
|
||||||
for _, pod := range *pods {
|
for _, pod := range *pods {
|
||||||
for _, container := range pod.Status.ContainerStatuses {
|
for _, container := range pod.Status.ContainerStatuses {
|
||||||
@@ -91,7 +93,7 @@ func buildContainerIdsMap(pods *[]v1.Pod) map[string]bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
result[url.Host] = true
|
result[url.Host] = pod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,14 +143,14 @@ func extractCgroup(lines []string) string {
|
|||||||
// /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3beae8e0_164d_4689_a087_efd902d8c2ab.slice/docker-<ID>.scope
|
// /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3beae8e0_164d_4689_a087_efd902d8c2ab.slice/docker-<ID>.scope
|
||||||
// /kubepods/besteffort/pod7709c1d5-447c-428f-bed9-8ddec35c93f4/<ID>
|
// /kubepods/besteffort/pod7709c1d5-447c-428f-bed9-8ddec35c93f4/<ID>
|
||||||
//
|
//
|
||||||
// This function extract the <ID> out of the cgroup path, the <ID> should match
|
// This function extract the <ID> out of the cgroup path, the <ID> should match
|
||||||
// the "Container ID:" field when running kubectl describe pod <POD>
|
// the "Container ID:" field when running kubectl describe pod <POD>
|
||||||
//
|
//
|
||||||
func normalizeCgroup(cgrouppath string) string {
|
func normalizeCgroup(cgrouppath string) string {
|
||||||
basename := strings.TrimSpace(path.Base(cgrouppath))
|
basename := strings.TrimSpace(path.Base(cgrouppath))
|
||||||
|
|
||||||
if strings.Contains(basename, "-") {
|
if strings.Contains(basename, "-") {
|
||||||
basename = basename[strings.Index(basename, "-") + 1:]
|
basename = basename[strings.Index(basename, "-")+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(basename, ".") {
|
if strings.Contains(basename, ".") {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package tlstapper
|
package tlstapper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/cilium/ebpf/rlimit"
|
"github.com/cilium/ebpf/rlimit"
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
"github.com/up9inc/mizu/tap/api"
|
"github.com/up9inc/mizu/tap/api"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const GLOABL_TAP_PID = 0
|
const GLOABL_TAP_PID = 0
|
||||||
@@ -58,10 +59,10 @@ func (t *TlsTapper) PollForLogging() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TlsTapper) GlobalTap(sslLibrary string) error {
|
func (t *TlsTapper) GlobalTap(sslLibrary string) error {
|
||||||
return t.tapPid(GLOABL_TAP_PID, sslLibrary)
|
return t.tapPid(GLOABL_TAP_PID, sslLibrary, api.UNKNOWN_NAMESPACE)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TlsTapper) AddPid(procfs string, pid uint32) error {
|
func (t *TlsTapper) AddPid(procfs string, pid uint32, namespace string) error {
|
||||||
sslLibrary, err := findSsllib(procfs, pid)
|
sslLibrary, err := findSsllib(procfs, pid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -69,7 +70,7 @@ func (t *TlsTapper) AddPid(procfs string, pid uint32) error {
|
|||||||
return nil // hide the error on purpose, its OK for a process to not use libssl.so
|
return nil // hide the error on purpose, its OK for a process to not use libssl.so
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.tapPid(pid, sslLibrary)
|
return t.tapPid(pid, sslLibrary, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TlsTapper) RemovePid(pid uint32) error {
|
func (t *TlsTapper) RemovePid(pid uint32) error {
|
||||||
@@ -85,12 +86,13 @@ func (t *TlsTapper) RemovePid(pid uint32) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TlsTapper) ClearPids() {
|
func (t *TlsTapper) ClearPids() {
|
||||||
|
t.poller.clearPids()
|
||||||
t.registeredPids.Range(func(key, v interface{}) bool {
|
t.registeredPids.Range(func(key, v interface{}) bool {
|
||||||
pid := key.(uint32)
|
pid := key.(uint32)
|
||||||
if pid == GLOABL_TAP_PID {
|
if pid == GLOABL_TAP_PID {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.RemovePid(pid); err != nil {
|
if err := t.RemovePid(pid); err != nil {
|
||||||
LogError(err)
|
LogError(err)
|
||||||
}
|
}
|
||||||
@@ -133,7 +135,7 @@ func setupRLimit() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TlsTapper) tapPid(pid uint32, sslLibrary string) error {
|
func (t *TlsTapper) tapPid(pid uint32, sslLibrary string, namespace string) error {
|
||||||
logger.Log.Infof("Tapping TLS (pid: %v) (sslLibrary: %v)", pid, sslLibrary)
|
logger.Log.Infof("Tapping TLS (pid: %v) (sslLibrary: %v)", pid, sslLibrary)
|
||||||
|
|
||||||
newSsl := sslHooks{}
|
newSsl := sslHooks{}
|
||||||
@@ -144,12 +146,14 @@ func (t *TlsTapper) tapPid(pid uint32, sslLibrary string) error {
|
|||||||
|
|
||||||
t.sslHooksStructs = append(t.sslHooksStructs, newSsl)
|
t.sslHooksStructs = append(t.sslHooksStructs, newSsl)
|
||||||
|
|
||||||
|
t.poller.addPid(pid, namespace)
|
||||||
|
|
||||||
pids := t.bpfObjects.tlsTapperMaps.PidsMap
|
pids := t.bpfObjects.tlsTapperMaps.PidsMap
|
||||||
|
|
||||||
if err := pids.Put(pid, uint32(1)); err != nil {
|
if err := pids.Put(pid, uint32(1)); err != nil {
|
||||||
return errors.Wrap(err, 0)
|
return errors.Wrap(err, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.registeredPids.Store(pid, true)
|
t.registeredPids.Store(pid, true)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ export default class Api {
|
|||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRecentTLSLinks = async () => {
|
|
||||||
const response = await client.get("/status/recentTLSLinks");
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
getOasServices = async () => {
|
getOasServices = async () => {
|
||||||
const response = await client.get("/oas");
|
const response = await client.get("/oas");
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -121,4 +116,4 @@ export function getWebsocketUrl(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
return websocketUrl;
|
return websocketUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
.httpsDomains
|
|
||||||
display: none
|
|
||||||
margin: 0
|
|
||||||
padding: 0
|
|
||||||
list-style: none
|
|
||||||
|
|
||||||
.customWarningStyle
|
|
||||||
&:hover
|
|
||||||
overflow-y: scroll
|
|
||||||
height: 85px
|
|
||||||
.httpsDomains
|
|
||||||
display: block
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import {Snackbar} from "@material-ui/core";
|
|
||||||
import MuiAlert from "@material-ui/lab/Alert";
|
|
||||||
import React, {useEffect} from "react";
|
|
||||||
import { RecoilState, useRecoilValue } from "recoil";
|
|
||||||
import TrafficViewerApiAtom from "../../recoil/TrafficViewerApi/atom";
|
|
||||||
import TrafficViewerApi from "../TrafficViewer/TrafficViewerApi";
|
|
||||||
import './TLSWarning.sass';
|
|
||||||
|
|
||||||
interface TLSWarningProps {
|
|
||||||
showTLSWarning: boolean
|
|
||||||
setShowTLSWarning: (show: boolean) => void
|
|
||||||
addressesWithTLS: Set<string>
|
|
||||||
setAddressesWithTLS: (addresses: Set<string>) => void
|
|
||||||
userDismissedTLSWarning: boolean
|
|
||||||
setUserDismissedTLSWarning: (flag: boolean) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TLSWarning: React.FC<TLSWarningProps> = ({showTLSWarning, setShowTLSWarning, addressesWithTLS, setAddressesWithTLS, userDismissedTLSWarning, setUserDismissedTLSWarning}) => {
|
|
||||||
|
|
||||||
const trafficViewerApi = useRecoilValue(TrafficViewerApiAtom as RecoilState<TrafficViewerApi>)
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
const getRecentTLSLinksFunc = trafficViewerApi?.getRecentTLSLinks ? trafficViewerApi?.getRecentTLSLinks : function(){}
|
|
||||||
const recentTLSLinks = await getRecentTLSLinksFunc();
|
|
||||||
if (recentTLSLinks?.length > 0) {
|
|
||||||
setAddressesWithTLS(new Set(recentTLSLinks));
|
|
||||||
setShowTLSWarning(true);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, [setShowTLSWarning, setAddressesWithTLS,trafficViewerApi]);
|
|
||||||
|
|
||||||
return (<Snackbar open={showTLSWarning && !userDismissedTLSWarning}>
|
|
||||||
<MuiAlert classes={{filledWarning: 'customWarningStyle'}} elevation={6} variant="filled"
|
|
||||||
onClose={() => setUserDismissedTLSWarning(true)} severity="warning">
|
|
||||||
Mizu is detecting TLS traffic, this type of traffic will not be displayed.
|
|
||||||
{addressesWithTLS.size > 0 &&
|
|
||||||
<ul className="httpsDomains"> {Array.from(addressesWithTLS, address => <li>{address}</li>)} </ul>}
|
|
||||||
</MuiAlert>
|
|
||||||
</Snackbar>);
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,6 @@ import {RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilSta
|
|||||||
import entriesAtom from "../../recoil/entries";
|
import entriesAtom from "../../recoil/entries";
|
||||||
import focusedEntryIdAtom from "../../recoil/focusedEntryId";
|
import focusedEntryIdAtom from "../../recoil/focusedEntryId";
|
||||||
import queryAtom from "../../recoil/query";
|
import queryAtom from "../../recoil/query";
|
||||||
import {TLSWarning} from "../TLSWarning/TLSWarning";
|
|
||||||
import trafficViewerApiAtom from "../../recoil/TrafficViewerApi"
|
import trafficViewerApiAtom from "../../recoil/TrafficViewerApi"
|
||||||
import TrafficViewerApi from "./TrafficViewerApi";
|
import TrafficViewerApi from "./TrafficViewerApi";
|
||||||
import {StatusBar} from "../UI/StatusBar";
|
import {StatusBar} from "../UI/StatusBar";
|
||||||
@@ -77,10 +76,6 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
const setLeftOffTop = useSetRecoilState(leftOffTopAtom);
|
const setLeftOffTop = useSetRecoilState(leftOffTopAtom);
|
||||||
const scrollableRef = useRef(null);
|
const scrollableRef = useRef(null);
|
||||||
|
|
||||||
const [showTLSWarning, setShowTLSWarning] = useState(false);
|
|
||||||
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
|
|
||||||
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>());
|
|
||||||
|
|
||||||
const handleQueryChange = useMemo(
|
const handleQueryChange = useMemo(
|
||||||
() =>
|
() =>
|
||||||
debounce(async (query: string) => {
|
debounce(async (query: string) => {
|
||||||
@@ -286,12 +281,6 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
<EntryDetailed/>
|
<EntryDetailed/>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
<TLSWarning showTLSWarning={showTLSWarning}
|
|
||||||
setShowTLSWarning={setShowTLSWarning}
|
|
||||||
addressesWithTLS={addressesWithTLS}
|
|
||||||
setAddressesWithTLS={setAddressesWithTLS}
|
|
||||||
userDismissedTLSWarning={userDismissedTLSWarning}
|
|
||||||
setUserDismissedTLSWarning={setUserDismissedTLSWarning}/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ type TrafficViewerApi = {
|
|||||||
analyzeStatus: () => any
|
analyzeStatus: () => any
|
||||||
fetchEntries: (leftOff: any, direction: number, query: any, limit: number, timeoutMs: number) => any
|
fetchEntries: (leftOff: any, direction: number, query: any, limit: number, timeoutMs: number) => any
|
||||||
getEntry: (entryId: any, query: string) => any
|
getEntry: (entryId: any, query: string) => any
|
||||||
getRecentTLSLinks: () => any,
|
|
||||||
webSocket: {
|
webSocket: {
|
||||||
close: () => void
|
close: () => void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import React, { CSSProperties } from "react";
|
import React from "react";
|
||||||
import styles from "./style/InformationIcon.module.sass"
|
import styles from "./style/InformationIcon.module.sass"
|
||||||
|
|
||||||
const DEFUALT_LINK = "https://getmizu.io/docs"
|
const DEFUALT_LINK = "https://getmizu.io/docs"
|
||||||
|
|
||||||
export interface InformationIconProps {
|
interface LinkProps {
|
||||||
link?: string,
|
link?: string,
|
||||||
style?: CSSProperties
|
className?: string
|
||||||
|
title?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InformationIcon: React.FC<InformationIconProps> = ({ link, style }) => {
|
export const Link: React.FC<LinkProps> = ({ link, className, title, children }) => {
|
||||||
return <React.Fragment>
|
return <a href={link} className={className} title={title} target="_blank">
|
||||||
<a href={DEFUALT_LINK ? DEFUALT_LINK : link} style={style} className={styles.linkStyle} title="documentation" target="_blank">
|
{children}
|
||||||
<span>Docs</span>
|
</a>
|
||||||
</a>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const InformationIcon: React.FC<LinkProps> = ({ className }) => {
|
||||||
|
return <Link title="documentation" className={`${styles.linkStyle} ${className}`} link={DEFUALT_LINK}>
|
||||||
|
<span>Docs</span>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
@@ -5,10 +5,10 @@ import Tooltip from "./Tooltip";
|
|||||||
import Checkbox from "./Checkbox"
|
import Checkbox from "./Checkbox"
|
||||||
import { StatusBar } from "./StatusBar";
|
import { StatusBar } from "./StatusBar";
|
||||||
import CustomModal from "./CustomModal";
|
import CustomModal from "./CustomModal";
|
||||||
import { InformationIcon } from "./InformationIcon";
|
import { InformationIcon, Link } from "./InformationIcon";
|
||||||
import SelectList from "./SelectList";
|
import SelectList from "./SelectList";
|
||||||
import NoDataMessage from "./NoDataMessage";
|
import NoDataMessage from "./NoDataMessage";
|
||||||
|
|
||||||
|
|
||||||
export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage }
|
export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage, Link }
|
||||||
export { StatusBar }
|
export { StatusBar }
|
||||||
@@ -62,11 +62,6 @@ export default class Api {
|
|||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRecentTLSLinks = async () => {
|
|
||||||
const response = await client.get("/status/recentTLSLinks");
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAuthStatus = async () => {
|
getAuthStatus = async () => {
|
||||||
const response = await client.get("/status/auth");
|
const response = await client.get("/status/auth");
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
Reference in New Issue
Block a user