Most similar to AuditPolicyConfiguration / –audit-policy-file
It can’t really have a default value, because you need to specify a webhook url.
Most similar to LogMaxAge / –audit-log-maxage INT
The default is 10s, but I’m unsure we should specificy it if we aren’t provided it as a config option.
--audit-webhook-config-file string Path to a kubeconfig formatted file that defines the audit webhook configuration. Requires the 'AdvancedAuditing' feature gate. --audit-webhook-mode string Strategy for sending audit events. Blocking indicates sending events should block server responses. Batch causes the backend to buffer and write events asynchronously. Known modes are batch,blocking. (default "batch") --audit-webhook-initial-backoff duration The amount of time to wait before retrying the first failed request. (default 10s) --audit-webhook-batch-buffer-size int The size of the buffer to store events before batching and writing. Only used in batch mode. (default 10000) --audit-webhook-batch-max-size int The maximum size of a batch. Only used in batch mode. (default 400) --audit-webhook-batch-max-wait duration The amount of time to wait before force writing the batch that hadn't reached the max size. Only used in batch mode. (default 30s) --audit-webhook-batch-throttle-burst int Maximum number of requests sent at the same moment if ThrottleQPS was not utilized before. Only used in batch mode. (default 15) --audit-webhook-batch-throttle-enable Whether batching throttling is enabled. Only used in batch mode. (default true) --audit-webhook-batch-throttle-qps float32 Maximum average number of batches per second. Only used in batch mode. (default 10)
// AuditPolicyConfiguration holds the options for configuring the api server audit policy.
type AuditPolicyConfiguration struct {
// Path is the local path to an audit policy.
Path string
// LogDir is the local path to the directory where logs should be stored.
LogDir string
// LogMaxAge is the number of days logs will be stored for. 0 indicates forever.
LogMaxAge *int32
// WebhookConfigPath is the local path to webhook policy.
WebhookConfigPath string
// WebhookInitialBackoff is the time to wait (in seconds) before retrying the first failed request.
WebhookInitialBackoff *int32 //defaults to 10s if not provided
//TODO(chuckha) add other options for audit policy.
}
// AuditPolicyConfiguration holds the options for configuring the api server audit policy.
type AuditPolicyConfiguration struct {
// Path is the local path to an audit policy.
Path string `json:"path"`
// LogDir is the local path to the directory where logs should be stored.
LogDir string `json:"logDir"`
// LogMaxAge is the number of days logs will be stored for. 0 indicates forever.
LogMaxAge *int32 `json:"logMaxAge,omitempty"`
// WebhookConfigPath is the local path to webhook policy.
WebhookConfigPath string `json:"webhookConfigPath"`
// WebhookInitialBackoff is the time to wait (in seconds) before retrying the first failed request.
WebhookInitialBackoff *int32 `json:"webhookInitialBackoff,omitempty"`
//TODO(chuckha) add other options for audit policy.
}
var (
// DefaultAuditPolicyLogMaxAge is defined as a var so its address can be taken
// It is the number of days to store audit logs
DefaultAuditPolicyLogMaxAge = int32(2)
// POSSIBLY NOT NEEDED, IF WE DO NOT WANT A DEFAULT
// DefaultAuditWebhookInitialBackoff also needs it's address taken
// It is the number of seconds to wait before retrying the first failed request.
DefaultAuditWebhookInitialBackoff = int32(2)
)
// SetDefaults_AuditPolicyConfiguration sets default values for the AuditPolicyConfiguration
func SetDefaults_AuditPolicyConfiguration(obj *MasterConfiguration) {
if obj.AuditPolicyConfiguration.LogDir == "" {
obj.AuditPolicyConfiguration.LogDir = constants.StaticPodAuditPolicyLogDir
}
if obj.AuditPolicyConfiguration.LogMaxAge == nil {
obj.AuditPolicyConfiguration.LogMaxAge = &DefaultAuditPolicyLogMaxAge
}
// POSSIBLY NOT NEEDED, IF WE DO NOT WANT A DEFAULT
if obj.AuditPolicyConfiguration.WebhookInitialBackoff == nil {
obj.AuditPolicyConfiguration.WebhookInitialBackoff = &DefaultAuditWebhookInitialBackoff
}
}
app/constants/constants.go::kubeaudit
// KubeAuditPolicyVolumeName is the name of the volume that will contain the audit policy
KubeAuditPolicyVolumeName = "audit"
// AuditPolicyDir is the directory that will contain the audit policy
AuditPolicyDir = "audit"
// AuditPolicyFile is the name of the audit policy file itself
AuditPolicyFile = "audit.yaml"
// AuditWebhookConfigFile is the name of the audit webhook config file itself
AuditWebhookConfigFile = "webhook.yaml"
// AuditPolicyLogFile is the name of the file audit logs get written to
AuditPolicyLogFile = "audit.log"
// KubeAuditPolicyLogVolumeName is the name of the volume that will contain the audit logs
KubeAuditPolicyLogVolumeName = "audit-log"
// StaticPodAuditPolicyLogDir is the name of the directory in the static pod that will have the audit logs
StaticPodAuditPolicyLogDir = "/var/log/kubernetes/audit"
app/constants/constants.go:: getstaticpodauditpolicyfile
// GetStaticPodAuditPolicyFile returns the path to the audit policy file within a static pod
func GetStaticPodAuditPolicyFile() string {
return filepath.Join(KubernetesDir, AuditPolicyDir, AuditPolicyFile)
}
// GetStaticPodAuditWebhookConfigFile returns the path to the audit webhook config file within a static pod
func GetStaticPodAuditWebhookConfigFile() string {
return filepath.Join(KubernetesDir, AuditPolicyDir, AuditWebhookConfigFile)
}
if features.Enabled(i.cfg.FeatureGates, features.Auditing) {
// Setup the AuditPolicy (either it was passed in and exists or it wasn't passed in and generate a default policy)
if i.cfg.AuditPolicyConfiguration.Path != "" {
// TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log.
if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.Path); err != nil {
return fmt.Errorf("error getting file info for audit policy file %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
}
} else {
i.cfg.AuditPolicyConfiguration.Path = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile)
if err := auditutil.CreateDefaultAuditLogPolicy(i.cfg.AuditPolicyConfiguration.Path); err != nil {
return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
}
}
// Verify the AuditWebhookConfigFile (verify it exists if it was passed in)
if i.cfg.AuditPolicyConfiguration.WebhookConfigPath != "" {
// TODO(chuckha) ensure passed in audit webhook config is valid so users don't have to find the error in the api server log.
if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.WebhookConfigPath); err != nil {
return fmt.Errorf("error getting file info for audit webhook config file %q [%v]", i.cfg.AuditPolicyConfiguration.WebhookConfigPath, err)
}
} else {
i.cfg.AuditPolicyConfiguration.WebhookConfigPath = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditWebhookConfigFile)
if err := auditutil.CreateDefaultAuditWebhookConfig(i.cfg.AuditPolicyConfiguration.WebhookConfigPath); err != nil {
return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.WebhookConfigPath, err)
}
}
}
if features.Enabled(cfg.FeatureGates, features.Auditing) {
command = append(command, "--audit-policy-file="+kubeadmconstants.GetStaticPodAuditPolicyFile())
command = append(command, "--audit-log-path="+filepath.Join(kubeadmconstants.StaticPodAuditPolicyLogDir, kubeadmconstants.AuditPolicyLogFile))
if cfg.AuditPolicyConfiguration.LogMaxAge == nil {
command = append(command, fmt.Sprintf("--audit-log-maxage=%d", kubeadmapiext.DefaultAuditPolicyLogMaxAge))
} else {
command = append(command, fmt.Sprintf("--audit-log-maxage=%d", *cfg.AuditPolicyConfiguration.LogMaxAge))
}
if cfg.AuditPolicyConfiguration.WebhookConfigPath != nil {
command = append(command, "--audit-webhook-config-file="+kubeadmconstants.GetStaticPodAuditWebhookConfigFile())
}
if cfg.AuditPolicyConfiguration.WebhookInitialBackoff != nil {
command = append(command, fmt.Sprintf("--audit-webhook-initial-backoff=%d", *cfg.AuditPolicyConfiguration.WebhookInitialBackoff))
}
}
if features.Enabled(cfg.FeatureGates, features.Auditing) {
// Read-only mount for the audit policy file.
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyVolumeName, cfg.AuditPolicyConfiguration.Path, kubeadmconstants.GetStaticPodAuditPolicyFile(), true, &hostPathFile)
// Read-only mount for the audit webhook config file.
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyVolumeName, cfg.AuditPolicyConfiguration.Path, kubeadmconstants.GetStaticPodAuditWebhookConfigFile(), true, &hostPathFile)
// Write mount for the audit logs.
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyLogVolumeName, cfg.AuditPolicyConfiguration.LogDir, kubeadmconstants.StaticPodAuditPolicyLogDir, false, &hostPathDirectoryOrCreate)
}
// CreateDefaultAuditLogPolicy writes the default audit log policy to disk.
func CreateDefaultAuditLogPolicy(policyFile string) error {
policy := auditv1beta1.Policy{
TypeMeta: metav1.TypeMeta{
APIVersion: "audit.k8s.io/v1beta1",
Kind: "Policy",
},
Rules: []auditv1beta1.PolicyRule{
{
Level: auditv1beta1.LevelMetadata,
},
},
}
return writePolicyToDisk(policyFile, &policy)
}
// CreateDefaultAuditWebhookConfig writes the default audit webhook config to disk.
func CreateDefaultAuditWebhookConfig(webhookConfigFile string) error {
// We do not have a default, but we do have a volume mapping for this file
return os.OpenFile(name, os.O_RDONLY|os.O_CREATE, 0644)
}
func writePolicyToDisk(policyFile string, policy *auditv1beta1.Policy) error {
// creates target folder if not already exists
if err := os.MkdirAll(filepath.Dir(policyFile), 0700); err != nil {
return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(policyFile), err)
}
// Registers auditv1beta1 with the runtime Scheme
auditv1beta1.AddToScheme(scheme.Scheme)
// writes the policy to disk
serialized, err := util.MarshalToYaml(policy, auditv1beta1.SchemeGroupVersion)
if err != nil {
return fmt.Errorf("failed to marshal audit policy to YAML: %v", err)
}
if err := ioutil.WriteFile(policyFile, serialized, 0600); err != nil {
return fmt.Errorf("failed to write audit policy to %v: %v", policyFile, err)
}
return nil
}
func writeWebhookConfigToDisk(webhookConfigFile string, policy *auditv1beta1.Policy) error {
// creates target folder if not already exists
if err := os.MkdirAll(filepath.Dir(webhookConfigFile), 0700); err != nil {
return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(webhookConfigFile), err)
}
// Registers auditv1beta1 with the runtime Scheme
auditv1beta1.AddToScheme(scheme.Scheme)
// writes the policy to disk
serialized, err := util.MarshalToYaml(policy, auditv1beta1.SchemeGroupVersion)
if err != nil {
return fmt.Errorf("failed to marshal audit webhook config to YAML: %v", err)
}
if err := ioutil.WriteFile(webhookConfigFile, serialized, 0600); err != nil {
return fmt.Errorf("failed to write audit webhook config to %v: %v", webhookConfigFile, err)
}
return nil
}
Fuzzer is looking for sample data types to generate fuzzer functions.
What will the mount be called?
I see audit audit-log I’m unsure if the audit KubAuditPolicyVolumeName of audit, is a single volume with a subdir I can place the webhook.yml into.
I think having a different name, within the same volume mount should work.
Added the other file we add on disk
A default AuditWebhookConfigFile is basically an empty file… Let’s figure out if the mount stuff works if we disable it’s creation.... less tests and code.
It looks like this is to test upgrades.... not sure what we should test for here… possible changing the webhook endpoint?
Tests command line arguments… should explore this a bit once we get it working.
Links works if the file is dropped into /cmd/kubeadm of a https://github.com/kubernetes/kubernetes checkout.