151 lines
4.7 KiB
Go
151 lines
4.7 KiB
Go
package unifi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// IDSList contains a list that contains all of the IDS Events on a controller.
|
|
type IDSList []*IDS
|
|
|
|
// IDS holds an Intrusion Prevention System Event.
|
|
type IDS struct {
|
|
SourceName string `json:"-"`
|
|
ID string `json:"_id"`
|
|
Archived FlexBool `json:"archived"`
|
|
Timestamp int64 `json:"timestamp"`
|
|
FlowID int64 `json:"flow_id"`
|
|
InIface string `json:"in_iface"`
|
|
EventType string `json:"event_type"`
|
|
SrcIP string `json:"src_ip"`
|
|
SrcMac string `json:"src_mac"`
|
|
SrcPort int `json:"src_port,omitempty"`
|
|
DestIP string `json:"dest_ip"`
|
|
DstMac string `json:"dst_mac"`
|
|
DestPort int `json:"dest_port,omitempty"`
|
|
Proto string `json:"proto"`
|
|
AppProto string `json:"app_proto,omitempty"`
|
|
Host string `json:"host"`
|
|
Usgip string `json:"usgip"`
|
|
UniqueAlertid string `json:"unique_alertid"`
|
|
SrcipCountry string `json:"srcipCountry"`
|
|
DstipCountry FlexBool `json:"dstipCountry"`
|
|
UsgipCountry string `json:"usgipCountry"`
|
|
SrcipGeo struct {
|
|
ContinentCode string `json:"continent_code"`
|
|
CountryCode string `json:"country_code"`
|
|
CountryCode3 string `json:"country_code3"`
|
|
CountryName string `json:"country_name"`
|
|
Region string `json:"region"`
|
|
City string `json:"city"`
|
|
PostalCode string `json:"postal_code"`
|
|
Latitude float64 `json:"latitude"`
|
|
Longitude float64 `json:"longitude"`
|
|
DmaCode int64 `json:"dma_code"`
|
|
AreaCode int64 `json:"area_code"`
|
|
} `json:"srcipGeo"`
|
|
DstipGeo bool `json:"dstipGeo"`
|
|
UsgipGeo struct {
|
|
ContinentCode string `json:"continent_code"`
|
|
CountryCode string `json:"country_code"`
|
|
CountryCode3 string `json:"country_code3"`
|
|
CountryName string `json:"country_name"`
|
|
Region string `json:"region"`
|
|
City string `json:"city"`
|
|
PostalCode string `json:"postal_code"`
|
|
Latitude float64 `json:"latitude"`
|
|
Longitude float64 `json:"longitude"`
|
|
DmaCode int64 `json:"dma_code"`
|
|
AreaCode int64 `json:"area_code"`
|
|
} `json:"usgipGeo"`
|
|
SrcipASN string `json:"srcipASN"`
|
|
DstipASN string `json:"dstipASN"`
|
|
UsgipASN string `json:"usgipASN"`
|
|
Catname string `json:"catname"`
|
|
InnerAlertAction string `json:"inner_alert_action"`
|
|
InnerAlertGID int64 `json:"inner_alert_gid"`
|
|
InnerAlertSignatureID int64 `json:"inner_alert_signature_id"`
|
|
InnerAlertRev int64 `json:"inner_alert_rev"`
|
|
InnerAlertSignature string `json:"inner_alert_signature"`
|
|
InnerAlertCategory string `json:"inner_alert_category"`
|
|
InnerAlertSeverity int64 `json:"inner_alert_severity"`
|
|
Key string `json:"key"`
|
|
Subsystem string `json:"subsystem"`
|
|
SiteID string `json:"site_id"`
|
|
SiteName string `json:"-"`
|
|
Time int64 `json:"time"`
|
|
Datetime time.Time `json:"datetime"`
|
|
Msg string `json:"msg"`
|
|
IcmpType int64 `json:"icmp_type,omitempty"`
|
|
IcmpCode int64 `json:"icmp_code,omitempty"`
|
|
}
|
|
|
|
// GetIDS returns Intrusion Detection Systems events.
|
|
// Returns all events that happened in site between from and to.
|
|
func (u *Unifi) GetIDS(sites Sites, from, to time.Time) ([]*IDS, error) {
|
|
data := []*IDS{}
|
|
|
|
for _, site := range sites {
|
|
u.DebugLog("Polling Controller for IDS/IPS Data, site %s (%s) ", site.Name, site.Desc)
|
|
|
|
ids, err := u.GetSiteIDS(site, from, to)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
|
|
for i := range ids {
|
|
ids[i].SourceName = u.URL
|
|
}
|
|
|
|
data = append(data, ids...)
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
// GetSiteIDS is a helper to offload the for-loop work.
|
|
// This method retreives the Intrusion Detection System Data for 1 Site.
|
|
func (u *Unifi) GetSiteIDS(site *Site, from, to time.Time) ([]*IDS, error) {
|
|
var response struct {
|
|
Data []*IDS `json:"data"`
|
|
}
|
|
|
|
URIpath := fmt.Sprintf(APIIPSEvents, site.Name)
|
|
|
|
params := fmt.Sprintf(`{"start":"%v000","end":"%v000","_limit":50000}`, from.Unix(), to.Unix())
|
|
|
|
req, err := u.UniReq(URIpath, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := u.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("invalid status code from server %s", resp.Status)
|
|
}
|
|
|
|
if err := json.Unmarshal(body, &response); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i := range response.Data {
|
|
response.Data[i].SiteName = site.SiteName
|
|
}
|
|
|
|
return response.Data, nil
|
|
}
|