edurange 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ my-user-script.sh
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in edurange.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Stefan Boesen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Edurange
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'edurange'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install edurange
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/edurange ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'edurange'
3
+
4
+ yaml_file = ARGV.shift
5
+ Edurange::Init.init(yaml_file)
6
+
7
+
8
+
data/edurange.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'edurange/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "edurange"
8
+ gem.version = Edurange::VERSION
9
+ gem.authors = ["Stefan Boesen"]
10
+ gem.email = ["stefan.boesen@gmail.com"]
11
+ gem.description = %q{EDURange Project}
12
+ gem.summary = %q{Automatic warspace simulations}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
data/final.yml ADDED
@@ -0,0 +1,41 @@
1
+ Nodes:
2
+ # Main_Box: # attacking box
3
+ # AMI_ID: ami-e720ad8e
4
+ # Users:
5
+ # - Team_1
6
+ # - Instructor
7
+ # Software:
8
+ # - Attacker_CTF
9
+
10
+ Victim: # victim host
11
+ AMI_ID: ami-e720ad8e
12
+ Users:
13
+ - Instructor
14
+ Software:
15
+ - Victim_CTF
16
+
17
+ Groups:
18
+ Team_1:
19
+ - { login: sboesen, pass: password }
20
+ Instructor:
21
+ - { login: weissr, pass: pass2 }
22
+
23
+ Software:
24
+ Victim_CTF:
25
+ IPTables:
26
+ # Ports open
27
+ 20:
28
+ Protocol: tcp
29
+ Hosts:
30
+ - 127.0.0.1
31
+ - All
32
+ 80:
33
+ Protocol: tcp
34
+ Hosts:
35
+ - 127.0.0.1
36
+ - All
37
+
38
+ Packages: # References to puppet modules so we can support different OS options. Otherwise we need to know what OS we're on...
39
+ - iptables
40
+ - apache
41
+
@@ -0,0 +1,49 @@
1
+ module Edurange
2
+ class EduMachine
3
+ attr_reader :uuid, :ami_id, :key_name, :vm_size, :ip_address
4
+
5
+ EC2_UTILS_PATH = "/home/ubuntu/.ec2/bin/"
6
+
7
+ def initialize(uuid, key_name, ami_id, vm_size="t1.micro")
8
+ # generate uuid
9
+ @uuid = uuid
10
+ @instance_id = nil
11
+ @key_name = key_name
12
+ @vm_size = vm_size
13
+ @ami_id = ami_id
14
+ end
15
+ def run(command)
16
+ # runs an ec2 command with full path.
17
+ command = EC2_UTILS_PATH + command
18
+ `#{command}`
19
+ end
20
+
21
+ def spin_up
22
+ # Pref user-data-file for ourselves
23
+
24
+ # Create & run instance, setting instance_id and IP to match the newly created ami
25
+ command = "ec2-run-instances #{@ami_id} -t #{@vm_size} --region us-east-1 --key #{@key_name} --user-data-file my-user-script.sh"
26
+ puts "Would run: #{command}"
27
+ self.run(command)
28
+ @instance_id = self.get_last_instance_id()
29
+ puts "Waiting for instance #{@instance_id} to spin up..."
30
+ sleep(40)
31
+ self.update_ec2_info()
32
+ self
33
+ end
34
+
35
+ def update_ec2_info
36
+ command = "ec2-describe-instances | grep INSTANCE | grep '#{@instance_id}'"
37
+ vm = self.run(command).split("\t")
38
+ p vm
39
+ @ip_address = vm[17] # public ip
40
+ @hostname = vm[3] # ec2 hostname
41
+ end
42
+
43
+ def get_last_instance_id
44
+ command = 'ec2-describe-instances | grep INSTANCE | tail -n 1'
45
+ vm = self.run(command)
46
+ return vm.split("\t")[1]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,73 @@
1
+ module Edurange
2
+ class Parser
3
+ def self.facter_facts(uuid)
4
+ facter_conf = <<conf
5
+ uuid=#{uuid}
6
+ services=apache2,vsftpd,iptables
7
+ conf
8
+ end
9
+ def self.parse_yaml(filename)
10
+ nodes = []
11
+ file = YAML.load_file(filename)
12
+
13
+ softwares = {}
14
+ file["Software"].each do |software|
15
+ softwares[software[0]] = software[1]
16
+ end
17
+
18
+ groups = {}
19
+ file["Groups"].each do |group|
20
+ groups[group[0]] = group[1]
21
+ end
22
+
23
+ file["Nodes"].each do |node|
24
+ node_name = node[0]
25
+ ami_id = node[1]["AMI_ID"]
26
+
27
+ users = []
28
+ users_groups = node[1]["Users"]
29
+ users_groups.each do |user_group|
30
+ users.push groups[user_group]
31
+ end
32
+ users.flatten!
33
+
34
+ software = []
35
+ software_groups = node[1]["Software"]
36
+ software_groups.each do |software_group|
37
+ software.push softwares[software_group]
38
+ end
39
+ software.flatten!
40
+
41
+ iptables_rules = []
42
+ packages = []
43
+ software.each do |sw|
44
+ if !sw["IPTables"].nil?
45
+ sw["IPTables"].each do |iptable_rule|
46
+ port = iptable_rule[0]
47
+ protocol = iptable_rule[1]["Protocol"]
48
+ hosts = iptable_rule[1]["Hosts"]
49
+ hosts.each do |host|
50
+ iptables_rules.push [protocol, port, host]
51
+ end
52
+ end
53
+ end
54
+ if !sw["Packages"].nil?
55
+ sw["Packages"].each do |package|
56
+ packages.push package
57
+ end
58
+ end
59
+ end
60
+ nodes.push [
61
+ ami_id,
62
+ users,
63
+ iptables_rules,
64
+ packages
65
+ ]
66
+ p ami_id
67
+ p users
68
+ p iptables_rules
69
+ p packages
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,86 @@
1
+ module Edurange
2
+ class PuppetMaster
3
+ def self.puppetmaster_ip
4
+ `curl http://169.254.169.254/latest/meta-data/public-ipv4 2>/dev/null`
5
+ end
6
+ def self.get_our_ssh_key
7
+ # make some ssh keys
8
+ `ssh-keygen -t rsa -f /home/ubuntu/.ssh/id_rsa -N '' -q` unless File.exists?("/home/ubuntu/.ssh/id_rsa")
9
+ # return our public key
10
+ file = File.open("/home/ubuntu/.ssh/id_rsa.pub", "rb")
11
+ contents = file.read
12
+ end
13
+
14
+ def self.gen_client_ssl_cert
15
+ # We need to:
16
+ # Generate unique name (UUIDgen)
17
+ uuid = `uuidgen`.chomp
18
+ # Create cert for name on puppetmaster
19
+ `sudo puppet cert --generate #{uuid}`
20
+ ssl_cert = `sudo cat /var/lib/puppet/ssl/certs/#{uuid}.pem`.chomp
21
+ ca_cert = `sudo cat /var/lib/puppet/ssl/certs/ca.pem`.chomp
22
+ private_key = `sudo cat /var/lib/puppet/ssl/private_keys/#{uuid}.pem`.chomp
23
+ return [uuid, ssl_cert, ca_cert, private_key]
24
+ end
25
+ def self.write_shell_config_file(ssh_key, puppetmaster_ip, certs, puppet_conf, facter_facts)
26
+ File.open("my-user-script.sh", 'w') do |file|
27
+ file_contents = <<contents
28
+ #!/bin/sh
29
+ set -e
30
+ set -x
31
+ echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt
32
+ apt-get update; apt-get upgrade -y
33
+
34
+ key='#{ssh_key.chomp}'
35
+ echo $key >> /home/ubuntu/.ssh/authorized_keys
36
+
37
+ echo #{puppetmaster_ip} puppet >> /etc/hosts
38
+ apt-get -y install puppet
39
+
40
+ mkdir -p /var/lib/puppet/ssl/certs
41
+ mkdir -p /var/lib/puppet/ssl/private_keys
42
+ mkdir -p /etc/puppet
43
+
44
+ mkdir -p /etc/facter/facts.d
45
+ echo '#{facter_facts}' >> "/etc/facter/facts.d/facts.txt"
46
+
47
+ echo '#{certs[1]}' >> "/var/lib/puppet/ssl/certs/#{certs[0]}.pem"
48
+ echo '#{certs[2]}' >> "/var/lib/puppet/ssl/certs/ca.pem"
49
+ echo '#{certs[3]}' >> "/var/lib/puppet/ssl/private_keys/#{certs[0]}.pem"
50
+
51
+ echo '#{puppet_conf.chomp}' > /etc/puppet/puppet.conf
52
+
53
+ sed -i /etc/default/puppet -e 's/START=no/START=yes/'
54
+ service puppet restart
55
+
56
+ echo "Goodbye World. The time is now $(date -R)!" | tee /root/output.txt
57
+ contents
58
+ file.write(file_contents)
59
+ end
60
+ end
61
+ def self.generate_puppet_conf(uuid)
62
+ conf_file = <<conf
63
+ [main]
64
+ logdir=/var/log/puppet
65
+ vardir=/var/lib/puppet
66
+ ssldir=/var/lib/puppet/ssl
67
+ rundir=/var/run/puppet
68
+ factpath=$vardir/lib/facter
69
+ templatedir=$confdir/templates
70
+ prerun_command=/etc/puppet/etckeeper-commit-pre
71
+ postrun_command=/etc/puppet/etckeeper-commit-post
72
+ runinterval=60 # run every minute for debug TODO REMOVE
73
+ pluginsync=true
74
+
75
+ [master]
76
+ # These are needed when the puppetmaster is run by passenger
77
+ # and can safely be removed if webrick is used.
78
+ ssl_client_header = SSL_CLIENT_S_DN
79
+ ssl_client_verify_header = SSL_CLIENT_VERIFY
80
+
81
+ [agent]
82
+ certname=#{uuid}
83
+ conf
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ module Edurange
2
+ VERSION = "0.0.1"
3
+ end
data/lib/edurange.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "edurange/version"
2
+ require "edurange/parser"
3
+ require "edurange/puppet_master"
4
+ require "edurange/edu_machine"
5
+
6
+ module Edurange
7
+ class Init
8
+ def self.init(filename)
9
+ Edurange::Parser.parse_yaml(filename)
10
+
11
+ end
12
+ end
13
+ end
data/parser.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'yaml'
2
+
3
+ file = YAML.load_file('final.yml')
4
+
5
+ softwares = {}
6
+ file["Software"].each do |software|
7
+ softwares[software[0]] = software[1]
8
+ end
9
+
10
+ groups = {}
11
+ file["Groups"].each do |group|
12
+ groups[group[0]] = group[1]
13
+ end
14
+
15
+ file["Nodes"].each do |node|
16
+ node_name = node[0]
17
+ ami_id = node[1]["AMI_ID"]
18
+
19
+ users = []
20
+ users_groups = node[1]["Users"]
21
+ users_groups.each do |user_group|
22
+ users.push groups[user_group]
23
+ end
24
+ users.flatten!
25
+
26
+ software = []
27
+ software_groups = node[1]["Software"]
28
+ software_groups.each do |software_group|
29
+ software.push softwares[software_group]
30
+ end
31
+ software.flatten!
32
+
33
+ iptables_rules = []
34
+ packages = []
35
+ software.each do |sw|
36
+ if !sw["IPTables"].nil?
37
+ sw["IPTables"].each do |iptable_rule|
38
+ port = iptable_rule[0]
39
+ protocol = iptable_rule[1]["Protocol"]
40
+ hosts = iptable_rule[1]["Hosts"]
41
+ hosts.each do |host|
42
+ iptables_rules.push [protocol, port, host]
43
+ end
44
+ end
45
+ end
46
+ if !sw["Packages"].nil?
47
+ sw["Packages"].each do |package|
48
+ packages.push package
49
+ end
50
+ end
51
+ end
52
+ p ami_id
53
+ p users
54
+ p iptables_rules
55
+ p packages
56
+ end
57
+
data/site.pp ADDED
@@ -0,0 +1,20 @@
1
+ node default {
2
+ include stdlib
3
+
4
+ file { "/tmp/test1":
5
+ ensure => present
6
+ }
7
+ file { "/tmp/derp":
8
+ ensure => present,
9
+ content => $aaaaaafact
10
+ }
11
+ }
12
+ define install_software {
13
+ $package = $name
14
+ package { $name:
15
+ name => $name,
16
+ ensure => latest,
17
+ }
18
+ }
19
+ $packages = split($services,',')
20
+ install_software{ $packages:; }
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: edurange
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stefan Boesen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-15 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: EDURange Project
15
+ email:
16
+ - stefan.boesen@gmail.com
17
+ executables:
18
+ - edurange
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - bin/edurange
28
+ - edurange.gemspec
29
+ - final.yml
30
+ - lib/edurange.rb
31
+ - lib/edurange/edu_machine.rb
32
+ - lib/edurange/parser.rb
33
+ - lib/edurange/puppet_master.rb
34
+ - lib/edurange/version.rb
35
+ - parser.rb
36
+ - site.pp
37
+ homepage: ''
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.24
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Automatic warspace simulations
61
+ test_files: []