-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Advanced audit as tech preview in origin #16128
Advanced audit as tech preview in origin #16128
Conversation
/approve |
aad80e2
to
2fc9096
Compare
@sttts mind double checking if we need more upstream PRs? I think I got the most important ones. |
} | ||
} | ||
// TODO: this should be done in config validation (along with the above) so we can provide | ||
// proper errors | ||
if err := cmdflags.Resolve(masterConfig.KubernetesMasterConfig.APIServerArguments, server.AddFlags); len(err) > 0 { | ||
if err := cmdflags.Resolve(args, server.AddFlags); len(err) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deads2k look what I found? I don't know how I have missed this in your PR 😨. Anyway, I've added extended test to verify that from now on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deads2k look what I found? I don't know how I have missed this in your PR . Anyway, I've added extended test to verify that from now on.
Yikes! Can't trust anyone these days :)
@deads2k this is ready for review as is. I don't want to grow this one bigger. I'm working on a followup where I turn on audit in the remaining api servers we have. |
2fc9096
to
933acd9
Compare
pkg/cmd/server/api/types.go
Outdated
@@ -474,6 +473,17 @@ type AuditConfig struct { | |||
MaximumRetainedFiles int | |||
// Maximum size in megabytes of the log file before it gets rotated. Defaults to 100MB. | |||
MaximumFileSizeMegabytes int | |||
|
|||
// Path to the file that defines the audit policy configuration. | |||
PolicyFile string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Policy files don't contain any sensitive data, right? If you had a similar config for an apiserver upstream, would you still use an external file reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upstream apiserver uses an external file, so do we. See https://github.com/kubernetes/kubernetes/blob/v1.7.0/cluster/gce/gci/configure-helper.sh#L490 as a reference. There are no sensitive data, this is a list of rules which requests should be logged at what level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upstream apiserver uses an external file, so do we. See https://github.com/kubernetes/kubernetes/blob/v1.7.0/cluster/gce/gci/configure-helper.sh#L490 as a reference. There are no sensitive data, this is a list of rules which requests should be logged at what level.
At the point where it is wired up we use an external file. At the point where our config is described, what is the benefit to a cluster-admin of managing a separate file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might get big and I think it's more handy to manage a totally separate file. Especially that this isn't the first one, based on what I've checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might get big and I think it's more handy to manage a totally separate file. Especially that this isn't the first one, based on what I've checked.
Others contain secrets. Of ones which don't contain secrets, I know of the scheduler file (used by a process we don't own) and some kubelet ones (also used by processes we don't own).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smarterclayton convinced me that this could be a file given potential future direction, but it still seems like a shame. See this other page for a complete response: xxxx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that same way we don't own audit and we won't anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that same way we don't own audit and we won't anymore.
That doesn't control our config file format. If we believed that, we'd have flags controlling our certs and flags for managing admission. The decision about how to expose the config for our server isn't based on how kube manages its config, but based upon how we'd like to manage it.
Owning the code backing audit does not mean that everyone must choose to expose it half in flags and half in files. You can see you aren't building that here.
pkg/cmd/server/api/types.go
Outdated
@@ -474,6 +473,17 @@ type AuditConfig struct { | |||
MaximumRetainedFiles int | |||
// Maximum size in megabytes of the log file before it gets rotated. Defaults to 100MB. | |||
MaximumFileSizeMegabytes int | |||
|
|||
// Path to the file that defines the audit policy configuration. | |||
PolicyFile string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't specified, the default behavior out should remain consistent with what it was before, right? Log everything as I recall? Either way, it should be described.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this file isn't specified, we fallback to the old audit scheme. So that after an upgrade we work the same way, as we did before. I turn the advanced audit on this config value being present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this file isn't specified, we fallback to the old audit scheme. So that after an upgrade we work the same way, as we did before. I turn the advanced audit on this config value being present.
You need to document what it does. It seems weird that not specifying a file and specifying an empty file give two different outcomes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An empty file means you wanted to give it and you just messed up its contents. Its lack, though means we're working in the old audit mode, for backwards compatibility. I'll be updating our docs with the advanced bits.
pkg/cmd/server/api/types.go
Outdated
// Format of saved audits (legacy or json). | ||
LogFormat string | ||
|
||
// Path to a kubeconfig formatted filpe that defines the audit webhook configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typoe: file
if err != nil { | ||
validationResults.AddErrors(field.Invalid(fldPath.Child("policyFile"), config.PolicyFile, err.Error())) | ||
} | ||
if len(policy.Rules) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why shouldn't this be treated the same as "no policy file specified"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's how it's done upstream, I want to be consistent with that behavior.
} | ||
} | ||
if len(config.LogFormat) > 0 && config.LogFormat != auditlog.FormatLegacy && config.LogFormat != auditlog.FormatJson { | ||
validationResults.AddErrors(field.Invalid(fldPath.Child("logFormat"), config.LogFormat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
field.NotSupported
fmt.Sprintf("invalid audit log format, allowed formats are %q", strings.Join(auditlog.AllowedFormats, ",")))) | ||
} | ||
if len(config.WebhookMode) > 0 && config.WebhookMode != auditwebhook.ModeBatch && config.WebhookMode != auditwebhook.ModeBlocking { | ||
validationResults.AddErrors(field.Invalid(fldPath.Child("logFormat"), config.WebhookMode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
field.NotSupported
validationResults.AddErrors(field.Invalid(fldPath.Child("logFormat"), config.LogFormat, | ||
fmt.Sprintf("invalid audit log format, allowed formats are %q", strings.Join(auditlog.AllowedFormats, ",")))) | ||
} | ||
if len(config.WebhookMode) > 0 && config.WebhookMode != auditwebhook.ModeBatch && config.WebhookMode != auditwebhook.ModeBlocking { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is auditFilePath + webhook valid. What does it mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It means you're getting audit send to both places. In the webhook config file you can have multiple backends and we'll send to all of them.
validationResults.AddErrors(field.Invalid(fldPath.Child("logFormat"), config.LogFormat, | ||
fmt.Sprintf("invalid audit log format, allowed formats are %q", strings.Join(auditlog.AllowedFormats, ",")))) | ||
} | ||
if len(config.WebhookMode) > 0 && config.WebhookMode != auditwebhook.ModeBatch && config.WebhookMode != auditwebhook.ModeBlocking { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
webhook mode shouldn't be set without the webhookconfigfile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll add another check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll do a different check, I'll check the mode only when file is passed.
@@ -253,6 +259,24 @@ func ValidateAuditConfig(config api.AuditConfig, fldPath *field.Path) Validation | |||
validationResults.AddErrors(field.Invalid(fldPath.Child("maximumFileSizeMegabytes"), config.MaximumFileSizeMegabytes, "must be greater than or equal to 0")) | |||
} | |||
|
|||
if len(config.PolicyFile) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing validation on webhookconfigfile?
933acd9
to
b40bc9d
Compare
/retest |
pkg/cmd/server/api/v1/swagger_doc.go
Outdated
@@ -90,6 +90,10 @@ var map_AuditConfig = map[string]string{ | |||
"maximumFileRetentionDays": "Maximum number of days to retain old log files based on the timestamp encoded in their filename.", | |||
"maximumRetainedFiles": "Maximum number of old log files to retain.", | |||
"maximumFileSizeMegabytes": "Maximum size in megabytes of the log file before it gets rotated. Defaults to 100MB.", | |||
"policyFile": "Path to the file that defines the audit policy configuration.", | |||
"logFormat": "Format of saved audits (legacy or json).", | |||
"webhookConfigFile": "Path to a kubeconfig formatted file that defines the audit webhook configuration.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
webhook or webHook?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we're using webHook
in builds, I'll change it.
pkg/cmd/server/api/types.go
Outdated
LogFormat string | ||
|
||
// Path to a kubeconfig formatted file that defines the audit webhook configuration. | ||
WebhookConfigFile string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebhookKubeconfigFile would be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebhookKubeconfigFile would be clearer.
Our config uses KubeConfig, but as I recall there are special allowances for webhooks to set a termination url path, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but the file format follows KubeConfig, I've already applied that change.
b40bc9d
to
61f4dfe
Compare
@openshift/sig-security |
@@ -55,6 +57,10 @@ func addVersionsToScheme(externalVersions ...schema.GroupVersion) { | |||
continue | |||
} | |||
} | |||
// we additionally need to enable audit versions, since we embed the audit | |||
// policy file inside master-config.yaml | |||
audit.AddToScheme(configapi.Scheme) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deads2k is this the right place to install audit types, or you want it to move it somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deads2k is this the right place to install audit types, or you want it to move it somewhere else?
Can you simplify the path leading here? I don't think we should pretend with externalVersions
anymore. We have a hardcoded set of things we add and we simply add them.
pkg/cmd/server/api/types.go
Outdated
// Path to a .kubeconfig formatted file that defines the audit webhook configuration. | ||
WebHookKubeConfig string | ||
// Strategy for sending audit events (block or batch). | ||
WebHookMode string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a typed string
@@ -253,6 +262,52 @@ func ValidateAuditConfig(config api.AuditConfig, fldPath *field.Path) Validation | |||
validationResults.AddErrors(field.Invalid(fldPath.Child("maximumFileSizeMegabytes"), config.MaximumFileSizeMegabytes, "must be greater than or equal to 0")) | |||
} | |||
|
|||
// setting policy file will turn the advanced auditing on | |||
if config.PolicyConfiguration != nil && len(config.PolicyFile) > 0 { | |||
validationResults.AddWarnings(field.Forbidden(fldPath.Child("policyFile"), "both policyFile and policyConfiguration are specified, the latter will take precedence")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's fail on this.
validationResults.AddErrors(field.Required(fldPath.Child("auditFilePath"), "advanced audit requires a separate log file")) | ||
} | ||
|
||
if len(config.WebHookKubeConfig) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we have a else preventing a webhookmode is there isn't a webhookkubeconfig? Either both or none, right?
minor comments |
61f4dfe
to
e8e6700
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: deads2k, mfojtik, soltysh The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue (batch tested with PRs 16480, 16486, 16270, 16128, 16489) |
# put change there - only want this for extended tests | ||
os::log::info "Turn on audit logging" | ||
cp "${SERVER_CONFIG_DIR}/master/master-config.yaml" "${SERVER_CONFIG_DIR}/master/master-config.orig2.yaml" | ||
openshift ex config patch "${SERVER_CONFIG_DIR}/master/master-config.orig2.yaml" --patch="{\"auditConfig\": {\"enabled\": true}}" > "${SERVER_CONFIG_DIR}/master/master-config.yaml" | ||
openshift ex config patch "${SERVER_CONFIG_DIR}/master/master-config.orig2.yaml" --patch="{\"auditConfig\": {\"enabled\": true, \"auditFilePath\": \"${LOG_DIR}/audit.log\"}}" > "${SERVER_CONFIG_DIR}/master/master-config.yaml" | ||
exit 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really ? merged ?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in #16534 /o\
@sttts this enables the advance auditing features in origin, ptal
@openshift/api-review for config changes