diff --git a/certs/122/ca.crt b/certs/122/ca.crt new file mode 100644 index 0000000..780b8ba --- /dev/null +++ b/certs/122/ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAnmgAwIBAgIUfq0rmw4AG29WDIMpu7VZdv8AFb4wDQYJKoZIhvcNAQEL +BQAwWDELMAkGA1UEBhMCSVIxDDAKBgNVBAgMA1l6ZDEMMAoGA1UEBwwDWXpkMQ8w +DQYDVQQKDAZGYXJ6YW4xDDAKBgNVBAsMA0RldjEOMAwGA1UEAwwFbG9jYWwwHhcN +MjMwODA4MTMwNjIxWhcNMjQwODA3MTMwNjIxWjBYMQswCQYDVQQGEwJJUjEMMAoG +A1UECAwDWXpkMQwwCgYDVQQHDANZemQxDzANBgNVBAoMBkZhcnphbjEMMAoGA1UE +CwwDRGV2MQ4wDAYDVQQDDAVsb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALKZCi9VUd9034vOddqqG0pzqtSqCfbDUms3RJ/TpFI092H7fL3u65gy +uf8W2XrgAAwGZ4hFT8uIpjDCh/AXE/mPORqUyy12bTDHy6WsD3OmbuHvmmPeSEJY +1kqeFZx3g7BQMKc/mAnOjDn6XANBhlV7IwwVNV+snYSSiZD25WMYPdyqqZAy3X1I +gzFAR9Xci3Ur+A+3nDX28vU/PjWaLTR4qVZ4g9Updl0YqjvueFoJ9t7BP0oWyA0h +BdemeV0w8N+EgPG3LxIh3RNBNtxGyzCXKI5LEv/5gE/isyI5X/+G4J0rE5q967vD +RD+TT1148eYfLY4aPi068trd/mtLoDUCAwEAAaNTMFEwHQYDVR0OBBYEFOUqohb4 +8Kr8IDWiQF906Qpqo/HRMB8GA1UdIwQYMBaAFOUqohb48Kr8IDWiQF906Qpqo/HR +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFmv5nhZMuZXYHbb +rBIv6xrnflZgIfJI/VcXxaYCZ8EjdZIKKRo/MJcY5YdEQT8ilzboiWB7gCQHoCcA +3X2bgrD4rghjPVyXIms8XKek+li0PLRNooja/mSc+acSzrmvfD8g3eYALvYqVCcx +1e8ugugcqAmol1KJe8YM8W3Dlv4v8emOgY6ux1Yrt0gCiyNrfZHbKbANO17vlLTg +POF9Q1dtueq/GSmVNnnmA8/BkylvBWlPKRRF2722Cp2Evyyq9b5hQ+TsGGLc9oUu +h3qc8KLx+VVxeuExuhEr65UN+qsv8CoPWRYAQMEEAfYOACnxocvVY84+sT7/KteJ +NMSpRcU= +-----END CERTIFICATE----- diff --git a/certs/122/client.crt b/certs/122/client.crt new file mode 100644 index 0000000..737fedc --- /dev/null +++ b/certs/122/client.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuTCCAqGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJJUjEM +MAoGA1UECAwDWXpkMQwwCgYDVQQHDANZemQxDzANBgNVBAoMBkZhcnphbjEMMAoG +A1UECwwDRGV2MQ4wDAYDVQQDDAVsb2NhbDAeFw0yMzA4MDgxMzA2MjdaFw0yNDA4 +MDcxMzA2MjdaMEoxDjAMBgNVBAMMBWxvY2FsMQwwCgYDVQQIDANZemQxCzAJBgNV +BAYTAklSMQ8wDQYDVQQKDAZGYXJ6YW4xDDAKBgNVBAsMA0RldjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAM8dGUvBLYW3Q3fu/FOsqkGhDpzm9F9ASk2V +gNHSmTQ5AHF8MJ/iUSf5jr0oAWwqTue4hVREywfqzNAlxg+G7HIUvzO76NMLeomP +I3YPaxggpB3Sd1BwEi+zkFrqr6P5T6s9rZC/DLBJruEd2HSTq+LeJrZmKVq4fa9q +WkczVR+3cL+1mXUSjAGmgZTLjEmhYl50lCtzrEse/BIqv1nSjS9F5H/GQXAeYW7L +PSlMTLhLNex6zxtODU07ib50L6/ditFoRpBuiLkDxHr+W/BPoAXyxXd9z3hWnC4d +o8h5bCPUGaM4vYc4MNs0k+YcCDTwMoYs17xNnAwaUhgEgtAjzLsCAwEAAaOBmzCB +mDAJBgNVHRMEAjAAMB0GA1UdDgQWBBTdnbo8ACvLipZQipT+dDMK673ATDAfBgNV +HSMEGDAWgBTlKqIW+PCq/CA1okBfdOkKaqPx0TALBgNVHQ8EBAMCBaAwKQYDVR0f +BCIwIDAeoBygGoYYaHR0cDovL2xvZ3N0YXNoL3Jvb3QuY3JsMBMGA1UdEQQMMAqC +CGxvZ3N0YXNoMA0GCSqGSIb3DQEBCwUAA4IBAQBSH3WnXKPMEYRFgj7rkNwWUbYG +sTPgjsqI9iXhDvcq0fTg1zmrh0bmne1hUTQOykdyJuwfI2glhTNiW/McY30PXTQP +dVDnYyMDUwfS9jYhBp3HnGFseImbPcvr/NnViEwYJyeHNnDHnemSXTPDkcjaV92H +CYHgsg/OxBTwBPJOiB5oUhbk+M21e9e3om9V/4A6ff9CiSXKfz5XAHkxIJcRzBca +LrgS+Ps1GxngH2d5VXPoCYNGCaM5wIzZ6dme3oMj8HJ+CaAp0HrdcIppof/pmrtr +7fDE9oPMBSgj9jec0amowkadCqlGQUms5ikgMcSTtm7qIg4ORfob4xCmnqh1 +-----END CERTIFICATE----- diff --git a/certs/122/client.key b/certs/122/client.key new file mode 100644 index 0000000..467e222 --- /dev/null +++ b/certs/122/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPHRlLwS2Ft0N3 +7vxTrKpBoQ6c5vRfQEpNlYDR0pk0OQBxfDCf4lEn+Y69KAFsKk7nuIVURMsH6szQ +JcYPhuxyFL8zu+jTC3qJjyN2D2sYIKQd0ndQcBIvs5Ba6q+j+U+rPa2QvwywSa7h +Hdh0k6vi3ia2ZilauH2valpHM1Uft3C/tZl1EowBpoGUy4xJoWJedJQrc6xLHvwS +Kr9Z0o0vReR/xkFwHmFuyz0pTEy4SzXses8bTg1NO4m+dC+v3YrRaEaQboi5A8R6 +/lvwT6AF8sV3fc94VpwuHaPIeWwj1BmjOL2HODDbNJPmHAg08DKGLNe8TZwMGlIY +BILQI8y7AgMBAAECggEBAMv9yB1x/kk2cLBe5Y3wgZy0afUmEMkERGrX9pIzEAx8 +nDAqdqXzPaXWyb0K+yOzJBZdCo0uWJ7Kp8HXgpVmedn/DzeAO9gp9R4pqm6szvlr +pNluo2/JglATVvoFLsudUdfCnwHy+idj22gEgl6H2ANSdOSwCMk+7yPn51U7fPsH +ZeXO/zgtziZ3hmk+T7hFClazFiFfypIYe5BHXxAPfW3183l+fTy7obdPwNyeMfvr +CdEHOZe3RHFcxAwSpI1DX1gNcFA+yspTZFcMLo8NxDXECYbMbR4wF5BckLK3B0rs +pJtjVgtt5vcBnsVjddWuziuYpgNuKjRZq2pML5Zr1tECgYEA/NMBbcCPW/iQ584/ +j2x71ssjl9psOKNT/NexdcC69oIkHFynBGbaRLnN5TLbG0/fOjit89hu5JdZXxOw +oo8TDwuXS0aSTZaib6D265L1zOX3bH5QxoVNuh2bIXAfZG+29jgR56tDZjQLTqQW +nzyUzkF+hhYtfhSVtaV0tVRYb8kCgYEA0bcan65658Y2GTEGy2DGRaT1lRWPP0Pq +4Hsqxo5u8PjQMB6TwIT5MWjdYIsnfaZBW6CRq3KWQ4GQPWQdejXzIubALSFW5gou +25YN13GITxRaQ6EMTtrwx2EsYDNt84BFUtHf8BVL6yyjTPa43aIA0TVLLMry6Qnw +w6nKIXsJAmMCgYBLffISRIpKCxmxrds6x0jfJT8Wi8j+zH46pGk/4PGyw79mnJ/e +Z5vLI7QAOURFjn74Uo5WnozWQv8TrbxzfcdSGcLuXj83XcBZFrZEN1if+xb7VWhn +Lsy7wzVcMa+d/OGj+bAW/gOdE/NAYyzCFYPVZqcSALNKz3i4iZQkxO+3SQKBgEjU +tkJObhCgHZmSFTH8Yd898qvb2Ou3wpJDNA/Q12aIgoSzmcx6YbBvIrKsoQJaAsi3 +ct9/4/99t4IaisIuiknMqWEC+xLY5n0MF7KCkzwjbVWfUI7yKjyT2r1uHvk5ytmA +Wa0fOEZsMipAZONTp8UAJSNhOAsGkL7i8HfAKtjRAoGBAICfu63+OjBgna4Sr+Rb +ov8JRLXIbm1R7sh89GQLZ9YZgbLkS7JIo5SuvdeZnKUIgFHbzP4gxpmE5BdtQiZw +8ESB2WgXLuNZcgLRWd+RRTmDkB28QbddtdoBDtO7SY55EX4Op65IG/EDI4Nji8Ql +Uw09jQN8meDHKIzEhg2SMICl +-----END PRIVATE KEY----- diff --git a/logs.json b/logs.json deleted file mode 100644 index 8af5f5a..0000000 --- a/logs.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "sources":[ - - {"name":"windows","proto" :"beats","port":50441,"tls":false,"path":"./Logs/windows.json"}, - {"name":"windows-tls","proto" :"beats","port":50442,"tls":true,"path":"./Logs/windows.json"}, - {"name":"test-tcp","proto" :"tcp","port":8585,"tls":false,"path":"./Logs/test.log"}, - {"name":"test-udp","proto" :"udp","port":8686,"tls":false,"path":"./Logs/test.log"} - ] -} \ No newline at end of file diff --git a/main.go b/main.go index 28f57f1..5a31b87 100644 --- a/main.go +++ b/main.go @@ -25,70 +25,59 @@ type JsonLogs struct { } type LogsMap map[string]JsonLogs +type Field struct { + Key string + Val string +} var ( dest, sources *string ca, cert, key *string inifity *bool delay *int64 + overwriteDate *bool + fields *string + fieldsList []Field logsMap LogsMap = make(LogsMap) tlsConfig *tls.Config + SendDelay time.Duration ) -func init() { - logsMap = LogsMap{} - - data, err := os.ReadFile("./logs.json") - if err != nil { - log.Fatal("logs.json not exist an current directory!") - } - - var j map[string]interface{} - err = json.Unmarshal(data, &j) +func main() { + err := loadSetting() if err != nil { log.Fatal(err) } - if sources, ok := j["sources"]; ok { - if ss, ok := sources.([]interface{}); ok { - for _, s := range ss { - tmp := s.(map[string]interface{}) - logsMap[tmp["name"].(string)] = JsonLogs{ - Name: tmp["name"].(string), - Port: int(tmp["port"].(float64)), - Protocol: tmp["proto"].(string), - Secure: tmp["tls"].(bool), - Logs: load(tmp["path"].(string)), - } - } - } else { - log.Fatal("parse failed : sources must be a array") - } - } else { - log.Fatal("parse failed : sources not found") - } - -} - -func main() { - - dest = flag.String("c", "", "destination") + dest = flag.String("c", "", "destination address") sources = flag.String("s", "", "sources") inifity = flag.Bool("i", false, "inifity mode") - delay = flag.Int64("d", 1, "send delay") - - ca = flag.String("ca", "", "ca") - cert = flag.String("cert", "", "cert") - key = flag.String("key", "", "key") + delay = flag.Int64("d", 0, "delay for each turn in inifity mode (miliseconds)") + overwriteDate = flag.Bool("overwrite-date", false, "overwrite date to now") + fields = flag.String("fields", "", "add field to log") + ca = flag.String("ca", "", "ca certificate") + cert = flag.String("cert", "", "cert certificate") + key = flag.String("key", "", "key certificate") flag.Parse() + SendDelay = time.Duration(*delay) * time.Millisecond + var incs []string if *sources != "" { incs = strings.Split(*sources, ",") } + if *fields != "" { + fl := strings.Split(*fields, ",") + for _, f := range fl { + kv := strings.Split(f, "=") + fieldsList = append(fieldsList, Field{ + Key: kv[0], + Val: kv[1], + }) + } + } - var err error tlsConfig, err = tls_config.LoadTLSCredentials(tls_config.Config{ CAPath: *ca, CertPath: *cert, @@ -123,21 +112,23 @@ func main() { } func sendBeatsLogs(ip string, mylog JsonLogs) { + // Address addr := fmt.Sprintf("%s:%d", ip, mylog.Port) - + // Default setting of conenction lconf := lumber.Config{ Addr: addr, CompressLevel: 3, Timeout: 30 * time.Second, BatchSize: 1, } + // Enable TLS if requested if mylog.Secure { if tlsConfig == nil { log.Fatalf("you want to use tls for %s but not specified certs/keys", mylog.Name) } lconf.TLSConfig = tlsConfig } - + // Create connection lc, err := lumber.NewClient(lconf) if err != nil { log.Fatalf("Failed to connect to Beat: %v", err) @@ -146,15 +137,24 @@ func sendBeatsLogs(ip string, mylog JsonLogs) { for { for _, msg := range mylog.Logs { - - payload := []interface{}{lumber.M2(msg)} + // Convert message to beat log + m := lumber.M2(msg) + // Overwrite timestamp field + dateNow := time.Now().Format("2006-01-02T15:04:05") + if _, ok := m.(map[string]interface{})["@timestamp"]; ok { + m.(map[string]interface{})["@timestamp"] = dateNow + } else { + log.Fatal("@timestampe field not found in the json to overwrite") + } + // Send payload data + payload := []interface{}{m} err := lc.Send(payload) if err != nil { log.Fatalf("Failed to send log to Beat: %v", err) } } log.Printf("send %d logs from datasource %s to server %s", len(mylog.Logs), mylog.Name, addr) - time.Sleep(time.Second) + time.Sleep(SendDelay) if !*inifity { break @@ -163,6 +163,26 @@ func sendBeatsLogs(ip string, mylog JsonLogs) { } +func addFields(m interface{}, fields []Field) interface{} { + if len(fields) == 0 { + return m + } + + if _, ok := m.(map[string]interface{})["fields"]; !ok { + m.(map[string]interface{})["fields"] = map[string]interface{}{} + } + + a, ok := m.(map[string]interface{})["fields"].(map[string]interface{}) + if !ok { + log.Fatal("failed to parse fields struct") + } + for _, f := range fields { + a[f.Key] = f.Val + } + + return a +} + func sendSyslogLogs(ip string, mylog JsonLogs) { var conn net.Conn var err error @@ -187,10 +207,9 @@ func sendSyslogLogs(ip string, mylog JsonLogs) { if err != nil { log.Fatalf("Failed to send log to Beat: %v", err) } - } log.Printf("send %d logs from datasource %s to server %s", len(mylog.Logs), mylog.Name, addr) - time.Sleep(time.Second) + time.Sleep(SendDelay) if !*inifity { break @@ -214,3 +233,40 @@ func send(ip string, log JsonLogs) { sendBeatsLogs(ip, log) } } + +func loadSetting() error { + logsMap = LogsMap{} + + data, err := os.ReadFile("./sources.json") + if err != nil { + return fmt.Errorf("sources.json not exist an current directory!") + } + + var j map[string]interface{} + err = json.Unmarshal(data, &j) + if err != nil { + return err + } + + if sources, ok := j["sources"]; ok { + if ss, ok := sources.([]interface{}); ok { + for _, s := range ss { + tmp := s.(map[string]interface{}) + logsMap[tmp["name"].(string)] = JsonLogs{ + Name: tmp["name"].(string), + Port: int(tmp["port"].(float64)), + Protocol: tmp["proto"].(string), + Secure: tmp["tls"].(bool), + Logs: load(tmp["path"].(string)), + } + } + } else { + return fmt.Errorf("parse failed : sources must be a array") + } + } else { + return fmt.Errorf("parse failed : sources not found") + } + + return nil + +} diff --git a/sources.json b/sources.json new file mode 100644 index 0000000..fb3f304 --- /dev/null +++ b/sources.json @@ -0,0 +1,10 @@ +{ + "sources":[ + + {"name":"windows68","proto" :"beats","port":15044,"tls":false,"path":"./Logs/windows.json"}, + {"name":"windows122","proto" :"beats","port":5044,"tls":false,"path":"./Logs/windows.json"}, + {"name":"windows-tls","proto" :"beats","port":5044,"tls":true,"path":"./Logs/windows.json"}, + {"name":"test-tcp","proto" :"tcp","port":8585,"tls":false,"path":"./Logs/test.log"}, + {"name":"test-udp","proto" :"udp","port":8686,"tls":false,"path":"./Logs/test.log"} + ] +} \ No newline at end of file