Skip to content

Commit

Permalink
Add audit log to Nutanix control plane template (#7190) (#7220)
Browse files Browse the repository at this point in the history
* Add audit log to Nutanix control plane template
 - add extra args for audit logs
 - add required extra volumes
 - change test manifests

* Fixed comments and missed unit test
# Conflicts:
#	pkg/providers/nutanix/config/cp-template.yaml
#	pkg/providers/nutanix/testdata/expected_cluster_api_server_cert_san_domain_name.yaml
#	pkg/providers/nutanix/testdata/expected_cluster_api_server_cert_san_ip.yaml
  • Loading branch information
jiayiwang7 authored Dec 20, 2023
1 parent b17be6f commit 1741b03
Show file tree
Hide file tree
Showing 11 changed files with 1,484 additions and 18 deletions.
39 changes: 29 additions & 10 deletions pkg/providers/nutanix/config/cp-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,35 @@ spec:
- localhost
- 127.0.0.1
- 0.0.0.0
{{- if .apiServerExtraArgs }}
extraArgs:
audit-policy-file: /etc/kubernetes/audit-policy.yaml
audit-log-path: /var/log/kubernetes/api-audit.log
audit-log-maxage: "30"
audit-log-maxbackup: "10"
audit-log-maxsize: "512"
{{- if .apiServerExtraArgs }}
{{ .apiServerExtraArgs.ToYaml | indent 10 }}
{{- end }}
{{- if .awsIamAuth}}
extraVolumes:
- hostPath: /var/lib/kubeadm/aws-iam-authenticator/
mountPath: /etc/kubernetes/aws-iam-authenticator/
name: authconfig
readOnly: false
- hostPath: /var/lib/kubeadm/aws-iam-authenticator/pki/
mountPath: /var/aws-iam-authenticator/
name: awsiamcert
readOnly: false
- hostPath: /etc/kubernetes/audit-policy.yaml
mountPath: /etc/kubernetes/audit-policy.yaml
name: audit-policy
pathType: File
readOnly: true
- hostPath: /var/log/kubernetes
mountPath: /var/log/kubernetes
name: audit-log-dir
pathType: DirectoryOrCreate
readOnly: false
{{- if .awsIamAuth}}
- hostPath: /var/lib/kubeadm/aws-iam-authenticator/
mountPath: /etc/kubernetes/aws-iam-authenticator/
name: authconfig
readOnly: false
- hostPath: /var/lib/kubeadm/aws-iam-authenticator/pki/
mountPath: /var/aws-iam-authenticator/
name: awsiamcert
readOnly: false
{{- end}}
controllerManager:
extraArgs:
Expand Down Expand Up @@ -235,6 +250,10 @@ spec:
owner: root:root
path: /var/lib/kubeadm/aws-iam-authenticator/pki/key.pem
{{- end}}
- content: |
{{ .auditPolicy | indent 8 }}
owner: root:root
path: /etc/kubernetes/audit-policy.yaml
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
Expand Down
8 changes: 8 additions & 0 deletions pkg/providers/nutanix/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/pkg/crypto"
"github.com/aws/eks-anywhere/pkg/providers"
"github.com/aws/eks-anywhere/pkg/providers/common"
"github.com/aws/eks-anywhere/pkg/registrymirror"
"github.com/aws/eks-anywhere/pkg/registrymirror/containerd"
"github.com/aws/eks-anywhere/pkg/templater"
Expand Down Expand Up @@ -158,7 +159,14 @@ func buildTemplateMapCP(
kubeletExtraArgs := clusterapi.SecureTlsCipherSuitesExtraArgs().
Append(clusterapi.ResolvConfExtraArgs(clusterSpec.Cluster.Spec.ClusterNetwork.DNS.ResolvConf)).
Append(clusterapi.ControlPlaneNodeLabelsExtraArgs(clusterSpec.Cluster.Spec.ControlPlaneConfiguration))

auditPolicy, err := common.GetAuditPolicy(clusterSpec.Cluster.Spec.KubernetesVersion)
if err != nil {
return nil, err
}

values := map[string]interface{}{
"auditPolicy": auditPolicy,
"apiServerExtraArgs": apiServerExtraArgs.ToPartialYaml(),
"clusterName": clusterSpec.Cluster.Name,
"controlPlaneEndpointIp": clusterSpec.Cluster.Spec.ControlPlaneConfiguration.Endpoint.Host,
Expand Down
43 changes: 43 additions & 0 deletions pkg/providers/nutanix/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (

"github.com/aws/eks-anywhere/internal/test"
anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/cluster"
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/release/api/v1alpha1"
)

//go:embed testdata/eksa-cluster.yaml
Expand Down Expand Up @@ -79,6 +81,47 @@ func TestNewNutanixTemplateBuilder(t *testing.T) {
assert.Equal(t, expectedSecret, secretSpec)
}

func TestNewNutanixTemplateBuilderGenerateCAPISpecControlPlaneFailure(t *testing.T) {
dcConf, machineConf, workerConfs := minimalNutanixConfigSpec(t)

t.Setenv(constants.EksaNutanixUsernameKey, "admin")
t.Setenv(constants.EksaNutanixPasswordKey, "password")
creds := GetCredsFromEnv()
builder := NewNutanixTemplateBuilder(&dcConf.Spec, &machineConf.Spec, &machineConf.Spec, workerConfs, creds, time.Now)
assert.NotNil(t, builder)

buildSpec := test.NewFullClusterSpec(t, "testdata/eksa-cluster.yaml")
buildSpec.VersionsBundles["no-version"] = &cluster.VersionsBundle{
KubeDistro: &cluster.KubeDistro{
Kubernetes: cluster.VersionedRepository{
Tag: "no-version",
Repository: "notarealrepo",
},
CoreDNS: cluster.VersionedRepository{
Tag: "no-version",
Repository: "notarealrepo",
},
Etcd: cluster.VersionedRepository{
Tag: "no-version",
Repository: "notarealrepo",
},
EtcdVersion: "no-version",
},
VersionsBundle: &v1alpha1.VersionsBundle{
Nutanix: v1alpha1.NutanixBundle{
KubeVip: v1alpha1.Image{
URI: "notarealuri",
},
},
},
}
buildSpec.Cluster.Spec.KubernetesVersion = "no-version"

cpSpec, err := builder.GenerateCAPISpecControlPlane(buildSpec)
assert.Error(t, err)
assert.Nil(t, cpSpec)
}

func TestNewNutanixTemplateBuilderGenerateSpecSecretFailure(t *testing.T) {
storedMarshal := jsonMarshal
jsonMarshal = fakemarshal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ spec:
- localhost
- 127.0.0.1
- 0.0.0.0
extraArgs:
audit-policy-file: /etc/kubernetes/audit-policy.yaml
audit-log-path: /var/log/kubernetes/api-audit.log
audit-log-maxage: "30"
audit-log-maxbackup: "10"
audit-log-maxsize: "512"
extraVolumes:
- hostPath: /etc/kubernetes/audit-policy.yaml
mountPath: /etc/kubernetes/audit-policy.yaml
name: audit-policy
pathType: File
readOnly: true
- hostPath: /var/log/kubernetes
mountPath: /var/log/kubernetes
name: audit-log-dir
pathType: DirectoryOrCreate
readOnly: false
controllerManager:
extraArgs:
enable-hostpath-provisioner: "true"
Expand Down Expand Up @@ -132,6 +149,164 @@ spec:
status: {}
owner: root:root
path: /etc/kubernetes/manifests/kube-vip.yaml
- content: |
apiVersion: audit.k8s.io/v1beta1
kind: Policy
rules:
# Log aws-auth configmap changes
- level: RequestResponse
namespaces: ["kube-system"]
verbs: ["update", "patch", "delete"]
resources:
- group: "" # core
resources: ["configmaps"]
resourceNames: ["aws-auth"]
omitStages:
- "RequestReceived"
# The following requests were manually identified as high-volume and low-risk,
# so drop them.
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core
resources: ["endpoints", "services", "services/status"]
- level: None
users: ["kubelet"] # legacy kubelet identity
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes", "nodes/status"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes", "nodes/status"]
- level: None
users:
- system:kube-controller-manager
- system:kube-scheduler
- system:serviceaccount:kube-system:endpoint-controller
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # core
resources: ["endpoints"]
- level: None
users: ["system:apiserver"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
# Don't log HPA fetching metrics.
- level: None
users:
- system:kube-controller-manager
verbs: ["get", "list"]
resources:
- group: "metrics.k8s.io"
# Don't log these read-only URLs.
- level: None
nonResourceURLs:
- /healthz*
- /version
- /swagger*
# Don't log events requests.
- level: None
resources:
- group: "" # core
resources: ["events"]
# node and pod status calls from nodes are high-volume and can be large, don't log responses for expected updates from nodes
- level: Request
users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
verbs: ["update","patch"]
resources:
- group: "" # core
resources: ["nodes/status", "pods/status"]
omitStages:
- "RequestReceived"
- level: Request
userGroups: ["system:nodes"]
verbs: ["update","patch"]
resources:
- group: "" # core
resources: ["nodes/status", "pods/status"]
omitStages:
- "RequestReceived"
# deletecollection calls can be large, don't log responses for expected namespace deletions
- level: Request
users: ["system:serviceaccount:kube-system:namespace-controller"]
verbs: ["deletecollection"]
omitStages:
- "RequestReceived"
# Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
# so only log at the Metadata level.
- level: Metadata
resources:
- group: "" # core
resources: ["secrets", "configmaps"]
- group: authentication.k8s.io
resources: ["tokenreviews"]
omitStages:
- "RequestReceived"
- level: Request
resources:
- group: ""
resources: ["serviceaccounts/token"]
# Get repsonses can be large; skip them.
- level: Request
verbs: ["get", "list", "watch"]
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apiextensions.k8s.io"
- group: "apiregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "metrics.k8s.io"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "scheduling.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
omitStages:
- "RequestReceived"
# Default level for known APIs
- level: RequestResponse
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apiextensions.k8s.io"
- group: "apiregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "metrics.k8s.io"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "scheduling.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
omitStages:
- "RequestReceived"
# Default level for all other requests.
- level: Metadata
omitStages:
- "RequestReceived"
owner: root:root
path: /etc/kubernetes/audit-policy.yaml
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
Expand Down
Loading

0 comments on commit 1741b03

Please sign in to comment.