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

Issue 479: Addressing Security vulnerabilities with authentication #488

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ spec:
from clients to controller and segment store See the following file
for a complete list of options: https://github.com/pravega/pravega/blob/master/documentation/src/docs/security/pravega-security-configurations.md'
properties:
controllerTokenSecret:
type: string
enabled:
description: Enabled specifies whether or not authentication is
enabled By default, authentication is not enabled
Expand All @@ -83,6 +85,8 @@ spec:
Parameters like username, password and acl optional - used only
by PasswordAuthHandler for authentication
type: string
segmentStoreTokenSecret:
type: string
type: object
bookkeeperUri:
description: BookkeeperUri specifies the hostname/IP address and port
Expand Down
2 changes: 2 additions & 0 deletions charts/pravega/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ The following table lists the configurable parameters of the pravega chart and t
| `tls` | Pravega security configuration passed to the Pravega processes | `{}` |
| `authentication.enabled` | Enable authentication to authorize client communication with Pravega | `false` |
| `authentication.passwordAuthSecret` | Name of Secret containing Password based Authentication Parameters, if authentication is enabled | |
| `authentication.segmentStoreTokenSecret` | Name of Secret containing tokenSigningkey for the ss, if authentication is enabled | |
| `authentication.controllerTokenSecret` | Name of Secret containing tokenSigningkey for controller, if authentication is enabled | |
| `zookeeperUri` | Zookeeper client service URI | `zookeeper-client:2181` |
| `bookkeeperUri` | Bookkeeper headless service URI | `bookkeeper-bookie-headless:3181` |
| `externalAccess.enabled` | Enable external access | `false` |
Expand Down
3 changes: 3 additions & 0 deletions charts/pravega/templates/pravega.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ spec:
enabled: {{ .Values.authentication.enabled }}
{{- if .Values.authentication.enabled }}
passwordAuthSecret: {{ .Values.authentication.passwordAuthSecret }}
segmentStoreTokenSecret: {{ .Values.authentication.segmentStoreTokenSecret }}
controllerTokenSecret: {{ .Values.authentication.controllerTokenSecret }}
{{- end }}

version: {{ .Values.version }}
zookeeperUri: {{ .Values.zookeeperUri }}
bookkeeperUri: {{ .Values.bookkeeperUri }}
Expand Down
4 changes: 4 additions & 0 deletions charts/pravega/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ authentication:
enabled: false
## passwordAuthSecret is ignored if authentication is disabled
passwordAuthSecret:
#segmentStoreToken is ignored if authentication is disabled
segmentStoreTokenSecret:
#controllerTokenSecret is ignored if authentication is disabled
controllerTokenSecret:

zookeeperUri: zookeeper-client:2181
bookkeeperUri: bookkeeper-bookie-headless:3181
Expand Down
4 changes: 4 additions & 0 deletions deploy/crds/pravega.pravega.io_pravegaclusters_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ spec:
from clients to controller and segment store See the following file
for a complete list of options: https://github.com/pravega/pravega/blob/master/documentation/src/docs/security/pravega-security-configurations.md'
properties:
controllerTokenSecret:
type: string
enabled:
description: Enabled specifies whether or not authentication is
enabled By default, authentication is not enabled
Expand All @@ -71,6 +73,8 @@ spec:
Parameters like username, password and acl optional - used only
by PasswordAuthHandler for authentication
type: string
segmentStoreTokenSecret:
type: string
type: object
bookkeeperUri:
description: BookkeeperUri specifies the hostname/IP address and port
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/pravega/v1beta1/pravegacluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ type AuthenticationParameters struct {
// name of Secret containing Password based Authentication Parameters like username, password and acl
// optional - used only by PasswordAuthHandler for authentication
PasswordAuthSecret string `json:"passwordAuthSecret,omitempty"`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For integration purposes, there needs to be a clear description of how to create the two secrets.
I can see through the code the format of the secret is straight forward, with one having one entry which is just a random string; and the other having two entries, one being the same random string, and one being a base64 encoded string of the admin/password, to be used with the password handler.

It won't be obvious to the common dweller though. :)

Having clear couple kubectl commands in the README that show exactly how to generate these 2 secrets is crucial so integrators know how to leverage this welcome enhancement.

Copy link
Contributor Author

@Prabhaker24 Prabhaker24 Jan 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sarlaccpit, I have added documentation in the auth section of our documentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the auth.md is very useful and detailed. It will be crucial information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sarlaccpit .

//name of secret containg TokenSigningKey
ControllerTokenSecret string `json:"controllerTokenSecret,omitempty"`

//name of secret containg TokenSigningKey and AuthToken
SegmentStoreTokenSecret string `json:"segmentStoreTokenSecret,omitempty"`
}

func (ap *AuthenticationParameters) IsEnabled() bool {
Expand Down
25 changes: 25 additions & 0 deletions pkg/controller/pravega/pravega_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pravega/pravega-operator/pkg/util"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -69,6 +70,7 @@ func makeControllerPodSpec(p *api.PravegaCluster) *corev1.PodSpec {
Args: []string{
"controller",
},
Env: ControllerDownwardAPIEnv(p),
Ports: []corev1.ContainerPort{
{
Name: "rest",
Expand Down Expand Up @@ -145,6 +147,29 @@ func makeControllerPodSpec(p *api.PravegaCluster) *corev1.PodSpec {
return podSpec
}

func ControllerDownwardAPIEnv(p *api.PravegaCluster) []corev1.EnvVar {

if p.Spec.Authentication.ControllerTokenSecret == "" {
return nil
}

env1 := []corev1.EnvVar{
{
Name: "controller_auth_tokenSigningKey",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: p.Spec.Authentication.ControllerTokenSecret,
},
Key: "controller_auth_tokenSigningKey",
},
},
},
}
return env1

}

func configureControllerTLSSecrets(podSpec *corev1.PodSpec, p *api.PravegaCluster) {
if p.Spec.TLS.IsSecureController() {
addSecretVolumeWithMount(podSpec, p, tlsVolumeName, p.Spec.TLS.Static.ControllerSecret, tlsVolumeName, tlsMountDir)
Expand Down
54 changes: 53 additions & 1 deletion pkg/controller/pravega/pravega_segmentstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pravega/pravega-operator/pkg/util"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -118,7 +119,7 @@ func makeSegmentstorePodSpec(p *api.PravegaCluster) corev1.PodSpec {
},
},
EnvFrom: environment,
Env: util.DownwardAPIEnv(),
Env: DownwardAPIEnv(p),
VolumeMounts: MakeSegmentStoreVolumeMount(p),
Resources: *p.Spec.Pravega.SegmentStoreResources,
ReadinessProbe: &corev1.Probe{
Expand Down Expand Up @@ -181,6 +182,57 @@ func makeSegmentstorePodSpec(p *api.PravegaCluster) corev1.PodSpec {
return podSpec
}

func DownwardAPIEnv(p *api.PravegaCluster) []corev1.EnvVar {
env1 := []corev1.EnvVar{
{
Name: "POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.name",
},
},
},
{
Name: "POD_NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.namespace",
},
},
},
}
if p.Spec.Authentication.SegmentStoreTokenSecret != "" {
envvar := corev1.EnvVar{
Name: "autoScale_tokenSigningKey",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: p.Spec.Authentication.SegmentStoreTokenSecret,
},
Key: "autoScale_tokenSigningKey",
},
},
}
env1 = append(env1, envvar)
envvar = corev1.EnvVar{
Name: "pravega_client_auth_token",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: p.Spec.Authentication.SegmentStoreTokenSecret,
},
Key: "pravega_client_auth_token",
},
},
}
env1 = append(env1, envvar)
}
return env1

}

func MakeSegmentStoreVolumeMount(p *api.PravegaCluster) []corev1.VolumeMount {
volumeMount := []corev1.VolumeMount{
{
Expand Down
23 changes: 0 additions & 23 deletions pkg/util/pravegacluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,29 +273,6 @@ func IsPodFaulty(pod *corev1.Pod) (bool, error) {
return false, nil
}

func DownwardAPIEnv() []corev1.EnvVar {
return []corev1.EnvVar{
{
Name: "POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.name",
},
},
},
{
Name: "POD_NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.namespace",
},
},
},
}
}

func PodAntiAffinity(component string, clusterName string) *corev1.Affinity {
return &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
Expand Down
8 changes: 0 additions & 8 deletions pkg/util/pravegacluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,6 @@ var _ = Describe("pravegacluster", func() {

})

Context("DownwardAPIEnv()", func() {

env := DownwardAPIEnv()
It("should not be nil", func() {
Ω(env).ShouldNot(BeNil())
})

})
Context("HealthcheckCommand()", func() {

out := HealthcheckCommand(1234)
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/resources/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ spec:
from clients to controller and segment store See the following file
for a complete list of options: https://github.com/pravega/pravega/blob/master/documentation/src/docs/security/pravega-security-configurations.md'
properties:
controllerTokenSecret:
description: name of secret containg TokenSigningKey
type: string
enabled:
description: Enabled specifies whether or not authentication is
enabled By default, authentication is not enabled
Expand All @@ -71,6 +74,9 @@ spec:
Parameters like username, password and acl optional - used only
by PasswordAuthHandler for authentication
type: string
segmentStoreTokenSecret:
description: name of secret containg TokenSigningKey and AuthToken
type: string
type: object
bookkeeperUri:
description: BookkeeperUri specifies the hostname/IP address and port
Expand Down
4 changes: 4 additions & 0 deletions tools/manifest_files/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ spec:
from clients to controller and segment store See the following file
for a complete list of options: https://github.com/pravega/pravega/blob/master/documentation/src/docs/security/pravega-security-configurations.md'
properties:
controllerTokenSecret:
type: string
enabled:
description: Enabled specifies whether or not authentication is
enabled By default, authentication is not enabled
Expand All @@ -80,6 +82,8 @@ spec:
Parameters like username, password and acl optional - used only
by PasswordAuthHandler for authentication
type: string
segmentStoreTokenSecret:
type: string
type: object
bookkeeperUri:
description: BookkeeperUri specifies the hostname/IP address and port
Expand Down