cfn-vpn 1.1.1 → 1.3.3

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: bb42ae1b12eb544e6d2d54276bb387efb5383c2037502a2ec155fd41ad522221
4
- data.tar.gz: c3e774c1baf08c3ca0cdca6dc7b11014191f69eb183b63fddd6bbb56be522362
3
+ metadata.gz: c46ffdf0579ffd7c1fd42efadc969bbd095f9f789dfcb5b9e3e2aef7f85e959c
4
+ data.tar.gz: 7a6e1a34fa32b2246a8998e8645381635e8c5adf7a6bf978c241ea4d7e4ee217
5
5
  SHA512:
6
- metadata.gz: b7c73bf1fcd82cb53a571f3bf60223b8eff89183a7afca82beead5b1ceb422370165b3a39c08c90ccf823a64bca8560babbda4210079a4a7a3c2122f0edf2a79
7
- data.tar.gz: 5e944fa67a1fee92a5a42bb2f6ae5117a9907443cca284dde9a49e25899fd719adc5e5e96e3a45095090e16e0f615b72348ddac24798a3d4636019c849f15d13
6
+ metadata.gz: 6aa8e34eab7fe87a36128e299a3603f6e2cad58bf55cc9a2ff4f3847306a0ce92ba20c6a9471f7356c43eee85ccd6a362bed7bf7feb14df2a97cb54cc0af546d
7
+ data.tar.gz: 5aefb22f6d9ea925877f0811897fdd3e4a47286769cb106e19a46df6ccd7d2ce29d30bdc93ea2c87c4fb686609a33c009186057b248af9b33645b15d72d8f22c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfn-vpn (1.0.0)
4
+ cfn-vpn (1.2.0)
5
5
  aws-sdk-acm (~> 1, < 2)
6
6
  aws-sdk-cloudformation (~> 1, < 2)
7
7
  aws-sdk-ec2 (~> 1.95, < 2)
@@ -9,46 +9,48 @@ PATH
9
9
  aws-sdk-ssm (~> 1, < 2)
10
10
  cfndsl (~> 1, < 2)
11
11
  netaddr (= 2.0.4)
12
+ rubyzip (~> 2.3)
12
13
  terminal-table (~> 1, < 2)
13
14
  thor (~> 0.20)
14
15
 
15
16
  GEM
16
17
  remote: https://rubygems.org/
17
18
  specs:
18
- aws-eventstream (1.1.0)
19
- aws-partitions (1.390.0)
20
- aws-sdk-acm (1.38.0)
21
- aws-sdk-core (~> 3, >= 3.109.0)
19
+ aws-eventstream (1.1.1)
20
+ aws-partitions (1.432.0)
21
+ aws-sdk-acm (1.39.0)
22
+ aws-sdk-core (~> 3, >= 3.112.0)
22
23
  aws-sigv4 (~> 1.1)
23
- aws-sdk-cloudformation (1.44.0)
24
- aws-sdk-core (~> 3, >= 3.109.0)
24
+ aws-sdk-cloudformation (1.49.0)
25
+ aws-sdk-core (~> 3, >= 3.112.0)
25
26
  aws-sigv4 (~> 1.1)
26
- aws-sdk-core (3.109.2)
27
+ aws-sdk-core (3.113.0)
27
28
  aws-eventstream (~> 1, >= 1.0.2)
28
29
  aws-partitions (~> 1, >= 1.239.0)
29
30
  aws-sigv4 (~> 1.1)
30
31
  jmespath (~> 1.0)
31
- aws-sdk-ec2 (1.208.0)
32
+ aws-sdk-ec2 (1.220.0)
32
33
  aws-sdk-core (~> 3, >= 3.109.0)
33
34
  aws-sigv4 (~> 1.1)
34
- aws-sdk-kms (1.39.0)
35
- aws-sdk-core (~> 3, >= 3.109.0)
35
+ aws-sdk-kms (1.43.0)
36
+ aws-sdk-core (~> 3, >= 3.112.0)
36
37
  aws-sigv4 (~> 1.1)
37
- aws-sdk-s3 (1.84.0)
38
- aws-sdk-core (~> 3, >= 3.109.0)
38
+ aws-sdk-s3 (1.91.0)
39
+ aws-sdk-core (~> 3, >= 3.112.0)
39
40
  aws-sdk-kms (~> 1)
40
41
  aws-sigv4 (~> 1.1)
41
- aws-sdk-ssm (1.97.0)
42
- aws-sdk-core (~> 3, >= 3.109.0)
42
+ aws-sdk-ssm (1.104.0)
43
+ aws-sdk-core (~> 3, >= 3.112.0)
43
44
  aws-sigv4 (~> 1.1)
44
- aws-sigv4 (1.2.2)
45
+ aws-sigv4 (1.2.3)
45
46
  aws-eventstream (~> 1, >= 1.0.2)
46
- cfndsl (1.2.0)
47
+ cfndsl (1.3.1)
47
48
  hana (~> 1.3)
48
- hana (1.3.6)
49
+ hana (1.3.7)
49
50
  jmespath (1.4.0)
50
51
  netaddr (2.0.4)
51
52
  rake (13.0.1)
53
+ rubyzip (2.3.0)
52
54
  terminal-table (1.8.0)
53
55
  unicode-display_width (~> 1.1, >= 1.1.1)
54
56
  thor (0.20.3)
@@ -63,4 +65,4 @@ DEPENDENCIES
63
65
  rake (~> 13.0)
64
66
 
65
67
  BUNDLED WITH
66
- 2.0.1
68
+ 2.1.4
data/cfn-vpn.gemspec CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "terminal-table", '~> 1', '<2'
38
38
  spec.add_dependency 'cfndsl', '~> 1', '<2'
39
39
  spec.add_dependency 'netaddr', '2.0.4'
40
+ spec.add_dependency 'rubyzip', '~> 2.3'
40
41
  spec.add_runtime_dependency 'aws-sdk-ec2', '~> 1.95', '<2'
41
42
  spec.add_runtime_dependency 'aws-sdk-acm', '~> 1', '<2'
42
43
  spec.add_runtime_dependency 'aws-sdk-s3', '~> 1', '<2'
data/docs/README.md CHANGED
@@ -31,7 +31,7 @@ dig @10.0.0.2 google.com
31
31
 
32
32
  ## Authentication Types
33
33
 
34
- `cfn-vpn` supports certificate and federated type authentication for AWS Client-VPN. It currently doesn't support Active Directory type authentication.
34
+ `cfn-vpn` supports certificate, federated and active directory type authentication for AWS Client-VPN.
35
35
  For further information on the authentication types please visit https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html
36
36
 
37
37
  ## CfnVpn Documentation
@@ -41,4 +41,4 @@ For further information on the authentication types please visit https://docs.aw
41
41
  3. [Managing Certificate Users](certificate-users.md)
42
42
  4. [Managing Routes](routes.md)
43
43
  5. [Stop and Start Client-VPN](scheduling.md)
44
- 6. [Managing Sessions](sessions.md)
44
+ 6. [Managing Sessions](sessions.md)
@@ -38,62 +38,117 @@ Optionally export the AWS region if not providing `--region` flag
38
38
  export AWS_REGION="us-east-1"
39
39
  ```
40
40
 
41
- ## Initialising CfnVpn
41
+
42
+ ## Initializing CfnVpn
42
43
 
43
44
  to launch a new CfnVpn stack run the `init` command along with the options.
44
45
 
45
46
  ### Certificate Authenticated VPN
46
47
 
47
- The following command and required option will launch a new certificate based Client-VPN
48
+ This is the default option when launching a ClientVPN using certificated based authentication. https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html#mutual
49
+
50
+ The following command and required options will launch a new certificate based Client-VPN
48
51
 
49
52
  ```sh
50
53
  cfn-vpn init [name] --bucket [s3-bucket] --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn]
51
54
  ```
52
55
 
56
+
53
57
  ### Federated SAML Authenticated VPN
54
58
 
59
+ This option is for when you want to manage users through an external directory provider like AWS SSO, OKTA or AzureAD. https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html#federated-authentication
60
+
55
61
  **Prerequisites:** Client-VPN requires a IAM SAML identity provider ARN, see the [AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) to create one.
56
62
 
57
63
  The following command and required option will launch a new federated based Client-VPN
58
64
 
59
65
  ```sh
60
- cfn-vpn init [name] --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn] --saml-arn [identity providor arn]
66
+ cfn-vpn init [name] --server-cn [server certificate name] \
67
+ --subnet-ids [list of subets to associate with the vpn] \
68
+ --saml-arn [identity providor arn]
69
+ ```
70
+
71
+ The default authorization rule for the associated subnets allows all. You can optionally change this by using the `--default-groups` flag to set groups on the default authorization rule.
72
+
73
+ ```diff
74
+ ! Group id's must be used if creating authorisation rules.
75
+ ! Each SAML providor will have different group id's and means of retrieving them.
76
+ ```
77
+
78
+ ```sh
79
+ cfn-vpn init [name] --server-cn [server certificate name] \
80
+ --subnet-ids [list of subnet to associate with the vpn] \
81
+ --saml-arn [identity provider arn] \
82
+ --default-groups [list of group ids]
83
+ ```
84
+
85
+ **AWS SSO**
86
+
87
+ If using AWS SSO as your SAML provider check this guide on how to set up SAML using AWS SSO https://codeburst.io/the-aws-client-vpn-federated-authentication-missing-example-655e0a1ff7f4
88
+
89
+ If you want to leverage the Self Service Portal you need to add the specify the `--saml-self-service-arn [self service identity provider arn]` You can follow the example here https://aws.amazon.com/blogs/security/authenticate-aws-client-vpn-users-with-aws-single-sign-on/ on how to setup the self sign-on sso application
90
+
91
+ ```sh
92
+ cfn-vpn init [name] --server-cn [server certificate name] \
93
+ --subnet-ids [list of subnet to associate with the vpn] \
94
+ --saml-arn [identity provider arn] \
95
+ --saml-self-service-arn [self service identity provider arn] \
96
+ --default-groups [list of group ids]
97
+ ```
98
+
99
+ ### AWS Directory Services Authenticated VPN
100
+
101
+ This option integrates Microsoft Active Directory or Simple AD through AWS Directory Service with AWS Client VPN.
102
+
103
+ The following command and required option will launch a new directory service based Client-VPN
104
+
105
+ ```sh
106
+ cfn-vpn init simple-ad --server-cn [server certificate name] \
107
+ --subnet-ids [list of subets to associate with the vpn] \
108
+ --directory-id [aws directirory serivce id]
61
109
  ```
62
110
 
63
- The default authorization rule for the associated subets allows all. You can optionally change this by using the `--default-groups` flag to set groups on the default authorization rule.
111
+ The default authorization rule for the associated subnets allows all. You can optionally change this by using the `--default-groups` flag to set groups on the default authorization rule. The group Id is the Active Directory Group ID or SID.
64
112
 
65
113
  ```sh
66
- cfn-vpn init [name] --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn] --saml-arn [identity providor arn] --default-groups [list of group ids]
114
+ cfn-vpn init simple-ad --server-cn [server certificate name] \
115
+ --subnet-ids [list of subets to associate with the vpn] \
116
+ --directory-id [aws directirory serivce id] \
117
+ --default-groups [list of group ids]
67
118
  ```
68
119
 
69
- ## Subnet Associations and Authorisation
120
+ See this guide for further help on setting up https://shogokobayashi.com/2019/05/18/aws-client-vpn-with-simplead/
121
+
122
+ ## Subnet Associations and Authorization
70
123
 
71
124
  AWS ClientVPN requires one or more subnets to be associated with the vpn. These subnets setup the default routes and by default cfn-vpn creates a allow all auth for the default routes.
72
125
  When using a federated ClientVPN you can modify the default auth to only allow specific groups by setting the groups in the `--default-groups` flag. This can also be modified later using the `modify` command.
73
126
 
74
- ## Additional Initialising Options
127
+ ## Additional Initializing Options
75
128
 
76
129
  ```
77
130
  Options:
78
- r, [--region=REGION] # AWS Region
79
- # Default: ap-southeast-2
80
- [--verbose], [--no-verbose] # set log level to debug
81
- --server-cn=SERVER_CN # server certificate common name
82
- [--client-cn=CLIENT_CN] # client certificate common name
83
- [--easyrsa-local], [--no-easyrsa-local] # run the easyrsa executable from your local rather than from docker
84
- [--bucket=BUCKET] # s3 bucket
85
- --subnet-ids=one two three # subnet id to associate your vpn with
86
- [--default-groups=one two three] # groups to allow through the subnet associations when using federated auth
87
- [--cidr=CIDR] # cidr from which to assign client IP addresses
88
- # Default: 10.250.0.0/16
89
- [--dns-servers=one two three] # DNS Servers to push to clients.
90
- [--split-tunnel], [--no-split-tunnel] # only push routes to the client on the vpn endpoint
91
- # Default: true
92
- [--internet-route=INTERNET_ROUTE] # [subnet-id] create a default route to the internet through a subnet
93
- [--protocol=PROTOCOL] # set the protocol for the vpn connections
94
- # Default: udp
95
- # Possible values: udp, tcp
96
- [--start=START] # cloudwatch event cron schedule in UTC to associate subnets to the client vpn
97
- [--stop=STOP] # cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn
98
- [--saml-arn=SAML_ARN] # IAM SAML idenditiy providor arn if using SAML federated authentication
99
- ```
131
+ r, [--region=REGION] # AWS Region
132
+ # Default: ap-southeast-2
133
+ [--verbose], [--no-verbose] # set log level to debug
134
+ --server-cn=SERVER_CN # server certificate common name
135
+ [--client-cn=CLIENT_CN] # client certificate common name
136
+ [--easyrsa-local], [--no-easyrsa-local] # run the easyrsa executable from your local rather than from docker
137
+ [--bucket=BUCKET] # s3 bucket, if not set one will be generated for you
138
+ --subnet-ids=one two three # subnet id to associate your vpn with
139
+ [--default-groups=one two three] # groups to allow through the subnet associations when using federated auth
140
+ [--cidr=CIDR] # cidr from which to assign client IP addresses
141
+ # Default: 10.250.0.0/16
142
+ [--dns-servers=one two three] # DNS Servers to push to clients.
143
+ [--split-tunnel], [--no-split-tunnel] # only push routes to the client on the vpn endpoint
144
+ # Default: true
145
+ [--internet-route=INTERNET_ROUTE] # [subnet-id] create a default route to the internet through a subnet
146
+ [--protocol=PROTOCOL] # set the protocol for the vpn connections
147
+ # Default: udp
148
+ # Possible values: udp, tcp
149
+ [--start=START] # cloudwatch event cron schedule in UTC to associate subnets to the client vpn
150
+ [--stop=STOP] # cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn
151
+ [--saml-arn=SAML_ARN] # IAM SAML idenditiy providor arn if using SAML federated authentication
152
+ [--saml-self-service-arn=SAML_SELF_SERVICE_ARN] # IAM SAML idenditiy providor arn for the self service portal
153
+ [--directory-id=DIRECTORY_ID] # AWS Directory Service directory id if using Active Directory authentication
154
+ ```
data/docs/routes.md CHANGED
@@ -4,24 +4,34 @@ Management of the VPN routes can be altered using the `routes` command or by usi
4
4
 
5
5
  **Note:** The default route via subnet association cannot be modified through this command. Use the `modify` command to alter the subnet associations.
6
6
 
7
- ## Routes Command
7
+ CfnVpn can create static routes for CIDRs as well as dynamically lookup IPs for dns endpoints and continue to monitor and update the routes if the IPs change.
8
8
 
9
+ ```sh
10
+ cfn-vpn help routes
11
+ ```
12
+
13
+ ## Dynamic DNS Routes
14
+
15
+ Dynamic DNS routes takes a dns endpoint and will query the record every 5 minutes to see if the IPs have changed and update the routes.
16
+
17
+ ### Add New
18
+
19
+ to add a new route run the routes command along with the `--dns` option
20
+
21
+ ```sh
22
+ cfn-vpn routes [name] --dns example.com
9
23
  ```
10
- Options:
11
- r, [--region=REGION] # AWS Region
12
- # Default: ap-southeast-2
13
- [--verbose], [--no-verbose] # set log level to debug
14
- [--cidr=CIDR] # cidr range
15
- [--subnet=SUBNET] # the target vpc subnet to route through, if none is supplied the default subnet is used
16
- [--desc=DESC] # description of the route
17
- [--groups=one two three] # override all authorised groups on thr route
18
- [--add-groups=one two three] # add authorised groups to an existing route
19
- [--del-groups=one two three] # remove authorised groups from an existing route
20
- [--delete], [--no-delete] # delete the route from the client vpn
21
-
22
- List, add or delete client vpn routes
24
+
25
+ ### Delete
26
+
27
+ to delete a route run the routes command along with the `--dns` option of the route to delete and the delete option
28
+
29
+ ```sh
30
+ cfn-vpn routes [name] --dns example.com --delete
23
31
  ```
24
32
 
33
+ ## Static CIDR Routes
34
+
25
35
  ### Add New
26
36
 
27
37
  to add a new route run the routes command along with the `--cidr` option
@@ -32,32 +42,32 @@ cfn-vpn routes [name] --cidr 10.151.0.0/16
32
42
 
33
43
  ### Delete
34
44
 
35
- to delete a route run the routes command along with the `--cidr` option of the route to delete and the delete option
45
+ to delete a route run the routes command along with the `--cidr` option of the route to delete and the delete option
36
46
 
37
47
  ```sh
38
48
  cfn-vpn routes [name] --cidr 10.151.0.0/16 --delete
39
49
  ```
40
50
 
41
- ### Manage Authorization Groups
51
+ ## Manage Authorization Groups
42
52
 
43
- When using federated authentication groups can be used to control access to certain routes. These can be managed on the routes by providing the `--groups [list of groups]` along with a space delimited list of groups to the `routes` command.
53
+ When using federated or active directory authentication groups can be used to control access to certain routes. These can be managed on the routes by providing the `--groups [list of groups]` along with a space delimited list of groups to the `routes` command. This is available for both DNS and CIDR routes
44
54
 
45
55
  To add groups to a new route or to override all groups on an exiting route use the `--groups` options
46
56
 
47
57
  ```sh
48
- cfn-vpn routes [name] --cidr 10.151.0.0/16 --groups devs ops
58
+ cfn-vpn routes [name] [--cidr 10.151.0.0/16] [--dns example.com] --groups devs ops
49
59
  ```
50
60
 
51
61
  To add groups to an existing route use the `--add-groups` options
52
62
 
53
63
  ```sh
54
- cfn-vpn routes [name] --cidr 10.151.0.0/16 --add-groups admin
64
+ cfn-vpn routes [name] [--cidr 10.151.0.0/16] [--dns example.com] --add-groups admin
55
65
  ```
56
66
 
57
67
  To delete groups from an existing route use the `--del-groups` options
58
68
 
59
69
  ```sh
60
- cfn-vpn routes [name] --cidr 10.151.0.0/16 --del-groups dev
70
+ cfn-vpn routes [name] [--cidr 10.151.0.0/16] [--dns example.com] --del-groups dev
61
71
  ```
62
72
 
63
73
  ## Modify Command
@@ -75,6 +85,10 @@ routes:
75
85
  desc: route to prod peered vpc
76
86
  groups:
77
87
  - ops
88
+ - dns: example.com
89
+ desc: my dev alb
90
+ groups:
91
+ - dev
78
92
  ```
79
93
 
80
94
  run the `modify` command and supply the yaml file to apply the changes
@@ -6,6 +6,7 @@ require 'cfnvpn/compiler'
6
6
  require 'cfnvpn/log'
7
7
  require 'cfnvpn/clientvpn'
8
8
  require 'cfnvpn/globals'
9
+ require 'cfnvpn/s3_bucket'
9
10
 
10
11
  module CfnVpn::Actions
11
12
  class Init < Thor::Group
@@ -20,7 +21,7 @@ module CfnVpn::Actions
20
21
  class_option :server_cn, required: true, desc: 'server certificate common name'
21
22
  class_option :client_cn, desc: 'client certificate common name'
22
23
  class_option :easyrsa_local, type: :boolean, default: false, desc: 'run the easyrsa executable from your local rather than from docker'
23
- class_option :bucket, desc: 's3 bucket'
24
+ class_option :bucket, desc: 's3 bucket, if not set one will be generated for you'
24
25
 
25
26
  class_option :subnet_ids, required: true, type: :array, desc: 'subnet id to associate your vpn with'
26
27
  class_option :default_groups, default: [], type: :array, desc: 'groups to allow through the subnet associations when using federated auth'
@@ -35,6 +36,8 @@ module CfnVpn::Actions
35
36
  class_option :stop, type: :string, desc: 'cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn'
36
37
 
37
38
  class_option :saml_arn, desc: 'IAM SAML idenditiy providor arn if using SAML federated authentication'
39
+ class_option :saml_self_service_arn, desc: 'IAM SAML idenditiy providor arn for the self service portal'
40
+ class_option :directory_id, desc: 'AWS Directory Service directory id if using Active Directory authentication'
38
41
 
39
42
  def self.source_root
40
43
  File.dirname(__FILE__)
@@ -62,23 +65,36 @@ module CfnVpn::Actions
62
65
  start: @options['start'],
63
66
  stop: @options['stop'],
64
67
  saml_arn: @options['saml_arn'],
68
+ saml_self_service_arn: @options['saml_self_service_arn'],
69
+ directory_id: @options['directory_id'],
65
70
  routes: []
66
71
  }
67
72
  end
68
73
 
69
- def set_type
70
- @config[:type] = @options['saml_arn'] ? 'federated' : 'certificate'
71
- @config[:default_groups] = @options['saml_arn'] ? @options['default_groups'] : []
72
- CfnVpn::Log.logger.info "initialising #{@config[:type]} client vpn"
74
+ def create_bucket_if_bucket_not_set
75
+ if !@options['bucket']
76
+ CfnVpn::Log.logger.info "creating s3 bucket"
77
+ bucket = CfnVpn::S3Bucket.new(@options['region'], @name)
78
+ bucket_name = bucket.generate_bucket_name
79
+ bucket.create_bucket(bucket_name)
80
+ @config[:bucket] = bucket_name
81
+ else
82
+ @config[:bucket] = @options['bucket']
83
+ end
73
84
  end
74
85
 
75
- def conditional_options_check
76
- if @config[:type] == 'certificate'
77
- if !@options['bucket']
78
- CfnVpn::Log.logger.error "--bucket option must be specified if creating a client vpn with certificate based authentication"
79
- exit 1
80
- end
86
+ def set_type
87
+ if @options['saml_arn']
88
+ @config[:type] = 'federated'
89
+ @config[:default_groups] = @options['default_groups']
90
+ elsif @options['directory_id']
91
+ @config[:type] = 'active-directory'
92
+ @config[:default_groups] = @options['default_groups']
93
+ else
94
+ @config[:type] = 'certificate'
95
+ @config[:default_groups] = []
81
96
  end
97
+ CfnVpn::Log.logger.info "initialising #{@config[:type]} client vpn"
82
98
  end
83
99
 
84
100
  def stack_exist
@@ -104,7 +120,7 @@ module CfnVpn::Actions
104
120
  # we only need the server certificate to ACM if it is a SAML federated client vpn
105
121
  @config[:client_cert_arn] = cert.upload_certificates(@options['region'],@client_cn,'client')
106
122
  # and only need to upload the certs to s3 if using certificate authenitcation
107
- s3 = CfnVpn::S3.new(@options['region'],@options['bucket'],@name)
123
+ s3 = CfnVpn::S3.new(@options['region'],@config[:bucket],@name)
108
124
  s3.store_object("#{@build_dir}/certificates/ca.tar.gz")
109
125
  end
110
126
  end
@@ -8,6 +8,7 @@ require 'cfnvpn/log'
8
8
  require 'cfnvpn/clientvpn'
9
9
  require 'cfnvpn/globals'
10
10
  require 'cfnvpn/config'
11
+ require 'cfnvpn/s3_bucket'
11
12
 
12
13
  module CfnVpn::Actions
13
14
  class Modify < Thor::Group
@@ -38,6 +39,8 @@ module CfnVpn::Actions
38
39
 
39
40
  class_option :param_yaml, type: :string, desc: 'pass in cfnvpn params through YAML file'
40
41
 
42
+ class_option :bucket, desc: 's3 bucket'
43
+
41
44
  def self.source_root
42
45
  File.dirname(__FILE__)
43
46
  end
@@ -88,13 +91,30 @@ module CfnVpn::Actions
88
91
  end
89
92
  end
90
93
 
91
- if @config[:saml_arn] && @options[:default_groups]
94
+ if (@config[:saml_arn] || @config[:directory_id]) && @options[:default_groups]
92
95
  @config[:default_groups] = @options[:default_groups]
93
96
  end
94
97
 
95
98
  CfnVpn::Log.logger.debug "Modified config:\n#{@config}"
96
99
  end
97
100
 
101
+ def create_bucket_if_bucket_not_set
102
+ if !@options['bucket'] && !@config.has_key?(:bucket)
103
+ if yes? "no s3 bucket supplied in the command or found in the config, select (Y) to generate a new one ot select (N) and re run teh command with the --bucket flag to import the existing bucket."
104
+ CfnVpn::Log.logger.info "creating s3 bucket"
105
+ bucket = CfnVpn::S3Bucket.new(@options['region'], @name)
106
+ bucket_name = bucket.generate_bucket_name
107
+ bucket.create_bucket(bucket_name)
108
+ @config[:bucket] = bucket_name
109
+ else
110
+ CfnVpn::Log.logger.info "rerun cfn-vpn modify #{name} command with the --bucket [BUCKET] flag"
111
+ exit 1
112
+ end
113
+ elsif @options['bucket']
114
+ @config[:bucket] = @options['bucket']
115
+ end
116
+ end
117
+
98
118
  def deploy_vpn
99
119
  compiler = CfnVpn::Compiler.new(@name, @config)
100
120
  template_body = compiler.compile
@@ -13,6 +13,7 @@ module CfnVpn::Actions
13
13
  class_option :verbose, desc: 'set log level to debug', type: :boolean
14
14
 
15
15
  class_option :cidr, desc: 'cidr range'
16
+ class_option :dns, desc: 'dns record to auto lookup ip'
16
17
  class_option :subnet, desc: 'the target vpc subnet to route through, if none is supplied the default subnet is used'
17
18
  class_option :desc, desc: 'description of the route'
18
19
 
@@ -32,26 +33,50 @@ module CfnVpn::Actions
32
33
 
33
34
  def set_config
34
35
  @config = CfnVpn::Config.get_config(@options[:region], @name)
35
- @route = @config[:routes].detect {|route| route[:cidr] == @options[:cidr]}
36
+
37
+ if @options[:cidr] && @options[:dns]
38
+ CfnVpn::Log.logger.error "only one of --dns or --cidr can be set"
39
+ exit 1
40
+ end
41
+
42
+ if @options[:dns]
43
+ if @options[:dns].include?("*")
44
+ CfnVpn::Log.logger.error("wild card DNS resolution is not supported, use a record that will be resolved by the wild card instead")
45
+ exit 1
46
+ end
47
+ @route = @config[:routes].detect {|route| route[:dns] == @options[:dns]}
48
+ elsif @options[:cidr]
49
+ @route = @config[:routes].detect {|route| route[:cidr] == @options[:cidr]}
50
+ end
36
51
  end
37
52
 
38
53
  def set_route
39
54
  @skip_update = false
55
+ @dns_route_cleanup = nil
40
56
  if @route && @options[:delete]
41
- CfnVpn::Log.logger.info "deleting route #{@options[:cidr]} "
42
- @config[:routes].reject! {|route| route[:cidr] == @options[:cidr]}
57
+ if @options[:dns]
58
+ CfnVpn::Log.logger.info "deleting auto lookup route for endpoint #{@options[:dns]}"
59
+ @config[:routes].reject! {|route| route[:dns] == @options[:dns]}
60
+ @dns_route_cleanup = @options[:dns]
61
+ elsif @options[:cidr]
62
+ CfnVpn::Log.logger.info "deleting route #{@options[:cidr]}"
63
+ @config[:routes].reject! {|route| route[:cidr] == @options[:cidr]}
64
+ end
43
65
  elsif @route
44
- CfnVpn::Log.logger.info "modifying groups for existing route #{@options[:cidr]}"
66
+ CfnVpn::Log.logger.info "existing route for #{@options[:cidr] ? @options[:cidr] : @options[:dns]} found"
45
67
  if @options[:groups]
68
+ CfnVpn::Log.logger.info "replacing groups #{@route[:groups]} with new #{@options[:groups]} for route authorization rule"
46
69
  @route[:groups] = @options[:groups]
47
70
  end
48
71
 
49
72
  if @options[:add_groups]
73
+ CfnVpn::Log.logger.info "adding new group(s) #{@options[:add_groups]} to route authorization rule"
50
74
  @route[:groups].concat(@options[:add_groups]).uniq!
51
75
  end
52
76
 
53
77
  if @options[:del_groups]
54
- @route[:groups].reject! {|group| @options[:add_groups].include? group}
78
+ CfnVpn::Log.logger.info "removing new group(s) #{@options[:del_groups]} to route authorization rule"
79
+ @route[:groups].reject! {|group| @options[:del_groups].include? group}
55
80
  end
56
81
 
57
82
  if @options[:desc]
@@ -65,9 +90,17 @@ module CfnVpn::Actions
65
90
  CfnVpn::Log.logger.info "adding new route for #{@options[:cidr]}"
66
91
  @config[:routes] << {
67
92
  cidr: @options[:cidr],
68
- desc: @options.fetch(:desc, "route for cidr #{@options[:cidr]}"),
93
+ desc: @options.fetch(:desc, ""),
94
+ subnet: @options.fetch(:subnet, @config[:subnet_ids].first),
95
+ groups: @options.fetch(:groups, []) + @options.fetch(:add_groups, [])
96
+ }
97
+ elsif !@route && @options[:dns]
98
+ CfnVpn::Log.logger.info "adding new route lookup for dns record #{@options[:dns]}"
99
+ @config[:routes] << {
100
+ dns: @options[:dns],
101
+ desc: @options.fetch(:desc, ""),
69
102
  subnet: @options.fetch(:subnet, @config[:subnet_ids].first),
70
- groups: @options.fetch(@options[:groups], []) + @options.fetch(@options[:add_groups], [])
103
+ groups: @options.fetch(:groups, []) + @options.fetch(:add_groups, [])
71
104
  }
72
105
  else
73
106
  @skip_update = true
@@ -76,6 +109,13 @@ module CfnVpn::Actions
76
109
  CfnVpn::Log.logger.debug "CONFIG: #{@config}"
77
110
  end
78
111
 
112
+ def create_bucket_if_bucket_not_set
113
+ if !@config.has_key?(:bucket)
114
+ CfnVpn::Log.logger.error "no bucket found in the config, run the cfn-vpn modify #{name} command to add a bucket"
115
+ exit 1
116
+ end
117
+ end
118
+
79
119
  def deploy_vpn
80
120
  unless @skip_update
81
121
  compiler = CfnVpn::Compiler.new(@name, @config)
@@ -123,8 +163,20 @@ module CfnVpn::Actions
123
163
  end
124
164
  end
125
165
 
126
- def get_routes
166
+ def cleanup_dns_routes
127
167
  @vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
168
+ unless @dns_route_cleanup.nil?
169
+ routes = @vpn.get_routes()
170
+ CfnVpn::Log.logger.info("Cleaning up expired routes for #{@dns_route_cleanup}")
171
+ expired_routes = routes.select {|route| route.description.include?(@dns_route_cleanup) }
172
+ expired_routes.each do |route|
173
+ @vpn.delete_route(route.destination_cidr, route.target_subnet)
174
+ @vpn.revoke_auth(route.destination_cidr)
175
+ end
176
+ end
177
+ end
178
+
179
+ def get_routes
128
180
  @endpoint = @vpn.get_endpoint_id()
129
181
  @routes = @vpn.get_routes()
130
182
  end
@@ -9,6 +9,7 @@ module CfnVpn
9
9
  def initialize(name,region)
10
10
  @client = Aws::EC2::Client.new(region: region)
11
11
  @name = name
12
+ @endpoint_id = self.get_endpoint_id()
12
13
  end
13
14
 
14
15
  def get_endpoint()
@@ -116,5 +117,22 @@ module CfnVpn
116
117
  return associations
117
118
  end
118
119
 
120
+ def delete_route(cidr, subnet)
121
+ @client.delete_client_vpn_route({
122
+ client_vpn_endpoint_id: @endpoint_id,
123
+ target_vpc_subnet_id: subnet,
124
+ destination_cidr_block: cidr
125
+ })
126
+ end
127
+
128
+ def revoke_auth(cidr)
129
+ endpoint_id = get_endpoint_id()
130
+ @client.revoke_client_vpn_ingress({
131
+ client_vpn_endpoint_id: @endpoint_id,
132
+ target_network_cidr: cidr,
133
+ revoke_all_groups: true
134
+ })
135
+ end
136
+
119
137
  end
120
138
  end