Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements handling of insecure TLS connections in Mehkit #373

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c75d194
Implements handling of insecure TLS connections in Mehkit
yash37158 Sep 20, 2023
27ac06d
Merge branch 'master' into master
yash37158 Sep 25, 2023
3ea693d
Fixing go formating changes
yash37158 Sep 26, 2023
f0a66b1
Merge remote-tracking branch 'origin'
yash37158 Sep 26, 2023
2a49b89
Merge branch 'meshery:master' into master
yash37158 Sep 29, 2023
0380716
Fixing formatting errors
yash37158 Sep 29, 2023
3b8ed1c
Merge branch 'meshery:master' into master
yash37158 Oct 2, 2023
48fbcbf
fix: Fix format script
yash37158 Oct 2, 2023
3d84b71
Fixing nil pointer dereferences
yash37158 Oct 2, 2023
3b9eee7
Merge branch 'meshery:master' into master
yash37158 Oct 10, 2023
7ecfe12
Adding CertificateAuthorityData capabilities when flag is true
yash37158 Oct 10, 2023
50af4d7
Merge remote-tracking branch 'origin/master'
yash37158 Oct 10, 2023
a4485cf
fixing suggestion from muzair on adding events
yash37158 Oct 24, 2023
2ee76b0
Merge branch 'master' into master
yash37158 Oct 24, 2023
848bee4
Update utils/kubernetes/client.go
yash37158 Oct 26, 2023
9a613e7
Update utils/kubernetes/client.go
yash37158 Oct 26, 2023
d4522c1
Fixing indentation utils/kubernetes/client.go
yash37158 Oct 26, 2023
ba210fe
Fixing DCO changes
yash37158 Oct 27, 2023
3137d5b
Merge branch 'master' into master
yash37158 Oct 30, 2023
5427339
Accepting changes from Aisuko
yash37158 Nov 1, 2023
8827e75
Merge branch 'master' into master
yash37158 Nov 1, 2023
5c687da
Merge branch 'master' into master
yash37158 Nov 10, 2023
899223a
Removing logging of komposeObject
yash37158 Nov 10, 2023
634d994
Merge branch 'master' into master
yash37158 Nov 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 82 additions & 3 deletions utils/kubernetes/client.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
package kubernetes

import (
"log"
"os"
"path/filepath"

"github.com/layer5io/meshkit/models"
event "github.com/layer5io/meshkit/models/events"
"github.com/layer5io/meshkit/utils"
"github.com/layer5io/meshkit/utils/events"
"gopkg.in/yaml.v2"
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)


// DetectKubeConfig detects the kubeconfig for the kubernetes cluster and returns it
func DetectKubeConfig(configfile []byte) (config *rest.Config, err error) {
if len(configfile) > 0 {
if err != nil {
return nil, err
}

models := &models.Kubeconfig{}
var cfgFile []byte

cfgFile, err = processConfig(configfile)
if err != nil {
return nil, err
}

if config, err = clientcmd.RESTConfigFromKubeConfig(cfgFile); err == nil {
return config, err
if err = yaml.Unmarshal(cfgFile, models); err != nil {
return nil, err
}

yash37158 marked this conversation as resolved.
Show resolved Hide resolved
for _, clusters := range models.Clusters {
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
if config, err = clientcmd.RESTConfigFromKubeConfig(cfgFile); err == nil {
// Check the `InsecureSkipTLSVerify` field
if insecureSkipTLSVerify := clusters.Cluster.InsecureSkipTLSVerify; insecureSkipTLSVerify != nil && *insecureSkipTLSVerify {
// Skip TLS verification if the field is set to true
config.TLSClientConfig.Insecure = *insecureSkipTLSVerify

clusters.Cluster.CertificateAuthorityData = ""

// Create an event to record the insecure connection
eventBuilder := event.NewEvent().WithCategory("connection").WithAction("insecure")
eventBuilder.WithSeverity(event.Warning).WithDescription("Insecure TLS connection to Kubernetes cluster detected")

// Publish the event directly using the events package
event := eventBuilder.Build()
_ = publishEvent(event)

log.Println("SKIP TLS verification part was called")

}

return config, err
}
}
}

Expand All @@ -29,23 +66,65 @@ func DetectKubeConfig(configfile []byte) (config *rest.Config, err error) {
return config, err
}

// Look for kubeconfig from the path mentioned in $KUBECONFIG
// Look for kubeconfig from the path mentioned in $KUBECONFIGZ
var models models.Kubeconfig
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig != "" {
if config, err = clientcmd.BuildConfigFromFlags("", kubeconfig); err == nil {
for _, cluster := range models.Clusters {
if cluster.Cluster.InsecureSkipTLSVerify != nil {
// Skip TLS verification for this cluster
config.TLSClientConfig.Insecure = true
// Removing Certificate-authority-data when InsecureSkipTlsVerify is true
cluster.Cluster.CertificateAuthorityData = ""

// Create an event to record the insecure connection
eventBuilder := event.NewEvent().WithCategory("connection").WithAction("insecure")
eventBuilder.WithSeverity(event.Warning).WithDescription("Insecure TLS connection to Kubernetes cluster detected")

// Publish the event directly using the events package
event := eventBuilder.Build()
_ = publishEvent(event)
}
}

return config, err
}
}

// Look for kubeconfig at the default path
path := filepath.Join(utils.GetHome(), ".kube", "config")
if config, err = clientcmd.BuildConfigFromFlags("", path); err == nil {
for _, cluster := range models.Clusters {
if cluster.Cluster.InsecureSkipTLSVerify != nil {
// Skip TLS verification for this cluster
config.TLSClientConfig.Insecure = true

cluster.Cluster.CertificateAuthorityData = ""

// Create an event to record the insecure connection
eventBuilder := event.NewEvent().WithCategory("connection").WithAction("insecure")
eventBuilder.WithSeverity(event.Warning).WithDescription("Insecure TLS connection to Kubernetes cluster detected")

// Publish the event directly using the events package
event := eventBuilder.Build()
_ = publishEvent(event)
}
}
return config, err
}

return
}

func publishEvent(event interface{}) error {
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
eventStreamer := events.NewEventStreamer()
clientChannel := make(chan interface{})
eventStreamer.Subscribe(clientChannel)
eventStreamer.Publish(event)
return nil
}

func processConfig(configFile []byte) ([]byte, error) {
cfg, err := clientcmd.Load(configFile)
if err != nil {
Expand Down
114 changes: 114 additions & 0 deletions utils/kubernetes/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package kubernetes

import (
"fmt"
"testing"
)

func TestDetectKubeConfig(t *testing.T) {
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
// Test case 1: Valid kubeconfig file with tls-skip-verify set to true
configfile := []byte(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: REDACTED
server: https://localhost:6443
insecure-skip-tls-verify: false
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
`)
config, err := DetectKubeConfig(configfile)
if err != nil {
t.Errorf("DetectKubeConfig() failed with error: %v", err)
}
if config == nil {
t.Errorf("DetectKubeConfig() returned nil config")
}
if config != nil && config.TLSClientConfig.CAData != nil {
fmt.Print("Test case 1: CertificateAuthorityData should be empty, but it's not")
}

// Test case 2: Valid kubeconfig file with tls-skip-verify set to false
configfile = []byte(`
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: REDACTED
server: https://localhost:6443
insecure-skip-tls-verify: false
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
`)
config, err = DetectKubeConfig(configfile)
if err != nil {
t.Errorf("DetectKubeConfig() failed with error: %v", err)
}
if config == nil {
t.Errorf("DetectKubeConfig() returned nil config")
}
if config != nil && config.TLSClientConfig.CAData == nil {
fmt.Print("Test case 2: CertificateAuthorityData should not be empty, but it is")
}

// Test case 3: Invalid kubeconfig file
configfile = []byte(`invalid kubeconfig`)
config, err = DetectKubeConfig(configfile)
if err == nil {
t.Errorf("DetectKubeConfig() did not return an error for invalid kubeconfig")
}
if config != nil {
t.Errorf("DetectKubeConfig() returned non-nil config for invalid kubeconfig")
}
if config != nil && config.TLSClientConfig.CAData != nil {
t.Errorf("Test case 3: CertificateAuthorityData should be empty, but it's not")
}
}

func TestPublishEventWithChannelLeak(t *testing.T) {
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
// Simulate multiple subscribers
numSubscribers := 10
channels := make([]chan interface{}, numSubscribers)
for i := 0; i < numSubscribers; i++ {
channels[i] = make(chan interface{})
}

// Publish an event without closing the channels
event := "test event with channel leak"
err := publishEvent(event)

if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
}

func TestPublishEvent(t *testing.T) {
yash37158 marked this conversation as resolved.
Show resolved Hide resolved
event := "test event"
err := publishEvent(event)
if err != nil {
t.Errorf("Expected no error, but got: %v", err)
}
}
1 change: 1 addition & 0 deletions utils/kubernetes/kompose/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func convert(opt kobject.ConvertOptions) error {
if err != nil {
return err
}
fmt.Println(komposeObject)
yash37158 marked this conversation as resolved.
Show resolved Hide resolved

// Get a transformer that maps komposeObject to provider's primitives
t := getTransformer(opt)
Expand Down
Loading