ca0e1ca769
This is an initial import of the osel codebase. The osel tool is a tool that initiates external security scans (initially through Qualys) upon reciept of AMQP events that indicate certain sensitive events have occurred, like a security group rule change. The commit history had to be thrown away because it contained some non-public data, so I would like to call out the following contributors: This uses go 1.10 and vgo for dependency management. Co-Authored-By: Charles Bitter <Charles_Bitter@cable.comcast.com> Co-Authored-By: Olivier Gagnon <Olivier_Gagnon@cable.comcast.com> Co-Authored-By: Joseph Sleiman <Joseph_Sleiman@comcast.com> Change-Id: Ib6abe2024fd91978b783ceee4cff8bb4678d7b15
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// EventSecurityGroupRuleChange is the event processor class for all changes to
|
|
// security groups. This includes additions and deletions. This must conform
|
|
// to the EventProcessor interface (see events.go).
|
|
type EventSecurityGroupRuleChange struct {
|
|
ChangeType string
|
|
}
|
|
|
|
// FillExtraData takes a security group change and enriches it with additional
|
|
// information about the affected IP addresses using the
|
|
// OpenStackActionInterface getPortList function.
|
|
func (s EventSecurityGroupRuleChange) FillExtraData(e *Event, openstack OpenStackActioner) error {
|
|
// PopulateIps: This function returns a map of security group to array of IP addresses for all ports in the specified tenantID.
|
|
|
|
err := openstack.Connect(e.EventData.TenantID, e.EventData.UserName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Make port list request to neutron
|
|
resultMap := openstack.GetPortList()
|
|
resultIPAddresses := make(map[string][]string)
|
|
for _, ipMap := range resultMap {
|
|
resultIPAddresses[ipMap.securityGroup] = append(resultIPAddresses[ipMap.securityGroup], ipMap.ipAddress)
|
|
}
|
|
e.IPs = resultIPAddresses
|
|
return nil
|
|
}
|
|
|
|
// FormatLogs takes the accumulated event data and composes the JSON message to
|
|
// be logged.
|
|
func (s EventSecurityGroupRuleChange) FormatLogs(e *Event, scannedIPAddresses []string) ([]string, error) {
|
|
var es osSecurityGroupRuleChange
|
|
var logLines []string
|
|
if e == nil {
|
|
return logLines, fmt.Errorf("Event must not be nil")
|
|
}
|
|
|
|
if err := json.Unmarshal(e.RawData, &es); err != nil {
|
|
return logLines, err
|
|
}
|
|
|
|
hostName, err := os.Hostname()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
es.Payload.ChangeType = s.ChangeType
|
|
es.Payload.SourceType = OselVersion
|
|
es.Payload.SourceMessageBus = hostName
|
|
es.Payload.QualysScanID = e.QualysScanID
|
|
es.Payload.QualysScanError = e.QualysScanError
|
|
|
|
affectedIPArray := e.IPs[es.Payload.SecurityGroupRule.SecurityGroupID]
|
|
qualysScanJoin := fmt.Sprintf("|%s|", strings.Join(scannedIPAddresses, "|"))
|
|
for _, affectedIPAddr := range affectedIPArray {
|
|
es.Payload.QualysScanID = ""
|
|
es.Payload.QualysScanError = ""
|
|
if strings.Index(qualysScanJoin, fmt.Sprintf("|%s|", affectedIPAddr)) > -1 {
|
|
es.Payload.QualysScanID = e.QualysScanID
|
|
es.Payload.QualysScanError = e.QualysScanError
|
|
} else {
|
|
es.Payload.QualysScanID = ""
|
|
es.Payload.QualysScanError = "Not scanned by Qualys"
|
|
}
|
|
es.Payload.AffectedIPAddr = affectedIPAddr
|
|
jsonLine, err := json.Marshal(es.Payload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
logLines = append(logLines, string(jsonLine))
|
|
}
|
|
return logLines, nil
|
|
}
|