Guest User

Untitled

a guest
Apr 26th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.34 KB | None | 0 0
  1. * audit-webhook needs
  2.  
  3. ** TODO --audit-webhook-config-file
  4.  
  5. Most similar to AuditPolicyConfiguration / --audit-policy-file
  6.  
  7. It can't really have a default value, because you need to specify a webhook url.
  8.  
  9. ** TODO --audit-webhook-initial-backoff
  10.  
  11. Most similar to LogMaxAge / --audit-log-maxage INT
  12.  
  13. The default is 10s, but I'm unsure we should specificy it if we aren't provided it as a config option.
  14.  
  15. ** TODO add other options for audit webhook
  16. #+BEGIN_EXAMPLE
  17. --audit-webhook-config-file string Path to a kubeconfig formatted file that defines the audit webhook configuration. Requires the 'AdvancedAuditing' feature gate.
  18. --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")
  19. --audit-webhook-initial-backoff duration The amount of time to wait before retrying the first failed request. (default 10s)
  20. --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)
  21. --audit-webhook-batch-max-size int The maximum size of a batch. Only used in batch mode. (default 400)
  22. --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)
  23. --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)
  24. --audit-webhook-batch-throttle-enable Whether batching throttling is enabled. Only used in batch mode. (default true)
  25. --audit-webhook-batch-throttle-qps float32 Maximum average number of batches per second. Only used in batch mode. (default 10)
  26. #+END_EXAMPLE
  27.  
  28. * Types, Defaults, and Constants
  29.  
  30. ** [[file:app/apis/kubeadm/types.go::AuditPolicyConfiguration%20holds%20the%20options][app/apis/kubeadm/types.go::AuditPolicyConfiguration struct]]
  31.  
  32. #+BEGIN_SRC go
  33. // AuditPolicyConfiguration holds the options for configuring the api server audit policy.
  34. type AuditPolicyConfiguration struct {
  35. // Path is the local path to an audit policy.
  36. Path string
  37. // LogDir is the local path to the directory where logs should be stored.
  38. LogDir string
  39. // LogMaxAge is the number of days logs will be stored for. 0 indicates forever.
  40. LogMaxAge *int32
  41. // WebhookConfigPath is the local path to webhook policy.
  42. WebhookConfigPath string
  43. // WebhookInitialBackoff is the time to wait (in seconds) before retrying the first failed request.
  44. WebhookInitialBackoff *int32 //defaults to 10s if not provided
  45. //TODO(chuckha) add other options for audit policy.
  46. }
  47. #+END_SRC
  48. ** [[file:app/apis/kubeadm/v1alpha1/types.go::type%20AuditPolicyConfiguration%20struct%20{][app/apis/kubeadm/v1alpha1/types.go::AuditPolicyConfiguration struct]]
  49.  
  50. #+BEGIN_SRC go
  51. // AuditPolicyConfiguration holds the options for configuring the api server audit policy.
  52. type AuditPolicyConfiguration struct {
  53. // Path is the local path to an audit policy.
  54. Path string `json:"path"`
  55. // LogDir is the local path to the directory where logs should be stored.
  56. LogDir string `json:"logDir"`
  57. // LogMaxAge is the number of days logs will be stored for. 0 indicates forever.
  58. LogMaxAge *int32 `json:"logMaxAge,omitempty"`
  59. // WebhookConfigPath is the local path to webhook policy.
  60. WebhookConfigPath string `json:"webhookConfigPath"`
  61. // WebhookInitialBackoff is the time to wait (in seconds) before retrying the first failed request.
  62. WebhookInitialBackoff *int32 `json:"webhookInitialBackoff,omitempty"`
  63. //TODO(chuckha) add other options for audit policy.
  64. }
  65. #+END_SRC
  66.  
  67. ** [[file:app/apis/kubeadm/v1alpha1/defaults.go::DefaultAuditPolicyLogMaxAge%20=%20int32(2)][app/apis/kubeadm/v1alpha1/default.go::DefaultAuditPolicyLogMaxAge =]]
  68.  
  69. #+BEGIN_SRC go
  70. var (
  71. // DefaultAuditPolicyLogMaxAge is defined as a var so its address can be taken
  72. // It is the number of days to store audit logs
  73. DefaultAuditPolicyLogMaxAge = int32(2)
  74. // POSSIBLY NOT NEEDED, IF WE DO NOT WANT A DEFAULT
  75. // DefaultAuditWebhookInitialBackoff also needs it's address taken
  76. // It is the number of seconds to wait before retrying the first failed request.
  77. DefaultAuditWebhookInitialBackoff = int32(2)
  78. )
  79. #+END_SRC
  80.  
  81. ** [[file:app/apis/kubeadm/v1alpha1/defaults.go::func%20SetDefaults_AuditPolicyConfiguration(][app/apis/kubeadm/v1alpha1/default.go::func SetDefaults_AuditPolicyConfiguration(]]
  82.  
  83. #+BEGIN_SRC go
  84. // SetDefaults_AuditPolicyConfiguration sets default values for the AuditPolicyConfiguration
  85. func SetDefaults_AuditPolicyConfiguration(obj *MasterConfiguration) {
  86. if obj.AuditPolicyConfiguration.LogDir == "" {
  87. obj.AuditPolicyConfiguration.LogDir = constants.StaticPodAuditPolicyLogDir
  88. }
  89. if obj.AuditPolicyConfiguration.LogMaxAge == nil {
  90. obj.AuditPolicyConfiguration.LogMaxAge = &DefaultAuditPolicyLogMaxAge
  91. }
  92. // POSSIBLY NOT NEEDED, IF WE DO NOT WANT A DEFAULT
  93. if obj.AuditPolicyConfiguration.WebhookInitialBackoff == nil {
  94. obj.AuditPolicyConfiguration.WebhookInitialBackoff = &DefaultAuditWebhookInitialBackoff
  95. }
  96. }
  97. #+END_SRC
  98.  
  99. [[file:app/constants/constants.go::kubeauditpolicyvolumename][app/constants/constants.go::kubeaudit]]
  100.  
  101. #+BEGIN_SRC go
  102. // KubeAuditPolicyVolumeName is the name of the volume that will contain the audit policy
  103. KubeAuditPolicyVolumeName = "audit"
  104. // AuditPolicyDir is the directory that will contain the audit policy
  105. AuditPolicyDir = "audit"
  106. // AuditPolicyFile is the name of the audit policy file itself
  107. AuditPolicyFile = "audit.yaml"
  108. // AuditWebhookConfigFile is the name of the audit webhook config file itself
  109. AuditWebhookConfigFile = "webhook.yaml"
  110. // AuditPolicyLogFile is the name of the file audit logs get written to
  111. AuditPolicyLogFile = "audit.log"
  112. // KubeAuditPolicyLogVolumeName is the name of the volume that will contain the audit logs
  113. KubeAuditPolicyLogVolumeName = "audit-log"
  114. // StaticPodAuditPolicyLogDir is the name of the directory in the static pod that will have the audit logs
  115. StaticPodAuditPolicyLogDir = "/var/log/kubernetes/audit"
  116. #+END_SRC
  117.  
  118. [[file:app/constants/constants.go::/%20getstaticpodauditpolicyfile%20returns%20the%20path%20to%20the%20audit%20policy%20file%20within%20a%20static%20pod][app/constants/constants.go:: getstaticpodauditpolicyfile]]
  119.  
  120. #+BEGIN_SRC go
  121. // GetStaticPodAuditPolicyFile returns the path to the audit policy file within a static pod
  122. func GetStaticPodAuditPolicyFile() string {
  123. return filepath.Join(KubernetesDir, AuditPolicyDir, AuditPolicyFile)
  124. }
  125. // GetStaticPodAuditWebhookConfigFile returns the path to the audit webhook config file within a static pod
  126. func GetStaticPodAuditWebhookConfigFile() string {
  127. return filepath.Join(KubernetesDir, AuditPolicyDir, AuditWebhookConfigFile)
  128. }
  129. #+END_SRC
  130.  
  131. * Implementation
  132. ** [[file:app/cmd/init.go::if%20features.Enabled(][app/cmd/init.go::if features.Enabled(]]
  133.  
  134. #+BEGIN_SRC go
  135. if features.Enabled(i.cfg.FeatureGates, features.Auditing) {
  136. // Setup the AuditPolicy (either it was passed in and exists or it wasn't passed in and generate a default policy)
  137. if i.cfg.AuditPolicyConfiguration.Path != "" {
  138. // TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log.
  139. if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.Path); err != nil {
  140. return fmt.Errorf("error getting file info for audit policy file %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
  141. }
  142. } else {
  143. i.cfg.AuditPolicyConfiguration.Path = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile)
  144. if err := auditutil.CreateDefaultAuditLogPolicy(i.cfg.AuditPolicyConfiguration.Path); err != nil {
  145. return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
  146. }
  147. }
  148. // Verify the AuditWebhookConfigFile (verify it exists if it was passed in)
  149. if i.cfg.AuditPolicyConfiguration.WebhookConfigPath != "" {
  150. // TODO(chuckha) ensure passed in audit webhook config is valid so users don't have to find the error in the api server log.
  151. if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.WebhookConfigPath); err != nil {
  152. return fmt.Errorf("error getting file info for audit webhook config file %q [%v]", i.cfg.AuditPolicyConfiguration.WebhookConfigPath, err)
  153. }
  154. } else {
  155. i.cfg.AuditPolicyConfiguration.WebhookConfigPath = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditWebhookConfigFile)
  156. if err := auditutil.CreateDefaultAuditWebhookConfig(i.cfg.AuditPolicyConfiguration.WebhookConfigPath); err != nil {
  157. return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.WebhookConfigPath, err)
  158. }
  159. }
  160.  
  161. }
  162. #+END_SRC
  163. ** [[file:app/phases/controlplane/manifests.go::features.auditing][app/phases/controlplane/manifests.go features.auditing]]
  164.  
  165. #+BEGIN_SRC go
  166. if features.Enabled(cfg.FeatureGates, features.Auditing) {
  167. command = append(command, "--audit-policy-file="+kubeadmconstants.GetStaticPodAuditPolicyFile())
  168. command = append(command, "--audit-log-path="+filepath.Join(kubeadmconstants.StaticPodAuditPolicyLogDir, kubeadmconstants.AuditPolicyLogFile))
  169. if cfg.AuditPolicyConfiguration.LogMaxAge == nil {
  170. command = append(command, fmt.Sprintf("--audit-log-maxage=%d", kubeadmapiext.DefaultAuditPolicyLogMaxAge))
  171. } else {
  172. command = append(command, fmt.Sprintf("--audit-log-maxage=%d", *cfg.AuditPolicyConfiguration.LogMaxAge))
  173. }
  174. if cfg.AuditPolicyConfiguration.WebhookConfigPath != nil {
  175. command = append(command, "--audit-webhook-config-file="+kubeadmconstants.GetStaticPodAuditWebhookConfigFile())
  176. }
  177. if cfg.AuditPolicyConfiguration.WebhookInitialBackoff != nil {
  178. command = append(command, fmt.Sprintf("--audit-webhook-initial-backoff=%d", *cfg.AuditPolicyConfiguration.WebhookInitialBackoff))
  179. }
  180. }
  181. #+END_SRC
  182.  
  183. ** [[file:app/phases/controlplane/volumes.go::/%20Read-only%20mount%20for%20the%20audit%20policy%20file.][app/phases/controlplane/volumes.go::/ Mounts for audit policy file / audit logs]]
  184.  
  185. #+BEGIN_SRC go
  186. if features.Enabled(cfg.FeatureGates, features.Auditing) {
  187. // Read-only mount for the audit policy file.
  188. mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyVolumeName, cfg.AuditPolicyConfiguration.Path, kubeadmconstants.GetStaticPodAuditPolicyFile(), true, &hostPathFile)
  189. // Read-only mount for the audit webhook config file.
  190. mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyVolumeName, cfg.AuditPolicyConfiguration.Path, kubeadmconstants.GetStaticPodAuditWebhookConfigFile(), true, &hostPathFile)
  191. // Write mount for the audit logs.
  192. mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeAuditPolicyLogVolumeName, cfg.AuditPolicyConfiguration.LogDir, kubeadmconstants.StaticPodAuditPolicyLogDir, false, &hostPathDirectoryOrCreate)
  193. }
  194. #+END_SRC
  195. ** [[file:app/util/audit/utils.go::func%20writePolicyToDisk(policyFile%20string,%20policy%20*auditv1beta1.Policy)%20error%20{][app/util/audit/utils.go::func writePolicyToDisk(policyFile string]]
  196.  
  197. #+BEGIN_SRC go
  198. // CreateDefaultAuditLogPolicy writes the default audit log policy to disk.
  199. func CreateDefaultAuditLogPolicy(policyFile string) error {
  200. policy := auditv1beta1.Policy{
  201. TypeMeta: metav1.TypeMeta{
  202. APIVersion: "audit.k8s.io/v1beta1",
  203. Kind: "Policy",
  204. },
  205. Rules: []auditv1beta1.PolicyRule{
  206. {
  207. Level: auditv1beta1.LevelMetadata,
  208. },
  209. },
  210. }
  211. return writePolicyToDisk(policyFile, &policy)
  212. }
  213.  
  214. // CreateDefaultAuditWebhookConfig writes the default audit webhook config to disk.
  215. func CreateDefaultAuditWebhookConfig(webhookConfigFile string) error {
  216. // We do not have a default, but we do have a volume mapping for this file
  217. return os.OpenFile(name, os.O_RDONLY|os.O_CREATE, 0644)
  218. }
  219.  
  220. func writePolicyToDisk(policyFile string, policy *auditv1beta1.Policy) error {
  221. // creates target folder if not already exists
  222. if err := os.MkdirAll(filepath.Dir(policyFile), 0700); err != nil {
  223. return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(policyFile), err)
  224. }
  225.  
  226. // Registers auditv1beta1 with the runtime Scheme
  227. auditv1beta1.AddToScheme(scheme.Scheme)
  228.  
  229. // writes the policy to disk
  230. serialized, err := util.MarshalToYaml(policy, auditv1beta1.SchemeGroupVersion)
  231. if err != nil {
  232. return fmt.Errorf("failed to marshal audit policy to YAML: %v", err)
  233. }
  234.  
  235. if err := ioutil.WriteFile(policyFile, serialized, 0600); err != nil {
  236. return fmt.Errorf("failed to write audit policy to %v: %v", policyFile, err)
  237. }
  238.  
  239. return nil
  240. }
  241. func writeWebhookConfigToDisk(webhookConfigFile string, policy *auditv1beta1.Policy) error {
  242. // creates target folder if not already exists
  243. if err := os.MkdirAll(filepath.Dir(webhookConfigFile), 0700); err != nil {
  244. return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(webhookConfigFile), err)
  245. }
  246.  
  247. // Registers auditv1beta1 with the runtime Scheme
  248. auditv1beta1.AddToScheme(scheme.Scheme)
  249.  
  250. // writes the policy to disk
  251. serialized, err := util.MarshalToYaml(policy, auditv1beta1.SchemeGroupVersion)
  252. if err != nil {
  253. return fmt.Errorf("failed to marshal audit webhook config to YAML: %v", err)
  254. }
  255.  
  256. if err := ioutil.WriteFile(webhookConfigFile, serialized, 0600); err != nil {
  257. return fmt.Errorf("failed to write audit webhook config to %v: %v", webhookConfigFile, err)
  258. }
  259.  
  260. return nil
  261. }
  262. #+end_src
  263. * tests
  264. ** [[file:app/apis/kubeadm/fuzzer/fuzzer.go::obj.AuditPolicyConfiguration%20=%20kubeadm.AuditPolicyConfiguration{][app/apis/kubeadm/fuzzer/fuzzer.go::obj.AuditPolicyConfiguration =]]
  265.  
  266. Fuzzer is looking for sample data types to generate fuzzer functions.
  267. ** [[file:app/phases/controlplane/volumes_test.go::Name:%20"audit",][app/phases/controlplane/volumes_test.go::Name: "audit"]]
  268.  
  269. What will the mount be called?
  270.  
  271. I see audit audit-log
  272. I'm unsure if the audit KubAuditPolicyVolumeName of audit, is a single volume with a subdir I can place the webhook.yml into.
  273. ** [[file:app/phases/controlplane/volumes_test.go::volMountMap%5Bkubeadmconstants.KubeAPIServer%5D%5B"audit"%5D%20=%20v1.VolumeMount{][app/phases/controlplane/volumes_test.go::volMountMap{...}{"audit"} = v1.VolumeMount]]
  274.  
  275. I think having a different name, within the same volume mount _should_ work.
  276. ** [[file:app/phases/controlplane/volumes_test.go::AuditPolicyConfiguration:%20kubeadmapi.AuditPolicyConfiguration{][app/phases/controlplane/volumes_test.go::AuditPolicyConfiguration:]]
  277.  
  278. Added the other file we add on disk
  279. ** [[file:app/util/audit/utils_test.go::func%20TestCreateDefaultAuditLogPolicy(t%20*testing.T)%20{][app/util/audit/utils_test.go::func TestCreateDefaultAuditLogPolicy(]]
  280.  
  281. A default AuditWebhookConfigFile is basically an empty file...
  282. Let's figure out if the mount stuff works if we disable it's creation.... less tests and code.
  283. ** [[file:app/cmd/upgrade/common_test.go::auditPolicy:][app/cmd/upgrade/common_test.go::auditPolicy:]]
  284.  
  285. It looks like this is to test upgrades.... not sure what we should test for here... possible changing the webhook endpoint?
  286. ** [[file:app/phases/controlplane/manifests_test.go::auditpolicyconfiguration][app/phases/controlplane/manifests_test.go::auditpolicyconfiguration]]
  287.  
  288. Tests command line arguments... should explore this a bit once we get it working.
  289.  
  290. # Local Variables:
  291. # eval: (org-babel-do-load-languages 'org-babel-load-languages '((go . nil)))
  292. # End:
Add Comment
Please, Sign In to add comment