mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-21 23:00:42 -08:00
feat(filesystem): scan in client/server mode (#1829)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
@@ -13,9 +13,11 @@ import (
|
||||
"github.com/aquasecurity/fanal/artifact"
|
||||
"github.com/aquasecurity/fanal/cache"
|
||||
"github.com/aquasecurity/trivy-db/pkg/db"
|
||||
tcache "github.com/aquasecurity/trivy/pkg/cache"
|
||||
"github.com/aquasecurity/trivy/pkg/commands/operation"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
||||
"github.com/aquasecurity/trivy/pkg/rpc/client"
|
||||
"github.com/aquasecurity/trivy/pkg/scanner"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/utils"
|
||||
@@ -25,9 +27,26 @@ const defaultPolicyNamespace = "appshield"
|
||||
|
||||
var errSkipScan = errors.New("skip subsequent processes")
|
||||
|
||||
type scannerConfig struct {
|
||||
// e.g. image name and file path
|
||||
Target string
|
||||
|
||||
// Cache
|
||||
ArtifactCache cache.ArtifactCache
|
||||
LocalArtifactCache cache.LocalArtifactCache
|
||||
|
||||
// Client/Server options
|
||||
RemoteOption client.ScannerOption
|
||||
|
||||
// Artifact options
|
||||
ArtifactOption artifact.Option
|
||||
|
||||
// Misconfiguration scanning options
|
||||
MisconfOption config.ScannerOption
|
||||
}
|
||||
|
||||
// InitializeScanner defines the initialize function signature of scanner
|
||||
type InitializeScanner func(context.Context, string, cache.ArtifactCache, cache.LocalArtifactCache, bool,
|
||||
artifact.Option, config.ScannerOption) (scanner.Scanner, func(), error)
|
||||
type InitializeScanner func(context.Context, scannerConfig) (scanner.Scanner, func(), error)
|
||||
|
||||
// InitCache defines cache initializer
|
||||
type InitCache func(c Option) (cache.Cache, error)
|
||||
@@ -37,7 +56,11 @@ func Run(ctx context.Context, opt Option, initializeScanner InitializeScanner, i
|
||||
ctx, cancel := context.WithTimeout(ctx, opt.Timeout)
|
||||
defer cancel()
|
||||
|
||||
return runWithTimeout(ctx, opt, initializeScanner, initCache)
|
||||
err := runWithTimeout(ctx, opt, initializeScanner, initCache)
|
||||
if xerrors.Is(err, context.DeadlineExceeded) {
|
||||
log.Logger.Warn("Increase --timeout value")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func runWithTimeout(ctx context.Context, opt Option, initializeScanner InitializeScanner, initCache InitCache) error {
|
||||
@@ -54,8 +77,8 @@ func runWithTimeout(ctx context.Context, opt Option, initializeScanner Initializ
|
||||
}
|
||||
defer cacheClient.Close()
|
||||
|
||||
// When scanning config files, it doesn't need to download the vulnerability database.
|
||||
if utils.StringInSlice(types.SecurityCheckVulnerability, opt.SecurityChecks) {
|
||||
// When scanning config files or running as client mode, it doesn't need to download the vulnerability database.
|
||||
if opt.RemoteAddr == "" && utils.StringInSlice(types.SecurityCheckVulnerability, opt.SecurityChecks) {
|
||||
if err = initDB(opt); err != nil {
|
||||
if errors.Is(err, errSkipScan) {
|
||||
return nil
|
||||
@@ -92,7 +115,14 @@ func runWithTimeout(ctx context.Context, opt Option, initializeScanner Initializ
|
||||
return nil
|
||||
}
|
||||
|
||||
func initFSCache(c Option) (cache.Cache, error) {
|
||||
func initCache(c Option) (cache.Cache, error) {
|
||||
// client/server mode
|
||||
if c.RemoteAddr != "" {
|
||||
remoteCache := tcache.NewRemoteCache(c.RemoteAddr, c.CustomHeaders, c.Insecure)
|
||||
return tcache.NopCache(remoteCache), nil
|
||||
}
|
||||
|
||||
// standalone mode
|
||||
utils.SetCacheDir(c.CacheDir)
|
||||
cache, err := operation.NewCache(c.CacheOption)
|
||||
if err != nil {
|
||||
@@ -181,7 +211,7 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
|
||||
}
|
||||
log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType)
|
||||
|
||||
// ScannerOptions is filled only when config scanning is enabled.
|
||||
// ScannerOption is filled only when config scanning is enabled.
|
||||
var configScannerOptions config.ScannerOption
|
||||
if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) {
|
||||
noProgress := opt.Quiet || opt.NoProgress
|
||||
@@ -199,16 +229,25 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
|
||||
}
|
||||
}
|
||||
|
||||
artifactOpt := artifact.Option{
|
||||
DisabledAnalyzers: disabledAnalyzers(opt),
|
||||
SkipFiles: opt.SkipFiles,
|
||||
SkipDirs: opt.SkipDirs,
|
||||
InsecureSkipTLS: opt.Insecure,
|
||||
Offline: opt.OfflineScan,
|
||||
NoProgress: opt.NoProgress || opt.Quiet,
|
||||
}
|
||||
|
||||
s, cleanup, err := initializeScanner(ctx, target, cacheClient, cacheClient, opt.Insecure, artifactOpt, configScannerOptions)
|
||||
s, cleanup, err := initializeScanner(ctx, scannerConfig{
|
||||
Target: target,
|
||||
ArtifactCache: cacheClient,
|
||||
LocalArtifactCache: cacheClient,
|
||||
RemoteOption: client.ScannerOption{
|
||||
RemoteURL: opt.RemoteAddr,
|
||||
CustomHeaders: opt.CustomHeaders,
|
||||
Insecure: opt.Insecure,
|
||||
},
|
||||
ArtifactOption: artifact.Option{
|
||||
DisabledAnalyzers: disabledAnalyzers(opt),
|
||||
SkipFiles: opt.SkipFiles,
|
||||
SkipDirs: opt.SkipDirs,
|
||||
InsecureSkipTLS: opt.Insecure,
|
||||
Offline: opt.OfflineScan,
|
||||
NoProgress: opt.NoProgress || opt.Quiet,
|
||||
},
|
||||
MisconfOption: configScannerOptions,
|
||||
})
|
||||
if err != nil {
|
||||
return types.Report{}, xerrors.Errorf("unable to initialize a scanner: %w", err)
|
||||
}
|
||||
@@ -225,7 +264,10 @@ func filter(ctx context.Context, opt Option, report types.Report) (types.Report,
|
||||
resultClient := initializeResultClient()
|
||||
results := report.Results
|
||||
for i := range results {
|
||||
resultClient.FillVulnerabilityInfo(results[i].Vulnerabilities, results[i].Type)
|
||||
// Fill vulnerability info only in standalone mode
|
||||
if opt.RemoteAddr == "" {
|
||||
resultClient.FillVulnerabilityInfo(results[i].Vulnerabilities, results[i].Type)
|
||||
}
|
||||
vulns, misconfSummary, misconfs, err := resultClient.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations,
|
||||
opt.Severities, opt.IgnoreUnfixed, opt.IncludeNonFailures, opt.IgnoreFile, opt.IgnorePolicy)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user