Skip to content

Commit 5a9a746

Browse files
authored
Merge pull request #1 from ncode/juliano/its_born
it's born
2 parents 6dbdb07 + 974d1be commit 5a9a746

17 files changed

Lines changed: 1682 additions & 1 deletion

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ go.work.sum
2323

2424
# env file
2525
.env
26+
27+
# idea
28+
.idea

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright [yyyy] [name of copyright owner]
189+
Copyright 2024 Juliano Martinez
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

cmd/auditServer.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright © 2024 Juliano Martinez <juliano@martinez.io>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"fmt"
20+
"github.com/ncode/vault-audit-filter/pkg/auditserver"
21+
"github.com/panjf2000/gnet"
22+
"github.com/spf13/viper"
23+
"log"
24+
25+
"github.com/spf13/cobra"
26+
)
27+
28+
// auditServerCmd represents the auditServer command
29+
var auditServerCmd = &cobra.Command{
30+
Use: "auditServer",
31+
Short: "A brief description of your command",
32+
Long: `A longer description that spans multiple lines and likely contains examples
33+
and usage of using your command. For example:
34+
35+
Cobra is a CLI library for Go that empowers applications.
36+
This application is a tool to generate the needed files
37+
to quickly create a Cobra application.`,
38+
Run: func(cmd *cobra.Command, args []string) {
39+
addr := fmt.Sprintf("udp://%s", viper.GetString("vault.audit_address"))
40+
server := auditserver.New(nil)
41+
log.Fatal(gnet.Serve(server, addr, gnet.WithMulticore(true)))
42+
},
43+
}
44+
45+
func init() {
46+
rootCmd.AddCommand(auditServerCmd)
47+
48+
// Here you will define your flags and configuration settings.
49+
50+
// Cobra supports Persistent Flags which will work for this command
51+
// and all subcommands, e.g.:
52+
// auditServerCmd.PersistentFlags().String("foo", "", "A help for foo")
53+
54+
// Cobra supports local flags which will only run when this command
55+
// is called directly, e.g.:
56+
// auditServerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
57+
}

cmd/root.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
Copyright © 2024 Juliano Martinez <juliano@martinez.io>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"fmt"
20+
"log/slog"
21+
"os"
22+
23+
"github.com/spf13/cobra"
24+
"github.com/spf13/viper"
25+
)
26+
27+
var logger *slog.Logger
28+
29+
func init() {
30+
logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
31+
}
32+
33+
var cfgFile string
34+
35+
// rootCmd represents the base command when called without any subcommands
36+
var rootCmd = &cobra.Command{
37+
Use: "vault-audit-filter",
38+
Short: "A brief description of your application",
39+
Long: `A longer description that spans multiple lines and likely contains
40+
examples and usage of using your application. For example:
41+
42+
Cobra is a CLI library for Go that empowers applications.
43+
This application is a tool to generate the needed files
44+
to quickly create a Cobra application.`,
45+
// Uncomment the following line if your bare application
46+
// has an action associated with it:
47+
// Run: func(cmd *cobra.Command, args []string) { },
48+
}
49+
50+
// Execute adds all child commands to the root command and sets flags appropriately.
51+
// This is called by main.main(). It only needs to happen once to the rootCmd.
52+
func Execute() {
53+
err := rootCmd.Execute()
54+
if err != nil {
55+
os.Exit(1)
56+
}
57+
}
58+
59+
func init() {
60+
cobra.OnInitialize(initConfig)
61+
62+
// Here you will define your flags and configuration settings.
63+
// Cobra supports persistent flags, which, if defined here,
64+
// will be global for your application.
65+
66+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.vault-audit-filter.yaml)")
67+
rootCmd.PersistentFlags().String("vault.address", "http://127.0.0.1:8200", "Vault source address")
68+
rootCmd.PersistentFlags().String("vault.token", "", "Vault source token")
69+
rootCmd.PersistentFlags().String("vault.audit_path", "/vault-audit-filter", "Vault audit path")
70+
rootCmd.PersistentFlags().String("vault.audit_address", "127.0.0.1:1269", "Courier audit device address to receive the audit")
71+
rootCmd.PersistentFlags().String("vault.audit_description", "Courier audit device", "Vault audit description")
72+
73+
// Cobra also supports local flags, which will only run
74+
// when this action is called directly.
75+
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
76+
}
77+
78+
// initConfig reads in config file and ENV variables if set.
79+
func initConfig() {
80+
if cfgFile != "" {
81+
// Use config file from the flag.
82+
viper.SetConfigFile(cfgFile)
83+
} else {
84+
// Find home directory.
85+
home, err := os.UserHomeDir()
86+
cobra.CheckErr(err)
87+
88+
// Search config in home directory with name ".vault-audit-filter" (without extension).
89+
viper.AddConfigPath(home)
90+
viper.SetConfigType("yaml")
91+
viper.SetConfigName(".vault-audit-filter")
92+
}
93+
94+
viper.BindPFlag("vault.address", rootCmd.PersistentFlags().Lookup("vault.address"))
95+
viper.BindPFlag("vault.token", rootCmd.PersistentFlags().Lookup("vault.token"))
96+
viper.BindPFlag("vault.audit_path", rootCmd.PersistentFlags().Lookup("vault.audit_path"))
97+
viper.BindPFlag("vault.audit_address", rootCmd.PersistentFlags().Lookup("vault.audit_address"))
98+
viper.BindPFlag("vault.audit_description", rootCmd.PersistentFlags().Lookup("vault.audit_description"))
99+
100+
viper.AutomaticEnv() // read in environment variables that match
101+
102+
// If a config file is found, read it in.
103+
if err := viper.ReadInConfig(); err == nil {
104+
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
105+
}
106+
107+
if viper.GetString("vault.token") == "" {
108+
logger.Error("vault.token is required")
109+
os.Exit(1)
110+
}
111+
112+
if !viper.IsSet("rule_groups") || len(viper.GetStringSlice("rule_groups")) == 0 {
113+
logger.Info("No rules defined in configuration; all audit logs will be printed")
114+
}
115+
}

cmd/setup.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright © 2024 Juliano Martinez <juliano@martinez.io>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"os"
20+
21+
"github.com/ncode/vault-audit-filter/pkg/vault"
22+
"github.com/spf13/cobra"
23+
"github.com/spf13/viper"
24+
)
25+
26+
// setupCmd represents the setup command
27+
var setupCmd = &cobra.Command{
28+
Use: "setup",
29+
Short: "Setup vault audit device",
30+
Long: ``,
31+
Run: func(cmd *cobra.Command, args []string) {
32+
client, err := vault.NewVaultClient(viper.GetString("vault.address"), vault.TokenAuth{Token: viper.GetString("vault.token")})
33+
if err != nil {
34+
logger.Error("setup", "unable to setup vault client", err.Error())
35+
os.Exit(1)
36+
}
37+
err = client.EnableAuditDevice(
38+
viper.GetString("vault.audit_path"),
39+
"socket",
40+
viper.GetString("vault.audit_description"),
41+
map[string]string{
42+
"address": viper.GetString("vault.audit_address"),
43+
"description": viper.GetString("vault.audit_description"),
44+
"socket_type": "udp",
45+
"log_raw": "false",
46+
},
47+
)
48+
if err != nil {
49+
logger.Error("setup", "unable to enable audit device", err.Error())
50+
os.Exit(1)
51+
}
52+
},
53+
}
54+
55+
func init() {
56+
rootCmd.AddCommand(setupCmd)
57+
58+
// Here you will define your flags and configuration settings.
59+
60+
// Cobra supports Persistent Flags which will work for this command
61+
// and all subcommands, e.g.:
62+
// setupCmd.PersistentFlags().String("foo", "", "A help for foo")
63+
64+
// Cobra supports local flags which will only run when this command
65+
// is called directly, e.g.:
66+
// setupCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
67+
}

configs/docker/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM scratch
2+
COPY vault-audit-filter /vault-audit-filter
3+
ENTRYPOINT ["/vault-audit-filter"]

configs/docker/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.PHONY: build docker-build down up
2+
3+
all: build docker-build down up
4+
5+
build:
6+
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" ../../
7+
8+
docker-build:
9+
docker build -t ncode/vault-audit-filter:dev .
10+
11+
up:
12+
docker compose up
13+
14+
down:
15+
docker compose down

configs/docker/config/config.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
rule_groups:
2+
- name: "normal_operations"
3+
rules:
4+
- 'Auth.PolicyResults.Allowed == true'
5+
log_file:
6+
file_path: "/var/log/vault_normal_operations.log"
7+
max_size: 100
8+
max_backups: 5
9+
max_age: 30
10+
compress: true
11+
12+
- name: "critical_events"
13+
rules:
14+
- 'Request.Operation == "delete" && Auth.PolicyResults.Allowed == true'
15+
- 'Request.Path startsWith "secret/metadata/" && Auth.PolicyResults.Allowed == true'
16+
- 'Request.Path == "secret/data/myapp/database" && Request.Operation == "update"'
17+
log_file:
18+
file_path: "/var/log/vault_critical_events.log"
19+
max_size: 100
20+
max_backups: 5
21+
max_age: 30
22+
compress: true

configs/docker/docker-compose.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
services:
2+
vault_primary:
3+
image: hashicorp/vault:latest
4+
container_name: vault_primary
5+
ports:
6+
- "8200:8200"
7+
environment:
8+
VAULT_DEV_ROOT_TOKEN_ID: "root"
9+
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
10+
cap_add:
11+
- IPC_LOCK
12+
command: "vault server -dev -dev-root-token-id=root -dev-listen-address=0.0.0.0:8200"
13+
14+
vault-audit-filter_auditserver:
15+
image: ncode/vault-audit-filter:dev
16+
container_name: vault-audit-filter_auditserver
17+
volumes:
18+
- ./config:/config:ro
19+
- ./logs:/var/log/
20+
depends_on:
21+
- vault_primary
22+
command: "auditServer --config /config/config.yaml --vault.token root --vault.audit_address vault-audit-filter_auditserver:1269"
23+
24+
vault-audit-filter_setup:
25+
image: ncode/vault-audit-filter:dev
26+
container_name: vault-audit-filter_setup
27+
depends_on:
28+
- vault-audit-filter_auditserver
29+
command: "setup --vault.token root --vault.address http://vault_primary:8200 --vault.audit_address vault-audit-filter_auditserver:1269"
30+
31+
vault_writer:
32+
image: hashicorp/vault:latest
33+
container_name: vault_writer
34+
depends_on:
35+
- vault-audit-filter_setup
36+
volumes:
37+
- ./scripts:/scripts:ro
38+
environment:
39+
VAULT_TOKEN: root
40+
VAULT_ADDR: http://vault_primary:8200
41+
cap_add:
42+
- IPC_LOCK
43+
entrypoint: "/scripts/writer.sh"
44+

configs/docker/scripts/writer.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
3+
sleep 5
4+
5+
set -x
6+
7+
vault kv put secret/data/myapp/config api_key=12345 environment=production
8+
vault kv metadata put -custom-metadata="replicate_to=vault_replica" secret/metadata/myapp/config
9+
vault kv metadata get secret/metadata/myapp/config
10+
11+
vault kv put secret/data/myapp/database username=dbuser password=supersecret host=db.example.com port=5432
12+
13+
vault kv get -field=api_key secret/data/myapp/config
14+
vault kv get -format=json secret/data/myapp/database
15+
16+
vault kv list secret/metadata/myapp/
17+
vault kv delete secret/data/myapp/config
18+
19+

0 commit comments

Comments
 (0)