-
Notifications
You must be signed in to change notification settings - Fork 88
Drone Specification
We encourage authors to develop new drones in Go. It allows us to deploy them without any dependencies. Drones using go should use the go-lair
library. Other languages are of course accepted.
When writing a parser, it is preferable to separate the parsing logic from the drone logic. For example, we have a go-nmap
repo and a drone-nmap
repo.
All drones should follow symantec versioning.
Drones should follow the Rule of Silence
and should not print unnecessary output. If using Go the log
package should be used where possible.
Drones should connect to the API server using the LAIR_API_SERVER
environment variable. If this variable is not defined, the drone should exit with the error message of :
Fatal: Missing LAIR_API_SERVER environment variable
Drones should take two required arguments when processing a file. The first argument should always be the project id. The second should always be the `file to process. For example:
drone-nmap DxQBSfgnyCSdS8yL6 file.xml
Drones should check for, and use, the LAIR_ID
environment variable as the project id if only single argument is provided.
Drones should support the following options:
-h show usage and exit
-v show version and exit
-force-ports disable data protection in the API server for excessive ports
-k disable validation of SSL certificate
-tags a comma separated list of tags to add to every host that is imported
The API server prevents drones from importing more than 500 ports per host. Some devices with "syn-flood protections" can show every port as open for a host, if this data is imported into Lair, it can be very troublesome. Drones should support a -force-ports
option to disable this protection.
Drones should communicate errors and success in a standard way and should follow the pattern below, including a timestamp is preferable:
Fatal Errors:
Fatal: Missing LAIR_API_SERVER environment variable
Non-Fatal Errors:
Error: Host 192.168.1.1 does not exist
Informational Messages:
Info: Host 192.168.1.1 was not imported
Operation completed successfully:
Success: Operation completed successfully
Below is an incomplete stub for a Go drone:
package main
import (
"flag"
"fmt"
"log"
"os"
)
const (
version = "1.0.0"
tool = "foo"
usage = `
Usage:
drone-foo <id> <filename>
export LAIR_ID=<id>; drone-foo <filename>
Options:
-v show version and exit
-h show usage and exit
-k allow insecure SSL connections
-force-ports disable data protection in the API server for excessive ports
-tags a comma separated list of tags to add to every host that is imported
`
)
func main() {
showVersion := flag.Bool("v", false, "")
insecureSSL := flag.Bool("k", false, "")
forcePorts := flag.Bool("force-ports", false, "")
tags := flag.String("tags", "", "")
flag.Usage = func() {
fmt.Println(usage)
}
flag.Parse()
if *showVersion {
log.Println(version)
os.Exit(0)
}
lairURL := os.Getenv("LAIR_API_SERVER")
if lairURL == "" {
log.Fatal("Fatal: Missing LAIR_API_SERVER environment variable")
}
lairPID := os.Getenv("LAIR_ID")
var filename string
switch len(flag.Args()) {
case 2:
lairPID = flag.Arg(0)
filename = flag.Arg(1)
case 1:
filename = flag.Arg(0)
default:
log.Fatal("Fatal: Missing required argument")
}
log.Println("Success: Operation completed successfully")
}