osel/security_group_events.go
Nate Johnston ca0e1ca769 Initial import of osel code
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
2018-03-24 15:30:57 +00:00

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
}