add process posture check to posture checks handlers

This commit is contained in:
bcmmbaga
2024-03-12 15:20:00 +03:00
parent 5f0eec0add
commit 9f41a1f20f
4 changed files with 171 additions and 1 deletions

View File

@ -864,6 +864,8 @@ components:
$ref: '#/components/schemas/GeoLocationCheck' $ref: '#/components/schemas/GeoLocationCheck'
peer_network_range_check: peer_network_range_check:
$ref: '#/components/schemas/PeerNetworkRangeCheck' $ref: '#/components/schemas/PeerNetworkRangeCheck'
process_check:
$ref: '#/components/schemas/ProcessCheck'
NBVersionCheck: NBVersionCheck:
description: Posture check for the version of NetBird description: Posture check for the version of NetBird
type: object type: object
@ -952,6 +954,31 @@ components:
required: required:
- ranges - ranges
- action - action
ProcessCheck:
description: Posture Check for binaries exist and are running in the peers system
type: object
properties:
processes:
type: array
items:
$ref: '#/components/schemas/Process'
required:
- processes
Process:
description: Describe the operational activity within peer's system.
type: object
properties:
path:
description: Path to the process executable file in a Unix-like operating system
type: string
example: "/usr/local/bin/netbird"
windows_path:
description: Path to the process executable file in a Windows operating system
type: string
example: "C:\ProgramData\NetBird\netbird.exe"
required:
- path
- windows_path
Location: Location:
description: Describe geographical location information description: Describe geographical location information
type: object type: object

View File

@ -201,6 +201,9 @@ type Checks struct {
// PeerNetworkRangeCheck Posture check for allow or deny access based on peer local network addresses // PeerNetworkRangeCheck Posture check for allow or deny access based on peer local network addresses
PeerNetworkRangeCheck *PeerNetworkRangeCheck `json:"peer_network_range_check,omitempty"` PeerNetworkRangeCheck *PeerNetworkRangeCheck `json:"peer_network_range_check,omitempty"`
// ProcessCheck Posture Check for binaries exist and are running in the peers system
ProcessCheck *ProcessCheck `json:"process_check,omitempty"`
} }
// City Describe city geographical location information // City Describe city geographical location information
@ -910,6 +913,20 @@ type PostureCheckUpdate struct {
Name string `json:"name"` Name string `json:"name"`
} }
// Process Describe the operational activity within peer's system.
type Process struct {
// Path Path to the process executable file in a Unix-like operating system
Path string `json:"path"`
// WindowsPath Path to the process executable file in a Windows operating system
WindowsPath string `json:"windows_path"`
}
// ProcessCheck Posture Check for binaries exist and are running in the peers system
type ProcessCheck struct {
Processes []Process `json:"processes"`
}
// Route defines model for Route. // Route defines model for Route.
type Route struct { type Route struct {
// Description Route description // Description Route description

View File

@ -221,6 +221,10 @@ func (p *PostureChecksHandler) savePostureChecks(
} }
} }
if processCheck := req.Checks.ProcessCheck; processCheck != nil {
postureChecks.Checks.ProcessCheck = toProcessCheck(processCheck)
}
if err := p.accountManager.SavePostureChecks(account.Id, user.Id, &postureChecks); err != nil { if err := p.accountManager.SavePostureChecks(account.Id, user.Id, &postureChecks); err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -235,7 +239,7 @@ func validatePostureChecksUpdate(req api.PostureCheckUpdate) error {
} }
if req.Checks == nil || (req.Checks.NbVersionCheck == nil && req.Checks.OsVersionCheck == nil && if req.Checks == nil || (req.Checks.NbVersionCheck == nil && req.Checks.OsVersionCheck == nil &&
req.Checks.GeoLocationCheck == nil && req.Checks.PeerNetworkRangeCheck == nil) { req.Checks.GeoLocationCheck == nil && req.Checks.PeerNetworkRangeCheck == nil && req.Checks.ProcessCheck == nil) {
return status.Errorf(status.InvalidArgument, "posture checks shouldn't be empty") return status.Errorf(status.InvalidArgument, "posture checks shouldn't be empty")
} }
@ -292,6 +296,21 @@ func validatePostureChecksUpdate(req api.PostureCheckUpdate) error {
} }
} }
if processCheck := req.Checks.ProcessCheck; processCheck != nil {
if len(processCheck.Processes) == 0 {
return status.Errorf(status.InvalidArgument, "processes for process check shouldn't be empty")
}
for _, process := range processCheck.Processes {
if process.WindowsPath == "" {
return status.Errorf(status.InvalidArgument, "windows path for process check shouldn't be empty")
}
if process.Path == "" {
return status.Errorf(status.InvalidArgument, "path for process check shouldn't be empty")
}
}
}
return nil return nil
} }
@ -322,6 +341,10 @@ func toPostureChecksResponse(postureChecks *posture.Checks) *api.PostureCheck {
checks.PeerNetworkRangeCheck = toPeerNetworkRangeCheckResponse(postureChecks.Checks.PeerNetworkRangeCheck) checks.PeerNetworkRangeCheck = toPeerNetworkRangeCheckResponse(postureChecks.Checks.PeerNetworkRangeCheck)
} }
if postureChecks.Checks.ProcessCheck != nil {
checks.ProcessCheck = toProcessCheckResponse(postureChecks.Checks.ProcessCheck)
}
return &api.PostureCheck{ return &api.PostureCheck{
Id: postureChecks.ID, Id: postureChecks.ID,
Name: postureChecks.Name, Name: postureChecks.Name,
@ -396,3 +419,28 @@ func toPeerNetworkRangeCheck(check *api.PeerNetworkRangeCheck) (*posture.PeerNet
Action: string(check.Action), Action: string(check.Action),
}, nil }, nil
} }
func toProcessCheckResponse(check *posture.ProcessCheck) *api.ProcessCheck {
processes := make([]api.Process, 0, len(check.Processes))
for _, process := range check.Processes {
processes = append(processes, (api.Process)(process))
}
return &api.ProcessCheck{
Processes: processes,
}
}
func toProcessCheck(check *api.ProcessCheck) *posture.ProcessCheck {
processes := make([]posture.Process, 0, len(check.Processes))
for _, process := range check.Processes {
processes = append(processes, posture.Process{
Path: process.Path,
WindowsPath: process.WindowsPath,
})
}
return &posture.ProcessCheck{
Processes: processes,
}
}

View File

@ -433,6 +433,43 @@ func TestPostureCheckUpdate(t *testing.T) {
handler.geolocationManager = nil handler.geolocationManager = nil
}, },
}, },
{
name: "Create Posture Checks Process Check",
requestType: http.MethodPost,
requestPath: "/api/posture-checks",
requestBody: bytes.NewBuffer(
[]byte(`{
"name": "default",
"description": "default",
"checks": {
"process_check": {
"processes": [
{
"path": "/usr/local/bin/netbird",
"windows_path": "C:\\ProgramData\\NetBird\\netbird.exe"
}
]
}
}
}`)),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedPostureCheck: &api.PostureCheck{
Id: "postureCheck",
Name: "default",
Description: str("default"),
Checks: api.Checks{
ProcessCheck: &api.ProcessCheck{
Processes: []api.Process{
{
Path: "/usr/local/bin/netbird",
WindowsPath: "C:\\ProgramData\\NetBird\\netbird.exe",
},
},
},
},
},
},
{ {
name: "Create Posture Checks Invalid Check", name: "Create Posture Checks Invalid Check",
requestType: http.MethodPost, requestType: http.MethodPost,
@ -937,4 +974,45 @@ func TestPostureCheck_validatePostureChecksUpdate(t *testing.T) {
}, },
) )
assert.Error(t, err) assert.Error(t, err)
// valid process check
processCheck := api.ProcessCheck{
Processes: []api.Process{
{
Path: "/usr/local/bin/netbird",
WindowsPath: "C:\\ProgramData\\NetBird\\netbird.exe",
},
},
}
err = validatePostureChecksUpdate(api.PostureCheckUpdate{Name: "Default", Checks: &api.Checks{ProcessCheck: &processCheck}})
assert.NoError(t, err)
// invalid process check
processCheck = api.ProcessCheck{
Processes: make([]api.Process, 0),
}
err = validatePostureChecksUpdate(api.PostureCheckUpdate{Name: "Default", Checks: &api.Checks{ProcessCheck: &processCheck}})
assert.Error(t, err)
// invalid process check
processCheck = api.ProcessCheck{
Processes: []api.Process{
{
Path: "/usr/local/bin/netbird",
},
},
}
err = validatePostureChecksUpdate(api.PostureCheckUpdate{Name: "Default", Checks: &api.Checks{ProcessCheck: &processCheck}})
assert.Error(t, err)
// invalid process check
processCheck = api.ProcessCheck{
Processes: []api.Process{
{
WindowsPath: "C:\\ProgramData\\NetBird\\netbird.exe",
},
},
}
err = validatePostureChecksUpdate(api.PostureCheckUpdate{Name: "Default", Checks: &api.Checks{ProcessCheck: &processCheck}})
assert.Error(t, err)
} }