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

Advanced audit as tech preview in origin #16128

Merged
merged 6 commits into from
Sep 22, 2017

Conversation

soltysh
Copy link
Member

@soltysh soltysh commented Sep 4, 2017

@sttts this enables the advance auditing features in origin, ptal

@openshift/api-review for config changes

@openshift-ci-robot openshift-ci-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Sep 4, 2017
@soltysh soltysh assigned sttts and unassigned mfojtik and bparees Sep 4, 2017
@mfojtik
Copy link
Contributor

mfojtik commented Sep 5, 2017

/approve

@openshift-merge-robot openshift-merge-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Sep 5, 2017
@openshift-ci-robot openshift-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Sep 19, 2017
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 19, 2017
@soltysh
Copy link
Member Author

soltysh commented Sep 19, 2017

@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 {
Copy link
Member Author

@soltysh soltysh Sep 19, 2017

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.

Copy link
Contributor

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 :)

@soltysh
Copy link
Member Author

soltysh commented Sep 19, 2017

@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.

@@ -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
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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).

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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.

@@ -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
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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.

Copy link
Member Author

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.

// Format of saved audits (legacy or json).
LogFormat string

// Path to a kubeconfig formatted filpe that defines the audit webhook configuration.
Copy link
Contributor

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 {
Copy link
Contributor

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"?

Copy link
Member Author

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,
Copy link
Contributor

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,
Copy link
Contributor

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 {
Copy link
Contributor

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?

Copy link
Member Author

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 {
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

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 {
Copy link
Contributor

Choose a reason for hiding this comment

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

missing validation on webhookconfigfile?

@soltysh
Copy link
Member Author

soltysh commented Sep 19, 2017

/retest

@@ -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.",
Copy link
Contributor

Choose a reason for hiding this comment

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

webhook or webHook?

Copy link
Member Author

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.

LogFormat string

// Path to a kubeconfig formatted file that defines the audit webhook configuration.
WebhookConfigFile string
Copy link
Contributor

Choose a reason for hiding this comment

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

WebhookKubeconfigFile would be clearer.

Copy link
Contributor

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?

Copy link
Member Author

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.

@soltysh
Copy link
Member Author

soltysh commented Sep 21, 2017

@sttts @deads2k @liggitt comments addressed ptal

@enj
Copy link
Contributor

enj commented Sep 21, 2017

@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)
Copy link
Member Author

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?

Copy link
Contributor

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.

// Path to a .kubeconfig formatted file that defines the audit webhook configuration.
WebHookKubeConfig string
// Strategy for sending audit events (block or batch).
WebHookMode string
Copy link
Contributor

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"))
Copy link
Contributor

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 {
Copy link
Contributor

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?

@deads2k
Copy link
Contributor

deads2k commented Sep 21, 2017

minor comments

@deads2k
Copy link
Contributor

deads2k commented Sep 21, 2017

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Sep 21, 2017
@openshift-merge-robot
Copy link
Contributor

[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 /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@openshift-merge-robot
Copy link
Contributor

Automatic merge from submit-queue (batch tested with PRs 16480, 16486, 16270, 16128, 16489)

@openshift-merge-robot openshift-merge-robot merged commit d2de881 into openshift:master Sep 22, 2017
@soltysh soltysh deleted the advanced_audit branch September 22, 2017 09:02
@soltysh
Copy link
Member Author

soltysh commented Sep 25, 2017

@soltysh
Copy link
Member Author

soltysh commented Sep 25, 2017

# 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
Copy link
Contributor

Choose a reason for hiding this comment

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

really ? merged ?!

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in #16534 /o\

@pweil- pweil- mentioned this pull request Sep 25, 2017
openshift-merge-robot added a commit that referenced this pull request Sep 25, 2017
Automatic merge from submit-queue

remove bad exit

@soltysh looks like you left an exit in there #16128

cc @mfojtik
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. needs-api-review size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants