Skip to content

Commit

Permalink
Autofix with config (#313)
Browse files Browse the repository at this point in the history
* autofix takes config file
  • Loading branch information
dani-santos-code authored Oct 29, 2020
1 parent c730a9d commit abac30a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 65 deletions.
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ To write the fixed manifest to a new file instead of modifying the source file,
kubeaudit autofix -f "/path/to/manifest.yml" -o "/path/to/fixed"
```

To fix a manifest based on custom rules specified on a kubeaudit config file, use the `-k/--kconfig` flag.

```
kubeaudit autofix -k "/path/to/kubeaudit-config.yml" -f "/path/to/manifest.yml" -o "/path/to/fixed"
```

### Cluster Mode

Kubeaudit can detect if it is running within a container in a cluster. If so, it will try to audit all Kubernetes resources in that cluster:
Expand Down Expand Up @@ -222,7 +228,50 @@ Auditors can also be run individually.

## Configuration File

Kubeaudit can be used with a configuration file instead of flags. See the [all command](docs/all.md).
The kubeaudit config can be used for two things:

1. Enabling only some auditors
1. Specifying configuration for auditors

Any configuration that can be specified using flags for the individual auditors can be represented using the config.

The config has the following format:

```yaml
enabledAuditors:
# Auditors are enabled by default if they are not explicitly set to "false"
apparmor: false
asat: false
capabilities: true
hostns: true
image: true
limits: true
mountds: true
netpols: true
nonroot: true
privesc: true
privileged: true
rootfs: true
seccomp: true
auditors:
capabilities:
# If no capabilities are specified and the 'capabilities' auditor is enabled,
# a list of recommended capabilities to drop is used
drop: ['AUDIT_WRITE', 'CHOWN']
image:
# If no image is specified and the 'image' auditor is enabled, WARN results
# will be generated for containers which use an image without a tag
image: 'myimage:mytag'
limits:
# If no limits are specified and the 'limits' auditor is enabled, WARN results
# will be generated for containers which have no cpu or memory limits specified
cpu: '750m'
memory: '500m'
```
For more details about each auditor, including a description of the auditor-specific configuration in the config, see the [Auditor Docs](#auditors).
**Note**: The kubeaudit config is not the same as the kubeconfig file specified with the `-c/--kubeconfig` flag, which refers to the Kubernetes config file (see [Local Mode](/README.md#local-mode)). Also note that only the `all` and `autofix` commands support using a kubeaudit config. It will not work with other commands.

## Override Errors

Expand Down
20 changes: 11 additions & 9 deletions cmd/commands/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ var auditAllConfig struct {
}

func auditAll(cmd *cobra.Command, args []string) {
conf := loadConfigFromFile(auditAllConfig.configFile)
conf := loadKubeAuditConfigFromFile(auditAllConfig.configFile)

// Config options set via flags override the config file
conf = setConfigFromFlags(cmd, conf)

allAuditors, err := all.Auditors(conf)
auditors, err := all.Auditors(conf)
if err != nil {
log.WithError(err).Fatal("Error creating auditors")
}

runAudit(allAuditors...)(cmd, args)
runAudit(auditors...)(cmd, args)
}

func setConfigFromFlags(cmd *cobra.Command, conf config.KubeauditConfig) config.KubeauditConfig {
Expand All @@ -50,19 +50,19 @@ func setConfigFromFlags(cmd *cobra.Command, conf config.KubeauditConfig) config.
return conf
}

func loadConfigFromFile(configFile string) config.KubeauditConfig {
if auditAllConfig.configFile == "" {
func loadKubeAuditConfigFromFile(configFile string) config.KubeauditConfig {
if configFile == "" {
return config.KubeauditConfig{}
}

reader, err := os.Open(auditAllConfig.configFile)
reader, err := os.Open(configFile)
if err != nil {
log.WithError(err).Fatal("Unable to open config file ", auditAllConfig.configFile)
log.WithError(err).Fatal("Unable to open config file ", configFile)
}

conf, err := config.New(reader)
if err != nil {
log.WithError(err).Fatal("Error parsing config file ", auditAllConfig.configFile)
log.WithError(err).Fatal("Error parsing config file ", configFile)
}

return conf
Expand All @@ -74,7 +74,9 @@ var auditAllCmd = &cobra.Command{
Long: `Run all audits
Example usage:
kubeaudit all -f /path/to/yaml`,
kubeaudit all -f /path/to/yaml
kubeaudit all -k /path/to/kubeaudit-config.yaml /path/to/yaml
`,
Run: auditAll,
}

Expand Down
25 changes: 20 additions & 5 deletions cmd/commands/autofix.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,29 @@ import (
"io"
"os"

"github.com/Shopify/kubeaudit/auditors/all"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var autofixConfig struct {
outFile string
outFile string
kubeauditConfigFile string
}

func autofix(cmd *cobra.Command, args []string) {
report := getReport()
conf := loadKubeAuditConfigFromFile(autofixConfig.kubeauditConfigFile)

conf = setConfigFromFlags(cmd, conf)

auditors, err := all.Auditors(conf)

if err != nil {
log.WithError(err).Fatal("Error creating auditors")
}

report := getReport(auditors...)

var err error
var f io.Writer
if autofixConfig.outFile != "" {
f, err = os.Create(autofixConfig.outFile)
Expand All @@ -40,15 +51,19 @@ var autofixCmd = &cobra.Command{
Short: "Automagically make a manifest secure",
Long: `This command automatically fixes all identified security issues for a given manifest
(ie. all ERROR results generated by 'kubeaudit all'). If no output file is specified using the -o flag,
the source manifest will be modified.
the source manifest will be modified. You can use the -k flag followed by the path to the kubeaudit
config file to run fixes based on custom rules.
Example usage:
kubeaudit autofix -f /path/to/yaml
kubeaudit autofix -f /path/to/yaml -o /path/for/fixed/yaml`,
kubeaudit autofix -f /path/to/yaml -o /path/for/fixed/yaml
kubeaudit autofix -k /path/to/kubeaudit-config.yaml -f /path/to/yaml
`,
Run: autofix,
}

func init() {
RootCmd.AddCommand(autofixCmd)
autofixCmd.Flags().StringVarP(&autofixConfig.outFile, "outfile", "o", "", "File to write fixed manifest to")
autofixCmd.Flags().StringVarP(&autofixConfig.kubeauditConfigFile, "kconfig", "k", "", "Path to kubeaudit config")
}
68 changes: 18 additions & 50 deletions docs/all.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,21 @@ kubeaudit all [flags]

## Flags

| Short | Long | Description | Default |
| :------ | :--------- | :---------------------------------------- | :--------------------------------------- |
| -k | --kconfig | Path to kubeaudit config | |
| Short | Long | Description | Default |
| :---- | :-------- | :----------------------- | :------ |
| -k | --kconfig | Path to kubeaudit config | |

Also see [Global Flags](/README.md#global-flags)

### Kubeaudit Config

The kubeaudit config can be used for two things:
1. Enabling only some auditors
1. Specifying configuration for auditors
A kubeaudit config file can be used instead of flags.

Any configuration that can be specified using flags for the individual auditors can be represented using the config.

The config has the following format:

```yaml
enabledAuditors:
# Auditors are enabled by default if they are not explicitly set to "false"
apparmor: false
asat: false
capabilities: true
hostns: true
image: true
limits: true
mountds: true
netpols: true
nonroot: true
privesc: true
privileged: true
rootfs: true
seccomp: true
auditors:
capabilities:
# If no capabilities are specified and the 'capabilities' auditor is enabled,
# a list of recommended capabilities to drop is used
drop: ["AUDIT_WRITE", "CHOWN"]
image:
# If no image is specified and the 'image' auditor is enabled, WARN results
# will be generated for containers which use an image without a tag
image: "myimage:mytag"
limits:
# If no limits are specified and the 'limits' auditor is enabled, WARN results
# will be generated for containers which have no cpu or memory limits specified
cpu: "750m"
memory: "500m"
```
kubeaudit all -k "/path/to/kubeaudit-config.yml" -f "/path/to/manifest.yml"
```

For more details about each auditor, including a description of the auditor-specific configuration in the config, see the [Auditor Docs](/README.md#auditors).
**Note**: The kubeaudit config is not the same as the kubeconfig file specified with the `-c/--kubeconfig` flag, which refers to the Kubernetes config file (see [Local Mode](/README.md#local-mode)). Also note that only the `all` command supports using a kubeaudit config. It will not work with other commands.
Also see [Configuration File](/README.md#configuration-file)

## Examples

Expand Down Expand Up @@ -161,42 +125,46 @@ $ kubeaudit all -f "internal/test/fixtures/all_resources/deployment-apps-v1.yml"
### Example with Kubeaudit Config

Consider the following kubeaudit config `config.yaml`

```yaml
enabledAuditors:
# Auditors are enabled by default if they are not explicitly set to "false"
hostns: false
image: false
limits: false
# Auditors are enabled by default if they are not explicitly set to "false"
hostns: false
image: false
limits: false
auditors:
capabilities:
drop: ["AUDIT_WRITE", "CHOWN"]
capabilities:
drop: ['AUDIT_WRITE', 'CHOWN']
```
The config can be passed to the `all` command using the `-k/--kconfig` flag:

```
$ kubeaudit all -k "config.yaml" -f "auditors/all/fixtures/audit_all_v1.yml"
```
### Example with Flags
The behaviour of the `all` command can also be customized by using flags. The `all` command supports all flags supported by invididual auditors (see the individual [auditor docs](/README.md#auditors) for all the flags). For example, the `caps` auditor supports specifying capabilities to drop with the `--drop/-d` flag so this flag can be used with the `all` command:
```
kubeaudit all -f "auditors/all/fixtures/audit_all_v1.yml" --drop "AUDIT_WRITE"
```
### Example with Kubeaudit Config and Flags
Passing flags in addition to the config will override the corresponding fields from the config. For example, if the capabilities to drop are specified with the `--drop/-d` flag:
```
kubeaudit all -f "auditors/all/fixtures/audit_all_v1.yml" --drop "AUDIT_WRITE"
```
And they are also specified in the Kubeaudit config file:
```yaml
auditors:
capabilities:
drop: ["CHOWN", "MKNOD]
```

The capabilities specified by the flag will take precedence over those specified in the config file resulting in only `AUDIT_WRITE` being dropped.

11 changes: 11 additions & 0 deletions docs/autofix.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ kubeaudit autofix -f [manifest] [flags]
| Short | Long | Description | Default |
| :------ | :--------- | :---------------------------------------- | :--------------------------------------- |
| -o | --outfile | File to write fixed manifest to | |
| -k | --kconfig | Path to kubeaudit config file | |

Also see [Global Flags](/README.md#global-flags)

Expand Down Expand Up @@ -263,3 +264,13 @@ To write the fixed manifest to a different file, use the `--outfile/-o` flag:
```
kubeaudit autofix -f "manifest.yml" -o "fixed.yaml"
```

### Using Custom Rules with Kubeaudit Config File

To fix a manifest based on custom rules specified on a kubeaudit config file (e.g disable some auditors), use the `-k/--kconfig` flag.

```
kubeaudit autofix -k "/path/to/kubeaudit-config.yml" -f "/path/to/manifest.yml" -o "/path/to/fixed"
```
Also see [Configuration File](/README.md#configuration-file)

0 comments on commit abac30a

Please sign in to comment.