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

Add configtest subcommand. skip un-ssh-able servers. #134

Merged
merged 1 commit into from
Jul 19, 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
30 changes: 29 additions & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ go getでエラーが発生した場合は、以下の点を確認する。

## Step6. Config

Vulの設定ファイルを作成する(TOMLフォーマット)
Vulの設定ファイルを作成する(TOMLフォーマット)
設定ファイルのチェックを行う

```
$ cat config.toml
Expand All @@ -209,6 +210,8 @@ host = "172.31.4.82"
port = "22"
user = "ec2-user"
keyPath = "/home/ec2-user/.ssh/id_rsa"

$ vuls configtest
```

## Step7. Setting up target servers for Vuls
Expand Down Expand Up @@ -484,6 +487,31 @@ host = "172.31.4.82"
- SSH public key authentication (with password, empty password)
- Password authentication

----

# Usage: Configtest

configtestサブコマンドは、config.tomlで定義されたサーバ/コンテナに対してSSH可能かどうかをチェックする。

```
$ vuls configtest --help
configtest:
configtest
[-config=/path/to/config.toml]
[-ask-key-password]
[-ssh-external]
[-debug]

[SERVER]...
-ask-key-password
Ask ssh privatekey password before scanning
-config string
/path/to/toml (default "/Users/kotakanbe/go/src/github.com/future-architect/vuls/config.toml")
-debug
debug mode
-ssh-external
Use external ssh command. Default: Use the Go native implementation
```

----

Expand Down
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ If an error occurred while go get, check the following points.

## Step6. Config

Create a config file(TOML format).
Create a config file(TOML format).
Then check the config.

```
$ cat config.toml
Expand All @@ -201,6 +202,8 @@ host = "172.31.4.82"
port = "22"
user = "ec2-user"
keyPath = "/home/ec2-user/.ssh/id_rsa"

$ vuls configtest
```

## Step7. Setting up target servers for Vuls
Expand Down Expand Up @@ -483,8 +486,31 @@ You can customize your configuration using this template.
- SSH public key authentication (with password, empty password)
- Password authentication


----

# Usage: Configtest

Configtest subcommand check if vuls is able to connect via ssh to servers/containers defined in the config.toml.

```
$ vuls configtest --help
configtest:
configtest
[-config=/path/to/config.toml]
[-ask-key-password]
[-ssh-external]
[-debug]

[SERVER]...
-ask-key-password
Ask ssh privatekey password before scanning
-config string
/path/to/toml (default "/Users/kotakanbe/go/src/github.com/future-architect/vuls/config.toml")
-debug
debug mode
-ssh-external
Use external ssh command. Default: Use the Go native implementation
```


----
Expand Down
157 changes: 157 additions & 0 deletions commands/configtest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/* 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 commands

import (
"flag"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/Sirupsen/logrus"
"github.com/google/subcommands"
"github.com/labstack/gommon/log"
"golang.org/x/net/context"

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

// ConfigtestCmd is Subcommand
type ConfigtestCmd struct {
configPath string
askKeyPassword bool
sshExternal bool

debug bool
}

// Name return subcommand name
func (*ConfigtestCmd) Name() string { return "configtest" }

// Synopsis return synopsis
func (*ConfigtestCmd) Synopsis() string { return "Test configuration" }

// Usage return usage
func (*ConfigtestCmd) Usage() string {
return `configtest:
configtest
[-config=/path/to/config.toml]
[-ask-key-password]
[-ssh-external]
[-debug]

[SERVER]...
`
}

// SetFlags set flag
func (p *ConfigtestCmd) SetFlags(f *flag.FlagSet) {
wd, _ := os.Getwd()
defaultConfPath := filepath.Join(wd, "config.toml")
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")

f.BoolVar(&p.debug, "debug", false, "debug mode")

f.BoolVar(
&p.askKeyPassword,
"ask-key-password",
false,
"Ask ssh privatekey password before scanning",
)

f.BoolVar(
&p.sshExternal,
"ssh-external",
false,
"Use external ssh command. Default: Use the Go native implementation")
}

// Execute execute
func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {

var keyPass string
var err error
if p.askKeyPassword {
prompt := "SSH key password: "
if keyPass, err = getPasswd(prompt); err != nil {
logrus.Error(err)
return subcommands.ExitFailure
}
}

c.Conf.Debug = p.debug

err = c.Load(p.configPath, keyPass, "")
if err != nil {
logrus.Errorf("Error loading %s, %s", p.configPath, err)
return subcommands.ExitUsageError
}

var servernames []string
if 0 < len(f.Args()) {
servernames = f.Args()
} else {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Errorf("Failed to read stdin: %s", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
if 0 < len(fields) {
servernames = fields
}
}
}

target := make(map[string]c.ServerInfo)
for _, arg := range servernames {
found := false
for servername, info := range c.Conf.Servers {
if servername == arg {
target[servername] = info
found = true
break
}
}
if !found {
logrus.Errorf("%s is not in config", arg)
return subcommands.ExitUsageError
}
}
if 0 < len(servernames) {
c.Conf.Servers = target
}

// logger
Log := util.NewCustomLogger(c.ServerInfo{})

Log.Info("Validating Config...")
if !c.Conf.Validate() {
return subcommands.ExitUsageError
}

Log.Info("Detecting Server/Contianer OS... ")
scan.InitServers(Log)

return subcommands.ExitSuccess
}
6 changes: 1 addition & 5 deletions commands/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,7 @@ func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{
logger := util.NewCustomLogger(c.ServerInfo{})

logger.Info("Detecting OS... ")
err = scan.InitServers(logger)
if err != nil {
logger.Errorf("Failed to init servers. err: %s", err)
return subcommands.ExitFailure
}
scan.InitServers(logger)

logger.Info("Installing...")
if errs := scan.Prepare(); 0 < len(errs) {
Expand Down
37 changes: 29 additions & 8 deletions commands/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ package commands
import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/Sirupsen/logrus"
c "github.com/future-architect/vuls/config"
Expand All @@ -31,6 +33,7 @@ import (
"github.com/future-architect/vuls/scan"
"github.com/future-architect/vuls/util"
"github.com/google/subcommands"
"github.com/labstack/gommon/log"
"golang.org/x/net/context"
)

Expand Down Expand Up @@ -260,8 +263,27 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
} else {
logrus.Infof("cve-dictionary: %s", p.cveDictionaryURL)
}

var servernames []string
if 0 < len(f.Args()) {
servernames = f.Args()
} else {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Errorf("Failed to read stdin: %s", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
if 0 < len(fields) {
servernames = fields
}
}
}

target := make(map[string]c.ServerInfo)
for _, arg := range f.Args() {
for _, arg := range servernames {
found := false
for servername, info := range c.Conf.Servers {
if servername == arg {
Expand All @@ -275,7 +297,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
return subcommands.ExitUsageError
}
}
if 0 < len(f.Args()) {
if 0 < len(servernames) {
c.Conf.Servers = target
}

Expand Down Expand Up @@ -359,12 +381,11 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
return subcommands.ExitFailure
}

Log.Info("Detecting Server OS... ")
err = scan.InitServers(Log)
if err != nil {
Log.Errorf("Failed to init servers. Check the configuration. err: %s", err)
return subcommands.ExitFailure
}
Log.Info("Detecting Server/Contianer OS... ")
scan.InitServers(Log)

Log.Info("Detecting Platforms... ")
scan.DetectPlatforms(Log)

Log.Info("Scanning vulnerabilities... ")
if errs := scan.Scan(); 0 < len(errs) {
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func main() {
subcommands.Register(&commands.ScanCmd{}, "scan")
subcommands.Register(&commands.PrepareCmd{}, "prepare")
subcommands.Register(&commands.HistoryCmd{}, "history")
subcommands.Register(&commands.ConfigtestCmd{}, "configtest")

var v = flag.Bool("v", false, "Show version")

Expand Down
4 changes: 1 addition & 3 deletions scan/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ func (l *base) dockerPs(option string) (string, error) {
cmd := fmt.Sprintf("docker ps %s", option)
r := l.ssh(cmd, noSudo)
if !r.isSuccess() {
return "", fmt.Errorf(
"Failed to %s. status: %d, stdout: %s, stderr: %s",
cmd, r.ExitStatus, r.Stdout, r.Stderr)
return "", fmt.Errorf("Failed to SSH: %s", r)
}
return r.Stdout, nil
}
Expand Down
Loading