Skip to content

Instantly share code, notes, and snippets.

@TheLonelyGhost
Last active October 6, 2015 20:44
Show Gist options
  • Save TheLonelyGhost/5d7fc502176444a517b9 to your computer and use it in GitHub Desktop.
Save TheLonelyGhost/5d7fc502176444a517b9 to your computer and use it in GitHub Desktop.
Export EC2 Security Group firewall settings based on the private key chosen to build the instance
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile true do
source 'https://rubygems.org'
gem 'aws-sdk', '~> 2'
end
require 'aws-sdk'
require 'csv'
def write_report_to_csv_set(report, firewall_file='./AWS_DUMP-firewall-rules.csv', instance_file='./AWS_DUMP-instances.csv')
#
instance_csv = CSV.open(instance_file, 'wb', write_headers: true, headers: [:instance_id, :name, :private_ip, :public_ip, :security_group_memberships])
firewall_csv = CSV.open(firewall_file, 'wb', write_headers: true, headers: [:protocol, :from_port, :to_port, :direction, :instance_id, :allowed_ip_ranges, :allowed_security_groups])
report.each do |instance_id, instance|
instance_csv << [ instance_id, instance['name'], instance['private_ip'], instance['public_ip'], instance['security_groups'].join(' | ') ]
instance['firewall'].each do |rule|
firewall_csv << [ rule['protocol'], rule['from_port'], rule['to_port'], rule['direction'], instance_id, rule['ip_ranges'].join(' | '), rule['security_groups'].join(' | ') ]
end
end
ensure
firewall_csv.close rescue nil
instance_csv.close rescue nil
end
def create_report(key_names=[])
client = Aws::EC2::Client.new(region: 'us-east-1')
response = client.describe_instances(
filters: [
{
name: 'key-name',
values: key_names
}
]
)
instances = response.reservations.map(&:instances).flatten(1)
security_group_ids = Set.new
instances.each do |instance|
instance.security_groups.each do |group|
security_group_ids << group.group_id
end
end
response = client.describe_security_groups(group_ids: security_group_ids.to_a)
security_groups = response.security_groups.each_with_object({}) {|group, obj| obj[group.group_id] = group }
instances.each_with_object({}) do |instance, report|
report[instance.instance_id] = {
'name' => (instance.tags.find(){|t| t.key == 'Name' }.value rescue '[N/A]'),
'private_ip' => instance.private_ip_address,
'public_ip' => instance.public_ip_address,
'security_groups' => instance.security_groups.map(&:group_name),
'firewall' => {}
}
report[instance.instance_id]['firewall'] = instance.security_groups.each_with_object([]) do |group, h|
security_groups[group.group_id].ip_permissions.each_with_object(h) do |perm, bounds|
ip_ranges = perm.ip_ranges.map(&:cidr_ip)
sec = Set.new(perm.user_id_group_pairs.map(&:group_name))
prospect = {
'protocol' => perm.ip_protocol,
'from_port' => perm.from_port,
'to_port' => perm.to_port,
'direction' => 'inbound',
'security_groups' => Set.new(sec),
'ip_ranges' => Set.new(ip_ranges)
}
bounds_key = bounds.index {|b| b['protocol'] == prospect['protocol'] && b['from_port'] == prospect['from_port'] && b['to_port'] == prospect['to_port'] && b['direction'] == prospect['direction'] }
if bounds_key
['ip_ranges', 'security_groups'].each do |attr|
prospect[attr].each do |p_group|
bounds[bounds_key][attr] << p_group
end
end
else
bounds << prospect
end
end
security_groups[group.group_id].ip_permissions_egress.each_with_object(h) do |perm, bounds|
ip_ranges = perm.ip_ranges.map(&:cidr_ip)
sec = Set.new(perm.user_id_group_pairs.map(&:group_name))
prospect = {
'protocol' => perm.ip_protocol,
'from_port' => perm.from_port,
'to_port' => perm.to_port,
'direction' => 'inbound',
'security_groups' => Set.new(sec),
'ip_ranges' => Set.new(ip_ranges)
}
bounds_key = bounds.index {|b| b['protocol'] == prospect['protocol'] && b['from_port'] == prospect['from_port'] && b['to_port'] == prospect['to_port'] }
if bounds_key
['ip_ranges', 'security_groups'].each do |attr|
prospect[attr].each do |p_group|
bounds[bounds_key][attr] << p_group
end
end
else
bounds << prospect
end
end
end
report[instance.instance_id]['firewall'].each do |rule|
[
'ip_ranges',
'security_groups'
].each {|attr| rule[attr] = rule[attr].to_a }
end
end
end
instance_ip_report = create_report(['SomeProdKeyName'])
write_report_to_csv_set(instance_ip_report)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment