Skip to content

Commit

Permalink
Support -report-azure-blob option
Browse files Browse the repository at this point in the history
  • Loading branch information
kotakanbe committed Jul 11, 2016
1 parent 185d85b commit a0e191e
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 35 deletions.
1 change: 1 addition & 0 deletions commands/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (*PrepareCmd) Usage() string {
[-ask-key-password]
[-debug]
[SERVER]...
`
}

Expand Down
73 changes: 58 additions & 15 deletions commands/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,29 @@ type ScanCmd struct {
cvssScoreOver float64
ignoreUnscoredCves bool

httpProxy string

// reporting
reportSlack bool
reportMail bool
reportJSON bool
reportText bool
reportS3 bool

httpProxy string
askSudoPassword bool
askKeyPassword bool

useYumPluginSecurity bool
useUnattendedUpgrades bool
// reporting
reportSlack bool
reportMail bool
reportJSON bool
reportText bool
reportS3 bool
reportAzureBlob bool

awsProfile string
awsS3Bucket string
awsRegion string

azureAccount string
azureKey string
azureContainer string

useYumPluginSecurity bool
useUnattendedUpgrades bool

sshExternal bool
}

Expand All @@ -81,7 +85,6 @@ func (*ScanCmd) Synopsis() string { return "Scan vulnerabilities" }
func (*ScanCmd) Usage() string {
return `scan:
scan
[SERVER]...
[-lang=en|ja]
[-config=/path/to/config.toml]
[-dbpath=/path/to/vuls.sqlite3]
Expand All @@ -90,6 +93,7 @@ func (*ScanCmd) Usage() string {
[-cvss-over=7]
[-ignore-unscored-cves]
[-ssh-external]
[-report-azure-blob]
[-report-json]
[-report-mail]
[-report-s3]
Expand All @@ -103,6 +107,13 @@ func (*ScanCmd) Usage() string {
[-aws-profile=default]
[-aws-region=us-west-2]
[-aws-s3-bucket=bucket_name]
[-azure-profile=default]
[-aws-region=us-west-2]
[-azure-account=accout]
[-azure-key=key]
[-azure-container=container]
[SERVER]...
`
}

Expand Down Expand Up @@ -174,12 +185,21 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&p.reportS3,
"report-s3",
false,
"Write report to S3 (bucket/yyyyMMdd_HHmm)",
"Write report to S3 (bucket/yyyyMMdd_HHmm/servername.json)",
)
f.StringVar(&p.awsProfile, "aws-profile", "default", "AWS Profile to use")
f.StringVar(&p.awsRegion, "aws-region", "us-east-1", "AWS Region to use")
f.StringVar(&p.awsProfile, "aws-profile", "default", "AWS profile to use")
f.StringVar(&p.awsRegion, "aws-region", "us-east-1", "AWS region to use")
f.StringVar(&p.awsS3Bucket, "aws-s3-bucket", "", "S3 bucket name")

f.BoolVar(&p.reportAzureBlob,
"report-azure-blob",
false,
"Write report to S3 (container/yyyyMMdd_HHmm/servername.json)",
)
f.StringVar(&p.azureAccount, "azure-account", "", "Azure account name to use. AZURE_STORAGE_ACCOUNT enviroment variable is used if not specified")
f.StringVar(&p.azureKey, "azure-key", "", "Azure account key to use. AZURE_STORAGE_ACCESS_KEY enviroment variable is used if not specified")
f.StringVar(&p.azureContainer, "azure-container", "", "Azure storage container name")

f.BoolVar(
&p.askKeyPassword,
"ask-key-password",
Expand Down Expand Up @@ -296,6 +316,29 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
}
reports = append(reports, report.S3Writer{})
}
if p.reportAzureBlob {
c.Conf.AzureAccount = p.azureAccount
if c.Conf.AzureAccount == "" {
c.Conf.AzureAccount = os.Getenv("AZURE_STORAGE_ACCOUNT")
}

c.Conf.AzureKey = p.azureKey
if c.Conf.AzureKey == "" {
c.Conf.AzureKey = os.Getenv("AZURE_STORAGE_ACCESS_KEY")
}

c.Conf.AzureContainer = p.azureContainer
if c.Conf.AzureContainer == "" {
Log.Error("Azure storage container name is requied with --azure-container option")
return subcommands.ExitUsageError
}
if err := report.CheckIfAzureContainerExists(); err != nil {
Log.Errorf("Failed to access to the Azure Blob container. err: %s", err)
Log.Error("Ensure the container or check Azure config before scanning")
return subcommands.ExitUsageError
}
reports = append(reports, report.AzureBlobWriter{})
}

c.Conf.DBPath = p.dbpath
c.Conf.CveDBPath = p.cvedbpath
Expand Down
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type Config struct {
AwsRegion string
S3Bucket string

AzureAccount string
AzureKey string
AzureContainer string

// CpeNames []string
// SummaryMode bool
UseYumPluginSecurity bool
Expand Down
18 changes: 9 additions & 9 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 92 additions & 0 deletions report/azureblob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package report

import (
"bytes"
"encoding/json"
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/storage"

c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)

// AzureBlobWriter writes results to AzureBlob
type AzureBlobWriter struct{}

// CheckIfAzureContainerExists check the existence of Azure storage container
func CheckIfAzureContainerExists() error {
cli, err := getBlobClient()
if err != nil {
return err
}
ok, err := cli.ContainerExists(c.Conf.AzureContainer)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("Container not found. Container: %s", c.Conf.AzureContainer)
}
return nil
}

func getBlobClient() (storage.BlobStorageClient, error) {
api, err := storage.NewBasicClient(c.Conf.AzureAccount, c.Conf.AzureKey)
if err != nil {
return storage.BlobStorageClient{}, err
}
return api.GetBlobService(), nil
}

// Write results to Azure Blob storage
func (w AzureBlobWriter) Write(scanResults []models.ScanResult) (err error) {
cli, err := getBlobClient()
if err != nil {
return err
}
timestr := time.Now().Format("20060102_1504")
for _, r := range scanResults {
name := ""
if r.Container.ContainerID == "" {
name = fmt.Sprintf("%s/%s.json", timestr, r.ServerName)
} else {
name = fmt.Sprintf("%s/%s_%s.json", timestr, r.ServerName, r.Container.Name)
}

jsonBytes, err := json.Marshal(r)
if err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
}

if err = cli.CreateBlockBlobFromReader(
c.Conf.AzureContainer,
name,
uint64(len(jsonBytes)),
bytes.NewReader(jsonBytes),
map[string]string{},
); err != nil {
// return fmt.Errorf("Failed to upload data to %s/%s, %s", c.Conf.S3Bucket, key, err)
//TODO
panic(err)
}
}
return
}
22 changes: 11 additions & 11 deletions report/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ import (
"github.com/future-architect/vuls/models"
)

// S3Writer writes results to S3
type S3Writer struct{}

func getS3() *s3.S3 {
return s3.New(session.New(&aws.Config{
Region: aws.String(c.Conf.AwsRegion),
Credentials: credentials.NewSharedCredentials("", c.Conf.AwsProfile),
}))
}

// CheckIfBucketExists check the existence of S3 bucket
func CheckIfBucketExists() error {
svc := getS3()
Expand All @@ -67,7 +57,17 @@ func CheckIfBucketExists() error {
return nil
}

// Write put results in S3
// S3Writer writes results to S3
type S3Writer struct{}

func getS3() *s3.S3 {
return s3.New(session.New(&aws.Config{
Region: aws.String(c.Conf.AwsRegion),
Credentials: credentials.NewSharedCredentials("", c.Conf.AwsProfile),
}))
}

// Write results to S3
func (w S3Writer) Write(scanResults []models.ScanResult) (err error) {

var jsonBytes []byte
Expand Down

0 comments on commit a0e191e

Please sign in to comment.