-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
130 lines (105 loc) · 3.25 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"bytes"
"context"
"encoding/json"
"github.com/aws/aws-lambda-go/lambda"
"log"
"net/http"
"os"
"strconv"
"time"
)
// GuardDuty Message
type Message struct {
Id string
Detail MessageDetail
}
type MessageDetail struct {
Type string
Service MessageService
Severity int
Title string
Description string
}
type MessageService struct {
Action MessageAction
EventFirstSeen string
EventLastSeen string
Count int
}
type MessageAction struct {
ActionType string
Map map[string]json.RawMessage
}
// Slack Message
type SlackMessage struct {
Text string `json:"text"`
Attachments []Attachment `json:"attachments"`
}
type Attachment struct {
Text string `json:"text"`
Color string `json:"color"`
Fields []Field `json:"fields"`
}
type Field struct {
Title string `json:"title"`
Value string `json:"value"`
Short bool `json:"short"`
}
func Handler(ctx context.Context, message Message) (string, error) {
// timestamp
location, _ := time.LoadLocation("Asia/Seoul")
var eventFirstSeen, _ = time.Parse(time.RFC3339, message.Detail.Service.EventFirstSeen)
var eventLastSeen, _ = time.Parse(time.RFC3339, message.Detail.Service.EventLastSeen)
var text = "GuardDuty Finding"
var color = "#0073bb"
var floatSeverity = float64(message.Detail.Severity)
// Severity levels
// - https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_findings.html?icmpid=docs_gd_help_panel
// - color는 console 배경색 참조
if floatSeverity >= 7 && floatSeverity <= 8.9 {
color = "#d13212"
} else if floatSeverity >= 5 && floatSeverity <= 6.9 {
color = "#eb5f07"
}
var fields []Field
fields = append(fields, Field{Title: "Type", Value: message.Detail.Type, Short: false})
fields = append(fields, Field{Title: "Severity", Value: strconv.Itoa(message.Detail.Severity), Short: false})
fields = append(fields, Field{Title: "Action Type", Value: message.Detail.Service.Action.ActionType, Short: false})
fields = append(fields, Field{Title: "Title", Value: message.Detail.Title, Short: false})
fields = append(fields, Field{Title: "Description", Value: message.Detail.Description, Short: false})
fields = append(fields, Field{Title: "EventFirstSeen", Value: eventFirstSeen.In(location).String(), Short: false})
fields = append(fields, Field{Title: "EventLastSeen", Value: eventLastSeen.In(location).String(), Short: false})
fields = append(fields, Field{Title: "Count", Value: strconv.Itoa(message.Detail.Service.Count), Short: false})
slackMessage := SlackMessage{
Text: text,
Attachments: []Attachment{
Attachment{
Color: color,
Fields: fields,
},
},
}
slackBody := sendSlack(slackMessage)
log.Printf("slackBody: %s\n", slackBody)
return slackBody, nil
}
func sendSlack(slackMessage SlackMessage) string {
webhookUrl := os.Getenv("WEBHOOK_URL")
slackBody, _ := json.Marshal(slackMessage)
req, err := http.NewRequest(http.MethodPost, webhookUrl, bytes.NewBuffer(slackBody))
if err != nil {
panic(err)
}
req.Header.Add("Content-type", "application/json")
client := &http.Client{Timeout: 10 * time.Second}
res, _ := client.Do(req)
defer res.Body.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(res.Body)
return buf.String()
}
func main() {
lambda.Start(Handler)
}