Skip to content

Commit

Permalink
Allow enabling mTLS for memcached
Browse files Browse the repository at this point in the history
This commit adds a new parameter 'SslVerifyMode' that allows
users to enable/enforce mTLS for memcached.

See https://docs.memcached.org/features/tls/

By default it is set to "None" or 0, but it can be set to "Request"
or "Require".

If set to "Require" it will:
1. prevent the creation of the non-tls memcached svc port (11211)
2. enforce client side certification validation
  • Loading branch information
lmiccini committed Jan 29, 2025
1 parent 9885387 commit 9ea6507
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
9 changes: 9 additions & 0 deletions apis/bases/memcached.openstack.org_memcacheds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ spec:
maximum: 32
minimum: 1
type: integer
sslVerifyMode:
default: None
description: Used to enforce client side tls cert validation
enum:
- None
- Request
- Require
type: string
tls:
description: TLS settings for memcached service
properties:
Expand All @@ -89,6 +97,7 @@ spec:
required:
- containerImage
- replicas
- sslVerifyMode
type: object
status:
description: MemcachedStatus defines the observed state of Memcached
Expand Down
5 changes: 5 additions & 0 deletions apis/memcached/v1beta1/memcached_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ type MemcachedSpecCore struct {
// TLS settings for memcached service
TLS tls.SimpleService `json:"tls,omitempty"`

// +kubebuilder:validation:Enum="None";"Request";"Require"
// +kubebuilder:default="None"
// Used to enforce client side tls cert validation
SslVerifyMode string `json:"sslVerifyMode"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=9932
// Maximum Memcached cache size in MB
Expand Down
9 changes: 9 additions & 0 deletions config/crd/bases/memcached.openstack.org_memcacheds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ spec:
maximum: 32
minimum: 1
type: integer
sslVerifyMode:
default: None
description: Used to enforce client side tls cert validation
enum:
- None
- Request
- Require
type: string
tls:
description: TLS settings for memcached service
properties:
Expand All @@ -89,6 +97,7 @@ spec:
required:
- containerImage
- replicas
- sslVerifyMode
type: object
status:
description: MemcachedStatus defines the observed state of Memcached
Expand Down
9 changes: 9 additions & 0 deletions controllers/memcached/memcached_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,15 @@ func (r *Reconciler) generateConfigMaps(
"-o ssl_chain_cert=/etc/pki/tls/certs/memcached.crt " +
"-o ssl_key=/etc/pki/tls/private/memcached.key " +
"-o ssl_ca_cert=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"

if instance.Spec.SslVerifyMode == "Request" {
memcachedTLSOptions = memcachedTLSOptions + " -o ssl_verify_mode=1"
} else if instance.Spec.SslVerifyMode == "Require" {
memcachedTLSOptions = memcachedTLSOptions + " -o ssl_verify_mode=2"
} else {
memcachedTLSOptions = memcachedTLSOptions + " -o ssl_verify_mode=0"
}

memcachedPort = fmt.Sprint(memcached.MemcachedTLSPort)
instance.Status.TLSSupport = true
} else {
Expand Down
17 changes: 12 additions & 5 deletions pkg/memcached/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,24 @@ import (
corev1 "k8s.io/api/core/v1"
)

// HeadlessService exposes all memcached repliscas for a memcached CR
// HeadlessService exposes all memcached replicas for a memcached CR
func HeadlessService(m *memcachedv1.Memcached) *corev1.Service {
labels := labels.GetLabels(m, "memcached", map[string]string{
"app": m.GetName(),
common.OwnerSelector: "infra-operator",
"cr": m.GetName(),
common.AppSelector: m.GetName(),
})

ports := []corev1.ServicePort{
{Name: "memcached-tls", Protocol: "TCP", Port: MemcachedTLSPort},
{Name: "memcached", Protocol: "TCP", Port: MemcachedPort},
}

if m.Spec.SslVerifyMode == "Require" {
ports = []corev1.ServicePort{{Name: "memcached-tls", Protocol: "TCP", Port: MemcachedTLSPort}}
}

details := &service.GenericServiceDetails{
Name: m.GetName(),
Namespace: m.GetNamespace(),
Expand All @@ -24,10 +34,7 @@ func HeadlessService(m *memcachedv1.Memcached) *corev1.Service {
common.AppSelector: m.GetName(),
"app": m.GetName(),
},
Ports: []corev1.ServicePort{
{Name: "memcached", Protocol: "TCP", Port: MemcachedPort},
{Name: "memcached-tls", Protocol: "TCP", Port: MemcachedTLSPort},
},
Ports: ports,
ClusterIP: "None",
}

Expand Down

0 comments on commit 9ea6507

Please sign in to comment.