-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Alpine support via Alpine-SecDB #272
Conversation
|
🚎 |
Umm, the GIF doesn't even load! |
|
||
// Ask the database for the latest commit we successfully applied. | ||
var dbCommit string | ||
dbCommit, err = db.GetKeyValue("alpineUpdater") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
// Append any changed vulnerabilities to the response. | ||
if commit == dbCommit { | ||
log.Debug("no alpine update") | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set FlagName/FlagValue before; then no need for else, just return; saves an indentation level.
for _, fix := range pkg.Fixes { | ||
version, err := types.NewVersion(pkg.Version) | ||
if err != nil { | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Warningf("could not parse package version '%s': %s. skipping", pkg.version, err.Error())
continue | ||
} | ||
|
||
var vuln database.Vulnerability |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use the database.Vulnerability{}
notation?
var vuln database.Vulnerability | ||
vuln.Name = fix | ||
vuln.Link = nvdURLPrefix + fix | ||
vuln.FixedIn = append(vuln.FixedIn, database.FeatureVersion{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why append()
if you just created the object?
// one. | ||
if ipkg.Feature.Name != "" && ipkg.Version.String() != "" { | ||
pkgSet[ipkg.Feature.Name+"#"+ipkg.Version.String()] = ipkg | ||
ipkg = database.FeatureVersion{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipkg = intermediary package, once you have both the name and version, we reset it so that we can parse a new one.
|
||
func (d *detector) Detect(data map[string][]byte) ([]database.FeatureVersion, error) { | ||
file, exists := data["lib/apk/db/installed"] | ||
if exists { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f, hasFile := data["lib/apk/db/installed"]
if !hasFile {
return []database.FeatureVersion{}, nil
}
simpler, avoids one level of indentation
Instead of adding a dependency on Git, did you consider simply fetching the tarball at HEAD?
|
It makes a lot of sense now because their database is extremely small. As the database gets bigger (hopefully.. but maybe never big enough to make sense), |
I'm absolutely open to changing to the tarball download if this a goal for the future. Do we have a plan for migrating existing fetchers to systems that could support this? |
FWIW, we run in contexts where shelling out to tools like |
@mattmoor Have you been unable to use Ubuntu fetchers for this same reason? They depend on bzr. |
@jzelinskie Yes, we have a variant (that we were supposed to upstream, which I'm running down) that basically makes the mechanism pluggable. The tl;dr is that we define an interface for the core methods that shell out to |
Does anyone have a feel for how maintained alpine-secdb is? It looks like it was last updated ~7 weeks ago? Really hoping for a good solution here for monitoring for vulnerable packages in Alpine, just wondering if there are any plans for how the upstream database will be kept up to date? |
@mwarkentin That's a very good question. We have contacted the main committer to ask about the license and whether we should expect this database to be a first-time citizen / updated regularly or not. We now know that the database is licensed under MIT but as far as I know, we have had no update on that second question yet. We hope that our implementation will increase demand on this important topic at Alpine. |
@Quentin-M Thanks! I agree that having an implementation like this could be a good driver for keeping the db updated. Please update if you get any further information about this. :) |
@mattmoor any timeline on upstreaming this work? If we could settle on a streamlined a process for backchanneling data sources for air-gapped Clair instances, that'd be great! |
FWIW, I wouldn't characterize it as a general air-gap solution so much as a pattern that enables it. No timeframe yet, so don't block this for it. |
@jzelinskie Have any e2e tested it on an image that actually contains one of the managed vulnerability? Also, I am aware that an existing namespace detector catched Alpine (probably wrongly) on some images, that'd be good to make sure they don't collide and that only the actual new Alpine detector gets it rather than the other one. |
) | ||
|
||
const ( | ||
secdbGitURL = "http://git.alpinelinux.org/cgit/alpine-secdb" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a note for 'httpss://' when supported?
} | ||
|
||
// Append any changed vulnerabilities to the response. | ||
for _, namespace := range []string{"v3.3", "v3.4"} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It'd be neat to extract the version->parser mapping outside of this function, at the top.
} | ||
} | ||
|
||
out, err := utils.Exec(f.repositoryLocalPath, "git", "rev-parse", "HEAD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the first time, we clone
. The next times, we just rev-parse HEAD
. Shouldn't we pull before? Otherwise even if HEAD
moved, we'd still be reading the old files when opening them.
continue | ||
} | ||
|
||
var vuln database.Vulnerability |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is not using database.Vulnerability{Name: "", Link: ""}
style a conscious decision?
Besides my comment regarding to potential Alpine detections with the existing detectors above, this looks fine. I think my idea around |
|
||
parseFunc, exists := parsers[namespace] | ||
if !exists { | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these are much better. Please just add a Warning here as well as an updater Note for that so we can be alerted when we need to take action. See https://github.com/coreos/clair/blob/master/updater/fetchers/ubuntu/ubuntu.go#L139
LGTM. Users will then be able to figure out action is needed by reading Prometheus. |
This change adjusts some names of types being exported and adds some documentation.
@jzelinskie Could you please provide me a alpine docker image which has some CVEs? |
@adityacs Very late, but
|
I'm making this PR now just to let people know that it's finally happening. Data is sourced from Alpine SecDB (MIT licensed). This fetcher adds
git
as a dependency on the system path./etc/alpine-release
/lib/apk/db/installed