Skip to content
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

Detect Platform and get instance-id of amazon ec2 #95

Merged
merged 1 commit into from
Jun 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ type ScanResult struct {

Container Container

Platform Platform

// Fqdn string
// NWLinks []NWLink
KnownCves []CveInfo
Expand Down Expand Up @@ -322,3 +324,12 @@ type Container struct {
ContainerID string
Name string
}

// Platform has platform information
type Platform struct {
gorm.Model `json:"-"`
ScanResultID uint `json:"-"`

Name string // aws or azure or gcp or other...
InstanceID string
}
68 changes: 64 additions & 4 deletions scan/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ import (
type linux struct {
ServerInfo config.ServerInfo

Family string
Release string
Family string
Release string
Platform models.Platform
osPackages
log *logrus.Entry

log *logrus.Entry
errs []error
}

Expand All @@ -56,10 +57,18 @@ func (l *linux) setDistributionInfo(fam, rel string) {
l.Release = rel
}

func (l *linux) getDistributionInfo() string {
func (l linux) getDistributionInfo() string {
return fmt.Sprintf("%s %s", l.Family, l.Release)
}

func (l *linux) setPlatform(p models.Platform) {
l.Platform = p
}

func (l linux) getPlatform() models.Platform {
return l.Platform
}

func (l linux) allContainers() (containers []config.Container, err error) {
switch l.ServerInfo.Container.Type {
case "", "docker":
Expand Down Expand Up @@ -131,6 +140,56 @@ func (l *linux) parseDockerPs(stdout string) (containers []config.Container, err
return
}

func (l *linux) detectPlatform() error {
ok, instanceID, err := l.detectRunningOnAws()
if err != nil {
return err
}
if ok {
l.setPlatform(models.Platform{
Name: "aws",
InstanceID: instanceID,
})
return nil
}

//TODO Azure, GCP...
l.setPlatform(models.Platform{
Name: "other",
})
return nil
}

func (l linux) detectRunningOnAws() (ok bool, instanceID string, err error) {
if r := l.ssh("type curl", noSudo); r.isSuccess() {
cmd := "curl --max-time 1 --retry 3 --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id"
if r := l.ssh(cmd, noSudo); r.isSuccess() {
id := strings.TrimSpace(r.Stdout)
return true, id, nil
} else if r.ExitStatus == 28 || r.ExitStatus == 7 {
// Not running on AWS
// 7 Failed to connect to host.
// 28 operation timeout.
return false, "", nil
}
}

if r := l.ssh("type wget", noSudo); r.isSuccess() {
cmd := "wget --tries=3 --timeout=1 --no-proxy -q -O - http://169.254.169.254/latest/meta-data/instance-id"
if r := l.ssh(cmd, noSudo); r.isSuccess() {
id := strings.TrimSpace(r.Stdout)
return true, id, nil
} else if r.ExitStatus == 4 {
// Not running on AWS
// 4 Network failure
return false, "", nil
}
}
return false, "", fmt.Errorf(
"Failed to curl or wget to AWS instance metadata on %s. container: %s",
l.ServerInfo.ServerName, l.ServerInfo.Container.Name)
}

func (l *linux) convertToModel() (models.ScanResult, error) {
var scoredCves, unscoredCves models.CveInfos
for _, p := range l.UnsecurePackages {
Expand Down Expand Up @@ -171,6 +230,7 @@ func (l *linux) convertToModel() (models.ScanResult, error) {
Family: l.Family,
Release: l.Release,
Container: container,
Platform: l.Platform,
KnownCves: scoredCves,
UnknownCves: unscoredCves,
}, nil
Expand Down
38 changes: 37 additions & 1 deletion scan/serverapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ var Log *logrus.Entry

var servers []osTypeInterface

// Base Interface of redhat, debian
// Base Interface of redhat, debian, freebsd
type osTypeInterface interface {
setServerInfo(config.ServerInfo)
getServerInfo() config.ServerInfo

setDistributionInfo(string, string)
getDistributionInfo() string

detectPlatform() error
getPlatform() models.Platform

checkRequiredPackagesInstalled() error
scanPackages() error
scanVulnByCpeName() error
Expand Down Expand Up @@ -136,6 +141,30 @@ func InitServers(localLogger *logrus.Entry) error {
return fmt.Errorf("Failed to detect Container OSes. err: %s", err)
}
servers = append(servers, containers...)

Log.Info("Detecting Platforms...")
errs := detectPlatforms()
if 0 < len(errs) {
// Only logging
Log.Errorf("Failed to detect platforms. err: %v", errs)
}
for i, s := range servers {
if s.getServerInfo().IsContainer() {
Log.Infof("(%d/%d) %s on %s is running on %s",
i+1, len(servers),
s.getServerInfo().Container.Name,
s.getServerInfo().ServerName,
s.getPlatform().Name,
)

} else {
Log.Infof("(%d/%d) %s is running on %s",
i+1, len(servers),
s.getServerInfo().ServerName,
s.getPlatform().Name,
)
}
}
return nil
}

Expand Down Expand Up @@ -328,6 +357,13 @@ func detectContainerOSesOnServer(containerHost osTypeInterface) (oses []osTypeIn
return oses
}

func detectPlatforms() []error {
timeoutSec := 1 * 60
return parallelSSHExec(func(o osTypeInterface) error {
return o.detectPlatform()
}, timeoutSec)
}

// Prepare installs requred packages to scan vulnerabilities.
func Prepare() []error {
return parallelSSHExec(func(o osTypeInterface) error {
Expand Down