Skip to content

Commit

Permalink
implement anonymisation proof writer
Browse files Browse the repository at this point in the history
  • Loading branch information
solnicki committed Nov 12, 2024
1 parent cc41366 commit f6842be
Show file tree
Hide file tree
Showing 14 changed files with 315 additions and 108 deletions.
67 changes: 0 additions & 67 deletions cmd/logveil/app.go

This file was deleted.

6 changes: 4 additions & 2 deletions cmd/logveil/logveil.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
"github.com/logmanager-oss/logveil/internal/anonymizer"
"github.com/logmanager-oss/logveil/internal/flags"
"github.com/logmanager-oss/logveil/internal/loader"
"github.com/logmanager-oss/logveil/internal/proof"
"github.com/logmanager-oss/logveil/internal/runner"
)

func Run() {
slog.Info("Anonymization process started...")

anonymizingDataDir, inputPath, outputPath, isVerbose, isLmExport := flags.LoadAndValidate()
anonymizingDataDir, inputPath, outputPath, isVerbose, isLmExport, isProofWriter := flags.LoadAndValidate()

if isVerbose {
slog.SetLogLoggerLevel(slog.LevelDebug)
Expand Down Expand Up @@ -45,7 +46,8 @@ func Run() {
slog.Error("loading anonymizing data from dir %s: %v", anonymizingDataDir, err)
return
}
anonymizer := anonymizer.New(anonymizingData)
proofWriter := proof.New(isProofWriter)
anonymizer := anonymizer.New(anonymizingData, proofWriter)

if isLmExport {
err := runner.AnonymizeLmExport(inputReader, outputWriter, anonymizer)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require github.com/stretchr/testify v1.9.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8XGgcUTlTxpp3mKhdR2Q9z9HbXM=
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
Expand Down
15 changes: 10 additions & 5 deletions internal/anonymizer/anonymizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ import (
"log/slog"
"strings"

"github.com/logmanager-oss/logveil/internal/proof"
"golang.org/x/exp/rand"
)

type Anonymizer struct {
anonData map[string][]string
randFunc func(int) int
anonData map[string][]string
randFunc func(int) int
proofWriter *proof.Proof
}

func New(anonData map[string][]string) *Anonymizer {
func New(anonData map[string][]string, proofWriter *proof.Proof) *Anonymizer {
return &Anonymizer{
anonData: anonData,
randFunc: rand.Intn,
anonData: anonData,
randFunc: rand.Intn,
proofWriter: proofWriter,
}
}

Expand All @@ -33,6 +36,8 @@ func (an *Anonymizer) Anonymize(logLine map[string]string) string {
if anonValues, exists := an.anonData[field]; exists {
newAnonValue := anonValues[an.randFunc(len(anonValues))]

an.proofWriter.Write(value, newAnonValue)

slog.Debug(fmt.Sprintf("Replacing the values for field %s. From %s to %s.\n", field, value, newAnonValue))

logLine["raw"] = strings.Replace(logLine["raw"], value, newAnonValue, -1)
Expand Down
4 changes: 3 additions & 1 deletion internal/anonymizer/anonymizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/logmanager-oss/logveil/internal/loader"
"github.com/logmanager-oss/logveil/internal/proof"
"github.com/stretchr/testify/assert"
)

Expand All @@ -29,7 +30,8 @@ func TestAnonimizer_AnonymizeData(t *testing.T) {
t.Fatalf("loading anonymizing data from dir %s: %v", tt.anonymizingDataDir, err)
}

anonymizer := New(anonymizingData)
proofWriter := proof.New(true)
anonymizer := New(anonymizingData, proofWriter)
// Disabling randomization so we know which values to expect
anonymizer.SetRandFunc(func(int) int { return 1 })
output := anonymizer.Anonymize(tt.input)
Expand Down
9 changes: 5 additions & 4 deletions internal/flags/initalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"flag"
)

func LoadAndValidate() (string, string, string, bool, bool) {
func LoadAndValidate() (string, string, string, bool, bool, bool) {
var anonymizationDataPath string
flag.Func("d", "Path to directory with anonymizing data", validateDir(anonymizationDataPath))

Expand All @@ -14,10 +14,11 @@ func LoadAndValidate() (string, string, string, bool, bool) {
var outputPath string
flag.Func("o", "Path to output file (default: Stdout)", validateOutput(outputPath))

var isVerbose = flag.Bool("v", false, "Enable verbose logging")
var isLmExport = flag.Bool("e", false, "Change input file type to LM export (default input file type is LM Backup)")
var isVerbose = flag.Bool("v", false, "Enable verbose logging (default: Disabled)")
var isLmExport = flag.Bool("e", false, "Change input file type to LM export (default: LM Backup)")
var isProofWriter = flag.Bool("p", true, "Disable proof wrtier (default: Enabled)")

flag.Parse()

return anonymizationDataPath, inputPath, outputPath, *isVerbose, *isLmExport
return anonymizationDataPath, inputPath, outputPath, *isVerbose, *isLmExport, *isProofWriter
}
47 changes: 34 additions & 13 deletions internal/inputs/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,32 @@ import (

"github.com/logmanager-oss/logveil/internal/anonymizer"
"github.com/logmanager-oss/logveil/internal/parser"
"github.com/logmanager-oss/logveil/internal/proof"
"github.com/logmanager-oss/logveil/internal/utils"
"github.com/stretchr/testify/assert"
)

func TestLmBackup(t *testing.T) {
tests := []struct {
name string
inputFilename string
outputFilename string
anonDataDir string
expectedOutput string
name string
isProofWriterEnabled bool
inputFilename string
anonDataDir string
expectedOutput string
expectedProof []map[string]interface{}
}{
{
name: "Test Test LM Backup Anonymizer",
inputFilename: "../../examples/logs/lm-2024-06-09_0000.gz",
anonDataDir: "../../examples/anon_data",
expectedOutput: "<189>date=2024-11-06 time=12:29:25 devname=\"LM-FW-70F-Praha\" devid=\"FGT70FTK22012016\" eventtime=1730892565525108329 tz=\"+0100\" logid=\"0000000013\" type=\"traffic\" subtype=\"forward\" level=\"notice\" vd=\"root\" srcip=10.20.0.53 srcport=57158 srcintf=\"lan1\" srcintfrole=\"wan\" dstip=227.51.221.89 dstport=80 dstintf=\"lan1\" dstintfrole=\"lan\" srccountry=\"China\" dstcountry=\"Czech Republic\" sessionid=179455916 proto=6 action=\"client-rst\" policyid=9 policytype=\"policy\" poluuid=\"d8ccb3e4-74d4-51ef-69a3-73b41f46df74\" policyname=\"Gitlab web from all\" service=\"HTTP\" trandisp=\"noop\" duration=6 sentbyte=80 rcvdbyte=44 sentpkt=2 rcvdpkt=1 appcat=\"unscanned\" srchwvendor=\"H3C\" devtype=\"Router\" mastersrcmac=\"00:23:89:39:a4:ef\" srcmac=\"00:23:89:39:a4:ef\" srcserver=0 dsthwvendor=\"H3C\" dstdevtype=\"Router\" masterdstmac=\"00:23:89:39:a4:fa\" dstmac=\"00:23:89:39:a4:fa\" dstserver=0\n",
name: "Test Test LM Backup Anonymizer",
isProofWriterEnabled: true,
inputFilename: "../../examples/logs/lm-2024-06-09_0000.gz",
anonDataDir: "../../examples/anon_data",
expectedOutput: "<189>date=2024-11-06 time=12:29:25 devname=\"LM-FW-70F-Praha\" devid=\"FGT70FTK22012016\" eventtime=1730892565525108329 tz=\"+0100\" logid=\"0000000013\" type=\"traffic\" subtype=\"forward\" level=\"notice\" vd=\"root\" srcip=10.20.0.53 srcport=57158 srcintf=\"lan1\" srcintfrole=\"wan\" dstip=227.51.221.89 dstport=80 dstintf=\"lan1\" dstintfrole=\"lan\" srccountry=\"China\" dstcountry=\"Czech Republic\" sessionid=179455916 proto=6 action=\"client-rst\" policyid=9 policytype=\"policy\" poluuid=\"d8ccb3e4-74d4-51ef-69a3-73b41f46df74\" policyname=\"Gitlab web from all\" service=\"HTTP\" trandisp=\"noop\" duration=6 sentbyte=80 rcvdbyte=44 sentpkt=2 rcvdpkt=1 appcat=\"unscanned\" srchwvendor=\"H3C\" devtype=\"Router\" mastersrcmac=\"00:23:89:39:a4:ef\" srcmac=\"00:23:89:39:a4:ef\" srcserver=0 dsthwvendor=\"H3C\" dstdevtype=\"Router\" masterdstmac=\"00:23:89:39:a4:fa\" dstmac=\"00:23:89:39:a4:fa\" dstserver=0\n",
expectedProof: []map[string]interface{}{
{"original": "dev-uplink", "new": "lan1"},
{"original": "95.80.197.108", "new": "227.51.221.89"},
{"original": "27.221.126.209", "new": "10.20.0.53"},
{"original": "wan1-lm", "new": "lan1"},
},
},
}
for _, tt := range tests {
Expand All @@ -33,22 +43,33 @@ func TestLmBackup(t *testing.T) {
}
defer input.Close()

var output bytes.Buffer

anonData, err := parser.LoadAnonData(tt.anonDataDir)
if err != nil {
t.Fatal(err)
}
anonymizer := anonymizer.New(anonData)

proofWriter := proof.New(tt.isProofWriterEnabled)
anonymizer := anonymizer.New(anonData, proofWriter)
// Disabling randomization so we know which values to expect
anonymizer.SetRandFunc(func(int) int { return 1 })

var output bytes.Buffer
err = AnonymizeLmBackup(input, &output, anonymizer)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, tt.expectedOutput, output.String())

proofWriter.Close()

actualProof, err := utils.UnpackProofOutput()
if err != nil {
t.Fatal(err)
}

assert.ElementsMatch(t, tt.expectedProof, actualProof)

os.Remove("proof.json")
})
}
}
46 changes: 33 additions & 13 deletions internal/inputs/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,31 @@ import (

"github.com/logmanager-oss/logveil/internal/anonymizer"
"github.com/logmanager-oss/logveil/internal/parser"
"github.com/logmanager-oss/logveil/internal/proof"
"github.com/logmanager-oss/logveil/internal/utils"
"github.com/stretchr/testify/assert"
)

func TestLmExport(t *testing.T) {
tests := []struct {
name string
inputFilename string
outputFilename string
anonDataDir string
expectedOutput string
name string
isProofWriterEnabled bool
inputFilename string
anonDataDir string
expectedOutput string
expectedProof []map[string]interface{}
}{
{
name: "Test LM Export Anonymizer",
inputFilename: "../../examples/logs/example_logs.csv",
anonDataDir: "../../examples/anon_data",
expectedOutput: "{\"@timestamp\": \"2024-06-05T14:59:27.000+00:00\", \"msg.src_ip\":\"10.20.0.53\", \"username\":\"ladislav.dosek\", \"organization\":\"Apple\"}\n",
name: "Test LM Export Anonymizer",
isProofWriterEnabled: true,
inputFilename: "../../examples/logs/example_logs.csv",
anonDataDir: "../../examples/anon_data",
expectedOutput: "{\"@timestamp\": \"2024-06-05T14:59:27.000+00:00\", \"msg.src_ip\":\"10.20.0.53\", \"username\":\"ladislav.dosek\", \"organization\":\"Apple\"}\n",
expectedProof: []map[string]interface{}{
{"original": "89.239.31.49", "new": "10.20.0.53"},
{"original": "[email protected]", "new": "ladislav.dosek"},
{"original": "TESTuser.test.com", "new": "Apple"},
},
},
}
for _, tt := range tests {
Expand All @@ -33,22 +42,33 @@ func TestLmExport(t *testing.T) {
}
defer input.Close()

var output bytes.Buffer

anonData, err := parser.LoadAnonData(tt.anonDataDir)
if err != nil {
t.Fatal(err)
}
anonymizer := anonymizer.New(anonData)

proofWriter := proof.New(tt.isProofWriterEnabled)
anonymizer := anonymizer.New(anonData, proofWriter)
// Disabling randomization so we know which values to expect
anonymizer.SetRandFunc(func(int) int { return 1 })

var output bytes.Buffer
err = AnonymizeLmExport(input, &output, anonymizer)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, tt.expectedOutput, output.String())

proofWriter.Close()

actualProof, err := utils.UnpackProofOutput()
if err != nil {
t.Fatal(err)
}

assert.ElementsMatch(t, tt.expectedProof, actualProof)

os.Remove("proof.json")
})
}
}
Loading

0 comments on commit f6842be

Please sign in to comment.