cfn-vpn 0.2.0 → 0.3.0

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.
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