Skip to content

Drone Specification

Tom Steele edited this page Aug 7, 2015 · 5 revisions

Language

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.

Versioning

All drones should follow symantec versioning.

Logging

Drones should follow the Rule of Silence and should not print unnecessary output. If using Go the log package should be used where possible.

Connecting to API Server

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

Required arguments

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.

Required options

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

Data Protection

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.

Messages

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

Getting started

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")
}