Skip to content

Commit

Permalink
SecurityMode: traffic segregation
Browse files Browse the repository at this point in the history
Co-authored-by: Luca Francescato <[email protected]>
  • Loading branch information
2 people authored and adamjensenbot committed Oct 13, 2023
1 parent 1257716 commit 9dd9602
Show file tree
Hide file tree
Showing 18 changed files with 1,047 additions and 33 deletions.
2 changes: 1 addition & 1 deletion build/liqonet/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -ldflags="-s -w" .
FROM alpine:3.18

RUN apk update && \
apk add iptables bash wireguard-tools tcpdump conntrack-tools curl && \
apk add iptables ipset bash wireguard-tools tcpdump conntrack-tools curl && \
rm -rf /var/cache/apk/*

COPY --from=goBuilder /tmp/builder/liqonet /usr/bin/liqonet
Expand Down
71 changes: 69 additions & 2 deletions cmd/liqonet/gateway-operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
"github.com/containernetworking/plugins/pkg/ns"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/leaderelection/resourcelock"
Expand All @@ -39,6 +42,7 @@ import (
liqonetutils "github.com/liqotech/liqo/pkg/liqonet/utils"
"github.com/liqotech/liqo/pkg/liqonet/utils/links"
liqonetsignals "github.com/liqotech/liqo/pkg/liqonet/utils/signals"
argsutils "github.com/liqotech/liqo/pkg/utils/args"
"github.com/liqotech/liqo/pkg/utils/mapper"
"github.com/liqotech/liqo/pkg/utils/restcfg"
)
Expand All @@ -51,9 +55,13 @@ type gatewayOperatorFlags struct {
tunnelMTU uint
tunnelListeningPort uint
updateStatusInterval time.Duration
securityMode *argsutils.StringEnum
}

func addGatewayOperatorFlags(liqonet *gatewayOperatorFlags) {
liqonet.securityMode = argsutils.NewEnum([]string{string(liqoconst.FullPodToPodSecurityMode),
string(liqoconst.IntraClusterTrafficSegregationSecurityMode)},
string(liqoconst.FullPodToPodSecurityMode))
flag.BoolVar(&liqonet.enableLeaderElection, "gateway.leader-elect", false,
"leader-elect enables leader election for controller manager.")
flag.DurationVar(&liqonet.leaseDuration, "gateway.lease-duration", 7*time.Second,
Expand All @@ -72,6 +80,7 @@ func addGatewayOperatorFlags(liqonet *gatewayOperatorFlags) {
"ping-loss-threshold is the number of lost packets after which the connection check is considered as failed.")
flag.DurationVar(&conncheck.PingInterval, "gateway.ping-interval", 2*time.Second,
"ping-interval is the interval between two connection checks")
flag.Var(liqonet.securityMode, "gateway.security-mode", "security-mode represents different security modes regarding connectivity among clusters")
}

func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOperatorFlags) {
Expand All @@ -82,6 +91,7 @@ func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOp
leaseDuration := gatewayFlags.leaseDuration
renewDeadLine := gatewayFlags.renewDeadline
retryPeriod := gatewayFlags.retryPeriod
securityMode := liqoconst.SecurityModeType(gatewayFlags.securityMode.String())

// If port is not in the correct range, then return an error.
if gatewayFlags.tunnelListeningPort < liqoconst.UDPMinPort || gatewayFlags.tunnelListeningPort > liqoconst.UDPMaxPort {
Expand All @@ -103,7 +113,10 @@ func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOp
klog.Errorf("unable to get pod namespace: %v", err)
os.Exit(1)
}
main, err := ctrl.NewManager(restcfg.SetRateLimiter(ctrl.GetConfigOrDie()), ctrl.Options{

config := restcfg.SetRateLimiter(ctrl.GetConfigOrDie())

main, err := ctrl.NewManager(config, ctrl.Options{
MapperProvider: mapper.LiqoMapperProvider(scheme),
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Expand All @@ -128,6 +141,36 @@ func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOp
klog.Errorf("unable to get main manager: %s", err)
os.Exit(1)
}

// Create a label selector to filter only the events for pods managed by a ShadowPod (i.e., remote offloaded pods).
reqRemoteLiqoPods, err := labels.NewRequirement(liqoconst.ManagedByLabelKey, selection.Equals, []string{liqoconst.ManagedByShadowPodValue})
utilruntime.Must(err)

// Create an accessory manager that cache only pods managed by a ShadowPod (i.e., remote offloaded pods).
// This manager caches only the pods that are offloaded from a remote cluster and are scheduled on this.
auxmgrOffloadedPods, err := ctrl.NewManager(config, ctrl.Options{
MapperProvider: mapper.LiqoMapperProvider(scheme),
Scheme: scheme,
MetricsBindAddress: "0", // Disable the metrics of the auxiliary manager to prevent conflicts.
NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) {
opts.ByObject = map[client.Object]cache.ByObject{
&corev1.Pod{}: {
Label: labels.NewSelector().Add(*reqRemoteLiqoPods),
},
}
return cache.New(config, opts)
},
})
if err != nil {
klog.Errorf("Unable to create auxiliary manager: %w", err)
os.Exit(1)
}

if err := main.Add(auxmgrOffloadedPods); err != nil {
klog.Errorf("Unable to add the auxiliary manager to the main one: %w", err)
os.Exit(1)
}

clientset := kubernetes.NewForConfigOrDie(main.GetConfig())
eventRecorder := main.GetEventRecorderFor(liqoconst.LiqoGatewayOperatorName + "." + podIP.String())
// This map is updated by the tunnel operator after a successful tunnel creation
Expand Down Expand Up @@ -157,7 +200,7 @@ func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOp
os.Exit(1)
}
tunnelController, err := tunneloperator.NewTunnelController(ctx, &wg, podIP.String(), podNamespace, eventRecorder,
clientset, main.GetClient(), &readyClustersMutex, readyClusters, gatewayNetns, hostNetns, int(MTU), int(port), updateStatusInterval)
clientset, main.GetClient(), &readyClustersMutex, readyClusters, gatewayNetns, hostNetns, int(MTU), int(port), updateStatusInterval, securityMode)
// If something goes wrong while creating and configuring the tunnel controller
// then make sure that we remove all the resources created during the create process.
if err != nil {
Expand Down Expand Up @@ -187,6 +230,30 @@ func runGatewayOperator(commonFlags *liqonetCommonFlags, gatewayFlags *gatewayOp
os.Exit(1)
}

if securityMode == liqoconst.IntraClusterTrafficSegregationSecurityMode {
podsInfo := &sync.Map{}
endpointslicesInfo := &sync.Map{}
offloadedPodController, err := tunneloperator.NewOffloadedPodController(auxmgrOffloadedPods.GetClient(), gatewayNetns, podsInfo, endpointslicesInfo)
if err != nil {
klog.Errorf("an error occurred while creating the offloaded pod controller: %v", err)
os.Exit(1)
}
if err = offloadedPodController.SetupWithManager(auxmgrOffloadedPods); err != nil {
klog.Errorf("unable to setup offloaded pod controller: %s", err)
os.Exit(1)
}
reflectedEndpointsliceController, err := tunneloperator.NewReflectedEndpointsliceController(
main.GetClient(), main.GetScheme(), gatewayNetns, podsInfo, endpointslicesInfo)
if err != nil {
klog.Errorf("an error occurred while creating the reflected endpointslice controller: %v", err)
os.Exit(1)
}
if err = reflectedEndpointsliceController.SetupWithManager(main); err != nil {
klog.Errorf("unable to setup reflected endpointslice controller: %s", err)
os.Exit(1)
}
}

klog.Info("Starting manager as Tunnel-Operator")
if err := main.Start(tunnelController.SetupSignalHandlerForTunnelOperator(ctx, &wg)); err != nil {
klog.Errorf("unable to start tunnel controller: %s", err)
Expand Down
2 changes: 2 additions & 0 deletions cmd/liqonet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

discoveryv1alpha1 "github.com/liqotech/liqo/apis/discovery/v1alpha1"
netv1alpha1 "github.com/liqotech/liqo/apis/net/v1alpha1"
offloadingv1alpha1 "github.com/liqotech/liqo/apis/offloading/v1alpha1"
liqoconst "github.com/liqotech/liqo/pkg/consts"
"github.com/liqotech/liqo/pkg/utils/restcfg"
)
Expand All @@ -47,6 +48,7 @@ func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(discoveryv1alpha1.AddToScheme(scheme))
utilruntime.Must(netv1alpha1.AddToScheme(scheme))
utilruntime.Must(offloadingv1alpha1.AddToScheme(scheme))
}

func main() {
Expand Down
1 change: 1 addition & 0 deletions deployments/liqo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
| networking.iptables.mode | string | `"nf_tables"` | Select the iptables mode to use. Possible values are "legacy" and "nf_tables". |
| networking.mtu | int | `1340` | Set the MTU for the interfaces managed by liqo: vxlan, tunnel and veth interfaces. The value is used by the gateway and route operators. The default value is configured to ensure correct behavior regardless of the combination of the underlying environments (e.g., cloud providers). This guarantees improved compatibility at the cost of possible limited performance drops. |
| networking.reflectIPs | bool | `true` | Reflect pod IPs and EnpointSlices to the remote clusters. |
| networking.securityMode | string | `"FullPodToPod"` | Select the mode to enforce security on connectivity among clusters. Possible values are "FullPodToPod" and "IntraClusterTrafficSegregation" |
| openshiftConfig.enable | bool | `false` | Enable/Disable the OpenShift support, enabling Openshift-specific resources, and setting the pod security contexts in a way that is compatible with Openshift. |
| openshiftConfig.virtualKubeletSCCs | list | `["anyuid"]` | Security context configurations granted to the virtual kubelet in the local cluster. The configuration of one or more SCCs for the virtual kubelet is not strictly required, and privileges can be reduced in production environments. Still, the default configuration (i.e., anyuid) is suggested to prevent problems (i.e., the virtual kubelet fails to add the appropriate labels) when attempting to offload pods not managed by higher-level abstractions (e.g., Deployments), and not associated with a properly privileged service account. Indeed, "anyuid" is the SCC automatically associated with pods created by cluster administrators. Any pod granted a more privileged SCC and not linked to an adequately privileged service account will fail to be offloaded. |
| proxy.config.listeningPort | int | `8118` | Port used by the proxy pod. |
Expand Down
46 changes: 46 additions & 0 deletions deployments/liqo/files/liqo-gateway-ClusterRole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand All @@ -21,6 +29,12 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods/status
verbs:
- get
- apiGroups:
- ""
resources:
Expand All @@ -30,6 +44,30 @@ rules:
- patch
- update
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices/endpoints
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices/endpoints/addresses
verbs:
- get
- list
- watch
- apiGroups:
- net.liqo.io
resources:
Expand Down Expand Up @@ -62,3 +100,11 @@ rules:
- get
- patch
- update
- apiGroups:
- offloading.liqo.io
resources:
- namespaceoffloadings
verbs:
- get
- list
- watch
3 changes: 3 additions & 0 deletions deployments/liqo/templates/liqo-gateway-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ spec:
{{- if .Values.common.extraArgs }}
{{- toYaml .Values.common.extraArgs | nindent 10 }}
{{- end }}
{{- if .Values.networking.securityMode}}
- --gateway.security-mode={{ .Values.networking.securityMode }}
{{- end }}
{{- if .Values.gateway.pod.extraArgs }}
{{- toYaml .Values.gateway.pod.extraArgs | nindent 10 }}
{{- end }}
Expand Down
2 changes: 2 additions & 0 deletions deployments/liqo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ networking:
# The default value is configured to ensure correct behavior regardless of the combination of the underlying environments
# (e.g., cloud providers). This guarantees improved compatibility at the cost of possible limited performance drops.
mtu: 1340
# -- Select the mode to enforce security on connectivity among clusters. Possible values are "FullPodToPod" and "IntraClusterTrafficSegregation"
securityMode: "FullPodToPod"

reflection:
skip:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ require (
k8s.io/component-helpers v0.28.2
k8s.io/klog/v2 v2.100.1
k8s.io/kubectl v0.28.2
k8s.io/kubernetes v1.26.2
k8s.io/metrics v0.28.2
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
sigs.k8s.io/aws-iam-authenticator v0.6.12
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI=
github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
Expand Down Expand Up @@ -1296,6 +1296,8 @@ k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5Ohx
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/kubectl v0.28.2 h1:fOWOtU6S0smdNjG1PB9WFbqEIMlkzU5ahyHkc7ESHgM=
k8s.io/kubectl v0.28.2/go.mod h1:6EQWTPySF1fn7yKoQZHYf9TPwIl2AygHEcJoxFekr64=
k8s.io/kubernetes v1.26.2 h1:6Ve0nzlF2noVXf9jMHSJgbRZC0EkyOV22GYEv1K7MZI=
k8s.io/kubernetes v1.26.2/go.mod h1:cv07eVU5+kF6ibpVtAvOGjIBsrfgevQL4ORK85/oqWc=
k8s.io/metrics v0.28.2 h1:Z/oMk5SmiT/Ji1SaWOPfW2l9W831BLO9/XxDq9iS3ak=
k8s.io/metrics v0.28.2/go.mod h1:QTIIdjMrq+KodO+rmp6R9Pr1LZO8kTArNtkWoQXw0sw=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
Expand Down
Loading

0 comments on commit 9dd9602

Please sign in to comment.