Skip to content

Commit

Permalink
ISSUE-1830: Adding changes for stopping the seceret and malware scans
Browse files Browse the repository at this point in the history
  • Loading branch information
varunsharma0286 committed Jul 13, 2023
1 parent a8c0624 commit 0e17447
Show file tree
Hide file tree
Showing 23 changed files with 690 additions and 63 deletions.
21 changes: 21 additions & 0 deletions deepfence_bootstrapper/controls/controls.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func SetAgentControls() {
if err != nil {
log.Error().Msgf("set controls: %v", err)
}

err = router.RegisterControl(ctl.StartSecretScan,
func(req ctl.StartSecretScanRequest) error {
return router.StartSecretsScan(req)
Expand Down Expand Up @@ -134,4 +135,24 @@ func SetAgentControls() {
if err != nil {
log.Error().Msgf("set controls: %v", err)
}

//Register the stop scan controls
err = router.RegisterControl(ctl.StopSecretScan,
func(req ctl.StopSecretScanRequest) error {
log.Info().Msg("StopSecretScanRequest called")
return router.StopSecretScan(req)
})
if err != nil {
log.Error().Msgf("set controls: %v", err)
}

err = router.RegisterControl(ctl.StopMalwareScan,
func(req ctl.StopMalwareScanRequest) error {
log.Info().Msg("StopMalwareScanRequest called")
return router.StopMalwareScan(req)
})
if err != nil {
log.Error().Msgf("set controls: %v", err)
}

}
2 changes: 1 addition & 1 deletion deepfence_bootstrapper/router/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
var controls map[ctl.ActionID]func(req []byte) error
var controls_guard sync.RWMutex

func RegisterControl[T ctl.StartVulnerabilityScanRequest | ctl.StartSecretScanRequest | ctl.StartComplianceScanRequest | ctl.StartMalwareScanRequest | ctl.StartAgentUpgradeRequest | ctl.SendAgentDiagnosticLogsRequest | ctl.DisableAgentPluginRequest | ctl.EnableAgentPluginRequest](id ctl.ActionID, callback func(req T) error) error {
func RegisterControl[T ctl.StartVulnerabilityScanRequest | ctl.StartSecretScanRequest | ctl.StartComplianceScanRequest | ctl.StartMalwareScanRequest | ctl.StartAgentUpgradeRequest | ctl.SendAgentDiagnosticLogsRequest | ctl.DisableAgentPluginRequest | ctl.EnableAgentPluginRequest | ctl.StopSecretScanRequest | ctl.StopMalwareScanRequest](id ctl.ActionID, callback func(req T) error) error {

controls_guard.Lock()
defer controls_guard.Unlock()
Expand Down
17 changes: 17 additions & 0 deletions deepfence_bootstrapper/router/malware_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,20 @@ func GetMalwareScannerJobCount() int32 {
}
return jobReport.RunningJobs
}

func StopMalwareScan(req ctl.StopMalwareScanRequest) error {
fmt.Printf("Stop Malware Scan : %v\n", req)
conn, err := grpc.Dial("unix://"+ebpfMalwareSocketPath, grpc.WithAuthority("dummy"),
grpc.WithInsecure())
if err != nil {
fmt.Printf("StopMalwareScannerJob::error in creating malware scanner client: %s\n", err.Error())
return err
}
defer conn.Close()
client := pb.NewScannersClient(conn)
var greq pb.StopScanRequest
greq.ScanId = req.BinArgs["scan_id"]

_, err = client.StopScan(context.Background(), &greq)
return err
}
23 changes: 23 additions & 0 deletions deepfence_bootstrapper/router/secret_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,26 @@ func GetSecretScannerJobCount() int32 {
}
return jobReport.RunningJobs
}

func StopSecretScan(req ctl.StopSecretScanRequest) error {
fmt.Printf("Stop Secret Scan : %v\n", req)
conn, err := grpc.Dial("unix://"+ebpfSocketPath, grpc.WithAuthority("dummy"),
grpc.WithInsecure())
if err != nil {
fmt.Printf("error in creating secret scanner client: %s\n", err.Error())
return err
}

defer conn.Close()
client := pb.NewScannersClient(conn)

var greq pb.StopScanRequest
greq.ScanId = req.BinArgs["scan_id"]

_, err := client.StopScan(context.Background(), &greq)
if err != nil {
fmt.Printf("StopSecretScan::error in client.StopScan: %s\n", err.Error())
}

return err
}
6 changes: 6 additions & 0 deletions deepfence_bootstrapper/supervisor/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ func (ph *procHandler) start() error {
}
cmd := exec.Command("/bin/bash", "-c", ph.command)
cmd.Env = ph.env
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
startLogging(ph.name, cmd)
if !ph.autorestart {
err := cmd.Start()
Expand Down Expand Up @@ -153,6 +156,9 @@ func (ph *procHandler) start() error {
time.Sleep(time.Second * 5)
cmd = exec.Command("/bin/bash", "-c", ph.command)
cmd.Env = ph.env
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
startLogging(ph.name, cmd)
}
}
Expand Down
2 changes: 1 addition & 1 deletion deepfence_ctl/cmd/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var imagesSubCmd = &cobra.Command{
req := http.Client().RegistryAPI.ListImageStubs(context.Background())
req = req.ModelRegistryImageStubsReq(
deepfence_server_client.ModelRegistryImageStubsReq{
ImageFilter: filters,
ImageFilter: deepfence_server_client.ReportersFieldsFilters{ContainsFilter: filters},
RegistryId: registry_id,
Window: deepfence_server_client.ModelFetchWindow{},
},
Expand Down
48 changes: 48 additions & 0 deletions deepfence_ctl/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,13 +397,59 @@ var scanResultsSubCmd = &cobra.Command{
},
}

var scanStopSubCmd = &cobra.Command{
Use: "stop",
Short: "Stop Scan",
Long: `This subcommand stops a scan`,
Run: func(cmd *cobra.Command, args []string) {

log.Info().Msgf("Command: %v", *cmd)
scan_type, _ := cmd.Flags().GetString("type")
if scan_type == "" {
log.Fatal().Msg("Please provide an type")
}

scan_id, _ := cmd.Flags().GetString("scan-id")
if scan_id == "" {
log.Fatal().Msg("Please provide a scan id")
}

var err error
var res interface{}
switch scan_type {
case "secret":
req := http.Client().SecretScanAPI.StopSecretScan(context.Background())
req = req.ModelStopScanRequest(deepfence_server_client.ModelStopScanRequest{
ScanId: scan_id,
ScanType: "SecretScan",
})
res, err = http.Client().SecretScanAPI.StopSecretScanExecute(req)
case "malware":
req := http.Client().MalwareScanAPI.StopMalwareScan(context.Background())
req = req.ModelStopScanRequest(deepfence_server_client.ModelStopScanRequest{
ScanId: scan_id,
ScanType: "MalwareScan",
})
res, err = http.Client().MalwareScanAPI.StopMalwareScanExecute(req)
default:
log.Fatal().Msg("Unsupported")
}

if err != nil {
log.Fatal().Msgf("Fail to execute: %v", err)
}
output.Out(res)
},
}

func init() {
rootCmd.AddCommand(scanCmd)
scanCmd.AddCommand(scanStartSubCmd)
scanCmd.AddCommand(scanStatusSubCmd)
scanCmd.AddCommand(scanListSubCmd)
scanCmd.AddCommand(scanResultsSubCmd)
scanCmd.AddCommand(scanSearchSubCmd)
scanCmd.AddCommand(scanStopSubCmd)

scanCmd.PersistentFlags().String("type", "", "Scan type")

Expand All @@ -421,4 +467,6 @@ func init() {

scanResultsSubCmd.PersistentFlags().String("scan-id", "", "Scan id")

scanStopSubCmd.PersistentFlags().String("scan-id", "", "Scan id")

}
8 changes: 4 additions & 4 deletions deepfence_server/apiDocs/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,15 @@ func (d *OpenApiDocs) AddScansOperations() {
d.AddOperation("stopVulnerabilityScan", http.MethodPost, "/deepfence/scan/stop/vulnerability",
"Stop Vulnerability Scan", "Stop Vulnerability Scan on agent or registry",
http.StatusAccepted, []string{tagVulnerability}, bearerToken, new(VulnerabilityScanTriggerReq), nil)
d.AddOperation("stopSecretScan", http.MethodPost, "/deepfence/scan/stop/secret",
"Stop Secret Scan", "Stop Secret Scan on agent or registry",
http.StatusAccepted, []string{tagSecretScan}, bearerToken, new(SecretScanTriggerReq), nil)
d.AddOperation("stopComplianceScan", http.MethodPost, "/deepfence/scan/stop/compliance",
"Stop Compliance Scan", "Stop Compliance Scan on agent or registry",
http.StatusAccepted, []string{tagCompliance}, bearerToken, new(ComplianceScanTriggerReq), nil)
d.AddOperation("stopMalwareScan", http.MethodPost, "/deepfence/scan/stop/malware",
"Stop Malware Scan", "Stop Malware Scan on agent or registry",
http.StatusAccepted, []string{tagMalwareScan}, bearerToken, new(MalwareScanTriggerReq), nil)
http.StatusOK, []string{tagMalwareScan}, bearerToken, new(StopScanRequest), nil)
d.AddOperation("stopSecretScan", http.MethodPost, "/deepfence/scan/stop/secret",
"Stop Secret Scan", "Stop Secret Scan on agent or registry",
http.StatusOK, []string{tagSecretScan}, bearerToken, new(StopScanRequest), nil)

// Status scan
d.AddOperation("statusVulnerabilityScan", http.MethodPost, "/deepfence/scan/status/vulnerability",
Expand Down
103 changes: 97 additions & 6 deletions deepfence_server/controls/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,37 @@ import (
)

var (
MaxStops = 5
MissingNode = errors.New("Missing node_id")
)

func GetAgentActions(ctx context.Context, nodeId string, work_num_to_extract int) ([]controls.Action, []error) {
func GetAgentActions(ctx context.Context, nodeId string,
work_num_to_extract int) ([]controls.Action, []error) {

// Append more actions here
actions := []controls.Action{}

if work_num_to_extract == 0 {
return actions, []error{}
}

// early return to avoid unnecessary checks
if err := CheckNodeExist(ctx, nodeId); err != nil {
log.Info().Msgf("Missing node: %s.... Skipping all actions", nodeId)
actions = []controls.Action{}
return actions, []error{}
}

//Extract the stop scans requests
stop_actions, stop_actions_err := ExtractStoppingAgentScans(ctx, nodeId, MaxStops)
if stop_actions_err == nil {
actions = append(actions, stop_actions...)
}

if work_num_to_extract == 0 {
if stop_actions_err != nil {
return actions, []error{stop_actions_err}
} else {
return actions, []error{}
}
}

upgrade_actions, upgrade_err := ExtractPendingAgentUpgrade(ctx, nodeId, work_num_to_extract)
work_num_to_extract -= len(upgrade_actions)
if upgrade_err == nil {
Expand Down Expand Up @@ -242,7 +257,9 @@ func hasPendingAgentScans(client neo4j.Driver, nodeId string, max_work int) (boo
return len(records) != 0, err
}

func ExtractStartingAgentScans(ctx context.Context, nodeId string, max_work int) ([]controls.Action, error) {
func ExtractStartingAgentScans(ctx context.Context, nodeId string,
max_work int) ([]controls.Action, error) {

res := []controls.Action{}
if len(nodeId) == 0 {
return res, MissingNode
Expand Down Expand Up @@ -310,6 +327,80 @@ func ExtractStartingAgentScans(ctx context.Context, nodeId string, max_work int)

}

func ExtractStoppingAgentScans(ctx context.Context, nodeId string,
max_work int) ([]controls.Action, error) {

res := []controls.Action{}
if len(nodeId) == 0 {
return res, MissingNode
}

client, err := directory.Neo4jClient(ctx)
if err != nil {
return res, err
}

session, err := client.Session(neo4j.AccessModeWrite)
if err != nil {
return res, err
}
defer session.Close()

tx, err := session.BeginTransaction(neo4j.WithTxTimeout(30 * time.Second))
if err != nil {
return res, err
}
defer tx.Close()

r, err := tx.Run(`MATCH (s) -[:SCHEDULED]-> (n:Node{node_id:$id})
WHERE s.status = '`+utils.SCAN_STATUS_CANCEL_PENDING+`'
WITH s LIMIT $max_work
SET s.status = '`+utils.SCAN_STATUS_CANCELLING+`', s.updated_at = TIMESTAMP()
WITH s
RETURN s.trigger_action`,
map[string]interface{}{"id": nodeId, "max_work": max_work})

if err != nil {
return res, err
}

records, err := r.Collect()

if err != nil {
return res, err
}

for _, record := range records {
var action controls.Action
if record.Values[0] == nil {
log.Error().Msgf("Invalid neo4j trigger_action result, skipping")
continue
}
err := json.Unmarshal([]byte(record.Values[0].(string)), &action)
if err != nil {
log.Error().Msgf("ExtractStoppingAgentScans Unmarshal of action failed: %v", err)
continue
}
switch action.ID {
case controls.StartSecretScan:
action.ID = controls.StopSecretScan
case controls.StartMalwareScan:
action.ID = controls.StopMalwareScan
default:
log.Info().Msgf("Stop functionality not implemented for action: %d", action.ID)
continue
}
res = append(res, action)
}

if len(res) != 0 {
err = tx.Commit()
}

return res, err

}

func hasPendingAgentUpgrade(client neo4j.Driver, nodeId string, max_work int) (bool, error) {
session, err := client.Session(neo4j.AccessModeRead)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion deepfence_server/handler/agent_controls.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ func (h *Handler) GetAgentControls(w http.ResponseWriter, r *http.Request) {
actions, errs := controls.GetAgentActions(ctx, agentId.NodeId, agentId.AvailableWorkload)
for _, err := range errs {
if err != nil {
log.Warn().Msgf("Cannot some actions for %s: %v, skipping", agentId.NodeId, err)
log.Warn().Msgf("Cannot process some actions for %s: %v, skipping",
agentId.NodeId, err)
}
}

Expand Down
Loading

0 comments on commit 0e17447

Please sign in to comment.