awsec 0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/{awsec.sh → awsec} +2 -3
- data/lib/aw_sec.rb +5 -0
- data/lib/aw_sec/core.rb +110 -0
- data/lib/aw_sec/providers.rb +29 -0
- data/lib/providers/ip_echo.rb +18 -0
- data/lib/providers/my_ip.rb +24 -0
- data/lib/version.rb +52 -0
- metadata +25 -33
- data/README.md +0 -4
data/bin/{awsec.sh → awsec}
RENAMED
@@ -4,8 +4,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'aw_sec'
|
|
4
4
|
require 'json'
|
5
5
|
require 'highline/import'
|
6
6
|
require 'optparse'
|
7
|
-
|
8
|
-
VERSION = '0.1'
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'version'))
|
9
8
|
|
10
9
|
config_path = File.join(Dir.home, '.awsec', 'awsec.json')
|
11
10
|
|
@@ -82,7 +81,7 @@ optparse = OptionParser.new do |opts|
|
|
82
81
|
end
|
83
82
|
|
84
83
|
opts.on('-v', '--version', 'AwSec version') do
|
85
|
-
say("AwSec v#{
|
84
|
+
say("AwSec v#{AwSec::Version.current}")
|
86
85
|
exit
|
87
86
|
end
|
88
87
|
|
data/lib/aw_sec.rb
ADDED
data/lib/aw_sec/core.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module AwSec
|
4
|
+
class Core
|
5
|
+
|
6
|
+
def self.secure(group_names, public_ip, options = {})
|
7
|
+
client = AwSec::Core.new
|
8
|
+
client.secure(group_names, public_ip, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def secure(group_names, public_ip, options = {})
|
12
|
+
public_ip = public_ip
|
13
|
+
@port = options[:port] || 22
|
14
|
+
@region = options[:aws_region]
|
15
|
+
@aws_key = options[:aws_key]
|
16
|
+
@aws_secret = options[:aws_secret]
|
17
|
+
revoke_all = options.has_key?(:revoke_all) ? options[:revoke_all] : true
|
18
|
+
wtlist = options[:whitelist] || []
|
19
|
+
|
20
|
+
whitelist = []
|
21
|
+
public_ip = "#{public_ip}/32" unless public_ip =~ /\//
|
22
|
+
wtlist.each do |ip|
|
23
|
+
whitelist << "#{ip}/32" unless ip =~ /\//
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "Connecting AWS..."
|
27
|
+
groups = get_groups(group_names)
|
28
|
+
groups.each do |group|
|
29
|
+
puts "Configuring #{group.name}"
|
30
|
+
granted_ips = list_ips(group) || []
|
31
|
+
puts "Existing IPs with access to port #{port}: #{granted_ips.join(',')}"
|
32
|
+
allowed_ips = granted_ips.select { |i| whitelist.include? i }
|
33
|
+
allowed_ips << public_ip
|
34
|
+
if revoke_all
|
35
|
+
granted_ips.each do |ip|
|
36
|
+
unless allowed_ips.include? ip
|
37
|
+
puts "Revoking access to #{ip}"
|
38
|
+
revoke_access(group, ip)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
granted_ips.uniq!
|
43
|
+
allowed_ips.each do |ip|
|
44
|
+
puts "Granting access to port #{port} to #{ip}"
|
45
|
+
safe_authorize_port(group, ip)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def list_ips(group)
|
51
|
+
result = []
|
52
|
+
group.ip_permissions.detect do |ip_permission|
|
53
|
+
result << ip_permission['ipRanges'].collect{ |i| i["cidrIp"] } if ip_permission["toPort"] == port
|
54
|
+
end
|
55
|
+
|
56
|
+
result.flatten!
|
57
|
+
end
|
58
|
+
|
59
|
+
def revoke_access(group, ip)
|
60
|
+
group.revoke_port_range(port..port, :cidr_ip => ip)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_groups(group_names)
|
64
|
+
groups = []
|
65
|
+
group_names.each do |group_name|
|
66
|
+
groups << conn.security_groups.get(group_name)
|
67
|
+
end
|
68
|
+
|
69
|
+
groups
|
70
|
+
end
|
71
|
+
|
72
|
+
def safe_authorize_port(group, ip)
|
73
|
+
if group.ip_permissions.nil?
|
74
|
+
authorized = false
|
75
|
+
else
|
76
|
+
authorized = is_authorized?(group, ip)
|
77
|
+
end
|
78
|
+
unless authorized
|
79
|
+
begin
|
80
|
+
group.authorize_port_range(port..port, :cidr_ip => ip)
|
81
|
+
rescue => exc
|
82
|
+
puts "Failed #{exc.message}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def is_authorized?(group, ip)
|
88
|
+
return group.ip_permissions.detect do |ip_permission|
|
89
|
+
ip_permission['ipRanges'].first && ip_permission['ipRanges'].first['cidrIp'] == ip &&
|
90
|
+
ip_permission['fromPort'] == port &&
|
91
|
+
ip_permission['ipProtocol'] == 'tcp' &&
|
92
|
+
ip_permission['toPort'] == port
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def port
|
97
|
+
@port
|
98
|
+
end
|
99
|
+
|
100
|
+
def conn
|
101
|
+
@conn ||= Fog::Compute.new({
|
102
|
+
:provider => 'AWS',
|
103
|
+
:region => @region,
|
104
|
+
:aws_access_key_id => @aws_key,
|
105
|
+
:aws_secret_access_key => @aws_secret
|
106
|
+
})
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module AwSec
|
2
|
+
module Providers
|
3
|
+
class Register
|
4
|
+
|
5
|
+
def self.register(name, klass)
|
6
|
+
@register ||= []
|
7
|
+
@register << { :name => name, :class => klass }
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.list
|
11
|
+
@register
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.provider(provider_name)
|
15
|
+
puts "Configuring #{provider_name}"
|
16
|
+
klass = Kernel.const_get(provider_name)
|
17
|
+
klass.new
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir.foreach(File.join(File.dirname(__FILE__), '..', 'providers')) do |file|
|
21
|
+
path = File.join(File.join(File.dirname(__FILE__), '..', 'providers', file))
|
22
|
+
unless File.directory? path
|
23
|
+
require path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module AwSec
|
4
|
+
module Providers
|
5
|
+
class EchoIp
|
6
|
+
|
7
|
+
Register.register('Echo IP', AwSec::Providers::EchoIp.new())
|
8
|
+
|
9
|
+
def get_public_ip(options)
|
10
|
+
Net::HTTP.get(URI "http://ipecho.net/plain")
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'highline/import'
|
3
|
+
|
4
|
+
module AwSec
|
5
|
+
module Providers
|
6
|
+
class MyIp
|
7
|
+
|
8
|
+
Register.register('My IP', AwSec::Providers::MyIp.new())
|
9
|
+
|
10
|
+
def get_public_ip(options)
|
11
|
+
Net::HTTP.get(URI "http://auto.whatismyip.com/ip.php?user=#{options[:my_ip_username]}&password=#{options[:my_ip_password]}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def configure
|
15
|
+
result = {}
|
16
|
+
result[:my_ip_username] = ask('My IP username')
|
17
|
+
result[:my_ip_password] = ask('My IP password') { |q| q.echo = "*" }
|
18
|
+
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module AwSec
|
4
|
+
class Version
|
5
|
+
|
6
|
+
##
|
7
|
+
# Change the MAJOR, MINOR and PATCH constants below
|
8
|
+
# to adjust the version of the Cloud66 Agent gem
|
9
|
+
#
|
10
|
+
# MAJOR:
|
11
|
+
# Defines the major version
|
12
|
+
# MINOR:
|
13
|
+
# Defines the minor version
|
14
|
+
# PATCH:
|
15
|
+
# Defines the patch version
|
16
|
+
MAJOR, MINOR, PATCH = 0, 1, 1
|
17
|
+
|
18
|
+
#ie. PRERELEASE_MODIFIER = 'beta1'
|
19
|
+
PRERELEASE_MODIFIER = nil
|
20
|
+
|
21
|
+
##
|
22
|
+
# Returns the major version ( big release based off of multiple minor releases )
|
23
|
+
def self.major
|
24
|
+
MAJOR
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Returns the minor version ( small release based off of multiple patches )
|
29
|
+
def self.minor
|
30
|
+
MINOR
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Returns the patch version ( updates, features and (crucial) bug fixes )
|
35
|
+
def self.patch
|
36
|
+
PATCH
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Returns the prerelease modifier ( not quite ready for public consumption )
|
41
|
+
def self.prerelease_modifier
|
42
|
+
PRERELEASE_MODIFIER
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Returns the current version of the Backup gem ( qualified for the gemspec )
|
47
|
+
def self.current
|
48
|
+
prerelease_modifier.nil? ? "#{major}.#{minor}.#{patch}" : "#{major}.#{minor}.#{patch}.#{prerelease_modifier}"
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,75 +1,67 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awsec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- Cloud 66
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2013-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rubygems
|
16
|
-
requirement: &70146232181040 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *70146232181040
|
25
14
|
- !ruby/object:Gem::Dependency
|
26
15
|
name: json
|
27
|
-
requirement: &
|
16
|
+
requirement: &70283797022900 !ruby/object:Gem::Requirement
|
28
17
|
none: false
|
29
18
|
requirements:
|
30
19
|
- - ! '>='
|
31
20
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
21
|
+
version: 1.6.3
|
33
22
|
type: :runtime
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *70283797022900
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement: &
|
26
|
+
name: fog
|
27
|
+
requirement: &70283797022280 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
|
-
- -
|
30
|
+
- - ~>
|
42
31
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
32
|
+
version: 1.4.0
|
44
33
|
type: :runtime
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70283797022280
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement: &
|
37
|
+
name: highline
|
38
|
+
requirement: &70283797021400 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
|
-
- -
|
41
|
+
- - ~>
|
53
42
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
43
|
+
version: 1.6.11
|
55
44
|
type: :runtime
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70283797021400
|
58
47
|
description: Open and close AWS Security Group from the terminal for more secure operations
|
59
48
|
email: khash@cloud66.com
|
60
49
|
executables:
|
61
|
-
- awsec
|
50
|
+
- awsec
|
62
51
|
extensions: []
|
63
|
-
extra_rdoc_files:
|
64
|
-
- README.md
|
52
|
+
extra_rdoc_files: []
|
65
53
|
files:
|
66
|
-
-
|
67
|
-
-
|
54
|
+
- lib/version.rb
|
55
|
+
- lib/aw_sec.rb
|
56
|
+
- lib/aw_sec/core.rb
|
57
|
+
- lib/aw_sec/providers.rb
|
58
|
+
- lib/providers/ip_echo.rb
|
59
|
+
- lib/providers/my_ip.rb
|
60
|
+
- bin/awsec
|
68
61
|
homepage: https://github.com/cloud66/awsec
|
69
62
|
licenses: []
|
70
63
|
post_install_message:
|
71
|
-
rdoc_options:
|
72
|
-
- --charset=UTF-8
|
64
|
+
rdoc_options: []
|
73
65
|
require_paths:
|
74
66
|
- lib
|
75
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/README.md
DELETED