cfn-vpn 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14100a22fc434fa08bc329c9b37b3fd8c72a8b03825c0ae2ebbb8b008229711b
4
- data.tar.gz: 72a211b53647c788bc149bca7c5c30d1f7ad6939f7c26573da4d483068fe2008
3
+ metadata.gz: eb761d025f597c4de716819ae68760c9852186b37505dc565f26c60fa4679788
4
+ data.tar.gz: 8347f65e8c83d6a4b579b2f5a3e5209e0c24e7e59971be79afcc75adf4ebc2ae
5
5
  SHA512:
6
- metadata.gz: 23f99dfeda3e9508f75b3fd8af5aa2a16f9062d96ba4a6a1c12b8cde8517c42c9a76e8b99e20c790972529870c588ef9c966b23d30b7f587697c2315355eabe2
7
- data.tar.gz: 86b27e631221e973769d2b61f98637a90e63b4c9fd4a463a540b0ee843c412bd66f3953fdb52cf96d488b4cf2c4ec60478936d978e606e1dd23413c3cc0a8f90
6
+ metadata.gz: 0e8bf02b14cde539575af2a00306aee0a582e0907db6b103520d001b02aab3daf5f4a331fc5fe4363829ef764771b210eacd4e72f526d16901d6cfe64a3c7607
7
+ data.tar.gz: 1cf6528468ccd43734549ef00f35238b76ae190691aceddc2e29aed5984cb98ea06e2a5ae66b46e19cad1048a107f1293a9aa877e9f624a15d8ec5cb07d012ad
data/Gemfile.lock CHANGED
@@ -1,20 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfn-vpn (0.1.0)
4
+ cfn-vpn (0.2.0)
5
5
  aws-sdk-acm (~> 1, < 2)
6
6
  aws-sdk-cloudformation (~> 1, < 2)
7
7
  aws-sdk-ec2 (~> 1.95, < 2)
8
- aws-sdk-ssm (~> 1, < 2)
8
+ aws-sdk-s3 (~> 1, < 2)
9
9
  cfhighlander (~> 0.9, < 1)
10
10
  cfndsl (~> 0.17, < 1)
11
+ terminal-table (~> 1, < 2)
11
12
  thor (~> 0.20)
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
15
16
  specs:
16
17
  aws-eventstream (1.0.3)
17
- aws-partitions (1.176.0)
18
+ aws-partitions (1.180.0)
18
19
  aws-sdk-acm (1.23.0)
19
20
  aws-sdk-core (~> 3, >= 3.56.0)
20
21
  aws-sigv4 (~> 1.1)
@@ -26,7 +27,7 @@ GEM
26
27
  aws-partitions (~> 1.0)
27
28
  aws-sigv4 (~> 1.1)
28
29
  jmespath (~> 1.0)
29
- aws-sdk-ec2 (1.95.0)
30
+ aws-sdk-ec2 (1.96.0)
30
31
  aws-sdk-core (~> 3, >= 3.56.0)
31
32
  aws-sigv4 (~> 1.1)
32
33
  aws-sdk-kms (1.22.0)
@@ -36,9 +37,6 @@ GEM
36
37
  aws-sdk-core (~> 3, >= 3.56.0)
37
38
  aws-sdk-kms (~> 1)
38
39
  aws-sigv4 (~> 1.1)
39
- aws-sdk-ssm (1.50.0)
40
- aws-sdk-core (~> 3, >= 3.56.0)
41
- aws-sigv4 (~> 1.1)
42
40
  aws-sigv4 (1.1.0)
43
41
  aws-eventstream (~> 1.0, >= 1.0.2)
44
42
  cfhighlander (0.9.0)
@@ -61,7 +59,10 @@ GEM
61
59
  netaddr (1.5.1)
62
60
  rake (10.5.0)
63
61
  rubyzip (1.2.3)
62
+ terminal-table (1.8.0)
63
+ unicode-display_width (~> 1.1, >= 1.1.1)
64
64
  thor (0.20.3)
65
+ unicode-display_width (1.6.0)
65
66
 
66
67
  PLATFORMS
67
68
  ruby
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CfnVpn
2
2
 
3
- Manages the resources required to create a client vpn in AWS.
3
+ Manages the resources required to create a [client vpn](https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/what-is.html) in AWS.
4
4
  Uses cloudformation to manage the state of the vpn resources.
5
5
 
6
6
  ## Installation
@@ -16,55 +16,152 @@ Install [docker](https://docs.docker.com/install/)
16
16
  Docker is required to generate the certificates required for the client vpn.
17
17
  The gem uses [openvpn/easy-rsa](https://github.com/OpenVPN/easy-rsa) project in [base2/aws-client-vpn](https://hub.docker.com/r/base2/aws-client-vpn) dokcer image.
18
18
 
19
+ Setup your [AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) by either setting a profile or exporting them as environment variables.
20
+
19
21
  ## Usage
20
22
 
21
- ### help
23
+ ```bash
24
+ Commands:
25
+ cfn-vpn --version, -v # print the version
26
+ cfn-vpn client [name] --bucket=BUCKET --client-cn=CLIENT_CN # Create a new client certificate
27
+ cfn-vpn config [name] --bucket=BUCKET --client-cn=CLIENT_CN # Retrieve the config for the AWS Client VPN
28
+ cfn-vpn help [COMMAND] # Describe available commands or one specific command
29
+ cfn-vpn init [name] --bucket=BUCKET --server-cn=SERVER_CN --subnet-id=SUBNET_ID # Create a AWS Client VPN
30
+ cfn-vpn modify [name] # Modify your AWS Client VPN
31
+ cfn-vpn revoke [name] --bucket=BUCKET --client-cn=CLIENT_CN # Revoke a client certificate
32
+ cfn-vpn routes [name] # List, add or delete client vpn routes
33
+ cfn-vpn sessions [name] # List and kill current vpn connections
34
+ cfn-vpn share [name] --bucket=BUCKET --client-cn=CLIENT_CN # Provide a user with a s3 signed download for certificates and config
35
+ ```
22
36
 
23
- Displays all possible commands
37
+ Global options
24
38
 
25
39
  ```bash
26
- Commands:
27
- cfn-vpn --version, -v # print the version
28
- cfn-vpn help [COMMAND] # Describe available commands or one specific command
29
- cfn-vpn init [name] --server-cn=SERVER_CN --subnet-id=SUBNET_ID # Ciinabox configuration initialization
40
+ p, [--profile=PROFILE] # AWS Profile
41
+ r, [--region=REGION] # AWS Region
42
+ # Default: ENV['AWS_REGION']
43
+ [--verbose], [--no-verbose] # set log level to debug
30
44
  ```
31
45
 
32
- ### init
33
46
 
34
- Initialises a new client vpn and creates all required resources to get it running.
47
+ ### Create a new AWS Client VPN
35
48
 
36
- ```bash
37
- Usage:
38
- cfn-vpn init [name] --server-cn=SERVER_CN --subnet-id=SUBNET_ID
39
-
40
- Options:
41
- p, [--profile=PROFILE] # AWS Profile
42
- r, [--region=REGION] # AWS Region
43
- --server-cn=SERVER_CN # server certificate common name
44
- [--client-cn=CLIENT_CN] # client certificate common name
45
- --subnet-id=SUBNET_ID # subnet id to associate your vpn with
46
- [--cidr=CIDR] # cidr from which to assign client IP addresses
47
- # Default: 10.250.0.0/16
48
-
49
- Ciinabox configuration initialization
49
+ This will create a new client vpn endpoint, associates it with a subnet and sets up a route to the internet.
50
+ During this process a new CA and certificate and keys are generated using [openvpn/easy-rsa](https://github.com/OpenVPN/easy-rsa) and uploaded to ACM.
51
+ These keys are bundled in a tar and stored encrypted in your provided s3 bucket.
52
+
53
+ `cfn-vpn init myvpn --bucket mybucket --server-cn myvpn.domain.tld --subnet-id subnet-123456ab`
54
+
55
+
56
+ ### Create a new client
57
+
58
+ This will generate a new client certificate and key against the CA generated in the `init`.
59
+ It will be bundled into a tar and stored encrypted in your provided s3 bucket.
60
+
61
+ `cfn-vpn client myvpn --client-cn user1 --bucket mybucket`
62
+
63
+
64
+ ### Revoke a client
65
+
66
+ This will revoke the client certificate and apply to the client VPN endpoint.
67
+ Note this wont terminate the session but will stop the client from reconnecting using the certificate.
68
+
69
+ `cfn-vpn revoke myvpn --client-cn user1 --bucket mybucket`
70
+
71
+
72
+ ### Download the config file
73
+
74
+ This will download the client certificate bundle from s3 and the Client VPN config file from the endpoint.
75
+ The config will be modified to include the local path of the client cert and key.
76
+
77
+ `cfn-vpn config myvpn --client-cn user1 --bucket mybucket`
78
+
79
+ *Optional:*
80
+
81
+ `--ignore-routes` By deafult AWS Client VPN will push all routes from your local through the VPN connection. Select this flag to only push routes specified in the Client VPN route table.
82
+
83
+
84
+ ### Modify the Client VPN config
85
+
86
+ This will modify some attributes of the client vpn endpoint.
87
+
88
+ `cfn-vpn config myvpn --dns-servers 8.8.8.8,8.8.4.4`
89
+
90
+ *Optional:*
91
+
92
+ `--dns-servers` Change the DNS servers pushed by the VPN.
93
+ `--subnet-id` Change the associated subnet.
94
+ `--cidr` Change the Client CIDR range.
95
+
96
+
97
+ ### Share client certificates with a user
98
+
99
+ This will generate a presigned url for the client's certificate and config file to allow them to download them to their local computer.
100
+
101
+ `cfn-vpn share myvpn --client-cn user1 --bucket mybucket`
102
+
103
+ You can then share the output with your user
104
+
105
+ ```
106
+ Download the certificates and config from the bellow presigned URLs which will expire in 1 hour.
107
+
108
+ Certificate:
109
+ <presigned url>
110
+
111
+ Config:
112
+ <presigned url>
113
+
114
+ Extract the certificates from the tar and place into a safe location.
115
+ tar xzfv user1.tar.gz -C <path>
116
+
117
+ Modify base2-ciinabox.config.ovpn to include the full location of your extracted certificates
118
+ echo "key /<path>/user1.key" >> myvpn.config.ovpn
119
+ echo "cert /<path>/user1.crt" >> myvpn.config.ovpn
120
+
121
+ Open myvpn.config.ovpn with your favourite openvpn client.
50
122
  ```
51
123
 
52
- ### config
53
124
 
54
- Downloads the opvn config file for the client vpn
125
+ ### Show and Kill Current Connections
126
+
127
+ This is show a table of current connections on the vpn. You can then kill sessions by using the connection id.
55
128
 
56
129
  ```bash
57
- Usage:
58
- cfn-vpn config [name]
130
+ $ cfn-vpn sessions myvpn
131
+ +-------------+---------------------+--------+-------------+-----------------------------------+---------------+--------------+
132
+ | Common Name | Connected (UTC) | Status | IP Address | Connection ID | Ingress Bytes | Egress Bytes |
133
+ +-------------+---------------------+--------+-------------+-----------------------------------+---------------+--------------+
134
+ | user1 | 2019-06-28 04:58:19 | active | 10.250.0.98 | cvpn-connection-05bcc579cb3fdf9a3 | 3000 | 2679 |
135
+ +-------------+---------------------+--------+-------------+-----------------------------------+---------------+--------------+
136
+ ```
137
+
138
+ Specify the `--kill` flag with the connection id to kill the session.
139
+
140
+ `cfn-vpn sessions myvpn --kill cvpn-connection-05bcc579cb3fdf9a3`
141
+
142
+
143
+ ### Show, Add and Remove Routes
59
144
 
60
- Options:
61
- [--profile=PROFILE] # AWS Profile
62
- [--region=REGION] # AWS Region
63
- # Default: ap-southeast-2
145
+ This will display the route table from the Client VPN.
64
146
 
65
- Ciinabox configuration initialization
147
+ ```bash
148
+ +---------------+-----------------------+--------+-----------------+------+-----------+
149
+ | Route | Description | Status | Target | Type | Origin |
150
+ +---------------+-----------------------+--------+-----------------+------+-----------+
151
+ | 10.0.0.0/16 | Default Route | active | subnet-123456ab | Nat | associate |
152
+ | 0.0.0.0/0 | Route to the internet | active | subnet-123456ab | Nat | add-route |
153
+ +---------------+-----------------------+--------+-----------------+------+-----------+
66
154
  ```
67
155
 
156
+ to add a new route specify the `--add` flag with the cidr and a description with the `--desc` flag.
157
+
158
+ `cfn-vpn routes myvpn --add 10.10.0.0/16 --desc "route to peered vpc"`
159
+
160
+ to delete a route specify the `--del` flag with the cidr you want to delete.
161
+
162
+ `cfn-vpn routes myvpn --del 10.10.0.0/16`
163
+
164
+
68
165
  ## Contributing
69
166
 
70
167
  Bug reports and pull requests are welcome on GitHub at https://github.com/base2services/aws-client-vpn.
data/cfn-vpn.gemspec CHANGED
@@ -36,11 +36,12 @@ Gem::Specification.new do |spec|
36
36
  spec.require_paths = ["lib"]
37
37
 
38
38
  spec.add_dependency "thor", "~> 0.20"
39
+ spec.add_dependency "terminal-table", '~> 1', '<2'
39
40
  spec.add_dependency 'cfhighlander', '~> 0.9', '<1'
40
41
  spec.add_dependency 'cfndsl', '~> 0.17', '<1'
41
42
  spec.add_runtime_dependency 'aws-sdk-ec2', '~> 1.95', '<2'
42
43
  spec.add_runtime_dependency 'aws-sdk-acm', '~> 1', '<2'
43
- spec.add_runtime_dependency 'aws-sdk-ssm', '~> 1', '<2'
44
+ spec.add_runtime_dependency 'aws-sdk-s3', '~> 1', '<2'
44
45
  spec.add_runtime_dependency 'aws-sdk-cloudformation', '~> 1', '<2'
45
46
 
46
47
  spec.add_development_dependency "bundler", "~> 2.0"
data/lib/cfnvpn.rb CHANGED
@@ -3,6 +3,11 @@ require 'cfnvpn/version'
3
3
  require 'cfnvpn/init'
4
4
  require 'cfnvpn/modify'
5
5
  require 'cfnvpn/config'
6
+ require 'cfnvpn/client'
7
+ require 'cfnvpn/revoke'
8
+ require 'cfnvpn/sessions'
9
+ require 'cfnvpn/routes'
10
+ require 'cfnvpn/share'
6
11
 
7
12
  module CfnVpn
8
13
  class Cli < Thor
@@ -13,7 +18,6 @@ module CfnVpn
13
18
  puts CfnVpn::VERSION
14
19
  end
15
20
 
16
- # Initializes ciinabox configuration
17
21
  register CfnVpn::Init, 'init', 'init [name]', 'Create a AWS Client VPN'
18
22
  tasks["init"].options = CfnVpn::Init.class_options
19
23
 
@@ -23,8 +27,20 @@ module CfnVpn
23
27
  register CfnVpn::Config, 'config', 'config [name]', 'Retrieve the config for the AWS Client VPN'
24
28
  tasks["config"].options = CfnVpn::Config.class_options
25
29
 
26
- end
30
+ register CfnVpn::Client, 'client', 'client [name]', 'Create a new client certificate'
31
+ tasks["client"].options = CfnVpn::Client.class_options
32
+
33
+ register CfnVpn::Revoke, 'revoke', 'revoke [name]', 'Revoke a client certificate'
34
+ tasks["revoke"].options = CfnVpn::Revoke.class_options
35
+
36
+ register CfnVpn::Sessions, 'sessions', 'sessions [name]', 'List and kill current vpn connections'
37
+ tasks["sessions"].options = CfnVpn::Sessions.class_options
27
38
 
28
- # Aws.config[:retry_limit] = if ENV.key? 'CFNVPN_AWS_RETRY_LIMIT' then (ENV['CFNVPN_AWS_RETRY_LIMIT'].to_i) else 10 end
39
+ register CfnVpn::Routes, 'routes', 'routes [name]', 'List, add or delete client vpn routes'
40
+ tasks["routes"].options = CfnVpn::Routes.class_options
29
41
 
42
+ register CfnVpn::Share, 'share', 'share [name]', 'Provide a user with a s3 signed download for certificates and config'
43
+ tasks["share"].options = CfnVpn::Share.class_options
44
+
45
+ end
30
46
  end
@@ -1,6 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'cfnvpn/acm'
3
- require 'cfnvpn/ssm'
3
+ require 'cfnvpn/s3'
4
4
  require 'cfnvpn/log'
5
5
 
6
6
  module CfnVpn
@@ -11,16 +11,34 @@ module CfnVpn
11
11
  @cfnvpn_name = cfnvpn_name
12
12
  @config_dir = "#{build_dir}/config"
13
13
  @cert_dir = "#{build_dir}/certificates"
14
+ @docker_cmd = %w(docker run -it --rm)
15
+ @easyrsa_image = "base2/aws-client-vpn"
14
16
  FileUtils.mkdir_p(@cert_dir)
15
17
  end
16
18
 
17
- def generate(server_cn,client_cn)
18
- cmd = ["docker", "run", "-it", "--rm"]
19
- cmd << "-e EASYRSA_REQ_CN=#{server_cn}"
20
- cmd << "-e EASYRSA_CLIENT_CN=#{client_cn}"
21
- cmd << "-v #{@cert_dir}:/easy-rsa/output"
22
- cmd << "base2/aws-client-vpn:3.0.5"
23
- return `#{cmd.join(' ')}`
19
+ def generate_ca(server_cn,client_cn)
20
+ @docker_cmd << "-e EASYRSA_REQ_CN=#{server_cn}"
21
+ @docker_cmd << "-e EASYRSA_CLIENT_CN=#{client_cn}"
22
+ @docker_cmd << "-v #{@cert_dir}:/easy-rsa/output"
23
+ @docker_cmd << @easyrsa_image
24
+ @docker_cmd << "sh -c 'create-ca'"
25
+ return `#{@docker_cmd.join(' ')}`
26
+ end
27
+
28
+ def generate_client(client_cn)
29
+ @docker_cmd << "-e EASYRSA_CLIENT_CN=#{client_cn}"
30
+ @docker_cmd << "-v #{@cert_dir}:/easy-rsa/output"
31
+ @docker_cmd << @easyrsa_image
32
+ @docker_cmd << "sh -c 'create-client'"
33
+ return `#{@docker_cmd.join(' ')}`
34
+ end
35
+
36
+ def revoke_client(client_cn)
37
+ @docker_cmd << "-e EASYRSA_CLIENT_CN=#{client_cn}"
38
+ @docker_cmd << "-v #{@cert_dir}:/easy-rsa/output"
39
+ @docker_cmd << @easyrsa_image
40
+ @docker_cmd << "sh -c 'revoke-client'"
41
+ return `#{@docker_cmd.join(' ')}`
24
42
  end
25
43
 
26
44
  def upload_certificates(region,cert,type,cn=nil)
@@ -32,23 +50,20 @@ module CfnVpn
32
50
  return arn
33
51
  end
34
52
 
35
- def store_certificate(region,cert)
36
- ssm = CfnVpn::SSM.new(@cfnvpn_name, region, @cert_dir)
37
- ssm.put_parameter(cert)
53
+ def store_certificate(bucket,bundle)
54
+ s3 = CfnVpn::S3.new(@region,bucket,@name)
55
+ s3.store_object("#{@cert_dir}/#{bundle}")
56
+ end
57
+
58
+ def retrieve_certificate(bucket,bundle)
59
+ s3 = CfnVpn::S3.new(@region,bucket,@name)
60
+ s3.get_object("#{@cert_dir}/#{bundle}")
38
61
  end
39
62
 
40
- def write_certificate(cert_body,name,force)
41
- file = "#{@config_dir}/#{name}"
42
- if File.file?(file)
43
- if force
44
- Log.logger.warn "overriding existing #{name}"
45
- File.write(file, cert_body)
46
- else
47
- Log.logger.info "#{name} already exists"
48
- end
49
- else
50
- File.write(file, cert_body)
51
- end
63
+ def extract_certificate(client_cn)
64
+ tar = "#{@config_dir}/#{client_cn}.tar.gz"
65
+ `tar xzfv #{tar} -C #{@config_dir} --strip 2`
66
+ File.delete(tar) if File.exist?(tar)
52
67
  end
53
68
 
54
69
  end
@@ -0,0 +1,42 @@
1
+ require 'thor'
2
+ require 'cfnvpn/log'
3
+ require 'cfnvpn/s3'
4
+
5
+ module CfnVpn
6
+ class Client < Thor::Group
7
+ include Thor::Actions
8
+ include CfnVpn::Log
9
+
10
+ argument :name
11
+
12
+ class_option :profile, aliases: :p, desc: 'AWS Profile'
13
+ class_option :region, aliases: :r, default: ENV['AWS_REGION'], desc: 'AWS Region'
14
+ class_option :verbose, desc: 'set log level to debug', type: :boolean
15
+
16
+ class_option :bucket, desc: 's3 bucket', required: true
17
+ class_option :client_cn, desc: 'client certificate common name', required: true
18
+
19
+ def self.source_root
20
+ File.dirname(__FILE__)
21
+ end
22
+
23
+ def set_loglevel
24
+ Log.logger.level = Logger::DEBUG if @options['verbose']
25
+ end
26
+
27
+ def set_directory
28
+ @build_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
29
+ @cert_dir = "#{@build_dir}/certificates"
30
+ end
31
+
32
+ def create_certificate
33
+ s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
34
+ s3.get_object("#{@cert_dir}/ca.tar.gz")
35
+ Log.logger.info "Generating new client certificate #{@options['client_cn']} using openvpn easy-rsa"
36
+ cert = CfnVpn::Certificates.new(@build_dir,@name)
37
+ Log.logger.debug cert.generate_client(@options['client_cn'])
38
+ s3.store_object("#{@cert_dir}/#{@options['client_cn']}.tar.gz")
39
+ end
40
+
41
+ end
42
+ end
@@ -1,5 +1,6 @@
1
1
  require 'aws-sdk-ec2'
2
2
  require 'cfnvpn/log'
3
+ require 'netaddr'
3
4
 
4
5
  module CfnVpn
5
6
  class ClientVpn
@@ -18,13 +19,17 @@ module CfnVpn
18
19
  Log.logger.error "unable to find endpoint with tag Key: cfnvpn:name with Value: #{@name}"
19
20
  raise "Unable to find client vpn"
20
21
  end
21
- resp.client_vpn_endpoints.first
22
+ return resp.client_vpn_endpoints.first
22
23
  end
23
24
 
24
25
  def get_endpoint_id()
25
26
  return get_endpoint().client_vpn_endpoint_id
26
27
  end
27
28
 
29
+ def get_dns_servers()
30
+ return get_endpoint().dns_servers
31
+ end
32
+
28
33
  def get_config(endpoint_id)
29
34
  resp = @client.export_client_vpn_client_configuration({
30
35
  client_vpn_endpoint_id: endpoint_id
@@ -32,5 +37,118 @@ module CfnVpn
32
37
  return resp.client_configuration
33
38
  end
34
39
 
40
+ def get_rekove_list(endpoint_id)
41
+ resp = @client.export_client_vpn_client_certificate_revocation_list({
42
+ client_vpn_endpoint_id: endpoint_id
43
+ })
44
+ return resp.certificate_revocation_list
45
+ end
46
+
47
+ def put_revoke_list(endpoint_id,revoke_list)
48
+ list = File.read(revoke_list)
49
+ @client.import_client_vpn_client_certificate_revocation_list({
50
+ client_vpn_endpoint_id: endpoint_id,
51
+ certificate_revocation_list: list
52
+ })
53
+ end
54
+
55
+ def get_sessions(endpoint_id)
56
+ params = {
57
+ client_vpn_endpoint_id: endpoint_id,
58
+ max_results: 20
59
+ }
60
+ resp = @client.describe_client_vpn_connections(params)
61
+ return resp.connections
62
+ end
63
+
64
+ def kill_session(endpoint_id, connection_id)
65
+ @client.terminate_client_vpn_connections({
66
+ client_vpn_endpoint_id: endpoint_id,
67
+ connection_id: connection_id
68
+ })
69
+ end
70
+
71
+ def get_target_networks(endpoint_id)
72
+ resp = @client.describe_client_vpn_target_networks({
73
+ client_vpn_endpoint_id: endpoint_id
74
+ })
75
+ return resp.client_vpn_target_networks.first
76
+ end
77
+
78
+ def add_route(cidr,description)
79
+ endpoint_id = get_endpoint_id()
80
+ subnet_id = get_target_networks(endpoint_id).target_network_id
81
+
82
+ @client.create_client_vpn_route({
83
+ client_vpn_endpoint_id: endpoint_id,
84
+ destination_cidr_block: cidr,
85
+ target_vpc_subnet_id: subnet_id,
86
+ description: description
87
+ })
88
+
89
+ resp = @client.authorize_client_vpn_ingress({
90
+ client_vpn_endpoint_id: endpoint_id,
91
+ target_network_cidr: cidr,
92
+ authorize_all_groups: true,
93
+ description: description
94
+ })
95
+
96
+ return resp.status
97
+ end
98
+
99
+ def del_route(cidr)
100
+ endpoint_id = get_endpoint_id()
101
+ subnet_id = get_target_networks(endpoint_id).target_network_id
102
+
103
+ revoke = @client.revoke_client_vpn_ingress({
104
+ revoke_all_groups: true,
105
+ client_vpn_endpoint_id: endpoint_id,
106
+ target_network_cidr: cidr
107
+ })
108
+
109
+ route = @client.delete_client_vpn_route({
110
+ client_vpn_endpoint_id: endpoint_id,
111
+ target_vpc_subnet_id: subnet_id,
112
+ destination_cidr_block: cidr
113
+ })
114
+
115
+ return route.status, revoke.status
116
+ end
117
+
118
+ def get_routes()
119
+ endpoint_id = get_endpoint_id()
120
+ resp = @client.describe_client_vpn_routes({
121
+ client_vpn_endpoint_id: endpoint_id,
122
+ max_results: 20
123
+ })
124
+ return resp.routes
125
+ end
126
+
127
+ def route_exists?(cidr)
128
+ routes = get_routes()
129
+ resp = routes.select { |route| route if route.destination_cidr == cidr }
130
+ return resp.any?
131
+ end
132
+
133
+ def get_routes()
134
+ endpoint_id = get_endpoint_id()
135
+ resp = @client.describe_client_vpn_routes({
136
+ client_vpn_endpoint_id: endpoint_id,
137
+ max_results: 20
138
+ })
139
+ return resp.routes
140
+ end
141
+
142
+ def get_route_with_mask()
143
+ routes = get_routes()
144
+ routes
145
+ .select { |r| r if r.destination_cidr != '0.0.0.0/0' }
146
+ .collect { |r| { route: r.destination_cidr.split('/').first, mask: NetAddr::CIDR.create(r.destination_cidr).wildcard_mask }}
147
+ end
148
+
149
+ def valid_cidr?(cidr)
150
+ return !(cidr =~ /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/).nil?
151
+ end
152
+
35
153
  end
36
154
  end
data/lib/cfnvpn/config.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'cfnvpn/clientvpn'
2
- require 'cfnvpn/ssm'
3
2
  require 'cfnvpn/log'
4
3
 
5
4
  module CfnVpn
@@ -12,9 +11,10 @@ module CfnVpn
12
11
  class_option :profile, desc: 'AWS Profile'
13
12
  class_option :region, default: ENV['AWS_REGION'], desc: 'AWS Region'
14
13
  class_option :verbose, desc: 'set log level to debug', type: :boolean
14
+ class_option :bucket, required: true, desc: 's3 bucket'
15
+ class_option :client_cn, required: true, desc: "client certificates to download"
15
16
 
16
- class_option :key_path, required: true, desc: 'full file path to the client vpn key'
17
- class_option :crt_path, required: true, desc: 'full file path to the client vpn certificate'
17
+ class_option :ignore_routes, alias: :i, type: :boolean, desc: "Ignore client VPN pushed routes and set routes in config file"
18
18
 
19
19
  def self.source_root
20
20
  File.dirname(__FILE__)
@@ -25,8 +25,8 @@ module CfnVpn
25
25
  end
26
26
 
27
27
  def create_config_directory
28
- @home_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
29
- @config_dir = "#{@home_dir}/config"
28
+ @build_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
29
+ @config_dir = "#{@build_dir}/config"
30
30
  Log.logger.debug("Creating config directory #{@config_dir}")
31
31
  FileUtils.mkdir_p(@config_dir)
32
32
  end
@@ -38,11 +38,44 @@ module CfnVpn
38
38
  @config = vpn.get_config(@endpoint_id)
39
39
  end
40
40
 
41
+ def download_certificates
42
+ download = true
43
+ if File.exists?("#{@config_dir}/#{@options['client_cn']}.crt")
44
+ download = yes? "Certificates for #{@options['client_cn']} already exist in #{@config_dir}. Do you want to download again? ", :green
45
+ end
46
+
47
+ if download
48
+ Log.logger.info "Downloading certificates for #{@options['client_cn']} to #{@config_dir}"
49
+ s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
50
+ s3.get_object("#{@config_dir}/#{@options['client_cn']}.tar.gz")
51
+ cert = CfnVpn::Certificates.new(@build_dir,@name)
52
+ Log.logger.debug cert.extract_certificate(@options['client_cn'])
53
+ end
54
+ end
55
+
41
56
  def alter_config
42
57
  string = (0...8).map { (65 + rand(26)).chr.downcase }.join
43
58
  @config.sub!(@endpoint_id, "#{string}.#{@endpoint_id}")
44
- @config.concat("\n\ncert #{@options['crt_path']}")
45
- @config.concat("\nkey #{@options['key_path']}\n")
59
+ @config.concat("\n\ncert #{@config_dir}/#{@options['client_cn']}.crt")
60
+ @config.concat("\nkey #{@config_dir}/#{@options['client_cn']}.key\n")
61
+ end
62
+
63
+ def add_routes
64
+ if @options['ignore_routes']
65
+ Log.logger.debug "Ignoring routes pushed by the client vpn"
66
+ @config.concat("\nroute-nopull\n")
67
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
68
+ routes = vpn.get_route_with_mask
69
+ Log.logger.debug "Found routes #{routes}"
70
+ routes.each do |r|
71
+ @config.concat("route #{r[:route]} #{r[:mask]}\n")
72
+ end
73
+ dns_servers = vpn.get_dns_servers()
74
+ if dns_servers.any?
75
+ Log.logger.debug "Found DNS servers #{dns_servers.join(' ')}"
76
+ @config.concat("dhcp-option DNS #{dns_servers.first}\n")
77
+ end
78
+ end
46
79
  end
47
80
 
48
81
  def write_config
data/lib/cfnvpn/init.rb CHANGED
@@ -20,6 +20,7 @@ module CfnVpn
20
20
 
21
21
  class_option :server_cn, required: true, desc: 'server certificate common name'
22
22
  class_option :client_cn, desc: 'client certificate common name'
23
+ class_option :bucket, required: true, desc: 's3 bucket'
23
24
 
24
25
  class_option :subnet_id, required: true, desc: 'subnet id to associate your vpn with'
25
26
  class_option :cidr, default: '10.250.0.0/16', desc: 'cidr from which to assign client IP addresses'
@@ -61,14 +62,16 @@ module CfnVpn
61
62
  def generate_server_certificates
62
63
  Log.logger.info "Generating certificates using openvpn easy-rsa"
63
64
  cert = CfnVpn::Certificates.new(@build_dir,@name)
64
- @client_cn = @options['client_cn'] ? @options['client_cn'] : "#{@name}.#{@options['server_cn']}"
65
- Log.logger.debug cert.generate(@options['server_cn'],@client_cn)
65
+ @client_cn = @options['client_cn'] ? @options['client_cn'] : "client-vpn.#{@options['server_cn']}"
66
+ Log.logger.debug cert.generate_ca(@options['server_cn'],@client_cn)
66
67
  end
67
68
 
68
69
  def upload_certificates
69
70
  cert = CfnVpn::Certificates.new(@build_dir,@name)
70
71
  @config['parameters']['ServerCertificateArn'] = cert.upload_certificates(@options['region'],'server','server',@options['server_cn'])
71
72
  @config['parameters']['ClientCertificateArn'] = cert.upload_certificates(@options['region'],@client_cn,'client')
73
+ s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
74
+ s3.store_object("#{@build_dir}/certificates/ca.tar.gz")
72
75
  end
73
76
 
74
77
  def deploy_vpn
@@ -0,0 +1,49 @@
1
+ require 'thor'
2
+ require 'cfnvpn/log'
3
+ require 'cfnvpn/s3'
4
+
5
+ module CfnVpn
6
+ class Revoke < Thor::Group
7
+ include Thor::Actions
8
+ include CfnVpn::Log
9
+
10
+ argument :name
11
+
12
+ class_option :profile, aliases: :p, desc: 'AWS Profile'
13
+ class_option :region, aliases: :r, default: ENV['AWS_REGION'], desc: 'AWS Region'
14
+ class_option :verbose, desc: 'set log level to debug', type: :boolean
15
+
16
+ class_option :bucket, desc: 's3 bucket', required: true
17
+ class_option :client_cn, desc: 'client certificate common name', required: true
18
+
19
+ def self.source_root
20
+ File.dirname(__FILE__)
21
+ end
22
+
23
+ def set_loglevel
24
+ Log.logger.level = Logger::DEBUG if @options['verbose']
25
+ end
26
+
27
+ def set_directory
28
+ @build_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
29
+ @cert_dir = "#{@build_dir}/certificates"
30
+ end
31
+
32
+ def revoke_certificate
33
+ cert = CfnVpn::Certificates.new(@build_dir,@name)
34
+ s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
35
+ s3.get_object("#{@cert_dir}/ca.tar.gz")
36
+ s3.get_object("#{@cert_dir}/#{@options['client_cn']}.tar.gz")
37
+ Log.logger.info "Generating new client certificate #{@options['client_cn']} using openvpn easy-rsa"
38
+ Log.logger.debug cert.revoke_client(@options['client_cn'])
39
+ end
40
+
41
+ def apply_rekocation_list
42
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
43
+ endpoint_id = vpn.get_endpoint_id()
44
+ vpn.put_revoke_list(endpoint_id,"#{@cert_dir}/crl.pem")
45
+ Log.logger.info("revoked client #{@options['client_cn']} from #{endpoint_id}")
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,83 @@
1
+ require 'thor'
2
+ require 'cfnvpn/log'
3
+ require 'cfnvpn/s3'
4
+
5
+ module CfnVpn
6
+ class Routes < Thor::Group
7
+ include Thor::Actions
8
+ include CfnVpn::Log
9
+
10
+ argument :name
11
+
12
+ class_option :profile, aliases: :p, desc: 'AWS Profile'
13
+ class_option :region, aliases: :r, default: ENV['AWS_REGION'], desc: 'AWS Region'
14
+ class_option :verbose, desc: 'set log level to debug', type: :boolean
15
+
16
+ class_option :add, desc: 'add cidr to route through the client vpn'
17
+ class_option :del, desc: 'delete cidr route from the client vpn'
18
+ class_option :desc, desc: 'description of the route'
19
+
20
+ def self.source_root
21
+ File.dirname(__FILE__)
22
+ end
23
+
24
+ def set_loglevel
25
+ Log.logger.level = Logger::DEBUG if @options['verbose']
26
+ end
27
+
28
+ def set_directory
29
+ @build_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
30
+ end
31
+
32
+ def add_route
33
+ if !@options['add'].nil?
34
+ if @options['desc'].nil?
35
+ Log.logger.error "--desc option must be provided if adding a new route"
36
+ exit 1
37
+ end
38
+
39
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
40
+
41
+ if vpn.route_exists?(@options['add'])
42
+ Log.logger.error "route #{@options['add']} already exists in the client vpn"
43
+ exit 1
44
+ end
45
+
46
+ Log.logger.info "Adding new route for #{@options['add']}"
47
+ vpn.add_route(@options['add'],@options['desc'])
48
+ end
49
+ end
50
+
51
+ def del_route
52
+ if !@options['del'].nil?
53
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
54
+
55
+ if !vpn.route_exists?(@options['del'])
56
+ Log.logger.error "route #{@options['del']} doesn't exist in the client vpn"
57
+ exit 1
58
+ end
59
+ delete = yes? "Delete route #{@options['del']}?", :yellow
60
+ if delete
61
+ Log.logger.info "Deleting route for #{@options['del']}"
62
+ vpn.del_route(@options['del'])
63
+ end
64
+ end
65
+ end
66
+
67
+ def get_routes
68
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
69
+ @routes = vpn.get_routes()
70
+ end
71
+
72
+ def display_routes
73
+ rows = @routes.collect do |s|
74
+ [ s.destination_cidr, s.description, s.status.code, s.target_subnet, s.type, s.origin ]
75
+ end
76
+ table = Terminal::Table.new(
77
+ :headings => ['Route', 'Description', 'Status', 'Target', 'Type', 'Origin'],
78
+ :rows => rows)
79
+ puts table
80
+ end
81
+
82
+ end
83
+ end
data/lib/cfnvpn/s3.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'aws-sdk-s3'
2
+ require 'fileutils'
3
+
4
+ module CfnVpn
5
+ class S3
6
+
7
+ def initialize(region, bucket, name)
8
+ @client = Aws::S3::Client.new(region: region)
9
+ @bucket = bucket
10
+ @name = name
11
+ @path = "cfnvpn/certificates/#{@name}"
12
+ end
13
+
14
+ def store_object(file)
15
+ body = File.open(file, 'rb').read
16
+ file_name = file.split('/').last
17
+ Log.logger.debug("uploading #{file} to s3://#{@bucket}/#{@path}/#{file_name}")
18
+ @client.put_object({
19
+ body: body,
20
+ bucket: @bucket,
21
+ key: "#{@path}/#{file_name}",
22
+ server_side_encryption: "AES256",
23
+ tagging: "cfnvpn:name=#{@name}"
24
+ })
25
+ end
26
+
27
+ def get_object(file)
28
+ file_name = file.split('/').last
29
+ Log.logger.debug("downloading s3://#{@bucket}/#{@path}/#{file_name} to #{file}")
30
+ @client.get_object(
31
+ response_target: file,
32
+ bucket: @bucket,
33
+ key: "#{@path}/#{file_name}")
34
+ end
35
+
36
+ def store_config(config)
37
+ Log.logger.debug("uploading config to s3://#{@bucket}/#{@path}/#{@name}.config.ovpn")
38
+ @client.put_object({
39
+ body: config,
40
+ bucket: @bucket,
41
+ key: "#{@path}/#{@name}.config.ovpn",
42
+ tagging: "cfnvpn:name=#{@name}"
43
+ })
44
+ end
45
+
46
+ def get_url(file)
47
+ presigner = Aws::S3::Presigner.new(client: @client)
48
+ params = {
49
+ bucket: @bucket,
50
+ key: "#{@path}/#{file}",
51
+ expires_in: 3600
52
+ }
53
+ presigner.presigned_url(:get_object, params)
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,64 @@
1
+ require 'thor'
2
+ require 'terminal-table'
3
+ require 'cfnvpn/log'
4
+ require 'cfnvpn/clientvpn'
5
+
6
+ module CfnVpn
7
+ class Sessions < Thor::Group
8
+ include Thor::Actions
9
+ include CfnVpn::Log
10
+
11
+ argument :name
12
+
13
+ class_option :profile, aliases: :p, desc: 'AWS Profile'
14
+ class_option :region, aliases: :r, default: ENV['AWS_REGION'], desc: 'AWS Region'
15
+ class_option :verbose, desc: 'set log level to debug', type: :boolean
16
+
17
+ class_option :kill, desc: 'connection id to kill the connection'
18
+
19
+ def self.source_root
20
+ File.dirname(__FILE__)
21
+ end
22
+
23
+ def set_loglevel
24
+ Log.logger.level = Logger::DEBUG if @options['verbose']
25
+ end
26
+
27
+ def set_directory
28
+ @build_dir = "#{ENV['HOME']}/.cfnvpn/#{@name}"
29
+ end
30
+
31
+ def get_endpoint
32
+ @vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
33
+ @endpoint_id = @vpn.get_endpoint_id()
34
+ end
35
+
36
+ def kill_session
37
+ if !@options['kill'].nil?
38
+ sessions = @vpn.get_sessions(@endpoint_id)
39
+ session = sessions.select { |s| s if s.connection_id == @options['kill'] }.first
40
+ if session.any? && session.status.code == "active"
41
+ terminate = yes? "Terminate connection #{@options['kill']} for #{session.common_name}?", :yellow
42
+ if terminate
43
+ Log.logger.info "Terminating connection #{@options['kill']} for #{session.common_name}"
44
+ @vpn.kill_session(@endpoint_id,@options['kill'])
45
+ end
46
+ else
47
+ Log.logger.error "Connection id #{@options['kill']} doesn't exist or is not active"
48
+ end
49
+ end
50
+ end
51
+
52
+ def display_sessions
53
+ sessions = @vpn.get_sessions(@endpoint_id)
54
+ rows = sessions.collect do |s|
55
+ [ s.common_name, s.connection_established_time, s.status.code, s.client_ip, s.connection_id, s.ingress_bytes, s.egress_bytes ]
56
+ end
57
+ table = Terminal::Table.new(
58
+ :headings => ['Common Name', 'Connected (UTC)', 'Status', 'IP Address', 'Connection ID', 'Ingress Bytes', 'Egress Bytes'],
59
+ :rows => rows)
60
+ puts table
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,85 @@
1
+ require 'cfnvpn/log'
2
+ require 'cfnvpn/s3'
3
+
4
+ module CfnVpn
5
+ class Share < Thor::Group
6
+ include Thor::Actions
7
+ include CfnVpn::Log
8
+
9
+ argument :name
10
+
11
+ class_option :profile, desc: 'AWS Profile'
12
+ class_option :region, default: ENV['AWS_REGION'], desc: 'AWS Region'
13
+ class_option :verbose, desc: 'set log level to debug', type: :boolean
14
+
15
+ class_option :bucket, required: true, desc: 's3 bucket'
16
+ class_option :client_cn, required: true, desc: "client certificates to download"
17
+ class_option :ignore_routes, alias: :i, type: :boolean, desc: "Ignore client VPN pushed routes and set routes in config file"
18
+
19
+ def self.source_root
20
+ File.dirname(__FILE__)
21
+ end
22
+
23
+ def set_loglevel
24
+ Log.logger.level = Logger::DEBUG if @options['verbose']
25
+ end
26
+
27
+ def copy_config_to_s3
28
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
29
+ @endpoint_id = vpn.get_endpoint_id()
30
+ Log.logger.debug "downloading client config for #{@endpoint_id}"
31
+ @config = vpn.get_config(@endpoint_id)
32
+ string = (0...8).map { (65 + rand(26)).chr.downcase }.join
33
+ @config.sub!(@endpoint_id, "#{string}.#{@endpoint_id}")
34
+ end
35
+
36
+ def add_routes
37
+ if @options['ignore_routes']
38
+ Log.logger.debug "Ignoring routes pushed by the client vpn"
39
+ @config.concat("\nroute-nopull\n")
40
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
41
+ routes = vpn.get_route_with_mask
42
+ Log.logger.debug "Found routes #{routes}"
43
+ routes.each do |r|
44
+ @config.concat("route #{r[:route]} #{r[:mask]}\n")
45
+ end
46
+ dns_servers = vpn.get_dns_servers()
47
+ if dns_servers.any?
48
+ Log.logger.debug "Found DNS servers #{dns_servers.join(' ')}"
49
+ @config.concat("dhcp-option DNS #{dns_servers.first}\n")
50
+ end
51
+ end
52
+ end
53
+
54
+ def upload_config
55
+ @s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
56
+ @s3.store_config(@config)
57
+ end
58
+
59
+ def get_certificate_url
60
+ @certificate_url = @s3.get_url("#{@options['client_cn']}.tar.gz")
61
+ Log.logger.debug "Certificate presigned url: #{@certificate_url}"
62
+ end
63
+
64
+ def get_config_url
65
+ @config_url = @s3.get_url("#{@name}.config.ovpn")
66
+ Log.logger.debug "Config presigned url: #{@config_url}"
67
+ end
68
+
69
+ def display_instructions
70
+ Log.logger.info "Share the bellow instruction with the user..."
71
+ say "\nDownload the certificates and config from the bellow presigned URLs which will expire in 1 hour."
72
+ say "\nCertificate:"
73
+ say "\tcurl #{@certificate_url} > #{@options['client_cn']}.tar.gz", :cyan
74
+ say "\nConfig:\n"
75
+ say "\tcurl #{@certificate_url} > #{@name}.config.ovpn", :cyan
76
+ say "\nExtract the certificates from the tar and place into a safe location."
77
+ say "\ttar xzfv #{@options['client_cn']}.tar.gz -C <path> --strip 2", :cyan
78
+ say "\nModify #{@name}.config.ovpn to include the full location of your extracted certificates"
79
+ say "\techo \"key /<path>/#{@options['client_cn']}.key\" >> #{@name}.config.ovpn", :cyan
80
+ say "\techo \"cert /<path>/#{@options['client_cn']}.crt\" >> #{@name}.config.ovpn", :cyan
81
+ say "\nOpen #{@name}.config.ovpn with your favourite openvpn client."
82
+ end
83
+
84
+ end
85
+ end
@@ -1,4 +1,4 @@
1
1
  module CfnVpn
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  CHANGE_SET_VERSION = VERSION.gsub('.', '-').freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-vpn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guslington
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-27 00:00:00.000000000 Z
11
+ date: 2019-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,26 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.20'
27
+ - !ruby/object:Gem::Dependency
28
+ name: terminal-table
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '2'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: cfhighlander
29
49
  requirement: !ruby/object:Gem::Requirement
@@ -105,7 +125,7 @@ dependencies:
105
125
  - !ruby/object:Gem::Version
106
126
  version: '2'
107
127
  - !ruby/object:Gem::Dependency
108
- name: aws-sdk-ssm
128
+ name: aws-sdk-s3
109
129
  requirement: !ruby/object:Gem::Requirement
110
130
  requirements:
111
131
  - - "~>"
@@ -193,13 +213,18 @@ files:
193
213
  - lib/cfnvpn/acm.rb
194
214
  - lib/cfnvpn/certificates.rb
195
215
  - lib/cfnvpn/cfhighlander.rb
216
+ - lib/cfnvpn/client.rb
196
217
  - lib/cfnvpn/clientvpn.rb
197
218
  - lib/cfnvpn/cloudformation.rb
198
219
  - lib/cfnvpn/config.rb
199
220
  - lib/cfnvpn/init.rb
200
221
  - lib/cfnvpn/log.rb
201
222
  - lib/cfnvpn/modify.rb
202
- - lib/cfnvpn/ssm.rb
223
+ - lib/cfnvpn/revoke.rb
224
+ - lib/cfnvpn/routes.rb
225
+ - lib/cfnvpn/s3.rb
226
+ - lib/cfnvpn/sessions.rb
227
+ - lib/cfnvpn/share.rb
203
228
  - lib/cfnvpn/templates/cfnvpn.cfhighlander.rb.tt
204
229
  - lib/cfnvpn/version.rb
205
230
  homepage: https://github.com/base2services/aws-client-vpn
data/lib/cfnvpn/ssm.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'aws-sdk-ssm'
2
- require 'fileutils'
3
- require 'cfnvpn/log'
4
-
5
- module CfnVpn
6
- class SSM
7
- include CfnVpn::Log
8
-
9
- def initialize(name,region,cert_dir)
10
- @name = name
11
- @cert_dir = cert_dir
12
- @path_prefix = "/cfnvpn/#{@name}"
13
- @client = Aws::SSM::Client.new(region: region)
14
- end
15
-
16
- def get_parameter(cert)
17
- begin
18
- resp = @client.get_parameter({
19
- name: "#{@path_prefix}/#{cert}",
20
- with_decryption: true
21
- })
22
- rescue Aws::SSM::Errors::ParameterNotFound
23
- Log.logger.debug("Parameter #{@path_prefix}/#{cert} not found")
24
- return false
25
- end
26
- Log.logger.debug("found parameter #{@path_prefix}/#{cert}")
27
- return resp.parameter.value
28
- end
29
-
30
- def put_parameter(cert)
31
- certificate = File.read("#{@cert_dir}/#{cert}")
32
- Log.logger.debug("Reading certificate #{@cert_dir}/#{cert}")
33
- ext = cert.split('.').last
34
- @client.put_parameter({
35
- name: "#{@path_prefix}/#{@name}.#{ext}",
36
- description: "cfn-vpn #{@name} #{cert}",
37
- value: certificate,
38
- type: "SecureString",
39
- overwrite: false,
40
- tags: [
41
- { key: "cfnvpn:name", value: @name },
42
- { key: "cfnvpn:certificate", value: cert }
43
- ],
44
- tier: "Advanced",
45
- })
46
- Log.logger.info("Stored #{cert} in ssm parameter #{@path_prefix}/#{@name}.#{ext}")
47
- end
48
-
49
- end
50
- end