• This repository has been archived on 29/Oct/2018
  • Stars
    star
    130
  • Rank 276,637 (Top 6 %)
  • Language
    CoffeeScript
  • License
    MIT License
  • Created about 11 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Follow on Twitter

 _  _   __  ____  ____  ____  _  _ 
/ )( \ /  \(  _ \(_  _)(  __)( \/ )
\ \/ /(  O ))   /  )(   ) _)  )  ( 
 \__/  \__/(__\_) (__) (____)(_/\_)

by Websecurify

Introduction

Vortex is a virtual machine management tool. It is similar to Vagrant. The rationale for writing this tool is to enable better management of development and production infrastructure at the same time. We, Websecurify, could not easily achieve this with Vagrant so the this tool was written to fill the gap.

You can do the following things with Vortex:

  1. Develop your application in a replicable dev environment.
  2. Easily manage your application in the same configuration into a prod environment.

Vortex removes any barriers from the time you start developing your application to the time it is already live and you need to maintain it.

Tool Philosophy

It is essential to understand the key principle behind Vortex, which is to always produce a replicable environment. This sounds nice and simple but it gets deeper than this.

What this means in practice is that virtual machines/nodes are disposable. In other words, they only exist fully provisioned and not in any other way. They also don't maintain any state. Once you halt a node, it is gone for good with all the data it was keeping within it. If you boot the node again it will launch a brand new instance. This is why there is no state.

State is essentially a 3rd-class citizen in Vortex. You provide it only by attaching external storages or by integrating with other services from your application. This sounds like a very extreme way of dealing with things but it does solve a few hard problems like scalability and the application effectiveness against hardware and other types of failure.

This philosophy is a constrain, which works in our favour and it is fully embraced in the design of the tool.

Tool Installation

The easiest way to install Vortex is via node's npm. You need to have nodejs installed for this. Simply type the following command:

npm install -g vortex

An alternative approach is to just copy the source files and execute them manually though nodejs. There are plans to create a standalone binary distributions if there is need for this.

Tool Usage

You can use Vortex as a library or via the command line, which is more convenient. At the moment there are no docs on the API but for now you can just check the source code for inspiration.

Here are a few examples of how to use Vortex via your shell:

vortex status 		# shows the status of all nodes
vortex boot 		# boots all nodes
vortex halt 		# halts all nodes
vortex provision 	# provision all nodes

The following additional helper actions are also available:

vortex up 			# boots and provisions a node
vortex down 		# halts a node

You can also specify which node you want to manipulate:

vortex shell my-node-name 	# starts interactive session on the selected node
vortex halt my-node-name 	# halts the selected node

To get the complete list of actions just use actions

vortex actions 	# get complete list of actions

By the default Vortex reads the configuration from vortex.json located inside the current working directory. However, you can specify an alternative location with the -f|--file option. For example:

vortex -f path/to/folder 		# loads path/to/folder/vortex.json manifest
vortex -f path/to/config.json 	# loads path/to/config.json manifest

Verbose messages can be obtained by using the -v|--verbose flag, which can also be combined with the -c|--colorize flag for better visual aid. For example:

vortex -vv 		# enables debug level logging
vortex -vvv -c 	# enables silly level logging with colorization

Vortex supports different providers to manage your virtual machines/nodes. Out of the box you have support for VirtualBox and Amazon. VirtualBox is the default provider. Here is an example how to select a different provider:

vortex --provider=Amazon boot 	# boots nodes into amazon ec2

The default provisioner, Roost, can also be configured with some command-line options. If you specify the -d|--dry flag the provisioner will only output information on what it will do but not perform any actions. This is useful if you are uncertain about the changes you are making to the roost manifests and you just want to check it out before doing it for real. For example:

vortex --provider=Amazon -d provision my-sensitive-node 	# dry-runs the provisioner

Here is another fun bit you can do. The shell action also accepts parameters which will be directly executed as commands. For example:

vortex shell -- -- ls -la 	# will list the home folder

You can apply commands to all nodes or the one you have specifically selected.

Vortex Manifest

The Vortex manifest file is a simple JSON document. By default you are only required to specify the nodes you want in your configuration:

{
	...
	
	"nodes": {
		"my-node": {
		}
	},
	
	...
}

This is the simplest possible configuration, which is not useful for anything just yet. To make this configuration useful for booting an image in Amazon you need to supply additional information. This is how it is done:

{
	...
	
	"amazon": {
		"accessKeyId": "YOUR ACCESS KEY GOES HERE",
		"secretAccessKey": "YOUR SECRET KEY GOES HERE",
		"region": "A REGION SUCH AS us-west-1, us-west-2, etc GOES HERE"
	},
	
	"nodes": {
		"ubuntu": {
			"amazon": {
				"imageId": "ami-2fb3201f",
				"securityGroups": ["default"],
				"keyName": "my-key",
				"privateKey": "path/to/my-key.pem",
				"username": "ubuntu"
			}
		}
	},
	
	...
}

Providing credentials inside configuration file is not always optimal but it saves you from typing longer and more complex commands. The reality of the situation is that you can do the following:

ACCESS_KEY_ID=bish SECRET_ACCESS_KEY=bosh AWS_REGION=us-west-1 vortex --provider=Amazon boot

The config file for this will be:

{
	...
	
	"nodes": {
		"ubuntu": {
			"amazon": {
				"imageId": "ami-2fb3201f",
				"securityGroups": ["default"],
				"keyName": "my-key",
				"privateKey": "path/to/my-key.pem",
				"username": "ubuntu"
			}
		}
	},
	
	...	
}

The same properties can also be provided per-node if this is what you want. Underneath all of this sits the aws-sdk for nodejs so all parameters are exactly the same as you will find in the SDK.

VirtualBox is configured in the same way. The only difference is that you need to specify VirtualBox specific configuration. For example:

{
	...
	
	"nodes": {
		"ubuntu": {
			"amazon": {
				"imageId": "ami-2fb3201f",
				"securityGroups": ["default"],
				"keyName": "my-key",
				"privateKey": "path/to/my-key.pem",
				"username": "ubuntu"
			},
			
			"virtualbox": {
				"username": "ubuntu",
				"password": "ubuntu",
				"vmId": "baseimage",
				"vmUrl": "http://path/to/baseimage.ova"
			}
		}
	},
	
	...	
}

If you have a lot of nodes that are similar with minor differences you can move the configuration out of the node structure and specify it globally like such:

{
	...
	
	"amazon": {
		"imageId": "ami-2fb3201f",
		"securityGroups": ["default"],
		"keyName": "my-key",
		"privateKey": "path/to/my-key.pem",
		"username": "ubuntu"
	},
	
	"virtualbox": {
		"username": "ubuntu",
		"password": "ubuntu",
		"vmId": "baseimage",
		"vmUrl": "http://path/to/baseimage.ova"
	},
	
	...
	
	"nodes": {
		"node1": {
			"amazon": {
				"username": "node1"
			}
		},
		"node2": {
			"amazon": {
				"username": "node2"
			}
		}	
	},
	
	...	
}

Last but not least, nodes can be launched in their own namespaces. Namespaces are useful when there are a lot of stuff going on and you just want to logically separate nodes into different groups (or soft-groups if you prefer). Here is an example:

{
	...
	
	namespace: "my-config",
	
	...

	"amazon": {
		"imageId": "ami-2fb3201f",
		"securityGroups": ["default"],
		"keyName": "my-key",
		"privateKey": "path/to/my-key.pem",
		"username": "ubuntu"
	},

	"virtualbox": {
		"username": "ubuntu",
		"password": "ubuntu",
		"vmId": "baseimage",
		"vmUrl": "http://path/to/baseimage.ova"
	},

	...

	"nodes": {
		"node1": {
			"amazon": {
				"username": "node1"
			}
		},
		"node2": {
			"amazon": {
				"username": "node2"
			}
		}	
	},

	...	
}

Now node1 and node2 will run in the namespace my-config and this will not interfere with other nodes that have similar names. Namespaces can be used per node as well so you can get very creative.

VirtualBox Options

The VirtualBox provider can be configured by supplying a "virtualbox" property at the top level of the manifest file or per-node. The following options are accepted everywhere:

  • vmId - (string) the id or name of the virtual machine to be used as a base image
  • vmUrl - (string) if the vmId is not found the image will be downloaded from a url
  • username - (string) username for ssh (defaults to vortex)
  • password - (string) password for ssh
  • privateKey - (string) path to public ssh key
  • passphrase - (string) passphrase for key

Amazon Options

The Amazon provider can be configured by supplying a "amazon" property at the top level of the manifest file or per-node. The following options are accepted everywhere:

  • accessKeyId - (string) your amazon access key id
  • secretAccessKey - (string) your amazon access key
  • region - (string) the region where you want to deploy
  • imageId - (string) the image id to use
  • securityGroups - (array of strings) security groups to apply
  • keyName - (string) keyname to use
  • disableApiTermination - (string) make the instance un-terminatable
  • username - (string) username for ssh (defaults to vortex)
  • password - (string) password for ssh
  • privateKey - (string) path to public ssh key
  • passphrase - (string) passphrase for key

Node Provisioning

Vortex comes with a built-in provisioner called roost - another project of ours. Roost manifest files can be either imported from an external file or embedded directly into your vortex manifest. Here is an example:

{
	...
	
	"nodes": {
		"ubuntu": {
			"roost": "roost.json"
		}
	},
	
	...
}

You can also do the following if this is too much of a trouble:

{
	...
	
	"nodes": {
		"ubuntu": {
			"roost": {
				"apt": {
					"update": true
				},
				
				"packages": [
					"nodejs"
				],
				
				"commands": [
					"uname -a"
				]
			}
		}
	},
	
	...
}

As a matter of fact, you can even apply a global roost file for all nodes. Just register the roost configuration outside of the nodes property.

Merging roost manifests is also possible when declared at multiple levels. For example, at top level you may want to apply some defaults and maybe even some updates. Per node you may want to apply generic configurations and have some additional provisioning options for each provider. Such complex setup is possible and here is an example:

{
	...
	
	"roost": {
		"apt": {
			"update": true
		}
	}
	
	...
	
	"nodes": {
		"ubuntu": {
			"roost": {
				"merge": true,
				
				"packages": [
					"nodejs"
				]
			},
			
			"virtualbox": {
				"roost": {
					"merge": true,
					
					"commands": [
						"cd /media/cdrom; ./VBoxLinuxAdditions-x86.run"
					]
				}
			}
		}
	},
	
	...
}

The manifest is built from the inner most configuration and merged upwards if the merge flag is set to true. This is a non-standard roost option.

For more information how the provisioner works just check the project page.

Vortex Plugins

Vortex can be extended with plugins. Plugins are essentially nodejs modules and are installed the same way you typically install nodejs modules, i.e. npm and package.json. A good starting doc how npm modules work can be found here.

In order to load a plugin you need to declare it in your Vortex manifest file. Here is an example:

{
	...
	
	"plugins": [
		"my-plugin"
	],
	
	...
}

Plugins are executed first and can affect everything from the actual manifest that was loaded to what providers and actions are exposed and much more.

The following workflow takes place when working with plugins.

  1. Each plugin is loaded via node's require.
  2. The module is inspected for two functions getVortex (takes priority) and vortex.
  • getVortex is used to retrieve an object that exposes a vortex function.
  • vortex is looked for to check if the plugin is compatible at this stage.
  1. Before execution the plugin is invoked via a call to vortex function. The following parameters are passed:
  • opt - command line options
  • manifest - the manifest file
  • provider - default provider
  • action - the action to be executed

Use getVortex to augment the Vortex environment such as install new actions, providers, etc. Use vortex to do something, mostly with the manifest file, before the actual action takes place.

Vortex plugins can do pretty much everything so here are some suggestions of what you could do if you spend some time writing a plugin:

  • A plugin, which fetches access credentials such as keys, usernames and password from a centralized storage.
  • A plugin, which adds another provisioner such as chef and puppet.
  • A plugin, which allows you extensive use of environment variables to configure all aspects of the manifest file.
  • A plugin, which double-checks all options before launching an action in order to prevent unexpected behaviour.

The list goes on and on. Get creative!

Node States

Each node can have the following states when querying via the Provider.prototype.status function:

  • paused - the node is currently paused and it is not available for interaction.
  • booting - the node is currently booting and it is not available for interaction.
  • running - the node is running and it is available for interaction.
  • halting - the node is halting and will soon become unavailable for interaction.
  • stopped - the node is stopped.

These states are also exposed when quering a node via the status action, i.e.

vortex status # shows a state such as booting, running, halting, stopped

More Repositories

1

acme-no-login

Demonstrates a login bypass attack against a sample MongoDB/NodeJS application
JavaScript
38
star
2

node-vxdocker

JavaScript
25
star
3

acme-no-login-ng

Demonstrates a login bypass attack against a sample MongoDB/NodeJS/AngularJS application
HTML
24
star
4

docker-secapps-driver

Python
16
star
5

node-roost

CoffeeScript
13
star
6

bootstrap-chrome-extension

CoffeeScript
10
star
7

go-proxify

JavaScript
7
star
8

go-camouflage

Go
7
star
9

node-inseptor

JavaScript
6
star
10

babel-plugin-import-css-to-jss

JavaScript
6
star
11

acme-lock-me-out

NodeJS and MongoDB Login Bruteforce Demo Project
JavaScript
4
star
12

node-pcap-packet

JavaScript
4
star
13

docker-aws-nodejs-build-deployer

Dockerfile
4
star
14

xulrunner-websecurify

JavaScript
4
star
15

node-proxify

JavaScript
3
star
16

node-vboxmanage

CoffeeScript
3
star
17

titanium-websecurify

JavaScript
3
star
18

lobby

Welcome to Websecurify
3
star
19

docker-devbox

Dockerfile
2
star
20

go-user-microservice

Go
2
star
21

node-connect-google-analytics

CoffeeScript
2
star
22

docker-s3-nodejs-build-deployer

Dockerfile
2
star
23

acme-labs

Asorted examples of vulnerable applications.
JavaScript
2
star
24

go-stripe-user-microservice

Go
2
star
25

node-codemirror-http

JavaScript
2
star
26

node-winterpress

CoffeeScript
1
star
27

node-html5-file-load

CoffeeScript
1
star
28

docker-eb-nodejs-build-deployer

Dockerfile
1
star
29

node-document-shim

JavaScript
1
star
30

node-self-shim

JavaScript
1
star
31

font-websecurify

HTML
1
star
32

go-http-meta-proxy

Go
1
star
33

node-soapy

JavaScript
1
star
34

node-wurker

CoffeeScript
1
star
35

https-browserify-ng

JavaScript
1
star
36

node-logsmith

JavaScript
1
star
37

course-was-101

PHP
1
star
38

node-mapenv

CoffeeScript
1
star
39

node-collide

CoffeeScript
1
star
40

sa-cognito-storage

JavaScript
1
star
41

acme-blog

PHP
1
star
42

grunt-git-pac-deploy

Grunt plugin to pac and deploy application via git.
JavaScript
1
star
43

node-fuzzer

JavaScript
1
star
44

node-angular-shim

JavaScript
1
star
45

go-aws-attach-volume

Go
1
star
46

node-once-in

CoffeeScript
1
star
47

node-window-shim

JavaScript
1
star
48

node-jquery-shim

JavaScript
1
star
49

acme-powerplant

Puppet
1
star
50

go-plug

Go
1
star
51

wintersmith-raw

CoffeeScript
1
star
52

ws-cognito-storage

JavaScript
1
star
53

node-file2json

JavaScript
1
star
54

go-http-proxy

Go
1
star
55

go-aws-associate-address

Go
1
star
56

sa-browserify-fs

JavaScript
1
star
57

http-browserify-ng

JavaScript
1
star
58

acme-node-sdlc

JavaScript
1
star
59

node-unwrappable

JavaScript
1
star
60

node-roost-mongodb

JavaScript
1
star
61

wintersmith-seo

CoffeeScript
1
star
62

https-browserify-ws

https module compatability for browserify
JavaScript
1
star
63

electron-browserify-fs

JavaScript
1
star
64

node-iterator6

1
star
65

babel-plugin-import-md-to-js

JavaScript
1
star
66

wintersmith-appengine

CoffeeScript
1
star
67

node-googlewallet

CoffeeScript
1
star
68

acme-library

Java
1
star