mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 11:18:06 +00:00
Squashed WNS + IRI DL work
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -12,7 +12,7 @@ gem 'mini_exiftool_vendored'
|
||||
gem 'rmagick'
|
||||
gem 'sshkey'
|
||||
gem 'zipruby'
|
||||
gem 'zip'
|
||||
gem 'zip-zip'
|
||||
gem 'credy'
|
||||
gem 'pg'
|
||||
gem 'cinch'
|
||||
|
||||
1
ads_students
Normal file
1
ads_students
Normal file
@@ -0,0 +1 @@
|
||||
c7154611,c3490435,c7149970,c7143104,c3457952,c3469799,c3414724,c3468394,c3433289,c3449827,c3452857,c3453527,c3459645,c3415781,c3403979,c7154207,c3461096,c3417960,c3468276,c3455839,c3395252,c3456658,c3461575,c3456985,c3471283,c3423870,c3449257,c3439405,c3433131,c3420038,c3455252,c3415736,c3465826,c3435127,c3470033,c3443008,c7144911,c3462292,c3445741,c3417771,c3433249,c3465220,c3468727,c3428394,c3426517,c3447995,c3420408,c3426667,c3470438,c3458366,c7166386,c3444619,c3422400,c3418906,c3457557,c3449023,c3444030,c3346276,c3454728,c3405964,c3466737,c3428565,c7129185,c3396733,c3440450,c3451999,c3459500,c3422916
|
||||
@@ -119,7 +119,7 @@ def get_delete_opts
|
||||
end
|
||||
|
||||
def parse_opts(opts)
|
||||
options = {:instances => '', :max_threads => 3, :id => nil, :all => false}
|
||||
options = {:instances => '', :max_threads => 5, :id => nil, :all => false}
|
||||
opts.each do |opt, arg|
|
||||
case opt
|
||||
when '--instances'
|
||||
|
||||
@@ -6,6 +6,16 @@ require_relative './print.rb'
|
||||
|
||||
class OVirtFunctions
|
||||
|
||||
# TODO supply this as a parameter/option instead
|
||||
def self.authz
|
||||
'@aet.leedsbeckett.ac.uk-authz'
|
||||
end
|
||||
|
||||
# @param [Hash] options -- command-line opts
|
||||
# @return [Boolean] is this secgen process using oVirt as the vagrant provider?
|
||||
def self.provider_ovirt?(options)
|
||||
options[:ovirtuser] and options[:ovirtpass] and options[:ovirturl]
|
||||
end
|
||||
|
||||
# Helper for removing VMs which Vagrant lost track of, i.e. exist but are reported as 'have not been created'.
|
||||
# @param [String] destroy_output_log -- logfile from vagrant destroy process which contains loose VMs
|
||||
@@ -64,6 +74,22 @@ class OVirtFunctions
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_userrole_role(ovirt_connection)
|
||||
roles_service(ovirt_connection).list.each do |role_item|
|
||||
if role_item.name == "UserRole"
|
||||
return role_item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.roles_service(ovirt_connection)
|
||||
ovirt_connection.system_service.roles_service
|
||||
end
|
||||
|
||||
def self.users_service(ovirt_connection)
|
||||
ovirt_connection.system_service.users_service
|
||||
end
|
||||
|
||||
def self.vms_service(ovirt_connection)
|
||||
ovirt_connection.system_service.vms_service
|
||||
end
|
||||
@@ -110,9 +136,95 @@ class OVirtFunctions
|
||||
failures.uniq
|
||||
end
|
||||
|
||||
# @param [String] options -- command-line opts, contains oVirt username, password and url
|
||||
def self.create_snapshot(options, scenario_path, vm_names)
|
||||
vms = []
|
||||
ovirt_connection = get_ovirt_connection(options)
|
||||
ovirt_vm_names = build_ovirt_names(scenario_path, options[:prefix], vm_names)
|
||||
ovirt_vm_names.each do |vm_name|
|
||||
vms << vms_service(ovirt_connection).list(search: "name=#{vm_name}")
|
||||
end
|
||||
|
||||
vms.each do |vm_list|
|
||||
vm_list.each do |vm|
|
||||
Print.std " VM: #{vm.name}"
|
||||
# find the service that manages that vm
|
||||
vm_service = vms_service(ovirt_connection).vm_service(vm.id)
|
||||
Print.std " Creating snapshot: #{vm.name}"
|
||||
begin
|
||||
vm_service.snapshots_service.add(
|
||||
OvirtSDK4::Snapshot.new(
|
||||
description: "Automated snapshot: #{Time.new.to_s}"
|
||||
)
|
||||
)
|
||||
rescue Exception => e
|
||||
Print.err '****************************************** Skipping'
|
||||
Print.err e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.assign_permissions(options, scenario_path, vm_names)
|
||||
ovirt_connection = get_ovirt_connection(options)
|
||||
username = options[:prefix].chomp
|
||||
user = get_user(ovirt_connection, username)
|
||||
if user
|
||||
vms = []
|
||||
|
||||
ovirt_vm_names = build_ovirt_names(scenario_path, username, vm_names)
|
||||
Print.std "Searching for VMs owned by #{username} #{ovirt_vm_names}"
|
||||
ovirt_vm_names.each do |vm_name|
|
||||
vms << vms_service(ovirt_connection).list(search: "name=#{vm_name}")
|
||||
end
|
||||
|
||||
vms.each do |vm_list|
|
||||
vm_list.each do |vm|
|
||||
Print.std " Found VM: #{vm.name}"
|
||||
|
||||
# find the service that manages that vm
|
||||
vm_service = vms_service(ovirt_connection).vm_service(vm.id)
|
||||
|
||||
# find the service that manages the permissions of that vm
|
||||
perm_service = vm_service.permissions_service
|
||||
|
||||
# add a permission for that user to use that VM
|
||||
perm_attr = {}
|
||||
perm_attr[:comment] = 'Automatic assignment'
|
||||
perm_attr[:role] = get_userrole_role(ovirt_connection)
|
||||
perm_attr[:user] = user
|
||||
Print.std " Adding permissions"
|
||||
begin
|
||||
perm_service.add OvirtSDK4::Permission.new(perm_attr)
|
||||
rescue Exception => e
|
||||
Print.err '****************************************** Skipping'
|
||||
Print.err e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
Print.info "No account with username #{username} found, skipping ..."
|
||||
end
|
||||
end
|
||||
|
||||
# @param [String] username
|
||||
# @return [OvirtUser]
|
||||
def self.get_user(ovirt_connection, username)
|
||||
un = username.chomp
|
||||
search_string = "usrname=#{un}#{authz}"
|
||||
puts "Searching for VMs owned by #{un}"
|
||||
user = users_service(ovirt_connection).list(search: search_string).first
|
||||
if user
|
||||
Print.std "Found user '#{un}' on oVirt"
|
||||
user
|
||||
else
|
||||
Print.err "User #{un} not found"
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# @param [String] options -- command-line opts, contains oVirt username, password and url
|
||||
def self.get_ovirt_connection(options)
|
||||
if options[:ovirtuser] and options[:ovirtpass] and options[:ovirturl]
|
||||
if provider_ovirt?(options)
|
||||
conn_attr = {}
|
||||
conn_attr[:url] = options[:ovirturl]
|
||||
conn_attr[:username] = options[:ovirtuser]
|
||||
@@ -127,4 +239,104 @@ class OVirtFunctions
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
## TODO: Remove me
|
||||
#
|
||||
## Included cliffe's permissions script to modify tomorrow!
|
||||
#
|
||||
# require 'ovirtsdk4'
|
||||
#
|
||||
# create_snapshots = true
|
||||
# assign_permissions = true
|
||||
#
|
||||
# authz = '@aet.leedsbeckett.ac.uk-authz'
|
||||
#
|
||||
# # read in the list of users (one username per line)
|
||||
# localuserslist = File.readlines('./userlist.complete')
|
||||
#
|
||||
# # connect to oVirt
|
||||
# conn_attr = {}
|
||||
# conn_attr[:url] = 'https://aet-ovirt.aet.leedsbeckett.ac.uk/ovirt-engine/api'
|
||||
# conn_attr[:username] = 'secgen@aet.leedsbeckett.ac.uk'
|
||||
# conn_attr[:password] = 'assay4?ravel'
|
||||
# conn_attr[:debug] = true
|
||||
# conn_attr[:headers] = {'Filter' => true }
|
||||
#
|
||||
# ovirt_connection = OvirtSDK4::Connection.new(conn_attr)
|
||||
# # get the service that manages the VMs
|
||||
# vms_service = ovirt_connection.system_service.vms_service
|
||||
# # puts vms_service.to_s
|
||||
#
|
||||
# # get the service that manages the users
|
||||
# users_service = ovirt_connection.system_service.users_service
|
||||
# # puts users_service.list
|
||||
#
|
||||
# # get the service that manages the roles
|
||||
# roles_service = ovirt_connection.system_service.roles_service
|
||||
# # puts roles_service.list
|
||||
#
|
||||
# # find the UserRole role
|
||||
# role = "";
|
||||
# roles_service.list().each do |role_item|
|
||||
# if role_item.name == "UserRole"
|
||||
# role = role_item
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # iterate through our local list of users
|
||||
# localuserslist.each do |username|
|
||||
# # find the user on oVirt
|
||||
# search_string = "usrname=#{username.chomp()}#{authz}"
|
||||
# puts "Searching for VMs owned by #{username.chomp()}"
|
||||
# user = users_service.list(search: search_string).first
|
||||
# # puts user.to_s
|
||||
#
|
||||
# if user
|
||||
# puts " Found user on oVirt"
|
||||
# # find any VMs we have access to that start with their username
|
||||
# vms = vms_service.list(search: "name=#{username.chomp()}-7-*")
|
||||
# vms.each do |vm|
|
||||
# puts " VM: #{vm.name}"
|
||||
#
|
||||
# # find the service that manages that vm
|
||||
# vm_service = vms_service.vm_service(vm.id)
|
||||
#
|
||||
# if assign_permissions
|
||||
# # find the service that manages the permissions of that vm
|
||||
# perm_service = vm_service.permissions_service
|
||||
#
|
||||
# # add a permission for that user to use that VM
|
||||
# perm_attr = {}
|
||||
# perm_attr[:comment] = 'Automatic assignment'
|
||||
# perm_attr[:role] = role
|
||||
# perm_attr[:user] = user
|
||||
# puts " Adding permissions"
|
||||
# begin
|
||||
# perm_service.add OvirtSDK4::Permission.new(perm_attr)
|
||||
# rescue Exception => e
|
||||
# puts "****************************************** Skipping"
|
||||
# puts e.message
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# if create_snapshots
|
||||
# puts " Creating snapshot"
|
||||
# begin
|
||||
# vm_service.snapshots_service.add(
|
||||
# OvirtSDK4::Snapshot.new(
|
||||
# description: "Automated snapshot: #{Time.new.to_s}"
|
||||
# )
|
||||
# )
|
||||
# rescue Exception => e
|
||||
# puts "****************************************** Skipping"
|
||||
# puts e.message
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# end
|
||||
# else
|
||||
# puts "Skipping missing user: #{username}"
|
||||
# end
|
||||
#
|
||||
# end
|
||||
@@ -28,7 +28,7 @@ class System
|
||||
# @return [Object] the list of selected modules
|
||||
def resolve_module_selection(available_modules, options)
|
||||
retry_count = 0
|
||||
|
||||
begin
|
||||
# Replace $IP_addresses with options ip_ranges if required
|
||||
begin
|
||||
if options[:ip_ranges] and $datastore['IP_addresses'] and !$datastore['replaced_ranges']
|
||||
@@ -80,8 +80,6 @@ class System
|
||||
exit
|
||||
end
|
||||
|
||||
begin
|
||||
|
||||
selected_modules = []
|
||||
self.num_actioned_module_conflicts = 0
|
||||
|
||||
@@ -184,7 +182,7 @@ class System
|
||||
end
|
||||
|
||||
# feed in input from any received datastores
|
||||
if selected.received_datastores != {}
|
||||
if selected.received_datastores != {} and $datastore != {}
|
||||
Print.verbose "Receiving datastores: #{selected.received_datastores}"
|
||||
selected.received_datastores.each do |input_into, datastore_list|
|
||||
datastore_list.each do |datastore_variablename_and_access_type|
|
||||
|
||||
@@ -140,10 +140,12 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
<% if @ovirt_template and @ovirt_template.include? 'kali_linux_msf' %>
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo \"auto lo\niface lo inet loopback\n\nauto eth0\niface eth0 inet static\n\taddress <%= resolve_network(selected_module)%>\" > /etc/network/interfaces"
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo '' > /etc/environment"
|
||||
<% elsif @ovirt_template and @ovirt_template.include? 'debian_desktop_kde' %>
|
||||
<% elsif @ovirt_template and (@ovirt_template.include? 'debian_desktop_kde') %>
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo \"\nauto eth1\niface eth1 inet static\n\taddress <%= resolve_network(selected_module)%>\" >> /etc/network/interfaces"
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo '' > /etc/environment"
|
||||
<% else %>
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo '' > /etc/environment"
|
||||
<% elsif @ovirt_template and ( @ovirt_template.include? 'debian_stretch_server_n' or @ovirt_template.include? 'debian_stretch_desktop_kde') %>
|
||||
<%= system.name %>.vm.provision 'shell', inline: "echo \"\nauto ens4\niface ens4 inet static\n\taddress <%= resolve_network(selected_module)%>\" >> /etc/network/interfaces"
|
||||
<% else %>
|
||||
<%= system.name %>.vm.network :<%= selected_module.attributes['type'].first %>, :ovirt__ip => "<%= resolve_network(selected_module)%>", :ovirt__network_name => '<%= "#{@options[:ovirtnetwork]}" %>'
|
||||
<% end %>
|
||||
<% else %>
|
||||
|
||||
22
modules/bases/debian_stretch/secgen_metadata.xml
Normal file
22
modules/bases/debian_stretch/secgen_metadata.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<base xmlns="http://www.github/cliffe/SecGen/base"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/base">
|
||||
<name>Debian 9 Stretch Server</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>For testing purposes, the default root password is puppet.</description>
|
||||
<cpu_word_size>64-bit</cpu_word_size>
|
||||
<type>server</type>
|
||||
<type>cli</type>
|
||||
|
||||
<platform>linux</platform>
|
||||
<platform>unix</platform>
|
||||
<distro>Debian 9 (stretch) TODO: 32-bit (i386)</distro>
|
||||
<url>https://app.vagrantup.com/summernguyen/boxes/debian-stretch-puppet/versions/1.0.0/providers/virtualbox.box</url>
|
||||
<ovirt_template>debian_stretch_server_n</ovirt_template>
|
||||
|
||||
<reference>https://atlas.hashicorp.com/puppetlabs</reference>
|
||||
<software_license>various</software_license>
|
||||
</base>
|
||||
21
modules/bases/debian_stretch_desktop_kde/secgen_metadata.xml
Normal file
21
modules/bases/debian_stretch_desktop_kde/secgen_metadata.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<base xmlns="http://www.github/cliffe/SecGen/base"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/base">
|
||||
<name>Debian 9 Stretch Desktop KDE</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>For testing purposes, the default root password is puppet.</description>
|
||||
<cpu_word_size>64-bit</cpu_word_size>
|
||||
<type>desktop</type>
|
||||
|
||||
<platform>linux</platform>
|
||||
<platform>unix</platform>
|
||||
<distro>Debian 9 (stretch) TODO: 32-bit (i386)</distro>
|
||||
<url>https://app.vagrantup.com/summernguyen/boxes/debian-stretch-puppet/versions/1.0.0/providers/virtualbox.box</url>
|
||||
<ovirt_template>debian_stretch_desktop_kde</ovirt_template>
|
||||
|
||||
<reference>https://atlas.hashicorp.com/puppetlabs</reference>
|
||||
<software_license>various</software_license>
|
||||
</base>
|
||||
@@ -3,7 +3,7 @@ require_relative '../../../../../lib/objects/local_string_encoder.rb'
|
||||
require 'rubygems'
|
||||
require 'zip'
|
||||
|
||||
class ZipFileGenerator < StringEncoder
|
||||
class ZipGenerator < StringEncoder
|
||||
attr_accessor :file_name
|
||||
attr_accessor :strings_to_leak
|
||||
attr_accessor :password
|
||||
@@ -64,4 +64,4 @@ class ZipFileGenerator < StringEncoder
|
||||
end
|
||||
end
|
||||
|
||||
ZipFileGenerator.new.run
|
||||
ZipGenerator.new.run
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../lib/objects/local_string_generator.rb'
|
||||
|
||||
class RandomWordpressVersion < StringGenerator
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Random Wordpress Version Generator'
|
||||
end
|
||||
|
||||
def generate
|
||||
one = ['1.5.2', '1.5.1.3', '1.5.1.2', '1.5.1.1', '1.5.1']
|
||||
versions = one
|
||||
|
||||
outputs << versions.sample.chomp
|
||||
end
|
||||
end
|
||||
|
||||
RandomWordpressVersion.new.run
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Random Wordpress 1x Version Generator</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Selects the version number of a random compatible WordPress version.</description>
|
||||
|
||||
<type>wordpress_version</type>
|
||||
<type>string_generator</type>
|
||||
<type>local_calculation</type>
|
||||
<platform>linux</platform>
|
||||
<platform>windows</platform>
|
||||
|
||||
<reference>https://wordpress.org</reference>
|
||||
|
||||
<output_type>generated_strings</output_type>
|
||||
</generator>
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../lib/objects/local_string_generator.rb'
|
||||
|
||||
class RandomWordpressVersion < StringGenerator
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Random Wordpress Version Generator'
|
||||
end
|
||||
|
||||
def generate
|
||||
two = ['2.9.2', '2.9.1', '2.9', '2.8.6', '2.8.5', '2.8.4', '2.8.3', '2.8.2', '2.8.1', '2.8', '2.7.1', '2.7', '2.6.5', '2.6.3', '2.6.2', '2.6.1', '2.6', '2.5.1', '2.5', '2.3.3', '2.3.2', '2.3.1', '2.3', '2.2.3', '2.2.2', '2.2.1', '2.2', '2.1.3', '2.1.2', '2.1.1', '2.1', '2.0.11', '2.0.10', '2.0.9', '2.0.8', '2.0.7', '2.0.6', '2.0.5', '2.0.4', '2.0.1', '2.0']
|
||||
versions = two
|
||||
|
||||
outputs << versions.sample.chomp
|
||||
end
|
||||
end
|
||||
|
||||
RandomWordpressVersion.new.run
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Random Wordpress 2x Version Generator</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Selects the version number of a random compatible WordPress version.</description>
|
||||
|
||||
<type>wordpress_version</type>
|
||||
<type>string_generator</type>
|
||||
<type>local_calculation</type>
|
||||
<platform>linux</platform>
|
||||
<platform>windows</platform>
|
||||
|
||||
<reference>https://wordpress.org</reference>
|
||||
|
||||
<output_type>generated_strings</output_type>
|
||||
</generator>
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../lib/objects/local_string_generator.rb'
|
||||
|
||||
class RandomWordpressVersion < StringGenerator
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Random Wordpress Version Generator'
|
||||
end
|
||||
|
||||
def generate
|
||||
three = ['3.9.23', '3.9.22', '3.9.21', '3.9.20', '3.9.19', '3.9.18', '3.9.17', '3.9.16', '3.9.15', '3.9.14', '3.9.13', '3.9.12', '3.9.11', '3.9.10', '3.9.9', '3.9.8', '3.9.7', '3.9.6', '3.9.5', '3.9.4', '3.9.3', '3.9.2', '3.9.1', '3.9', '3.8.25', '3.8.24', '3.8.23', '3.8.22', '3.8.21', '3.8.20', '3.8.19', '3.8.18', '3.8.17', '3.8.16', '3.8.15', '3.8.14', '3.8.13', '3.8.12', '3.8.11', '3.8.10', '3.8.9', '3.8.8', '3.8.7', '3.8.6', '3.8.5', '3.8.4', '3.8.3', '3.8.2', '3.8.1', '3.8', '3.7.25', '3.7.24', '3.7.23', '3.7.22', '3.7.21', '3.7.20', '3.7.19', '3.7.18', '3.7.17', '3.7.16', '3.7.15', '3.7.14', '3.7.13', '3.7.12', '3.7.11', '3.7.10', '3.7.9', '3.7.8', '3.7.7', '3.7.6', '3.7.5', '3.7.4', '3.7.3', '3.7.2', '3.7.1', '3.7', '3.6.1', '3.6', '3.5.2', '3.5.1', '3.5', '3.4.2', '3.4.1', '3.4', '3.3.3', '3.3.2', '3.3.1', '3.3', '3.2.1', '3.2', '3.1.4', '3.1.3', '3.1.2', '3.1.1', '3.1', '3.0.6', '3.0.5', '3.0.4', '3.0.3', '3.0.2', '3.0.1', '3.0']
|
||||
|
||||
outputs << three.sample.chomp
|
||||
end
|
||||
end
|
||||
|
||||
RandomWordpressVersion.new.run
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Random Wordpress 3x Version Generator</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Selects the version number of a random compatible WordPress version.</description>
|
||||
|
||||
<type>wordpress_version</type>
|
||||
<type>string_generator</type>
|
||||
<type>local_calculation</type>
|
||||
<platform>linux</platform>
|
||||
<platform>windows</platform>
|
||||
|
||||
<reference>https://wordpress.org</reference>
|
||||
|
||||
<output_type>generated_strings</output_type>
|
||||
</generator>
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../lib/objects/local_string_generator.rb'
|
||||
|
||||
class RandomWordpressVersion < StringGenerator
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Random Wordpress Version Generator'
|
||||
end
|
||||
|
||||
def generate
|
||||
four = ['4.9.4', '4.9.3', '4.9.2', '4.9.1', '4.9', '4.8.5', '4.8.4', '4.8.3', '4.8.2', '4.8.1', '4.8', '4.7.9', '4.7.8', '4.7.7', '4.7.6', '4.7.5', '4.7.4', '4.7.3', '4.7.2', '4.7.1', '4.7', '4.6.10', '4.6.9', '4.6.8', '4.6.7', '4.6.6', '4.6.5', '4.6.4', '4.6.3', '4.6.2', '4.6.1', '4.6', '4.5.13', '4.5.12', '4.5.11', '4.5.10', '4.5.9', '4.5.8', '4.5.7', '4.5.6', '4.5.5', '4.5.4', '4.5.3', '4.5.2', '4.5.1', '4.5', '4.4.14', '4.4.13', '4.4.12', '4.4.11', '4.4.10', '4.4.9', '4.4.8', '4.4.7', '4.4.6', '4.4.5', '4.4.4', '4.4.3', '4.4.2', '4.4.1', '4.4', '4.3.15', '4.3.14', '4.3.13', '4.3.12', '4.3.11', '4.3.10', '4.3.9', '4.3.8', '4.3.7', '4.3.6', '4.3.5', '4.3.4', '4.3.3', '4.3.2', '4.3.1', '4.3', '4.2.19', '4.2.18', '4.2.17', '4.2.16', '4.2.15', '4.2.14', '4.2.13', '4.2.12', '4.2.11', '4.2.10', '4.2.9', '4.2.8', '4.2.7', '4.2.6', '4.2.5', '4.2.4', '4.2.3', '4.2.2', '4.2.1', '4.2', '4.1.22', '4.1.21', '4.1.20', '4.1.19', '4.1.18', '4.1.17', '4.1.16', '4.1.15', '4.1.14', '4.1.13', '4.1.12', '4.1.11', '4.1.10', '4.1.9', '4.1.8', '4.1.7', '4.1.6', '4.1.5', '4.1.4', '4.1.3', '4.1.2', '4.1.1', '4.1', '4.0.22', '4.0.21', '4.0.20', '4.0.19', '4.0.18', '4.0.17', '4.0.16', '4.0.15', '4.0.14', '4.0.13', '4.0.12', '4.0.11', '4.0.10', '4.0.9', '4.0.8', '4.0.7', '4.0.6', '4.0.5', '4.0.4', '4.0.3', '4.0.2', '4.0.1', '4.0']
|
||||
versions = four
|
||||
|
||||
outputs << versions.sample.chomp
|
||||
end
|
||||
end
|
||||
|
||||
RandomWordpressVersion.new.run
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Random Wordpress 4x Version Generator</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Selects the version number of a random compatible WordPress version.</description>
|
||||
|
||||
<type>wordpress_version</type>
|
||||
<type>string_generator</type>
|
||||
<type>local_calculation</type>
|
||||
<platform>linux</platform>
|
||||
<platform>windows</platform>
|
||||
|
||||
<reference>https://wordpress.org</reference>
|
||||
|
||||
<output_type>generated_strings</output_type>
|
||||
</generator>
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../lib/objects/local_string_generator.rb'
|
||||
|
||||
class RandomWordpressVersion < StringGenerator
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Random Wordpress Version Generator'
|
||||
end
|
||||
|
||||
def generate
|
||||
one = ['1.5.2', '1.5.1.3', '1.5.1.2', '1.5.1.1', '1.5.1']
|
||||
two = ['2.9.2', '2.9.1', '2.9', '2.8.6', '2.8.5', '2.8.4', '2.8.3', '2.8.2', '2.8.1', '2.8', '2.7.1', '2.7', '2.6.5', '2.6.3', '2.6.2', '2.6.1', '2.6', '2.5.1', '2.5', '2.3.3', '2.3.2', '2.3.1', '2.3', '2.2.3', '2.2.2', '2.2.1', '2.2', '2.1.3', '2.1.2', '2.1.1', '2.1', '2.0.11', '2.0.10', '2.0.9', '2.0.8', '2.0.7', '2.0.6', '2.0.5', '2.0.4', '2.0.1', '2.0']
|
||||
three = ['3.9.23', '3.9.22', '3.9.21', '3.9.20', '3.9.19', '3.9.18', '3.9.17', '3.9.16', '3.9.15', '3.9.14', '3.9.13', '3.9.12', '3.9.11', '3.9.10', '3.9.9', '3.9.8', '3.9.7', '3.9.6', '3.9.5', '3.9.4', '3.9.3', '3.9.2', '3.9.1', '3.9', '3.8.25', '3.8.24', '3.8.23', '3.8.22', '3.8.21', '3.8.20', '3.8.19', '3.8.18', '3.8.17', '3.8.16', '3.8.15', '3.8.14', '3.8.13', '3.8.12', '3.8.11', '3.8.10', '3.8.9', '3.8.8', '3.8.7', '3.8.6', '3.8.5', '3.8.4', '3.8.3', '3.8.2', '3.8.1', '3.8', '3.7.25', '3.7.24', '3.7.23', '3.7.22', '3.7.21', '3.7.20', '3.7.19', '3.7.18', '3.7.17', '3.7.16', '3.7.15', '3.7.14', '3.7.13', '3.7.12', '3.7.11', '3.7.10', '3.7.9', '3.7.8', '3.7.7', '3.7.6', '3.7.5', '3.7.4', '3.7.3', '3.7.2', '3.7.1', '3.7', '3.6.1', '3.6', '3.5.2', '3.5.1', '3.5', '3.4.2', '3.4.1', '3.4', '3.3.3', '3.3.2', '3.3.1', '3.3', '3.2.1', '3.2', '3.1.4', '3.1.3', '3.1.2', '3.1.1', '3.1', '3.0.6', '3.0.5', '3.0.4', '3.0.3', '3.0.2', '3.0.1', '3.0']
|
||||
four = ['4.9.4', '4.9.3', '4.9.2', '4.9.1', '4.9', '4.8.5', '4.8.4', '4.8.3', '4.8.2', '4.8.1', '4.8', '4.7.9', '4.7.8', '4.7.7', '4.7.6', '4.7.5', '4.7.4', '4.7.3', '4.7.2', '4.7.1', '4.7', '4.6.10', '4.6.9', '4.6.8', '4.6.7', '4.6.6', '4.6.5', '4.6.4', '4.6.3', '4.6.2', '4.6.1', '4.6', '4.5.13', '4.5.12', '4.5.11', '4.5.10', '4.5.9', '4.5.8', '4.5.7', '4.5.6', '4.5.5', '4.5.4', '4.5.3', '4.5.2', '4.5.1', '4.5', '4.4.14', '4.4.13', '4.4.12', '4.4.11', '4.4.10', '4.4.9', '4.4.8', '4.4.7', '4.4.6', '4.4.5', '4.4.4', '4.4.3', '4.4.2', '4.4.1', '4.4', '4.3.15', '4.3.14', '4.3.13', '4.3.12', '4.3.11', '4.3.10', '4.3.9', '4.3.8', '4.3.7', '4.3.6', '4.3.5', '4.3.4', '4.3.3', '4.3.2', '4.3.1', '4.3', '4.2.19', '4.2.18', '4.2.17', '4.2.16', '4.2.15', '4.2.14', '4.2.13', '4.2.12', '4.2.11', '4.2.10', '4.2.9', '4.2.8', '4.2.7', '4.2.6', '4.2.5', '4.2.4', '4.2.3', '4.2.2', '4.2.1', '4.2', '4.1.22', '4.1.21', '4.1.20', '4.1.19', '4.1.18', '4.1.17', '4.1.16', '4.1.15', '4.1.14', '4.1.13', '4.1.12', '4.1.11', '4.1.10', '4.1.9', '4.1.8', '4.1.7', '4.1.6', '4.1.5', '4.1.4', '4.1.3', '4.1.2', '4.1.1', '4.1', '4.0.22', '4.0.21', '4.0.20', '4.0.19', '4.0.18', '4.0.17', '4.0.16', '4.0.15', '4.0.14', '4.0.13', '4.0.12', '4.0.11', '4.0.10', '4.0.9', '4.0.8', '4.0.7', '4.0.6', '4.0.5', '4.0.4', '4.0.3', '4.0.2', '4.0.1', '4.0']
|
||||
versions = one + two + three + four
|
||||
|
||||
outputs << versions.sample.chomp
|
||||
end
|
||||
end
|
||||
|
||||
RandomWordpressVersion.new.run
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Random Wordpress Version Generator</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Selects the version number of a random compatible WordPress version.</description>
|
||||
|
||||
<type>wordpress_version</type>
|
||||
<type>string_generator</type>
|
||||
<type>local_calculation</type>
|
||||
<platform>linux</platform>
|
||||
<platform>windows</platform>
|
||||
|
||||
<reference>https://wordpress.org</reference>
|
||||
|
||||
<output_type>generated_strings</output_type>
|
||||
</generator>
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../../lib/objects/local_hackerbot_config_generator.rb'
|
||||
|
||||
class IDS < HackerbotConfigGenerator
|
||||
|
||||
attr_accessor :backup_server_ip
|
||||
attr_accessor :ids_server_ip
|
||||
attr_accessor :web_server_ip
|
||||
attr_accessor :desktop_ip
|
||||
attr_accessor :hackerbot_server_ip
|
||||
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Hackerbot Config Generator HvHB1'
|
||||
self.title = 'HvHB1'
|
||||
|
||||
self.local_dir = File.expand_path('../../',__FILE__)
|
||||
self.templates_path = "#{self.local_dir}/templates/"
|
||||
self.config_template_path = "#{self.local_dir}/templates/lab.xml.erb"
|
||||
self.html_template_path = "#{self.local_dir}/templates/labsheet.html.erb"
|
||||
|
||||
self.backup_server_ip = []
|
||||
self.web_server_ip = []
|
||||
self.ids_server_ip = []
|
||||
self.desktop_ip = []
|
||||
self.hackerbot_server_ip = []
|
||||
end
|
||||
|
||||
def get_options_array
|
||||
super + [['--backup_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--desktop_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--ids_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--web_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--hackerbot_server_ip', GetoptLong::REQUIRED_ARGUMENT]]
|
||||
end
|
||||
|
||||
def process_options(opt, arg)
|
||||
super
|
||||
case opt
|
||||
when '--backup_server_ip'
|
||||
self.backup_server_ip << arg;
|
||||
when '--ids_server_ip'
|
||||
self.ids_server_ip << arg;
|
||||
when '--web_server_ip'
|
||||
self.web_server_ip << arg;
|
||||
when '--desktop_ip'
|
||||
self.desktop_ip << arg;
|
||||
when '--hackerbot_server_ip'
|
||||
self.desktop_ip << arg;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
IDS.new.run
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Hackerbot config for a test covering all the hackerbot labs</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a lab test..</description>
|
||||
|
||||
<type>hackerbot_config</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
<read_fact>accounts</read_fact>
|
||||
<read_fact>flags</read_fact>
|
||||
<read_fact>root_password</read_fact>
|
||||
<read_fact>backup_server_ip</read_fact>
|
||||
<read_fact>desktop_ip</read_fact>
|
||||
<read_fact>hackerbot_server_ip</read_fact>
|
||||
|
||||
<default_input into="accounts">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<value>vagrant</value>
|
||||
</input>
|
||||
</generator>
|
||||
</default_input>
|
||||
|
||||
<default_input into="flags">
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
</default_input>
|
||||
|
||||
<default_input into="root_password">
|
||||
<value>puppet</value>
|
||||
</default_input>
|
||||
|
||||
<output_type>hackerbot</output_type>
|
||||
|
||||
</generator>
|
||||
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<article class="markdown-body">
|
||||
|
||||
<%= self.html_rendered %>
|
||||
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
<attack>
|
||||
<% $file = SecureRandom.hex(2) %>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<prompt>Use scp to copy the desktop /bin/ directory to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-bin-backup-<%= $file %>/, which should then include the backed up bin/ directory.</prompt>
|
||||
|
||||
<post_command>ls /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/ls /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/mkdir > /dev/null; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( You didn't copy to the remote /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/... Remember that the trailing / changes whether you are copying directories or their contents...</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
<attack>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>It's your job to set up remote backups for <%= $second_user %> (a user on your system). Use rsync to create a full (epoch) remote backup of /home/<%= $second_user %> from your desktop system to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>.</prompt>
|
||||
|
||||
<post_command>ls /home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>/<%= $files.sample %> > /dev/null; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( You didn't copy to remote ssh /home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>/ Remember that the trailing / changes whether you are copying directories or their contents...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Doesn't look like you have backed up all of <%= $second_user %>'s files to /home/<%= $main_user %>/remote-rsync-backup/<%= $second_user %>. Try SSHing to the server and look at what you have backed up there.</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
<attack>
|
||||
<% $first_notes = SecureRandom.hex(2) %>
|
||||
<% $hidden_flag = 'not_a_flag' %>
|
||||
<!--shell on the desktop-->
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>The <%= $second_user %> user is about to create some files...</prompt>
|
||||
|
||||
<post_command>sudo -u <%= $second_user %> bash -c 'echo "Note to self: drink more water <%= $first_notes %>" > /home/<%= $second_user %>/notes; echo "Beep boop beep" > /home/<%= $second_user %>/logs/log2; echo <%= $hidden_flag %> > /home/<%= $second_user %>/personal_secrets/flag; echo $?'</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( Oh no. Access errors. <%= $second_user %> failed to write the files... The user needs to be able to write to their files!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Ok, good... </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<!-- topic: Rsync differential-->
|
||||
<prompt>Create a differential backup of <%= $second_user %>'s desktop files to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-rsync-differential1/.</prompt>
|
||||
|
||||
<!--grep retval=0 when match is found, 1/2 otherwise-->
|
||||
|
||||
<post_command>grep '<%= $hidden_flag %>' /home/<%= $main_user %>/remote-rsync-differential1/<%= $second_user %>/personal_secrets/flag > /dev/null; status1=$?; ls /home/<%= $main_user %>/remote-rsync-differential1/<%= $second_user %>/<%= $files.sample %> > /dev/null; status2=$?; echo $status1$status2</post_command>
|
||||
<condition>
|
||||
<output_matches>0[1-9]</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %> </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>[1-9][1-9]</output_matches>
|
||||
<message>:( You didn't backup to the specified remote directory.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>00</output_matches>
|
||||
<message>:( You backed up to the correct location, but it wasn't an differential backup... You probably need to ssh in and delete that last backup and try again.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
|
||||
<attack>
|
||||
<!--shell on the desktop-->
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>I am going to attack you now!</prompt>
|
||||
|
||||
<post_command>rm -r /home/<%= $second_user %>/*; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( Oh no. Access errors. <%= $second_user %>. You need to let this happen!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>I just deleted all <%= $second_user %>'s files! They don't call me Hackerbot for nothin'!</message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
|
||||
<attack>
|
||||
<!--shell on the desktop server-->
|
||||
|
||||
<!-- topic: Rsync incremental-->
|
||||
<prompt>Restore <%= $second_user %>'s notes file to it's earliest state</prompt>
|
||||
|
||||
<post_command>grep '<%= $first_notes %>' /home/<%= $second_user %>/notes > /dev/null; status1=$?; echo $status1</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %> </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>[0-9]</output_matches>
|
||||
<message>:( That's not the earliest state...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
<attack>
|
||||
<% $rand_alert0 = SecureRandom.hex(3)
|
||||
$rand_tmp_restingplace = "/tmp/#{SecureRandom.hex(3)}" %>
|
||||
<!--get the snort alerts before-->
|
||||
<!--and make a copy of the file to a new location -->
|
||||
<pre_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $web_server_ip %> 'cp <%= $sensitive_files_location %>clients.csv <%= $rand_tmp_restingplace %>; chmod 644 <%= $rand_tmp_restingplace %>'; stat0=$?; echo -$stat0; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; echo --$?</pre_shell>
|
||||
<!--exploit and read contents of sensitive file over the network-->
|
||||
<get_shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</get_shell>
|
||||
<!--trigger the rule by sending the data-->
|
||||
<post_command>cat <%= $rand_tmp_restingplace %>; echo --$?</post_command>
|
||||
<!--get the snort alerts after, and diff for new alerts generated-->
|
||||
<post_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; echo --$?; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5 | grep <%= $rand_alert0 %> >/dev/null; echo triggered:$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/etc/snort/rules/my.rules /tmp/snort_rules; echo rules:$?; grep '^alert.*msg:".*<%= $rand_alert0 %>.*".*content:"' /tmp/snort_rules >/dev/null; echo good_rule:$? </post_shell>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<prompt>You need to monitor your sensitive list of clients. The file contains credit card details and national insurance numbers. You have a copy in <%= $sensitive_files_location %>clients.csv Use one or more Snort rules to detect unencrypted transport of the file. The alert must include the message "<%= $rand_alert0 %>". (This attack may take a while.)</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>good_rule:1</output_matches>
|
||||
<message>:( Couldn't find your snort rule on the IDS server in /etc/snort/rules/my.rules. You are missing content matching or the message from your rule.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>triggered:1</output_matches>
|
||||
<message>:( Your rule wasn't triggered.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>triggered:0.*good_rule:0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--1</output_matches>
|
||||
<message>:( Failed to scp to the ids server (<%= $ids_server_ip %>)</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>-1</output_matches>
|
||||
<message>:( Failed to ssh to the web server (<%= $web_server_ip %>)</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--0</output_matches>
|
||||
<message>Continuing...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not quite right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<attack>
|
||||
<% $rand_alert2 = SecureRandom.hex(3)
|
||||
$rand_tmp_restingplace_fake = "/tmp/#{SecureRandom.hex(3)}" %>
|
||||
<!--get the snort alerts before-->
|
||||
<!--and make a copy of the file to a new location -->
|
||||
<pre_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $web_server_ip %> 'cp <%= $sensitive_files_location %>fake_clients.csv <%= $rand_tmp_restingplace_fake %>; chmod 644 <%= $rand_tmp_restingplace_fake %>'; stat0=$?; echo -$stat0; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; echo --$?</pre_shell>
|
||||
<!--exploit and read contents of sensitive file over the network-->
|
||||
<get_shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</get_shell>
|
||||
<!--trigger the rule by sending the data-->
|
||||
<post_command>cat <%= $rand_tmp_restingplace_fake %>; echo --$?</post_command>
|
||||
<!--get the snort alerts after, and diff for new alerts generated-->
|
||||
<post_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; echo --$?; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5 | grep <%= $rand_alert2 %> >/dev/null; echo triggered:$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/etc/snort/rules/my.rules /tmp/snort_rules; echo rules:$?; grep '^alert.*msg:".*<%= $rand_alert2 %>.*".*pcre:"' /tmp/snort_rules >/dev/null; echo good_rule:$? </post_shell>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<prompt>You need to monitor your sensitive list of clients. The file contains credit card details and national insurance numbers. You have a copy in <%= $sensitive_files_location %>clients.csv and another in fake_clients.csv Create a rule that matches either file. Use REGEXP so that your rule doesn't include any of the actual data. Use one or more Snort rules to detect unencrypted transport of either of the files. The alert must include the message "<%= $rand_alert2 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>good_rule:1</output_matches>
|
||||
<message>:( Couldn't find your snort rule on the IDS server in /etc/snort/rules/my.rules. You are missing *regular expression* matching or the message from your rule.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>triggered:1</output_matches>
|
||||
<message>:( Your rule wasn't triggered.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>triggered:0.*good_rule:0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--1</output_matches>
|
||||
<message>:( Failed to scp to the ids server (<%= $ids_server_ip %>)</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>-1</output_matches>
|
||||
<message>:( Failed to ssh to the web server (<%= $web_server_ip %>)</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--0</output_matches>
|
||||
<message>Continuing...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not quite right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,19 @@
|
||||
<attack>
|
||||
<% $file = SecureRandom.hex(2) %>
|
||||
<prompt>An attempt to write /tmp/<%= $file %> is coming from user <%= $second_user %>. Stop the attack by creating the file without permission for other users to write to the file.</prompt>
|
||||
|
||||
<post_command>sudo -u <%= $second_user %> bash -c 'echo boom > /tmp/<%= $file %>'; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_equals>0</output_equals>
|
||||
<message>:( We managed to write to your file! You need to use access controls to protect the file. Create a new file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
<attack>
|
||||
<% $log_file = $log_files.sample %>
|
||||
<!-- topic: Protecting integrity with file attributes-->
|
||||
<prompt>An attempt to delete /home/<%= $main_user %>/<%= $log_file %> is coming. Stop the attack using file attributes.</prompt>
|
||||
|
||||
<post_command>rm --interactive=never /home/<%= $main_user %>/<%= $log_file %>; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Operation not permitted</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition> <!-- TODO: chmod to defeat the defense? -->
|
||||
<output_matches>Permission denied</output_matches>
|
||||
<message>:( You did protect the file, but not using file attributes.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_equals>0</output_equals>
|
||||
<message>:( We managed to delete your file! You need to use file attributes to protect the file. Create a new file.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( The file should exist!</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
<attack>
|
||||
<% $log_file = $log_files.first %>
|
||||
<!-- topic: Protecting integrity with file attributes-->
|
||||
<prompt>An attempt to overwrite /home/<%= $main_user %>/<%= $log_file %> is coming. Stop the attack by making the file append only.</prompt>
|
||||
|
||||
<post_command>echo 'your logs are gone!' > /home/<%= $main_user %>/<%= $log_file %>; echo 'appended!' >> /home/<%= $main_user %>/<%= $log_file %>; tail -n2 /home/<%= $main_user %>/<%= $log_file %>; echo $?</post_command>
|
||||
<condition>
|
||||
<output_not_matches>appended!</output_not_matches>
|
||||
<message>:( You stopped anything from being appended to the file. What kind of log file do you think this is?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Operation not permitted</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( The file should exist!</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Protecting integrity with read-only filesystems-->
|
||||
<prompt>An attempt to edit a file in /etc/ is coming. Stop the attack by bind mounting /etc/ as read-only. (Don't forget to 'sudo umount /etc/' to reverse this after you complete this challenge!)</prompt>
|
||||
|
||||
<post_command>echo 'not read only!' > /etc/you_were_hacked; adduser --disabled-password --gecos "" yourehacked</post_command>
|
||||
<condition>
|
||||
<output_matches>Read-only file system</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted</output_matches>
|
||||
<message>:( You stopped the attack, but not by using read only bind mounting...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
<attack>
|
||||
<% $random_user = 'user' + SecureRandom.hex(3) %>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to add a new user is coming, let it happen. But first create a backup of /etc/passwd to /home/<%= $main_user %>/backups/passwd.</prompt>
|
||||
|
||||
<post_command>rm /etc/.pwd.lock; sudo adduser <%= $random_user %> --gecos '<%= $random_user %>' --disabled-password --quiet; echo $?</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>returned error code</output_matches>
|
||||
<message>:( Couldn't add a user -- make sure /etc/ is not still read-only mounted!.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>User added</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>already exists</output_matches>
|
||||
<message>:( Remove the user and try again.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>Now after the attack, find the username added by diffing using a backup. What username was created?</question>
|
||||
<answer>^<%= $random_user %>$</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to edit a config file is coming, let it happen. But first make sure you have a backup of the /etc/ directory at /home/<%= $main_user %>/backups/etc/.</prompt>
|
||||
<post_command>changedf=`find /etc/ -name '*.sh' | sort -R | head -n 1`; echo '# <%= $flags.pop %>' >> $changedf; echo $changedf</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>/etc/</output_matches>
|
||||
<message>A flag has been inserted into a random file in /etc/. Find the flag. Get to work!</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We are trying to write to /etc/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right... We are trying to write to /etc/</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to edit a config file is coming, let it happen. But first make sure you have a backup of the /etc/ directory at /home/<%= $main_user %>/backups/etc/.</prompt>
|
||||
<post_command>changedf=`find /home/<%= $main_user %>/backups/etc/ -name '*.sh' | sort -R | head -n 1`; echo '# <%= $flags.pop %>' >> $changedf; echo $changedf</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>/home/<%= $main_user %>/backups/</output_matches>
|
||||
<message>A flag has been inserted into a random file IN YOUR BACKUPS! (Did you really think that was a safe place to store them?) Find the flag. Get to work!</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We are trying to write to /home/<%= $main_user %>/backups/etc/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right... We are trying to write to /home/<%= $main_user %>/backups/etc/</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
<attack>
|
||||
<% $random = SecureRandom.hex %>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Creating a new file in /home/<%= $main_user %>/... Let it happen.</prompt>
|
||||
|
||||
<post_command>echo '<%= $random %>' > /home/<%= $main_user %>/something_secret; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Created /home/<%= $main_user %>/something_secret</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the SHA1 hash of /home/<%= $main_user %>/something_secret?</question>
|
||||
<answer>^<%= Digest::SHA1.hexdigest ("#{$random + "\n"}") %>$</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,26 @@
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to create a new file in /etc/, use hash comparisons to detect which new file changes.</prompt>
|
||||
<post_command>x=`find /etc/ -type d | sort -R | head -n 1`; mktemp -p $x -t "XXXXXXXX"</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/etc.*</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We need to be able to write to /secrets/something_secret/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,26 @@
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to copy a new random binary in /bin/|/usr/bin/ use hash comparisons to find the filename of the copied file.</prompt>
|
||||
<post_command>srcf=`find /bin/ /usr/bin/ -executable | sort -R | head -n 1`; srcf="${srcf%\\n}"; dest=$srcf.$RANDOM; cp $srcf $dest; echo $dest</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/bin/</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!--copied a new random file in /etc/ use hash comparisons to find the filename. -->
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to copy a new random file in /etc/ use hash comparisons to find the filename.</prompt>
|
||||
<post_command>srcf=`find /etc/ -type f | sort -R | head -n 1`; srcf="${srcf%\\n}"; dest=$srcf.$RANDOM; cp $srcf $dest; echo $dest</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/etc.*</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... </message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,119 @@
|
||||
# Hacker vs Hackerbot 2
|
||||
|
||||
## Troubleshooting with oVirt during the test
|
||||
|
||||
In the unlikely event you experience technical issues with our infrastructure during the test, please keep the following in mind.
|
||||
|
||||
* If your Snort alert file fills with "BAD TRAFFIC" alerts, let us know asap and we can fix that for you by changing the network interface type.
|
||||
|
||||
* If copy and paste stops working, simply copy your flags to a text file rather than the submission site, and let us know when you finish the test so we can help you submit these before you leave.
|
||||
|
||||
* If a VM looses its IP addresses (particularly the IDS server), simply run `sudo ifconfig eth1 *IP_ADDRESS*`, where `*IP_ADDRESS*` is the expected IP address (listed in the section below).
|
||||
|
||||
* If you experience any technical issues, which you believe to be outside your control, let us know before you leave the room. However, keep in mind we won't give hints for the actual test challenges.
|
||||
|
||||
## Getting started
|
||||
### VMs in this lab
|
||||
|
||||
==Start these VMs== (if you haven't already):
|
||||
|
||||
- hackerbot_server (leave it running, you don't log into this)
|
||||
- ids_server (IP address: <%= $ids_server_ip %>)
|
||||
- web_server (IP address: <%= $web_server_ip %>)
|
||||
- desktop
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
### Your login details for the "desktop" and "backup_server" VMs
|
||||
User: <%= $main_user %>
|
||||
Password: <%= $main_password %>
|
||||
(You can copy-paste this password!)
|
||||
|
||||
You won't login to the hackerbot_server, but all the VMs need to be running to complete the lab.
|
||||
|
||||
### For marks in the module
|
||||
1. **You need to submit flags**. Note that the flags and the challenges in your VMs are different to other's in the class. Flags will be revealed to you as you complete challenges throughout the module. Flags look like this: ==flag{*somethingrandom*}==. Follow the link on the module page to submit your flags.
|
||||
|
||||
## Hackerbot!
|
||||

|
||||
|
||||
This exercise involves interacting with Hackerbot, a chatbot who will task you to complete tasks and will attack your systems. If you satisfy Hackerbot by completing the challenges, she will reveal flags to you.
|
||||
|
||||
---
|
||||
|
||||
Some commands you may find useful include:
|
||||
* `rsync`
|
||||
* `chattr`
|
||||
* `lsattr`
|
||||
* `chmod`
|
||||
* `hashdeep`
|
||||
* `shasum`
|
||||
* `mount`
|
||||
* `umount`
|
||||
* `diff`
|
||||
* `tcpdump`
|
||||
* `wireshark`
|
||||
* `kdesudo`
|
||||
* `ssh`
|
||||
* `snort`
|
||||
* `sudo service snort stop`
|
||||
* `sudo service snort start`
|
||||
* `netstat`
|
||||
* `ps`
|
||||
* `lsof`
|
||||
* `top`
|
||||
|
||||
Remember you can learn more about the commands by running:
|
||||
```bash
|
||||
man *command*
|
||||
```
|
||||
|
||||
## Getting Snort up and running
|
||||
|
||||
**On the ids_server VM:**
|
||||
|
||||
==Change Snort's output== to something more readable:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*,
|
||||
|
||||
> ":wq" to write changes and quit)
|
||||
|
||||
==Add the following lines:==
|
||||
`output alert_fast`
|
||||
|
||||
`include $RULE_PATH/my.rules`
|
||||
|
||||
==Create a new rules file:==
|
||||
|
||||
```bash
|
||||
sudo touch /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
Let us edit the rules file without sudo:
|
||||
|
||||
```bash
|
||||
sudo chown <%= $main_user %> /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Change Snort's interface== to the interface with IP address <%= $ids_server_ip %> (likely eth1), and set the local network to your IP address range (or "any"):
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.debian.conf
|
||||
```
|
||||
> If you are not sure which interface to use, list the interfaces with `ifconfig` or `ip a s`
|
||||
> Set the interface and HOME network range, and exit vi (Esc, ":wq").
|
||||
|
||||
==Restart Snort:==
|
||||
|
||||
```bash
|
||||
sudo service snort stop
|
||||
sudo service snort start
|
||||
```
|
||||
> Using "reload" or "restart" may not update the interface.
|
||||
|
||||
Snort should now be running, monitoring network traffic for activity.
|
||||
|
||||
### Good luck!
|
||||
@@ -0,0 +1,170 @@
|
||||
<%
|
||||
require 'json'
|
||||
require 'securerandom'
|
||||
require 'digest/sha1'
|
||||
require 'fileutils'
|
||||
require 'erb'
|
||||
|
||||
if self.accounts.empty?
|
||||
abort('Sorry, you need to provide an account')
|
||||
end
|
||||
|
||||
$first_account = JSON.parse(self.accounts.first)
|
||||
$second_account = JSON.parse(self.accounts[1])
|
||||
|
||||
$files = []
|
||||
$log_files = []
|
||||
if $first_account.key?("leaked_filenames") && $first_account['leaked_filenames'].size > 0
|
||||
$files = $first_account['leaked_filenames']
|
||||
$log_files = $first_account['leaked_filenames'].grep(/log/)
|
||||
end
|
||||
|
||||
if $files.empty?
|
||||
$files = ['myfile', 'afile', 'filee', 'thefile']
|
||||
end
|
||||
if $log_files.empty?
|
||||
$log_files = ['log', 'thelog', 'logs', 'frogonalog']
|
||||
end
|
||||
|
||||
$main_user = $first_account['username'].to_s
|
||||
$main_password = $first_account['password'].to_s
|
||||
$second_user = $second_account['username'].to_s
|
||||
$example_file = "/home/#{$second_user}/#{$files.sample}"
|
||||
$example_dir = "/home/#{$second_user}/personal_secrets/"
|
||||
|
||||
$web_server_ip = self.web_server_ip.first
|
||||
$ids_server_ip = self.ids_server_ip.first
|
||||
$backup_server_ip = self.backup_server_ip.first
|
||||
$desktop_ip = self.desktop_ip.first
|
||||
$hackerbot_server_ip = self.hackerbot_server_ip.first
|
||||
$root_password = self.root_password
|
||||
$flags = self.flags
|
||||
|
||||
$sensitive_files_location = "/home/#{$main_user}/trade_secrets/"
|
||||
|
||||
REQUIRED_FLAGS = 10
|
||||
while $flags.length < REQUIRED_FLAGS
|
||||
$flags << "flag{#{SecureRandom.hex}}"
|
||||
Print.err "Warning: Not enough flags provided to hackerbot_config generator, some flags won't be tracked/marked!"
|
||||
end
|
||||
|
||||
def get_binding
|
||||
binding
|
||||
end
|
||||
-%>
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<hackerbot
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/hackerbot">
|
||||
<!--<hackerbot xmlns="http://www.github/cliffe/SecGen/hackerbotz"-->
|
||||
|
||||
<name>Hackerbot</name>
|
||||
|
||||
<AIML_chatbot_rules>config/AIML</AIML_chatbot_rules>
|
||||
|
||||
<!--Method for gaining shell access, can be overwritten per-attack-->
|
||||
<!--<get_shell>bash</get_shell>-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@{{chat_ip_address}} /bin/bash</get_shell>
|
||||
|
||||
|
||||
<messages>
|
||||
<show_attack_numbers />
|
||||
|
||||
<greeting>You are about to be attacked!</greeting>
|
||||
|
||||
<!--Must provide alternatives for each message-->
|
||||
<say_ready>When you are ready, simply say 'ready'.</say_ready>
|
||||
<say_ready>'Ready'?</say_ready>
|
||||
<next>Ok, I'll do what I can to move things along...</next>
|
||||
<next>Moving things along to the next one...</next>
|
||||
<previous>Ok, I'll do what I can to back things up...</previous>
|
||||
<previous>Ok, backing up.</previous>
|
||||
<goto>Ok, skipping it along.</goto>
|
||||
<goto>Let me see what I can do to goto that attack.</goto>
|
||||
<last_attack>That was the last one for now. You can rest easy, until next time... (End.)</last_attack>
|
||||
<last_attack>That was the last one. Game over?</last_attack>
|
||||
<first_attack>You are back to the beginning!</first_attack>
|
||||
<first_attack>This is where it all began.</first_attack>
|
||||
<getting_shell>Doing my thing...</getting_shell>
|
||||
<getting_shell>Here we go...</getting_shell>
|
||||
<got_shell>...</got_shell>
|
||||
<got_shell>....</got_shell>
|
||||
<repeat>Let me know when you are 'ready', if you want to move on say 'next', or 'previous' and I'll move things along.</repeat>
|
||||
<repeat>Say 'ready', 'next', or 'previous'.</repeat>
|
||||
|
||||
<!--Single responses:-->
|
||||
<help>I am waiting for you to say 'ready', 'next', 'previous', 'list', 'goto *X*', or 'answer *X*'</help>
|
||||
<say_answer>Say "The answer is *X*".</say_answer>
|
||||
<no_quiz>There is no question to answer</no_quiz>
|
||||
<correct_answer>Correct</correct_answer>
|
||||
<incorrect_answer>Incorrect</incorrect_answer>
|
||||
<invalid>That's not possible.</invalid>
|
||||
<non_answer>Wouldn't you like to know.</non_answer>
|
||||
|
||||
<!--can be overwritten per-attack-->
|
||||
<shell_fail_message>Oh no. Failed to get shell... You need to let us in.</shell_fail_message>
|
||||
</messages>
|
||||
|
||||
<tutorial_info>
|
||||
<title>HvHB1</title>
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'intro.md.erb').result(self.get_binding) %></tutorial>
|
||||
<footer>
|
||||
<%= File.read self.templates_path + 'license.md.erb' %>
|
||||
|
||||
Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%= Time.new.to_s %>)
|
||||
</footer>
|
||||
|
||||
<provide_tutorial>true</provide_tutorial>
|
||||
|
||||
</tutorial_info>
|
||||
|
||||
|
||||
<!-- 2 random permission attacks-->
|
||||
<%
|
||||
$permission_attacks = ['file_perms_attack_1.xml.erb', 'file_perms_attack_2.xml.erb', 'file_perms_attack_3.xml.erb', 'file_perms_attack_4.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $permission_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $permission_attacks.pop ).result(self.get_binding) %>
|
||||
|
||||
<!-- 4x random integrity attacks-->
|
||||
<%
|
||||
$integrity_attacks = ['integrity_attack1.xml.erb', 'integrity_attack2.xml.erb', 'integrity_attack3.xml.erb', 'integrity_attack4.xml.erb', 'integrity_attack5.xml.erb', 'integrity_attack6.xml.erb', 'integrity_attack7.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
|
||||
<!--Three flags from using rsync to backup and recover-->
|
||||
<%= ERB.new(File.read self.templates_path + 'backups_rsync_steps_attacks.xml.erb' ).result(self.get_binding) %>
|
||||
|
||||
|
||||
<!--2x network monitoring-->
|
||||
<%
|
||||
$network_monitoring = ['network_monitoring_1.xml.erb', 'network_monitoring_2.xml.erb', 'network_monitoring_3.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $network_monitoring.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $network_monitoring.pop ).result(self.get_binding) %>
|
||||
|
||||
<!-- 2x random services -->
|
||||
<%= ERB.new(File.read self.templates_path + 'random_service_ids_rule.xml.erb').result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + 'random_service_ids_rule.xml.erb').result(self.get_binding) %>
|
||||
|
||||
<!--3x Snort rules-->
|
||||
<%
|
||||
$snort_rules = ['snort_rule_1.xml.erb', 'snort_rule_2.xml.erb', 'snort_rule_3.xml.erb', 'snort_rule_4.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $snort_rules.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $snort_rules.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $snort_rules.pop ).result(self.get_binding) %>
|
||||
|
||||
<!--1x exfiltration rule-->
|
||||
<%
|
||||
$snort_exfil_rules = ['exfiltration_rule_1.xml.erb', 'exfiltration_rule_2.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $snort_exfil_rules.pop ).result(self.get_binding) %>
|
||||
|
||||
<!--1x live analysis-->
|
||||
<%= ERB.new(File.read self.templates_path + 'live_analysis_1.xml.erb' ).result(self.get_binding) %>
|
||||
|
||||
|
||||
</hackerbot>
|
||||
@@ -0,0 +1,121 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
.markdown-body h4[id^='hackerbot']:after {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
content: url("images/skullandusb.svg");
|
||||
width: 30px;
|
||||
}
|
||||
article {
|
||||
float: right;
|
||||
width: calc(100% - 300px);
|
||||
}
|
||||
.toc {
|
||||
float: left;
|
||||
font-size: smaller;
|
||||
color: #1a1d22;
|
||||
width: 300px;
|
||||
position: fixed;
|
||||
height: calc(100% - 56px);
|
||||
overflow-y: scroll;
|
||||
font-family: sans-serif;
|
||||
margin-top: 50px;
|
||||
}
|
||||
.toc ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.toc li { /* Space between menu items*/
|
||||
margin: 1em 0;
|
||||
}
|
||||
.toc a {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:hover {
|
||||
color: #6c036d;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:visited {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.markdown-body pre {
|
||||
background-color: #570138;
|
||||
color: whitesmoke;
|
||||
}
|
||||
.markdown-body p code span, li code .pln {
|
||||
color: black !important;
|
||||
}
|
||||
.markdown-body p code {
|
||||
background-color: whitesmoke;
|
||||
border: 1px solid #eaecef;
|
||||
}
|
||||
.markdown-body img[alt="small-left"] {
|
||||
max-width: 100px;
|
||||
float: left;
|
||||
}
|
||||
.markdown-body img[alt="small-right"] {
|
||||
max-width: 100px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="tiny-right"] {
|
||||
max-width: 30px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="small"] {
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
mark {
|
||||
background-color: white;
|
||||
color: #5b29bd;
|
||||
font-weight: bolder;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
}
|
||||
.toc {
|
||||
float: none;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
height: auto;
|
||||
}
|
||||
article {
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
<div class="toc">
|
||||
<%= self.html_TOC_rendered %>
|
||||
</div>
|
||||
|
||||
<article class="markdown-body">
|
||||
<%= self.html_rendered %>
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js?autoload=true&skin=sunburst&lang=css"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||

|
||||
@@ -0,0 +1,30 @@
|
||||
<attack>
|
||||
<% $rand_port_live = rand(65535) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $web_server_ip %> 'setsid nc -l -p <%= $rand_port_live %> &' & sleep 4; killall -9 ssh; echo 'OK'</pre_shell>
|
||||
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>About to do something to your web server, let it happen...</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>OK</output_matches>
|
||||
<message>Ok, answer this.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>OK..</output_matches>
|
||||
<message>Ok, answer this.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>Ok...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What port has just been opened by a process on your web server?</question>
|
||||
<answer><%= $rand_port_live %></answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,22 @@
|
||||
<attack>
|
||||
<% $rand1 = SecureRandom.hex(2) %>
|
||||
<pre_shell>curl -v -H 'Something-worth-noting: <%= $rand1 %>:<%= $flags.pop %>' <%= $web_server_ip %> > /dev/null; echo $? </pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>#1 Monitor the network traffic using Tcpdump or Wireshark, and look out for a string starting with "<%= $rand1 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Hope you found the flag! Moving on...</message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to talk to the web server (<%= $web_server_ip %>)</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>Ok, next up...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,20 @@
|
||||
<attack>
|
||||
<get_shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</get_shell>
|
||||
<post_command>whoami > /dev/null; echo "<%= $flags.pop %>" > /dev/null; echo 'Find the flag! (in the network traffic)'</post_command>
|
||||
|
||||
<prompt>Your webserver is about to be scanned/attacked. Use Tcpdump and/or Wireshark to view the behaviour of the attacker. There is a flag to be found over the wire. </prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>Find the flag</output_matches>
|
||||
<message>Hope you caught that.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to contact the web server (<%= $web_server_ip %>)</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,25 @@
|
||||
<attack>
|
||||
<% $rand_port = rand(65535) %>
|
||||
<pre_shell>nmap -p <%= $rand_port %> {{chat_ip_address}} > /dev/null; echo $? </pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Monitor the network traffic, and look out for attempts to scan your desktop VM. You need to identify what port the connection attempt is to.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Hope you found the port number.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to scan </message>
|
||||
</condition>
|
||||
|
||||
<quiz>
|
||||
<question>Now after the attack, what port number was scanned?</question>
|
||||
<answer>^<%= $rand_port %>$</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,31 @@
|
||||
<attack>
|
||||
<% $services = {'FTP'=>'20','Telnet'=>'23','SMTP'=>'25','HTTP'=>'80','POP3'=>'110','IMAP'=>'143','SNMP'=>'161','LDAP'=>'389','HTTPS'=>'443','LDAPS'=>'636'}
|
||||
$rand_service1 = $services.keys.sample
|
||||
$rand_alert3 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p 1000,<%= $services[$rand_service1] %> <%= $web_server_ip %> > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -u /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any TCP connection attempt to <%= $rand_service1 %> (just the connection attempt, does not require content inspection) on <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert3 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to scan your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches><%= $rand_alert3 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,34 @@
|
||||
<attack>
|
||||
<% $rand_port = rand(65535)
|
||||
$rand_alert1 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p <%= $rand_port - 1 %>-<%= $rand_port + 1 %> <%= $web_server_ip %> > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any TCP connection attempt to TCP port <%= $rand_port %> to <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert1 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to scan your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert1 %>.*<%= $rand_alert1 %></output_matches>
|
||||
<message>:( Almost. The alert did fire, but it fired more than once!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches><%= $rand_alert1 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,26 @@
|
||||
<attack>
|
||||
<% $rand_content1 = SecureRandom.hex(3)
|
||||
$rand_alert2 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; (sleep 1; echo "USER <%= $rand_content1 %>"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110 > /dev/null; (sleep 1; echo "user test"; echo "pass test"; echo "stat"; echo "quit"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110 > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any packet with the contents "<%= $rand_content1 %>" to <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert2 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert2 %>.*<%= $rand_alert2 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert2 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,33 @@
|
||||
<!--Email login attempt
|
||||
Tries a port scan, then connects twice once with caps, then lower, first with actual user, then incorrect creds, last 2 should trigger the rule
|
||||
-->
|
||||
<attack>
|
||||
<% $rand_alert4 = SecureRandom.hex(3)
|
||||
%>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p 110 <%= $web_server_ip %> > /dev/null; (sleep 1; echo "USER <%= $main_user %>"; echo "PASS <%= $main_user_pass %>"; echo "STAT"; echo "QUIT"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; (sleep 1; echo "user test"; echo "pass test"; echo "stat"; echo "quit"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any unencrypted POP3 email *user authentication attempt* (someone trying to log in), to a mail server on <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert4 %>". Up to three flags will be awarded, based on the quality of the rule.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>8-) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:( The alert did get triggered, but it fired only under some conditions. Is your rule caps sensitive?</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!--Email login attempt
|
||||
Tries a port scan, then connects twice once with caps, then lower, first with actual user, then incorrect creds, last 2 should trigger the rule
|
||||
-->
|
||||
<attack>
|
||||
<% $rand_alert4 = SecureRandom.hex(3)
|
||||
$flag1 = $flags.pop
|
||||
$flag2 = $flags.pop
|
||||
$flag3 = $flags.pop
|
||||
%>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p 110 <%= $web_server_ip %> > /dev/null; (sleep 1; echo "USER <%= $main_user %>"; echo "PASS <%= $main_user_pass %>"; echo "STAT"; echo "QUIT"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; (sleep 1; echo "user test"; echo "pass test"; echo "stat"; echo "quit"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any unencrypted POP3 email *user authentication attempt* (someone trying to log in), to a mail server on <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert4 %>". Up to three flags will be awarded, based on the quality of the rule.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*Classification.*User.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:-D Well done! ALL THREE FLAGS!: <%= $flag1 %>, <%= $flag2 %>, <%= $flag3 %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>8-) Well done! Two flags: <%= $flag1 %>, <%= $flag2 %>. Could be further improved with a classification.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:) Well done! <%= $flag1 %>. The alert did get triggered, but it fired only under some conditions. Is your rule caps sensitive? More flags are to be had from a better rule ;-)</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,34 @@
|
||||
<attack>
|
||||
<% $rand_alert5 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; curl <%= $web_server_ip %> >/dev/null; curl <%= $web_server_ip %>/contact.html >/dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects access to http://<%= $web_server_ip %> but NOT http://<%= $web_server_ip %>/contact.html. The alert must include the message "<%= $rand_alert5 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to test your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert5 %>.*<%= $rand_alert5 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert5 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,7 @@
|
||||
fixtures:
|
||||
repositories:
|
||||
"stdlib": "https://github.com/puppetlabs/puppetlabs-stdlib"
|
||||
"staging": "https://github.com/voxpupuli/puppet-staging"
|
||||
"translate": "https://github.com/puppetlabs/puppetlabs-translate"
|
||||
symlinks:
|
||||
"mysql": "#{source_dir}"
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"excludes": [
|
||||
"**/contrib/**",
|
||||
"**/examples/**",
|
||||
"**/tests/**",
|
||||
"**/spec/**",
|
||||
"**/pkg/**"
|
||||
]
|
||||
}
|
||||
5
modules/services/unix/database/mysql_stretch_compatible/mysql/.gitattributes
vendored
Normal file
5
modules/services/unix/database/mysql_stretch_compatible/mysql/.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#This file is generated by ModuleSync, do not edit.
|
||||
*.rb eol=lf
|
||||
*.erb eol=lf
|
||||
*.pp eol=lf
|
||||
*.sh eol=lf
|
||||
23
modules/services/unix/database/mysql_stretch_compatible/mysql/.gitignore
vendored
Normal file
23
modules/services/unix/database/mysql_stretch_compatible/mysql/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.*.sw[op]
|
||||
.metadata
|
||||
.yardoc
|
||||
.yardwarns
|
||||
*.iml
|
||||
/.bundle/
|
||||
/.idea/
|
||||
/.vagrant/
|
||||
/coverage/
|
||||
/bin/
|
||||
/doc/
|
||||
/Gemfile.local
|
||||
/Gemfile.lock
|
||||
/junit/
|
||||
/log/
|
||||
/log/
|
||||
/pkg/
|
||||
/spec/fixtures/manifests/
|
||||
/spec/fixtures/modules/
|
||||
/tmp/
|
||||
/vendor/
|
||||
/convert_report.txt
|
||||
.DS_Store
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
default_set: 'centos-64-x64'
|
||||
sets:
|
||||
'centos-59-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'centos-59-x64'
|
||||
'centos-64-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'centos-64-x64'
|
||||
'fedora-18-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'fedora-18-x64'
|
||||
'debian-607-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'debian-607-x64'
|
||||
'debian-70rc1-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'debian-70rc1-x64'
|
||||
'ubuntu-server-10044-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'ubuntu-server-10044-x64'
|
||||
'ubuntu-server-12042-x64':
|
||||
nodes:
|
||||
"main.foo.vm":
|
||||
prefab: 'ubuntu-server-12042-x64'
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>puppetlabs-mysql</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.puppetlabs.geppetto.pp.dsl.ui.modulefileBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.puppetlabs.geppetto.pp.dsl.ui.puppetNature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,2 @@
|
||||
--color
|
||||
--format documentation
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
require:
|
||||
- rubocop-i18n
|
||||
- rubocop-rspec
|
||||
AllCops:
|
||||
DisplayCopNames: true
|
||||
TargetRubyVersion: '2.1'
|
||||
Include:
|
||||
- "./**/*.rb"
|
||||
Exclude:
|
||||
- bin/*
|
||||
- ".vendor/**/*"
|
||||
- Gemfile
|
||||
- Rakefile
|
||||
- pkg/**/*
|
||||
- spec/fixtures/**/*
|
||||
- vendor/**/*
|
||||
Metrics/LineLength:
|
||||
Description: People have wide screens, use them.
|
||||
Max: 200
|
||||
RSpec/BeforeAfterAll:
|
||||
Description: Beware of using after(:all) as it may cause state to leak between tests.
|
||||
A necessary evil in acceptance testing.
|
||||
Exclude:
|
||||
- spec/acceptance/**/*.rb
|
||||
RSpec/HookArgument:
|
||||
Description: Prefer explicit :each argument, matching existing module's style
|
||||
EnforcedStyle: each
|
||||
Style/BlockDelimiters:
|
||||
Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to
|
||||
be consistent then.
|
||||
EnforcedStyle: braces_for_chaining
|
||||
Style/ClassAndModuleChildren:
|
||||
Description: Compact style reduces the required amount of indentation.
|
||||
EnforcedStyle: compact
|
||||
Style/EmptyElse:
|
||||
Description: Enforce against empty else clauses, but allow `nil` for clarity.
|
||||
EnforcedStyle: empty
|
||||
Style/FormatString:
|
||||
Description: Following the main puppet project's style, prefer the % format format.
|
||||
EnforcedStyle: percent
|
||||
Style/FormatStringToken:
|
||||
Description: Following the main puppet project's style, prefer the simpler template
|
||||
tokens over annotated ones.
|
||||
EnforcedStyle: template
|
||||
Style/Lambda:
|
||||
Description: Prefer the keyword for easier discoverability.
|
||||
EnforcedStyle: literal
|
||||
Style/RegexpLiteral:
|
||||
Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168
|
||||
EnforcedStyle: percent_r
|
||||
Style/TernaryParentheses:
|
||||
Description: Checks for use of parentheses around ternary conditions. Enforce parentheses
|
||||
on complex expressions for better readability, but seriously consider breaking
|
||||
it up.
|
||||
EnforcedStyle: require_parentheses_when_complex
|
||||
Style/TrailingCommaInArguments:
|
||||
Description: Prefer always trailing comma on multiline argument lists. This makes
|
||||
diffs, and re-ordering nicer.
|
||||
EnforcedStyleForMultiline: comma
|
||||
Style/TrailingCommaInLiteral:
|
||||
Description: Prefer always trailing comma on multiline literals. This makes diffs,
|
||||
and re-ordering nicer.
|
||||
EnforcedStyleForMultiline: comma
|
||||
Style/SymbolArray:
|
||||
Description: Using percent style obscures symbolic intent of array's contents.
|
||||
EnforcedStyle: brackets
|
||||
inherit_from: ".rubocop_todo.yml"
|
||||
Style/CollectionMethods:
|
||||
Enabled: true
|
||||
Style/MethodCalledOnDoEndBlock:
|
||||
Enabled: true
|
||||
Style/StringMethods:
|
||||
Enabled: true
|
||||
Layout/EndOfLine:
|
||||
Enabled: false
|
||||
Metrics/AbcSize:
|
||||
Enabled: false
|
||||
Metrics/BlockLength:
|
||||
Enabled: false
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
Metrics/CyclomaticComplexity:
|
||||
Enabled: false
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
Metrics/ParameterLists:
|
||||
Enabled: false
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: false
|
||||
RSpec/DescribeClass:
|
||||
Enabled: false
|
||||
RSpec/ExampleLength:
|
||||
Enabled: false
|
||||
RSpec/MessageExpectation:
|
||||
Enabled: false
|
||||
RSpec/MultipleExpectations:
|
||||
Enabled: false
|
||||
RSpec/NestedGroups:
|
||||
Enabled: false
|
||||
Style/AsciiComments:
|
||||
Enabled: false
|
||||
Style/IfUnlessModifier:
|
||||
Enabled: false
|
||||
Style/SymbolProc:
|
||||
Enabled: false
|
||||
@@ -0,0 +1,2 @@
|
||||
GetText/DecorateString:
|
||||
Enabled: false
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
appveyor.yml:
|
||||
environment:
|
||||
PUPPET_GEM_VERSION: "~> 4.0"
|
||||
matrix:
|
||||
- RUBY_VERSION: 24-x64
|
||||
CHECK: "syntax lint"
|
||||
- RUBY_VERSION: 24-x64
|
||||
CHECK: metadata_lint
|
||||
- RUBY_VERSION: 24-x64
|
||||
CHECK: rubocop
|
||||
|
||||
.travis.yml:
|
||||
bundle_args: --without system_tests
|
||||
docker_sets:
|
||||
- set: docker/centos-7
|
||||
options:
|
||||
- set: docker/ubuntu-14.04
|
||||
options:
|
||||
docker_defaults:
|
||||
bundler_args: ""
|
||||
secure: ""
|
||||
branches:
|
||||
- release
|
||||
extras:
|
||||
- rvm: 2.1.9
|
||||
script: "\"bundle exec rake release_checks\""
|
||||
|
||||
Gemfile:
|
||||
required:
|
||||
':system_tests':
|
||||
- gem: 'puppet-module-posix-system-r#{minor_version}'
|
||||
platforms: ruby
|
||||
- gem: 'puppet-module-win-system-r#{minor_version}'
|
||||
platforms:
|
||||
- mswin
|
||||
- mingw
|
||||
- x64_mingw
|
||||
- gem: beaker
|
||||
version: '~> 3.13'
|
||||
from_env: BEAKER_VERSION
|
||||
- gem: beaker-abs
|
||||
from_env: BEAKER_ABS_VERSION
|
||||
version: '~> 0.1'
|
||||
- gem: beaker-pe
|
||||
- gem: beaker-hostgenerator
|
||||
from_env: BEAKER_HOSTGENERATOR_VERSION
|
||||
- gem: beaker-rspec
|
||||
from_env: BEAKER_RSPEC_VERSION
|
||||
':development':
|
||||
- gem: puppet-blacksmith
|
||||
version: '~> 3.4'
|
||||
- gem: puppet-lint-i18n
|
||||
|
||||
Rakefile:
|
||||
requires:
|
||||
- puppet_blacksmith/rake_tasks
|
||||
- puppet_pot_generator/rake_tasks
|
||||
|
||||
spec/spec_helper.rb:
|
||||
spec_overrides:
|
||||
- "require 'spec_helper_local'"
|
||||
|
||||
.rubocop.yml:
|
||||
default_configs:
|
||||
inherit_from: .rubocop_todo.yml
|
||||
require:
|
||||
- rubocop-i18n
|
||||
- rubocop-rspec
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
sudo: false
|
||||
dist: trusty
|
||||
language: ruby
|
||||
cache: bundler
|
||||
before_install:
|
||||
- bundle -v
|
||||
- rm Gemfile.lock || true
|
||||
- gem update --system
|
||||
- gem --version
|
||||
- bundle -v
|
||||
script:
|
||||
- 'bundle exec rake $CHECK'
|
||||
bundler_args: --without system_tests
|
||||
rvm:
|
||||
- 2.4.1
|
||||
- 2.1.9
|
||||
env:
|
||||
- PUPPET_GEM_VERSION="~> 4.0" CHECK=spec
|
||||
- PUPPET_GEM_VERSION="~> 5.0" CHECK=spec
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
-
|
||||
bundler_args:
|
||||
dist: trusty
|
||||
env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/centos-7
|
||||
rvm: 2.4.1
|
||||
script: bundle exec rake beaker
|
||||
services: docker
|
||||
sudo: required
|
||||
-
|
||||
bundler_args:
|
||||
dist: trusty
|
||||
env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/ubuntu-14.04
|
||||
rvm: 2.4.1
|
||||
script: bundle exec rake beaker
|
||||
services: docker
|
||||
sudo: required
|
||||
-
|
||||
env: CHECK=rubocop
|
||||
-
|
||||
env: CHECK="syntax lint"
|
||||
-
|
||||
env: CHECK=metadata_lint
|
||||
-
|
||||
rvm: 2.1.9
|
||||
script: "bundle exec rake release_checks"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^v\d/
|
||||
- release
|
||||
notifications:
|
||||
email: false
|
||||
deploy:
|
||||
provider: puppetforge
|
||||
user: puppet
|
||||
password:
|
||||
secure: ""
|
||||
on:
|
||||
tags: true
|
||||
all_branches: true
|
||||
condition: "$DEPLOY_TO_FORGE = yes"
|
||||
@@ -0,0 +1,885 @@
|
||||
# Change log
|
||||
|
||||
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org).
|
||||
|
||||
## Supported Release [5.3.0]
|
||||
### Summary
|
||||
This release uses the PDK convert functionality which in return makes the module PDK compliant. It also includes a roll up of maintenance changes, a new task and support for `GRANTS FUNCTION`.
|
||||
|
||||
### Added
|
||||
- Add support for `GRANTS FUNCTION` ([MODULES-2075](https://tickets.puppet.com/browse/MODULES-2075)).
|
||||
- Add Export database task.
|
||||
- PDK Convert mysql ([MODULES-6454](https://tickets.puppet.com/browse/MODULES-6454)).
|
||||
|
||||
### Changed
|
||||
- Allow authentication plugin to be changed.
|
||||
- Update mysql_user provider.
|
||||
- Plugins don't exist before 5.5; password field name changed
|
||||
- Fix helpful rubocops and disable hurtful cops.
|
||||
- Addressing puppet-lint and rubocop errors
|
||||
- Remove update bundler and add ignore .DS_Store
|
||||
- Skip rubocop warning in task.
|
||||
- Fix a typo in a classname in the changelog.
|
||||
|
||||
## Supported Release [5.2.1]
|
||||
### Summary
|
||||
This release fixes CVE-2018-6508 which is a potential arbitrary code execution via tasks.
|
||||
|
||||
### Fixed
|
||||
- Fix export and mysql tasks for arbitrary remote code
|
||||
|
||||
## Supported Release [5.2.0]
|
||||
|
||||
### Added
|
||||
- Compatibility for puppet-staging 3.0.0
|
||||
|
||||
### Fixed
|
||||
- Centralize all mysql command calls for providers
|
||||
- Add paths to `mysql_datadir` provider for RedHat Software Collections
|
||||
|
||||
## Supported Release [5.1.0]
|
||||
### Summary
|
||||
This release adds Tasks to the Mysql module.
|
||||
|
||||
#### Added
|
||||
- Adds the execute sql task.
|
||||
|
||||
## Supported Release [5.0.0]
|
||||
### Summary
|
||||
This is a major release that adds support for string translation. Currently the only supported language besides
|
||||
English is Japanese.
|
||||
|
||||
#### Added
|
||||
- Several gem dependencies required for translation.
|
||||
- Wrapping of strings that require translation. Strings in ruby code are now wrapped with `_()` and strings in puppet code with `translate()`.
|
||||
- Debian 9 support
|
||||
|
||||
#### Changed
|
||||
- The default php_package_name for Debian and Ubuntu to `php-mysql`
|
||||
|
||||
## Supported Release 4.0.1
|
||||
### Summary
|
||||
This is a small bugfix release that makes `mysql_install_db` optional and fixes some regular expression issues.
|
||||
|
||||
#### Bugfixes
|
||||
- ([MODULES-5528](https://tickets.puppet.com/browse/MODULES-5528)) Fixes the `mysql_install_db` command so that it is optional
|
||||
- ([MODULES-5602](https://tickets.puppet.com/browse/MODULES-5602)) Removes superfluous backslashes in some regular expressions that were causing instability
|
||||
|
||||
## Supported Release 4.0.0
|
||||
### Summary
|
||||
This release sees the enablement of rubocop, also an update to the lib directory with rubocop fixes and several other changes and fixes. Also a bump to the Puppet version compatibility and several Puppet language updates.
|
||||
|
||||
#### Added
|
||||
- Updated README.md with example how to install MySQL Community Server 5.6 on Centos 7.3
|
||||
- Enabled Rubocop and addition of Rubocop fixes for /lib directory.
|
||||
|
||||
#### Removed
|
||||
- Dropped legacy tests for db.pp.
|
||||
|
||||
#### Changed
|
||||
- Replaced validate function calls with datatypes in db.pp.
|
||||
- Bumped recommended puppet version to between 4.7.0 and 6.0.0.
|
||||
- Conditionalize name validation in mysql_grant type. ([MODULES-4604](https://tickets.puppet.com/browse/MODULES-4604))
|
||||
|
||||
#### Fixed
|
||||
- Removal of invalid parameter provider on Mysql_user[user@localhost] in mysql::db ([MODULES-4115](https://tickets.puppet.com/browse/MODULES-4115))
|
||||
- Fixed server_service_name for Debian/stretch.
|
||||
- Spec fixes for Puppet 5.
|
||||
- Test update for fix:create procedure, then grant ([MODULES-5390](https://tickets.puppet.com/browse/MODULES-5390))
|
||||
- Fixing empty user/password issue for xtrabackup. Now defaults as undef instead of ''.
|
||||
- Remove unsupported Ubuntu versions ([MODULES-5501](https://tickets.puppet.com/browse/MODULES-5501))
|
||||
|
||||
## Supported Release 3.11.0
|
||||
### Summary
|
||||
This release includes README and metadata translations to Japanese, as well as some enhancements and bugfixes.
|
||||
|
||||
#### Added
|
||||
- New flag for successful backups
|
||||
- Solaris support improvements
|
||||
- New parameter `optional_args` for extra innobackupex options
|
||||
- Specify environment variables (e.g. https_proxy) for MySQLTuner download.
|
||||
- Check to only install bzip2 if `$backupcompress` is `true`
|
||||
- Debian 9 compatibility
|
||||
- Japanese README
|
||||
|
||||
#### Fixed
|
||||
- Syntax errors
|
||||
- Bug where error logs were being created before the datadir was initialized (MODULES-4743)
|
||||
|
||||
## Supported Release 3.10.0
|
||||
### Summary
|
||||
This release includes new features for setting TLS options on a mysql user, a new parameter to allow specifying tool to import sql files, as well as various bugfixes.
|
||||
|
||||
#### Features
|
||||
- (MODULES-3879) Adds `import_cat_cmd` parameter to specify the command to read sql files
|
||||
- Adds support for setting `tls_options` in `mysql_user`
|
||||
|
||||
#### Bugfixes
|
||||
- (MODULES-3557) Adds Ubuntu 16.04 package names for language bindings
|
||||
- (MODULES-3907) Adds MySQL/Percona 5.7 initialize on fresh deploy
|
||||
|
||||
## Supported Release 3.9.0
|
||||
### Summary
|
||||
This release adds Percona 5.7 support and compatibility with Ubuntu 16.04, in addition to various bugfixes.
|
||||
|
||||
#### Features
|
||||
- (MODULES-3441) Adds the `mysqld_version` fact
|
||||
- (MODULES-3513) Adds a new backup dump parameter `maxallowedpacket`
|
||||
- Adds new parameter `xtrabackup_package_name` to `mysql::backup::xtrabackup` class
|
||||
- Adds ability to revoke GRANT privilege
|
||||
|
||||
#### Bugfixes
|
||||
- Fixes a bug where `mysql_user` fails if facter cannot retrieve fqdn.
|
||||
- Fix global parameter usage in backup script
|
||||
- Adds support for `puppet-staging` version `2.0.0`
|
||||
- (MODULES-3601) Moves binary logging configuration to take place after package install
|
||||
- (MODULES-3711) Add limit to mysql server ID generated value
|
||||
- (MODULES-3698) Fixes defaults for SLES12
|
||||
- Updates user name length restrictions for MySQL version 5.7.8 and above.
|
||||
- Fixes a bug where error log is not writable by owner
|
||||
|
||||
## Supported Release 3.8.0
|
||||
### Summary
|
||||
This release adds Percona 5.7 support and compatibility with Ubuntu 16.04, in addition to various bugfixes.
|
||||
|
||||
#### Features
|
||||
- Adds support for Percona 5.7
|
||||
- Adds support for Ubuntu 16.04 (Xenial)
|
||||
|
||||
#### Known Limitations
|
||||
- The mysqlbackup.sh script will not work on MySQL 5.7.0 and up.
|
||||
|
||||
#### Bugfixes
|
||||
- Use mysql_install_db only with uniq defaults-extra-file
|
||||
- Updates mysqlbackup.sh to ensure backup directory exist
|
||||
- Loosen MariaDB recognition to fix it on Debian 8
|
||||
- Allow mysql::backup::mysqldump to access root_group in tests
|
||||
- Fixed problem with ignoring parameters from global configs
|
||||
- Fixes ordering issue that initialized mysqld before config is set
|
||||
- (MODULES-1256) Fix parameters on OpenSUSE 12
|
||||
- Fixes install errors on Debian-based OS by configuring the base of includedir
|
||||
- Configure the configfile location for mariadb
|
||||
- Default mysqld_type return value should be 'mysql' if another type is not detected
|
||||
- Make sure that bzip2 is installed before setting up the cron tab job using mysqlbackup.sh
|
||||
- Fixes path issue on FreeBSD
|
||||
- Check that /var/lib/mysql actually contains files
|
||||
- Removes mysql regex when checking type
|
||||
- (MODULES-2111) Add the system database to user related actions
|
||||
- Updates default group for logfiles on Debian-based OS to 'adm'
|
||||
- Fixes an issue with Amazon linux major release 4 installation
|
||||
- Fixes 'mysql_install_db' script support on Gentoo
|
||||
- Removes erroneous anchors to mysql::client from mysql::db
|
||||
- Adds path to be able to find MySQL 5.5 installation on CentOS
|
||||
|
||||
## Supported Release 3.7.0
|
||||
### Summary
|
||||
|
||||
A large release with several new features. Also includes a considerable amount of bugfixes, many around compatibility and improvements to current functionality.
|
||||
|
||||
#### Features
|
||||
|
||||
- Now uses mariadb in OpenSuSE >= 13.1.
|
||||
- Switch to rspec-puppet-facts.
|
||||
- Additional function to check if table exists before grant.
|
||||
- Add ability to input password hash directly.
|
||||
- Now checking major release instead of specific release.
|
||||
- Debian 8 support.
|
||||
|
||||
#### Bugfixes
|
||||
|
||||
- Minor doc update.
|
||||
- Fixes improper use of function `warn` in backup manifest of server.
|
||||
- Fixes to Compatibility with PE 3.3.
|
||||
- Fixes `when not managing config file` in `mysql_server_spec`.
|
||||
- Improved user validation and munging.
|
||||
- Fixes fetching the mysql_user password for MySQL >=5.7.6.
|
||||
- Fixes unique server_id within my.cnf, the issue were the entire mac address was not being read in to generate the id.
|
||||
- Corrects the daemon_dev_package_name for mariadb on redhat.
|
||||
- Fix version compare to properly suppress show_diff for root password.
|
||||
- Fixes to ensure compatibility with future parser.
|
||||
- Solaris removed from PE in metadata as its not supported.
|
||||
- Use MYSQL_PWD to avoid mysqldump warnings.
|
||||
- Use temp cnf file instead of env variable which creates acceptance test failures.
|
||||
- No longer hash passwords that are already hashed.
|
||||
- Fix Gemfile to work with ruby 1.8.7.
|
||||
- Fixed MySQL 5.7.6++ compatibility.
|
||||
- Fixing error when disabling service management and the service does not exist.
|
||||
- Ubuntu vivid should use systemd not upstart.
|
||||
- Fixed new mysql_datadir provider on CentOS for MySQl 5.7.6 compatibility.
|
||||
- Ensure if service restart to wait till mysql is up.
|
||||
- Move all dependencies to not have them in case of service unmanaged.
|
||||
- Re-Added the ability to set a empty string as option parameter.
|
||||
- Fixes edge-case with dropping pre-existing users with grants.
|
||||
- Fix logic for choosing rspec version.
|
||||
- Refactored main acceptance suite.
|
||||
- Skip idempotency tests on test cells that do have PUP-5016 unfixed.
|
||||
- Fix tmpdir to be shared across examples.
|
||||
- Update to current msync configs [006831f].
|
||||
- Fix mysql_grant with MySQL ANSI_QUOTES mode.
|
||||
- Generate .my.cnf for all sections.
|
||||
|
||||
## Supported Release 3.6.2
|
||||
### Summary
|
||||
|
||||
Small release for support of newer PE versions. This increments the version of PE in the metadata.json file.
|
||||
|
||||
## 2015-09-22 - Supported Release 3.6.1
|
||||
### Summary
|
||||
This is a security and bugfix release that fixes incorrect username truncation in the munge for the mysql_user type, incorrect function used in `mysql::server::backup` and fixes compatibility issues with PE 3.3.x.
|
||||
|
||||
#### Bugfixes
|
||||
- Loosen the regex in mysql_user munging so the username is not unintentionally truncated.
|
||||
- Use `warning()` not `warn()`
|
||||
- Metadata had inadvertantly dropped 3.3.x support
|
||||
- Some 3.3.x compatibility issues in `mysqltuner` were corrected
|
||||
|
||||
## 2015-08-10 - Supported Release 3.6.0
|
||||
### Summary
|
||||
This release adds the ability to use mysql::db and `mysql_*` types against unmanaged or external mysql instances.
|
||||
|
||||
#### Features
|
||||
- Add ability to use mysql::db WITHOUT mysql::server (ie, externally)
|
||||
- Add prescript attribute to mysql::server::backup for xtrabackup
|
||||
- Add postscript ability to xtrabackup provider.
|
||||
|
||||
#### Bugfixes
|
||||
- Fix default root passwords blocking puppet on mysql 5.8
|
||||
- Fix service dependency when package_manage is false
|
||||
- Fix selinux permissions on my.cnf
|
||||
|
||||
## 2015-07-23 - Supported Release 3.5.0
|
||||
### Summary
|
||||
A small release to add explicit support to newer Puppet versions and accumulated patches.
|
||||
|
||||
#### Features/Improvements
|
||||
- Start running tests against puppet 4
|
||||
- Support longer usernames on newer MariaDB versions
|
||||
- Add parameters for Solaris 11 and 12
|
||||
|
||||
#### Bugfixes
|
||||
- Fix references to the mysql-server package
|
||||
- mysql_server_id doesn't throw and error on machines without macaddress
|
||||
|
||||
## 2015-05-19 - Supported Release 3.4.0
|
||||
### Summary
|
||||
This release includes the addition of extra facts, OpenBSD compatibility, and a number of other features, improvements and bug fixes.
|
||||
|
||||
#### Features/Improvements
|
||||
- Added server_id fact which includes mac address for better uniqueness
|
||||
- Added OpenBSD compatibility, only for 'OpenBSD -current' (due to the recent switch to mariadb)
|
||||
- Added a $mysql_group parameter, and use that instead of the $root_group parameter to define the group membership of the mysql error log file.
|
||||
- Updated tests for rspec-puppet 2 and future parser
|
||||
- Further acceptance testing improvements
|
||||
- MODULES-1928 - allow log-error to be undef
|
||||
- Split package installation and database install
|
||||
- README wording improvements
|
||||
- Added options for including/excluding triggers and routines
|
||||
- Made the 'TRIGGER' privilege of mysqldump backups depend on whether or not we are actually backing up triggers
|
||||
- Cleaned up the privilege assignment in the mysqldump backup script
|
||||
- Add a fact for capturing the mysql version installed
|
||||
|
||||
#### Bugfixes
|
||||
- mysql backup: fix regression in mysql_user call
|
||||
- Set service_ensure to undef, in the case of an unmanaged service
|
||||
- README Typos fixed
|
||||
- Bugfix on Xtrabackup crons
|
||||
- Fixed a permission problem that was preventing triggers from being backed up
|
||||
- MODULES-1981: Revoke and grant difference of old and new privileges
|
||||
- Fix an issue were we assume triggers work
|
||||
- Change default for mysql::server::backup to ignore_triggers = false
|
||||
|
||||
#### Deprecations
|
||||
mysql::server::old_root_password property
|
||||
|
||||
## 2015-03-03 - Supported Release 3.3.0
|
||||
### Summary
|
||||
This release includes major README updates, the addition of backup providers, and a fix for managing the log-bin directory.
|
||||
|
||||
#### Features
|
||||
- Add package_manage parameters to `mysql::server` and `mysql::client` (MODULES-1143)
|
||||
- README improvements
|
||||
- Add `mysqldump`, `mysqlbackup`, and `xtrabackup` backup providers.
|
||||
|
||||
#### Bugfixes
|
||||
- log-error overrides were not being properly used (MODULES-1804)
|
||||
- check for full path for log-bin to stop puppet from managing file '.'
|
||||
|
||||
## 2015-02-09 - Supported Release 3.2.0
|
||||
### Summary
|
||||
This release includes several new features and bugfixes, including support for various plugins, making the output from mysql_password more consistent when input is empty and improved username validation.
|
||||
|
||||
#### Features
|
||||
- Add type and provider to manage plugins
|
||||
- Add support for authentication plugins
|
||||
- Add support for mysql_install_db on freebsd
|
||||
- Add `create_root_user` and `create_root_my_cnf` parameters to `mysql::server`
|
||||
|
||||
#### Bugfixes
|
||||
- Remove dependency on stdlib >= 4.1.0 (MODULES-1759)
|
||||
- Make grant autorequire user
|
||||
- Remove invalid parameter 'provider' from mysql_user instance (MODULES-1731)
|
||||
- Return empty string for empty input in mysql_password
|
||||
- Fix `mysql::account_security` when fqdn==localhost
|
||||
- Update username validation (MODULES-1520)
|
||||
- Future parser fix in params.pp
|
||||
- Fix package name for debian 8
|
||||
- Don't start the service until the server package is installed and the config file is in place
|
||||
- Test fixes
|
||||
- Lint fixes
|
||||
|
||||
## 2014-12-16 - Supported Release 3.1.0
|
||||
### Summary
|
||||
|
||||
This release includes several new features, including SLES12 support, and a number of bug fixes.
|
||||
|
||||
#### Notes
|
||||
|
||||
`mysql::server::mysqltuner` has been refactored to fetch the mysqltuner script from github by default. If you are running on a non-network-connected system, you will need to download that file and have it available to your node at a path specified by the `source` parameter to the `mysqltuner` class.
|
||||
|
||||
#### Features
|
||||
- Add support for install_options for all package resources (MODULES-1484)
|
||||
- Add log-bin directory creation
|
||||
- Allow mysql::db to import multiple files (MODULES-1338)
|
||||
- SLES12 support
|
||||
- Improved identifier quoting detections
|
||||
- Reworked `mysql::server::mysqltuner` so that we are no longer packaging the script as it is licensed under the GPL.
|
||||
|
||||
#### Bugfixes
|
||||
- Fix regression in username validation
|
||||
- Proper containment for mysql::client in mysql::db
|
||||
- Support quoted usernames of length 15 and 16 chars
|
||||
|
||||
## 2014-11-11 - Supported Release 3.0.0
|
||||
### Summary
|
||||
|
||||
Added several new features including MariaDB support and future parser
|
||||
|
||||
#### Backwards-incompatible Changes
|
||||
* Remove the deprecated `database`, `database_user`, and `database_grant` resources. The correct resources to use are `mysql`, `mysql_user`, and `mysql_grant` respectively.
|
||||
|
||||
#### Features
|
||||
* Add MariaDB Support
|
||||
* The mysqltuner perl script has been updated to 1.3.0 based on work at http://github.com/major/MySQLTuner-perl
|
||||
* Add future parse support, fixed issues with undef to empty string
|
||||
* Pass the backup credentials to 'SHOW DATABASES'
|
||||
* Ability to specify the Includedir for `mysql::server`
|
||||
* `mysql::db` now has an import\_timeout feature that defaults to 300
|
||||
* The `mysql` class has been removed
|
||||
* `mysql::server` now takes an `override_options` hash that will affect the installation
|
||||
* Ability to install both dev and client dev
|
||||
|
||||
#### BugFix
|
||||
* `mysql::server::backup` now passes `ensure` param to the nested `mysql_grant`
|
||||
* `mysql::server::service` now properly requires the presence of the `log_error` file
|
||||
* `mysql::config` now occurs before `mysql::server::install_db` correctly
|
||||
|
||||
## 2014-07-15 - Supported Release 2.3.1
|
||||
### Summary
|
||||
|
||||
This release merely updates metadata.json so the module can be uninstalled and
|
||||
upgraded via the puppet module command.
|
||||
|
||||
## 2014-05-14 - Supported Release 2.3.0
|
||||
|
||||
This release primarily adds support for RHEL7 and Ubuntu 14.04 but it
|
||||
also adds a couple of new parameters to allow for further customization,
|
||||
as well as ensuring backups can backup stored procedures properly.
|
||||
|
||||
#### Features
|
||||
Added `execpath` to allow a custom executable path for non-standard mysql installations.
|
||||
Added `dbname` to mysql::db and use ensure_resource to create the resource.
|
||||
Added support for RHEL7 and Fedora Rawhide.
|
||||
Added support for Ubuntu 14.04.
|
||||
Create a warning for if you disable SSL.
|
||||
Ensure the error logfile is owned by MySQL.
|
||||
Disable ssl on FreeBSD.
|
||||
Add PROCESS privilege for backups.
|
||||
|
||||
#### Bugfixes
|
||||
|
||||
#### Known Bugs
|
||||
* No known bugs
|
||||
|
||||
## 2014-03-04 - Supported Release 2.2.3
|
||||
### Summary
|
||||
|
||||
This is a supported release. This release removes a testing symlink that can
|
||||
cause trouble on systems where /var is on a seperate filesystem from the
|
||||
modulepath.
|
||||
|
||||
#### Features
|
||||
#### Bugfixes
|
||||
#### Known Bugs
|
||||
* No known bugs
|
||||
|
||||
## 2014-03-04 - Supported Release 2.2.2
|
||||
### Summary
|
||||
This is a supported release. Mostly comprised of enhanced testing, plus a
|
||||
bugfix for Suse.
|
||||
|
||||
#### Bugfixes
|
||||
- PHP bindings on Suse
|
||||
- Test fixes
|
||||
|
||||
#### Known Bugs
|
||||
* No known bugs
|
||||
|
||||
## 2014-02-19 - Version 2.2.1
|
||||
|
||||
### Summary
|
||||
|
||||
Minor release that repairs mysql_database{} so that it sees the correct
|
||||
collation settings (it was only checking the global mysql ones, not the
|
||||
actual database and constantly setting it over and over since January 22nd).
|
||||
|
||||
Also fixes a bunch of tests on various platforms.
|
||||
|
||||
|
||||
## 2014-02-13 - Version 2.2.0
|
||||
|
||||
### Summary
|
||||
|
||||
#### Features
|
||||
- Add `backupdirmode`, `backupdirowner`, `backupdirgroup` to
|
||||
mysql::server::backup to allow customizing the mysqlbackupdir.
|
||||
- Support multiple options of the same name, allowing you to
|
||||
do 'replicate-do-db' => ['base1', 'base2', 'base3'] in order to get three
|
||||
lines of replicate-do-db = base1, replicate-do-db = base2 etc.
|
||||
|
||||
#### Bugfixes
|
||||
- Fix `restart` so it actually stops mysql restarting if set to false.
|
||||
- DRY out the defaults_file functionality in the providers.
|
||||
- mysql_grant fixed to work with root@localhost/@.
|
||||
- mysql_grant fixed for WITH MAX_QUERIES_PER_HOUR
|
||||
- mysql_grant fixed so revoking all privileges accounts for GRANT OPTION
|
||||
- mysql_grant fixed to remove duplicate privileges.
|
||||
- mysql_grant fixed to handle PROCEDURES when removing privileges.
|
||||
- mysql_database won't try to create existing databases, breaking replication.
|
||||
- bind_address renamed bind-address in 'mysqld' options.
|
||||
- key_buffer renamed to key_buffer_size.
|
||||
- log_error renamed to log-error.
|
||||
- pid_file renamed to pid-file.
|
||||
- Ensure mysql::server::root_password runs before mysql::server::backup
|
||||
- Fix options_override -> override_options in the README.
|
||||
- Extensively rewrite the README to be accurate and awesome.
|
||||
- Move to requiring stdlib 3.2.0, shipped in PE3.0
|
||||
- Add many new tests.
|
||||
|
||||
|
||||
## 2013-11-13 - Version 2.1.0
|
||||
|
||||
### Summary
|
||||
|
||||
The most important changes in 2.1.0 are improvements to the my.cnf creation,
|
||||
as well as providers. Setting options to = true strips them to be just the
|
||||
key name itself, which is required for some options.
|
||||
|
||||
The provider updates fix a number of bugs, from lowercase privileges to
|
||||
deprecation warnings.
|
||||
|
||||
Last, the new hiera integration functionality should make it easier to
|
||||
externalize all your grants, users, and, databases. Another great set of
|
||||
community submissions helped to make this release.
|
||||
|
||||
#### Features
|
||||
- Some options can not take a argument. Gets rid of the '= true' when an
|
||||
option is set to true.
|
||||
- Easier hiera integration: Add hash parameters to mysql::server to allow
|
||||
specifying grants, users, and databases.
|
||||
|
||||
#### Bugfixes
|
||||
- Fix an issue with lowercase privileges in mysql_grant{} causing them to be reapplied needlessly.
|
||||
- Changed defaults-file to defaults-extra-file in providers.
|
||||
- Ensure /root/.my.cnf is 0600 and root owned.
|
||||
- database_user deprecation warning was incorrect.
|
||||
- Add anchor pattern for client.pp
|
||||
- Documentation improvements.
|
||||
- Various test fixes.
|
||||
|
||||
|
||||
## 2013-10-21 - Version 2.0.1
|
||||
|
||||
### Summary
|
||||
|
||||
This is a bugfix release to handle an issue where unsorted mysql_grant{}
|
||||
privileges could cause Puppet to incorrectly reapply the permissions on
|
||||
each run.
|
||||
|
||||
#### Bugfixes
|
||||
- Mysql_grant now sorts privileges in the type and provider for comparison.
|
||||
- Comment and test tweak for PE3.1.
|
||||
|
||||
|
||||
## 2013-10-14 - Version 2.0.0
|
||||
|
||||
### Summary
|
||||
|
||||
(Previously detailed in the changelog for 2.0.0-rc1)
|
||||
|
||||
This module has been completely refactored and works significantly different.
|
||||
The changes are broad and touch almost every piece of the module.
|
||||
|
||||
See the README.md for full details of all changes and syntax.
|
||||
Please remain on 1.0.0 if you don't have time to fully test this in dev.
|
||||
|
||||
* mysql::server, mysql::client, and mysql::bindings are the primary interface
|
||||
classes.
|
||||
* mysql::server takes an `override_options` parameter to set my.cnf options,
|
||||
with the hash format: { 'section' => { 'thing' => 'value' }}
|
||||
* mysql attempts backwards compatibility by forwarding all parameters to
|
||||
mysql::server.
|
||||
|
||||
|
||||
## 2013-10-09 - Version 2.0.0-rc5
|
||||
|
||||
### Summary
|
||||
|
||||
Hopefully the final rc! Further fixes to mysql_grant (stripping out the
|
||||
cleverness so we match a much wider range of input.)
|
||||
|
||||
#### Bugfixes
|
||||
- Make mysql_grant accept '.*'@'.*' in terms of input for user@host.
|
||||
|
||||
|
||||
## 2013-10-09 - Version 2.0.0-rc4
|
||||
|
||||
### Summary
|
||||
|
||||
Bugfixes to mysql_grant and mysql_user form the bulk of this rc, as well as
|
||||
ensuring that values in the override_options hash that contain a value of ''
|
||||
are created as just "key" in the conf rather than "key =" or "key = false".
|
||||
|
||||
#### Bugfixes
|
||||
- Improve mysql_grant to work with IPv6 addresses (both long and short).
|
||||
- Ensure @host users work as well as user@host users.
|
||||
- Updated my.cnf template to support items with no values.
|
||||
|
||||
|
||||
## 2013-10-07 - Version 2.0.0-rc3
|
||||
|
||||
### Summary
|
||||
Fix mysql::server::monitor's use of mysql_user{}.
|
||||
|
||||
#### Bugfixes
|
||||
- Fix myql::server::monitor's use of mysql_user{} to grant the proper
|
||||
permissions. Add specs as well. (Thanks to treydock!)
|
||||
|
||||
|
||||
## 2013-10-03 - Version 2.0.0-rc2
|
||||
|
||||
### Summary
|
||||
Bugfixes
|
||||
|
||||
#### Bugfixes
|
||||
- Fix a duplicate parameter in mysql::server
|
||||
|
||||
|
||||
## 2013-10-03 - Version 2.0.0-rc1
|
||||
|
||||
### Summary
|
||||
|
||||
This module has been completely refactored and works significantly different.
|
||||
The changes are broad and touch almost every piece of the module.
|
||||
|
||||
See the README.md for full details of all changes and syntax.
|
||||
Please remain on 1.0.0 if you don't have time to fully test this in dev.
|
||||
|
||||
* mysql::server, mysql::client, and mysql::bindings are the primary interface
|
||||
classes.
|
||||
* mysql::server takes an `override_options` parameter to set my.cnf options,
|
||||
with the hash format: { 'section' => { 'thing' => 'value' }}
|
||||
* mysql attempts backwards compatibility by forwarding all parameters to
|
||||
mysql::server.
|
||||
|
||||
---
|
||||
## 2013-09-23 - Version 1.0.0
|
||||
|
||||
### Summary
|
||||
|
||||
This release introduces a number of new type/providers, to eventually
|
||||
replace the database_ ones. The module has been converted to call the
|
||||
new providers rather than the previous ones as they have a number of
|
||||
fixes, additional options, and work with puppet resource.
|
||||
|
||||
This 1.0.0 release precedes a large refactoring that will be released
|
||||
almost immediately after as 2.0.0.
|
||||
|
||||
#### Features
|
||||
- Added mysql_grant, mysql_database, and mysql_user.
|
||||
- Add `mysql::bindings` class and refactor all other bindings to be contained underneath mysql::bindings:: namespace.
|
||||
- Added support to back up specified databases only with 'mysqlbackup' parameter.
|
||||
- Add option to mysql::backup to set the backup script to perform a mysqldump on each database to its own file
|
||||
|
||||
#### Bugfixes
|
||||
- Update my.cnf.pass.erb to allow custom socket support
|
||||
- Add environment variable for .my.cnf in mysql::db.
|
||||
- Add HOME environment variable for .my.cnf to mysqladmin command when
|
||||
(re)setting root password
|
||||
|
||||
---
|
||||
## 2013-07-15 - Version 0.9.0
|
||||
#### Features
|
||||
- Add `mysql::backup::backuprotate` parameter
|
||||
- Add `mysql::backup::delete_before_dump` parameter
|
||||
- Add `max_user_connections` attribute to `database_user` type
|
||||
|
||||
#### Bugfixes
|
||||
- Add client package dependency for `mysql::db`
|
||||
- Remove duplicate `expire_logs_days` and `max_binlog_size` settings
|
||||
- Make root's `.my.cnf` file path dynamic
|
||||
- Update pidfile path for Suse variants
|
||||
- Fixes for lint
|
||||
|
||||
## 2013-07-05 - Version 0.8.1
|
||||
#### Bugfixes
|
||||
- Fix a typo in the Fedora 19 support.
|
||||
|
||||
## 2013-07-01 - Version 0.8.0
|
||||
#### Features
|
||||
- mysql::perl class to install perl-DBD-mysql.
|
||||
- minor improvements to the providers to improve reliability
|
||||
- Install the MariaDB packages on Fedora 19 instead of MySQL.
|
||||
- Add new `mysql` class parameters:
|
||||
- `max_connections`: The maximum number of allowed connections.
|
||||
- `manage_config_file`: Opt out of puppetized control of my.cnf.
|
||||
- `ft_min_word_len`: Fine tune the full text search.
|
||||
- `ft_max_word_len`: Fine tune the full text search.
|
||||
- Add new `mysql` class performance tuning parameters:
|
||||
- `key_buffer`
|
||||
- `thread_stack`
|
||||
- `thread_cache_size`
|
||||
- `myisam-recover`
|
||||
- `query_cache_limit`
|
||||
- `query_cache_size`
|
||||
- `max_connections`
|
||||
- `tmp_table_size`
|
||||
- `table_open_cache`
|
||||
- `long_query_time`
|
||||
- Add new `mysql` class replication parameters:
|
||||
- `server_id`
|
||||
- `sql_log_bin`
|
||||
- `log_bin`
|
||||
- `max_binlog_size`
|
||||
- `binlog_do_db`
|
||||
- `expire_logs_days`
|
||||
- `log_bin_trust_function_creators`
|
||||
- `replicate_ignore_table`
|
||||
- `replicate_wild_do_table`
|
||||
- `replicate_wild_ignore_table`
|
||||
- `expire_logs_days`
|
||||
- `max_binlog_size`
|
||||
|
||||
#### Bugfixes
|
||||
- No longer restart MySQL when /root/.my.cnf changes.
|
||||
- Ensure mysql::config runs before any mysql::db defines.
|
||||
|
||||
## 2013-06-26 - Version 0.7.1
|
||||
#### Bugfixes
|
||||
- Single-quote password for special characters
|
||||
- Update travis testing for puppet 3.2.x and missing Bundler gems
|
||||
|
||||
## 2013-06-25 - Version 0.7.0
|
||||
This is a maintenance release for community bugfixes and exposing
|
||||
configuration variables.
|
||||
|
||||
* Add new `mysql` class parameters:
|
||||
- `basedir`: The base directory mysql uses
|
||||
- `bind_address`: The IP mysql binds to
|
||||
- `client_package_name`: The name of the mysql client package
|
||||
- `config_file`: The location of the server config file
|
||||
- `config_template`: The template to use to generate my.cnf
|
||||
- `datadir`: The directory MySQL's datafiles are stored
|
||||
- `default_engine`: The default engine to use for tables
|
||||
- `etc_root_password`: Whether or not to add the mysql root password to
|
||||
/etc/my.cnf
|
||||
- `java_package_name`: The name of the java package containing the java
|
||||
connector
|
||||
- `log_error`: Where to log errors
|
||||
- `manage_service`: Boolean dictating if mysql::server should manage the
|
||||
service
|
||||
- `max_allowed_packet`: Maximum network packet size mysqld will accept
|
||||
- `old_root_password`: Previous root user password
|
||||
- `php_package_name`: The name of the phpmysql package to install
|
||||
- `pidfile`: The location mysql will expect the pidfile to be
|
||||
- `port`: The port mysql listens on
|
||||
- `purge_conf_dir`: Value fed to recurse and purge parameters of the
|
||||
/etc/mysql/conf.d resource
|
||||
- `python_package_name`: The name of the python mysql package to install
|
||||
- `restart`: Whether to restart mysqld
|
||||
- `root_group`: Use specified group for root-owned files
|
||||
- `root_password`: The root MySQL password to use
|
||||
- `ruby_package_name`: The name of the ruby mysql package to install
|
||||
- `ruby_package_provider`: The installation suite to use when installing the
|
||||
ruby package
|
||||
- `server_package_name`: The name of the server package to install
|
||||
- `service_name`: The name of the service to start
|
||||
- `service_provider`: The name of the service provider
|
||||
- `socket`: The location of the MySQL server socket file
|
||||
- `ssl_ca`: The location of the SSL CA Cert
|
||||
- `ssl_cert`: The location of the SSL Certificate to use
|
||||
- `ssl_key`: The SSL key to use
|
||||
- `ssl`: Whether or not to enable ssl
|
||||
- `tmpdir`: The directory MySQL's tmpfiles are stored
|
||||
* Deprecate `mysql::package_name` parameter in favor of
|
||||
`mysql::client_package_name`
|
||||
* Fix local variable template deprecation
|
||||
* Fix dependency ordering in `mysql::db`
|
||||
* Fix ANSI quoting in queries
|
||||
* Fix travis support (but still messy)
|
||||
* Fix typos
|
||||
|
||||
## 2013-01-11 - Version 0.6.1
|
||||
* Fix providers when /root/.my.cnf is absent
|
||||
|
||||
## 2013-01-09 - Version 0.6.0
|
||||
* Add `mysql::server::config` define for specific config directives
|
||||
* Add `mysql::php` class for php support
|
||||
* Add `backupcompress` parameter to `mysql::backup`
|
||||
* Add `restart` parameter to `mysql::config`
|
||||
* Add `purge_conf_dir` parameter to `mysql::config`
|
||||
* Add `manage_service` parameter to `mysql::server`
|
||||
* Add syslog logging support via the `log_error` parameter
|
||||
* Add initial SuSE support
|
||||
* Fix remove non-localhost root user when fqdn != hostname
|
||||
* Fix dependency in `mysql::server::monitor`
|
||||
* Fix .my.cnf path for root user and root password
|
||||
* Fix ipv6 support for users
|
||||
* Fix / update various spec tests
|
||||
* Fix typos
|
||||
* Fix lint warnings
|
||||
|
||||
## 2012-08-23 - Version 0.5.0
|
||||
* Add puppetlabs/stdlib as requirement
|
||||
* Add validation for mysql privs in provider
|
||||
* Add `pidfile` parameter to mysql::config
|
||||
* Add `ensure` parameter to mysql::db
|
||||
* Add Amazon linux support
|
||||
* Change `bind_address` parameter to be optional in my.cnf template
|
||||
* Fix quoting root passwords
|
||||
|
||||
## 2012-07-24 - Version 0.4.0
|
||||
* Fix various bugs regarding database names
|
||||
* FreeBSD support
|
||||
* Allow specifying the storage engine
|
||||
* Add a backup class
|
||||
* Add a security class to purge default accounts
|
||||
|
||||
## 2012-05-03 - Version 0.3.0
|
||||
* 14218 Query the database for available privileges
|
||||
* Add mysql::java class for java connector installation
|
||||
* Use correct error log location on different distros
|
||||
* Fix set_mysql_rootpw to properly depend on my.cnf
|
||||
|
||||
## 2012-04-11 - Version 0.2.0
|
||||
|
||||
## 2012-03-19 - William Van Hevelingen <blkperl@cat.pdx.edu>
|
||||
* (#13203) Add ssl support (f7e0ea5)
|
||||
|
||||
## 2012-03-18 - Nan Liu <nan@puppetlabs.com>
|
||||
* Travis ci before script needs success exit code. (0ea463b)
|
||||
|
||||
## 2012-03-18 - Nan Liu <nan@puppetlabs.com>
|
||||
* Fix Puppet 2.6 compilation issues. (9ebbbc4)
|
||||
|
||||
## 2012-03-16 - Nan Liu <nan@puppetlabs.com>
|
||||
* Add travis.ci for testing multiple puppet versions. (33c72ef)
|
||||
|
||||
## 2012-03-15 - William Van Hevelingen <blkperl@cat.pdx.edu>
|
||||
* (#13163) Datadir should be configurable (f353fc6)
|
||||
|
||||
## 2012-03-16 - Nan Liu <nan@puppetlabs.com>
|
||||
* Document create_resources dependency. (558a59c)
|
||||
|
||||
## 2012-03-16 - Nan Liu <nan@puppetlabs.com>
|
||||
* Fix spec test issues related to error message. (eff79b5)
|
||||
|
||||
## 2012-03-16 - Nan Liu <nan@puppetlabs.com>
|
||||
* Fix mysql service on Ubuntu. (72da2c5)
|
||||
|
||||
## 2012-03-16 - Dan Bode <dan@puppetlabs.com>
|
||||
* Add more spec test coverage (55e399d)
|
||||
|
||||
## 2012-03-16 - Nan Liu <nan@puppetlabs.com>
|
||||
* (#11963) Fix spec test due to path changes. (1700349)
|
||||
|
||||
## 2012-03-07 - François Charlier <fcharlier@ploup.net>
|
||||
* Add a test to check path for 'mysqld-restart' (b14c7d1)
|
||||
|
||||
## 2012-03-07 - François Charlier <fcharlier@ploup.net>
|
||||
* Fix path for 'mysqld-restart' (1a9ae6b)
|
||||
|
||||
## 2012-03-15 - Dan Bode <dan@puppetlabs.com>
|
||||
* Add rspec-puppet tests for mysql::config (907331a)
|
||||
|
||||
## 2012-03-15 - Dan Bode <dan@puppetlabs.com>
|
||||
* Moved class dependency between sever and config to server (da62ad6)
|
||||
|
||||
## 2012-03-14 - Dan Bode <dan@puppetlabs.com>
|
||||
* Notify mysql restart from set_mysql_rootpw exec (0832a2c)
|
||||
|
||||
## 2012-03-15 - Nan Liu <nan@puppetlabs.com>
|
||||
* Add documentation related to osfamily fact. (8265d28)
|
||||
|
||||
## 2012-03-14 - Dan Bode <dan@puppetlabs.com>
|
||||
* Mention osfamily value in failure message (e472d3b)
|
||||
|
||||
## 2012-03-14 - Dan Bode <dan@puppetlabs.com>
|
||||
* Fix bug when querying for all database users (015490c)
|
||||
|
||||
## 2012-02-09 - Nan Liu <nan@puppetlabs.com>
|
||||
* Major refactor of mysql module. (b1f90fd)
|
||||
|
||||
## 2012-01-11 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Ruby and Python's MySQL libraries are named differently on different distros. (1e926b4)
|
||||
|
||||
## 2012-01-11 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Per @ghoneycutt, we should fail explicitly and explain why. (09af083)
|
||||
|
||||
## 2012-01-11 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Removing duplicate declaration (7513d03)
|
||||
|
||||
## 2012-01-10 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Use socket value from params class instead of hardcoding. (663e97c)
|
||||
|
||||
## 2012-01-10 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Instead of hardcoding the config file target, pull it from mysql::params (031a47d)
|
||||
|
||||
## 2012-01-10 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Moved $socket to within the case to toggle between distros. Added a $config_file variable to allow per-distro config file destinations. (360eacd)
|
||||
|
||||
## 2012-01-10 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Pretty sure this is a bug, 99% of Linux distros out there won't ever hit the default. (3462e6b)
|
||||
|
||||
## 2012-02-09 - William Van Hevelingen <blkperl@cat.pdx.edu>
|
||||
* Changed the README to use markdown (3b7dfeb)
|
||||
|
||||
## 2012-02-04 - Daniel Black <grooverdan@users.sourceforge.net>
|
||||
* (#12412) mysqltuner.pl update (b809e6f)
|
||||
|
||||
## 2011-11-17 - Matthias Pigulla <mp@webfactory.de>
|
||||
* (#11363) Add two missing privileges to grant: event_priv, trigger_priv (d15c9d1)
|
||||
|
||||
## 2011-12-20 - Jeff McCune <jeff@puppetlabs.com>
|
||||
* (minor) Fixup typos in Modulefile metadata (a0ed6a1)
|
||||
|
||||
## 2011-12-19 - Carl Caum <carl@carlcaum.com>
|
||||
* Only notify Exec to import sql if sql is given (0783c74)
|
||||
|
||||
## 2011-12-19 - Carl Caum <carl@carlcaum.com>
|
||||
* (#11508) Only load sql_scripts on DB creation (e3b9fd9)
|
||||
|
||||
## 2011-12-13 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Require not needed due to implicit dependencies (3058feb)
|
||||
|
||||
## 2011-12-13 - Justin Ellison <justin.ellison@buckle.com>
|
||||
* Bug #11375: puppetlabs-mysql fails on CentOS/RHEL (a557b8d)
|
||||
|
||||
## 2011-06-03 - Dan Bode <dan@puppetlabs.com> - 0.0.1
|
||||
* initial commit
|
||||
|
||||
[5.3.0]:https://github.com/puppetlabs/puppetlabs-mysql/compare/5.2.1...5.3.0
|
||||
[5.2.1]:https://github.com/puppetlabs/puppetlabs-mysql/compare/5.2.0...5.2.1
|
||||
[5.2.0]:https://github.com/puppetlabs/puppetlabs-mysql/compare/5.1.0...5.2.0
|
||||
[5.1.0]:https://github.com/puppetlabs/puppetlabs-mysql/compare/5.0.0...5.1.0
|
||||
[5.0.0]:https://github.com/puppetlabs/puppetlabs-mysql/compare/4.0.1...5.0.0
|
||||
@@ -0,0 +1,271 @@
|
||||
# Contributing to Puppet modules
|
||||
|
||||
So you want to contribute to a Puppet module: Great! Below are some instructions to get you started doing
|
||||
that very thing while setting expectations around code quality as well as a few tips for making the
|
||||
process as easy as possible.
|
||||
|
||||
### Table of Contents
|
||||
|
||||
1. [Getting Started](#getting-started)
|
||||
1. [Commit Checklist](#commit-checklist)
|
||||
1. [Submission](#submission)
|
||||
1. [More about commits](#more-about-commits)
|
||||
1. [Testing](#testing)
|
||||
- [Running Tests](#running-tests)
|
||||
- [Writing Tests](#writing-tests)
|
||||
1. [Get Help](#get-help)
|
||||
|
||||
## Getting Started
|
||||
|
||||
- Fork the module repository on GitHub and clone to your workspace
|
||||
|
||||
- Make your changes!
|
||||
|
||||
## Commit Checklist
|
||||
|
||||
### The Basics
|
||||
|
||||
- [x] my commit is a single logical unit of work
|
||||
|
||||
- [x] I have checked for unnecessary whitespace with "git diff --check"
|
||||
|
||||
- [x] my commit does not include commented out code or unneeded files
|
||||
|
||||
### The Content
|
||||
|
||||
- [x] my commit includes tests for the bug I fixed or feature I added
|
||||
|
||||
- [x] my commit includes appropriate documentation changes if it is introducing a new feature or changing existing functionality
|
||||
|
||||
- [x] my code passes existing test suites
|
||||
|
||||
### The Commit Message
|
||||
|
||||
- [x] the first line of my commit message includes:
|
||||
|
||||
- [x] an issue number (if applicable), e.g. "(MODULES-xxxx) This is the first line"
|
||||
|
||||
- [x] a short description (50 characters is the soft limit, excluding ticket number(s))
|
||||
|
||||
- [x] the body of my commit message:
|
||||
|
||||
- [x] is meaningful
|
||||
|
||||
- [x] uses the imperative, present tense: "change", not "changed" or "changes"
|
||||
|
||||
- [x] includes motivation for the change, and contrasts its implementation with the previous behavior
|
||||
|
||||
## Submission
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
- Make sure you have a [GitHub account](https://github.com/join)
|
||||
|
||||
- [Create a ticket](https://tickets.puppet.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppet.com/browse/) you are patching for.
|
||||
|
||||
### Push and PR
|
||||
|
||||
- Push your changes to your fork
|
||||
|
||||
- [Open a Pull Request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the repository in the puppetlabs organization
|
||||
|
||||
## More about commits
|
||||
|
||||
1. Make separate commits for logically separate changes.
|
||||
|
||||
Please break your commits down into logically consistent units
|
||||
which include new or changed tests relevant to the rest of the
|
||||
change. The goal of doing this is to make the diff easier to
|
||||
read for whoever is reviewing your code. In general, the easier
|
||||
your diff is to read, the more likely someone will be happy to
|
||||
review it and get it into the code base.
|
||||
|
||||
If you are going to refactor a piece of code, please do so as a
|
||||
separate commit from your feature or bug fix changes.
|
||||
|
||||
We also really appreciate changes that include tests to make
|
||||
sure the bug is not re-introduced, and that the feature is not
|
||||
accidentally broken.
|
||||
|
||||
Describe the technical detail of the change(s). If your
|
||||
description starts to get too long, that is a good sign that you
|
||||
probably need to split up your commit into more finely grained
|
||||
pieces.
|
||||
|
||||
Commits which plainly describe the things which help
|
||||
reviewers check the patch and future developers understand the
|
||||
code are much more likely to be merged in with a minimum of
|
||||
bike-shedding or requested changes. Ideally, the commit message
|
||||
would include information, and be in a form suitable for
|
||||
inclusion in the release notes for the version of Puppet that
|
||||
includes them.
|
||||
|
||||
Please also check that you are not introducing any trailing
|
||||
whitespace or other "whitespace errors". You can do this by
|
||||
running "git diff --check" on your changes before you commit.
|
||||
|
||||
2. Sending your patches
|
||||
|
||||
To submit your changes via a GitHub pull request, we _highly_
|
||||
recommend that you have them on a topic branch, instead of
|
||||
directly on "master".
|
||||
It makes things much easier to keep track of, especially if
|
||||
you decide to work on another thing before your first change
|
||||
is merged in.
|
||||
|
||||
GitHub has some pretty good
|
||||
[general documentation](http://help.github.com/) on using
|
||||
their site. They also have documentation on
|
||||
[creating pull requests](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
|
||||
|
||||
In general, after pushing your topic branch up to your
|
||||
repository on GitHub, you can switch to the branch in the
|
||||
GitHub UI and click "Pull Request" towards the top of the page
|
||||
in order to open a pull request.
|
||||
|
||||
3. Update the related JIRA issue.
|
||||
|
||||
If there is a JIRA issue associated with the change you
|
||||
submitted, then you should update the ticket to include the
|
||||
location of your branch, along with any other commentary you
|
||||
may wish to make.
|
||||
|
||||
# Testing
|
||||
|
||||
## Getting Started
|
||||
|
||||
Our Puppet modules provide [`Gemfile`](./Gemfile)s, which can tell a Ruby package manager such as [bundler](http://bundler.io/) what Ruby packages,
|
||||
or Gems, are required to build, develop, and test this software.
|
||||
|
||||
Please make sure you have [bundler installed](http://bundler.io/#getting-started) on your system, and then use it to
|
||||
install all dependencies needed for this project in the project root by running
|
||||
|
||||
```shell
|
||||
% bundle install --path .bundle/gems
|
||||
Fetching gem metadata from https://rubygems.org/........
|
||||
Fetching gem metadata from https://rubygems.org/..
|
||||
Using rake (10.1.0)
|
||||
Using builder (3.2.2)
|
||||
-- 8><-- many more --><8 --
|
||||
Using rspec-system-puppet (2.2.0)
|
||||
Using serverspec (0.6.3)
|
||||
Using rspec-system-serverspec (1.0.0)
|
||||
Using bundler (1.3.5)
|
||||
Your bundle is complete!
|
||||
Use `bundle show [gemname]` to see where a bundled gem is installed.
|
||||
```
|
||||
|
||||
NOTE: some systems may require you to run this command with sudo.
|
||||
|
||||
If you already have those gems installed, make sure they are up-to-date:
|
||||
|
||||
```shell
|
||||
% bundle update
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
With all dependencies in place and up-to-date, run the tests:
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```shell
|
||||
% bundle exec rake spec
|
||||
```
|
||||
|
||||
This executes all the [rspec tests](http://rspec-puppet.com/) in the directories defined [here](https://github.com/puppetlabs/puppetlabs_spec_helper/blob/699d9fbca1d2489bff1736bb254bb7b7edb32c74/lib/puppetlabs_spec_helper/rake_tasks.rb#L17) and so on.
|
||||
rspec tests may have the same kind of dependencies as the module they are testing. Although the module defines these dependencies in its [metadata.json](./metadata.json),
|
||||
rspec tests define them in [.fixtures.yml](./fixtures.yml).
|
||||
|
||||
### Acceptance Tests
|
||||
|
||||
Some Puppet modules also come with acceptance tests, which use [beaker][]. These tests spin up a virtual machine under
|
||||
[VirtualBox](https://www.virtualbox.org/), controlled with [Vagrant](http://www.vagrantup.com/), to simulate scripted test
|
||||
scenarios. In order to run these, you need both Virtualbox and Vagrant installed on your system.
|
||||
|
||||
Run the tests by issuing the following command
|
||||
|
||||
```shell
|
||||
% bundle exec rake spec_clean
|
||||
% bundle exec rspec spec/acceptance
|
||||
```
|
||||
|
||||
This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml),
|
||||
install Puppet, copy this module, and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb)
|
||||
and then run all the tests under [spec/acceptance](./spec/acceptance).
|
||||
|
||||
## Writing Tests
|
||||
|
||||
### Unit Tests
|
||||
|
||||
When writing unit tests for Puppet, [rspec-puppet][] is your best friend. It provides tons of helper methods for testing your manifests against a
|
||||
catalog (e.g. contain_file, contain_package, with_params, etc). It would be ridiculous to try and top rspec-puppet's [documentation][rspec-puppet_docs]
|
||||
but here's a tiny sample:
|
||||
|
||||
Sample manifest:
|
||||
|
||||
```puppet
|
||||
file { "a test file":
|
||||
ensure => present,
|
||||
path => "/etc/sample",
|
||||
}
|
||||
```
|
||||
|
||||
Sample test:
|
||||
|
||||
```ruby
|
||||
it 'does a thing' do
|
||||
expect(subject).to contain_file("a test file").with({:path => "/etc/sample"})
|
||||
end
|
||||
```
|
||||
|
||||
### Acceptance Tests
|
||||
|
||||
Writing acceptance tests for Puppet involves [beaker][] and its cousin [beaker-rspec][]. A common pattern for acceptance tests is to create a test manifest, apply it
|
||||
twice to check for idempotency or errors, then run expectations.
|
||||
|
||||
```ruby
|
||||
it 'does an end-to-end thing' do
|
||||
pp = <<-EOF
|
||||
file { 'a test file':
|
||||
ensure => present,
|
||||
path => "/etc/sample",
|
||||
content => "test string",
|
||||
}
|
||||
|
||||
apply_manifest(pp, :catch_failures => true)
|
||||
apply_manifest(pp, :catch_changes => true)
|
||||
|
||||
end
|
||||
|
||||
describe file("/etc/sample") do
|
||||
it { is_expected.to contain "test string" }
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
# If you have commit access to the repository
|
||||
|
||||
Even if you have commit access to the repository, you still need to go through the process above, and have someone else review and merge
|
||||
in your changes. The rule is that **all changes must be reviewed by a project developer that did not write the code to ensure that
|
||||
all changes go through a code review process.**
|
||||
|
||||
The record of someone performing the merge is the record that they performed the code review. Again, this should be someone other than the author of the topic branch.
|
||||
|
||||
# Get Help
|
||||
|
||||
### On the web
|
||||
* [Puppet help messageboard](http://puppet.com/community/get-help)
|
||||
* [Writing tests](https://docs.puppet.com/guides/module_guides/bgtm.html#step-three-module-testing)
|
||||
* [General GitHub documentation](http://help.github.com/)
|
||||
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
|
||||
|
||||
### On chat
|
||||
* Slack (slack.puppet.com) #forge-modules, #puppet-dev, #windows, #voxpupuli
|
||||
* IRC (freenode) #puppet-dev, #voxpupuli
|
||||
|
||||
|
||||
[rspec-puppet]: http://rspec-puppet.com/
|
||||
[rspec-puppet_docs]: http://rspec-puppet.com/documentation/
|
||||
[beaker]: https://github.com/puppetlabs/beaker
|
||||
[beaker-rspec]: https://github.com/puppetlabs/beaker-rspec
|
||||
@@ -0,0 +1,137 @@
|
||||
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
|
||||
|
||||
def location_for(place_or_version, fake_version = nil)
|
||||
if place_or_version =~ %r{\A(git[:@][^#]*)#(.*)}
|
||||
[fake_version, { git: Regexp.last_match(1), branch: Regexp.last_match(2), require: false }].compact
|
||||
elsif place_or_version =~ %r{\Afile:\/\/(.*)}
|
||||
['>= 0', { path: File.expand_path(Regexp.last_match(1)), require: false }]
|
||||
else
|
||||
[place_or_version, { require: false }]
|
||||
end
|
||||
end
|
||||
|
||||
def gem_type(place_or_version)
|
||||
if place_or_version =~ %r{\Agit[:@]}
|
||||
:git
|
||||
elsif !place_or_version.nil? && place_or_version.start_with?('file:')
|
||||
:file
|
||||
else
|
||||
:gem
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments
|
||||
minor_version = ruby_version_segments[0..1].join('.')
|
||||
|
||||
group :development do
|
||||
gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0')
|
||||
gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0')
|
||||
gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
|
||||
gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9')
|
||||
gem "puppet-module-posix-default-r#{minor_version}", require: false, platforms: [:ruby]
|
||||
gem "puppet-module-posix-dev-r#{minor_version}", require: false, platforms: [:ruby]
|
||||
gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
|
||||
gem "puppet-module-win-dev-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
|
||||
gem "puppet-blacksmith", '~> 3.4', require: false
|
||||
gem "puppet-lint-i18n", require: false
|
||||
end
|
||||
group :system_tests do
|
||||
gem "puppet-module-posix-system-r#{minor_version}", require: false, platforms: [:ruby]
|
||||
gem "puppet-module-win-system-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw]
|
||||
gem "beaker", *location_for(ENV['BEAKER_VERSION'] || '~> 3.13')
|
||||
gem "beaker-abs", *location_for(ENV['BEAKER_ABS_VERSION'] || '~> 0.1')
|
||||
gem "beaker-pe", require: false
|
||||
gem "beaker-hostgenerator"
|
||||
gem "beaker-rspec"
|
||||
end
|
||||
|
||||
puppet_version = ENV['PUPPET_GEM_VERSION']
|
||||
puppet_type = gem_type(puppet_version)
|
||||
facter_version = ENV['FACTER_GEM_VERSION']
|
||||
hiera_version = ENV['HIERA_GEM_VERSION']
|
||||
|
||||
def puppet_older_than?(version)
|
||||
puppet_version = ENV['PUPPET_GEM_VERSION']
|
||||
!puppet_version.nil? &&
|
||||
Gem::Version.correct?(puppet_version) &&
|
||||
Gem::Requirement.new("< #{version}").satisfied_by?(Gem::Version.new(puppet_version.dup))
|
||||
end
|
||||
|
||||
gems = {}
|
||||
|
||||
gems['puppet'] = location_for(puppet_version)
|
||||
|
||||
# If facter or hiera versions have been specified via the environment
|
||||
# variables, use those versions. If not, and if the puppet version is < 3.5.0,
|
||||
# use known good versions of both for puppet < 3.5.0.
|
||||
if facter_version
|
||||
gems['facter'] = location_for(facter_version)
|
||||
elsif puppet_type == :gem && puppet_older_than?('3.5.0')
|
||||
gems['facter'] = ['>= 1.6.11', '<= 1.7.5', require: false]
|
||||
end
|
||||
|
||||
if hiera_version
|
||||
gems['hiera'] = location_for(ENV['HIERA_GEM_VERSION'])
|
||||
elsif puppet_type == :gem && puppet_older_than?('3.5.0')
|
||||
gems['hiera'] = ['>= 1.0.0', '<= 1.3.0', require: false]
|
||||
end
|
||||
|
||||
if Gem.win_platform? && (puppet_type != :gem || puppet_older_than?('3.5.0'))
|
||||
# For Puppet gems < 3.5.0 (tested as far back as 3.0.0) on Windows
|
||||
if puppet_type == :gem
|
||||
gems['ffi'] = ['1.9.0', require: false]
|
||||
gems['minitar'] = ['0.5.4', require: false]
|
||||
gems['win32-eventlog'] = ['0.5.3', '<= 0.6.5', require: false]
|
||||
gems['win32-process'] = ['0.6.5', '<= 0.7.5', require: false]
|
||||
gems['win32-security'] = ['~> 0.1.2', '<= 0.2.5', require: false]
|
||||
gems['win32-service'] = ['0.7.2', '<= 0.8.8', require: false]
|
||||
else
|
||||
gems['ffi'] = ['~> 1.9.0', require: false]
|
||||
gems['minitar'] = ['~> 0.5.4', require: false]
|
||||
gems['win32-eventlog'] = ['~> 0.5', '<= 0.6.5', require: false]
|
||||
gems['win32-process'] = ['~> 0.6', '<= 0.7.5', require: false]
|
||||
gems['win32-security'] = ['~> 0.1', '<= 0.2.5', require: false]
|
||||
gems['win32-service'] = ['~> 0.7', '<= 0.8.8', require: false]
|
||||
end
|
||||
|
||||
gems['win32-dir'] = ['~> 0.3', '<= 0.4.9', require: false]
|
||||
|
||||
if RUBY_VERSION.start_with?('1.')
|
||||
gems['win32console'] = ['1.3.2', require: false]
|
||||
# sys-admin was removed in Puppet 3.7.0 and doesn't compile under Ruby 2.x
|
||||
gems['sys-admin'] = ['1.5.6', require: false]
|
||||
end
|
||||
|
||||
# Puppet < 3.7.0 requires these.
|
||||
# Puppet >= 3.5.0 gem includes these as requirements.
|
||||
# The following versions are tested to work with 3.0.0 <= puppet < 3.7.0.
|
||||
gems['win32-api'] = ['1.4.8', require: false]
|
||||
gems['win32-taskscheduler'] = ['0.2.2', require: false]
|
||||
gems['windows-api'] = ['0.4.3', require: false]
|
||||
gems['windows-pr'] = ['1.2.3', require: false]
|
||||
elsif Gem.win_platform?
|
||||
# If we're using a Puppet gem on Windows which handles its own win32-xxx gem
|
||||
# dependencies (>= 3.5.0), set the maximum versions (see PUP-6445).
|
||||
gems['win32-dir'] = ['<= 0.4.9', require: false]
|
||||
gems['win32-eventlog'] = ['<= 0.6.5', require: false]
|
||||
gems['win32-process'] = ['<= 0.7.5', require: false]
|
||||
gems['win32-security'] = ['<= 0.2.5', require: false]
|
||||
gems['win32-service'] = ['<= 0.8.8', require: false]
|
||||
end
|
||||
|
||||
gems.each do |gem_name, gem_params|
|
||||
gem gem_name, *gem_params
|
||||
end
|
||||
|
||||
# Evaluate Gemfile.local and ~/.gemfile if they exist
|
||||
extra_gemfiles = [
|
||||
"#{__FILE__}.local",
|
||||
File.join(Dir.home, '.gemfile'),
|
||||
]
|
||||
|
||||
extra_gemfiles.each do |gemfile|
|
||||
if File.file?(gemfile) && File.readable?(gemfile)
|
||||
eval(File.read(gemfile), binding)
|
||||
end
|
||||
end
|
||||
# vim: syntax=ruby
|
||||
@@ -0,0 +1,6 @@
|
||||
## Maintenance
|
||||
|
||||
Maintainers:
|
||||
- Puppet Forge Modules Team `forge-modules |at| puppet |dot| com`
|
||||
|
||||
Tickets: https://tickets.puppet.com/browse/MODULES. Make sure to set component to `mysql`.
|
||||
@@ -0,0 +1,15 @@
|
||||
Puppet Module - puppetlabs-mysql
|
||||
|
||||
Copyright 2018 Puppet, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
||||
require 'puppet-syntax/tasks/puppet-syntax'
|
||||
require 'puppet_blacksmith/rake_tasks'
|
||||
require 'puppet_pot_generator/rake_tasks'
|
||||
@@ -0,0 +1,13 @@
|
||||
def mysql_id_get
|
||||
Facter.value(:macaddress).split(':')[2..-1].reduce(0) { |total, value| (total << 6) + value.hex }
|
||||
end
|
||||
|
||||
Facter.add('mysql_server_id') do
|
||||
setcode do
|
||||
begin
|
||||
mysql_id_get
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
Facter.add('mysql_version') do
|
||||
setcode do
|
||||
mysql_ver = Facter::Util::Resolution.exec('mysql --version')
|
||||
mysql_ver.match(%r{\d+\.\d+\.\d+})[0] if mysql_ver
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user