cfn-vpn 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 672ae92015c16fcc2ce33e05a22ca651b4974d4669d91115c2f5d49b36aa4062
4
- data.tar.gz: 3e595961778b5d67112b6219d690cd589e8523813f22e7a3a196dfab6d77d59d
3
+ metadata.gz: d057b56046024cd10c21a62c616fb41ef38be5443860e5b7c33593638c1e3e23
4
+ data.tar.gz: feec8bfb3aece7986731846dbcb7f7d9c165029cef2f3cd48677f07eafea992e
5
5
  SHA512:
6
- metadata.gz: fee3ea79a3c51a77aaa5b6be535fc950ecfd32de121e6aadd363ef4def0af7fe201b414624036d9553f8a7158cb9e6fe16189972b599bcfd8df688c0dec09051
7
- data.tar.gz: 4bcc5243d2365706f57d07bf2c0cbad79debde39952d8535407cd58fb26d5d1e77857cedbf0170d726c8a56c7f70a2a90a26349991a0c3a7bf51fd824eae2bb4
6
+ metadata.gz: cd2f72dba1ad154853d7b6493f3bb4a84a8443a9a97bbe557e5ce2f6bc938f5a765008364a7f91a12e390d4cdb1e9e22adec45dbfdb37036e7c9bac841f1d2c3
7
+ data.tar.gz: 26d45cbb3f81877a5ab7c6555ed3d91cba1410d206229cf7b594263708991f297009c79744802af17e1f6be903c349f8ac93bed891f67d94b23e914f60ae650f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cfn-vpn (1.2.0)
4
+ cfn-vpn (1.3.4)
5
5
  aws-sdk-acm (~> 1, < 2)
6
6
  aws-sdk-cloudformation (~> 1, < 2)
7
7
  aws-sdk-ec2 (~> 1.95, < 2)
@@ -24,7 +24,7 @@ GEM
24
24
  aws-sdk-cloudformation (1.49.0)
25
25
  aws-sdk-core (~> 3, >= 3.112.0)
26
26
  aws-sigv4 (~> 1.1)
27
- aws-sdk-core (3.113.0)
27
+ aws-sdk-core (3.119.0)
28
28
  aws-eventstream (~> 1, >= 1.0.2)
29
29
  aws-partitions (~> 1, >= 1.239.0)
30
30
  aws-sigv4 (~> 1.1)
data/docs/README.md CHANGED
@@ -41,4 +41,5 @@ 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)
45
+ 7. [Slack Notifications](slack-notifications.md)
@@ -85,5 +85,5 @@ Modify base2-ciinabox.config.ovpn to include the full location of your extracted
85
85
  echo "key /<path>/user1.key" >> myvpn.config.ovpn
86
86
  echo "cert /<path>/user1.crt" >> myvpn.config.ovpn
87
87
 
88
- Open myvpn.config.ovpn with your favourite openvpn client.
88
+ Open myvpn.config.ovpn with your favorite openvpn client.
89
89
  ```
@@ -50,7 +50,7 @@ This is the default option when launching a ClientVPN using certificated based a
50
50
  The following command and required options will launch a new certificate based Client-VPN
51
51
 
52
52
  ```sh
53
- cfn-vpn init [name] --bucket [s3-bucket] --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn]
53
+ cfn-vpn init [name] --bucket [s3-bucket] --server-cn [server certificate name] --subnet-ids [list of subnets to associate with the vpn]
54
54
  ```
55
55
 
56
56
 
@@ -63,19 +63,38 @@ This option is for when you want to manage users through an external directory p
63
63
  The following command and required option will launch a new federated based Client-VPN
64
64
 
65
65
  ```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]
66
+ cfn-vpn init [name] --server-cn [server certificate name] \
67
+ --subnet-ids [list of subnets to associate with the vpn] \
68
+ --saml-arn [identity provider arn]
67
69
  ```
68
70
 
69
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.
70
72
 
73
+ ```diff
74
+ ! Group id's must be used if creating authorization rules.
75
+ ! Each SAML provider will have different group id's and means of retrieving them.
76
+ ```
77
+
71
78
  ```sh
72
- 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]
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]
73
83
  ```
74
84
 
75
85
  **AWS SSO**
76
86
 
77
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
78
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
+ ```
79
98
 
80
99
  ### AWS Directory Services Authenticated VPN
81
100
 
@@ -84,13 +103,18 @@ This option integrates Microsoft Active Directory or Simple AD through AWS Direc
84
103
  The following command and required option will launch a new directory service based Client-VPN
85
104
 
86
105
  ```sh
87
- cfn-vpn init simple-ad --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn] --directory-id [aws directirory serivce id]
106
+ cfn-vpn init simple-ad --server-cn [server certificate name] \
107
+ --subnet-ids [list of subnets to associate with the vpn] \
108
+ --directory-id [aws directory service id]
88
109
  ```
89
110
 
90
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.
91
112
 
92
113
  ```sh
93
- cfn-vpn init simple-ad --server-cn [server certificate name] --subnet-ids [list of subets to associate with the vpn] --directory-id [aws directirory serivce id] --default-groups [list of group ids]
114
+ cfn-vpn init simple-ad --server-cn [server certificate name] \
115
+ --subnet-ids [list of subnets to associate with the vpn] \
116
+ --directory-id [aws directory service id] \
117
+ --default-groups [list of group ids]
94
118
  ```
95
119
 
96
120
  See this guide for further help on setting up https://shogokobayashi.com/2019/05/18/aws-client-vpn-with-simplead/
@@ -104,25 +128,30 @@ When using a federated ClientVPN you can modify the default auth to only allow s
104
128
 
105
129
  ```
106
130
  Options:
107
- r, [--region=REGION] # AWS Region
108
- # Default: ap-southeast-2
109
- [--verbose], [--no-verbose] # set log level to debug
110
- --server-cn=SERVER_CN # server certificate common name
111
- [--client-cn=CLIENT_CN] # client certificate common name
112
- [--easyrsa-local], [--no-easyrsa-local] # run the easyrsa executable from your local rather than from docker
113
- [--bucket=BUCKET] # s3 bucket
114
- --subnet-ids=one two three # subnet id to associate your vpn with
115
- [--default-groups=one two three] # groups to allow through the subnet associations when using federated auth
116
- [--cidr=CIDR] # cidr from which to assign client IP addresses
117
- # Default: 10.250.0.0/16
118
- [--dns-servers=one two three] # DNS Servers to push to clients.
119
- [--split-tunnel], [--no-split-tunnel] # only push routes to the client on the vpn endpoint
120
- # Default: true
121
- [--internet-route=INTERNET_ROUTE] # [subnet-id] create a default route to the internet through a subnet
122
- [--protocol=PROTOCOL] # set the protocol for the vpn connections
123
- # Default: udp
124
- # Possible values: udp, tcp
125
- [--start=START] # cloudwatch event cron schedule in UTC to associate subnets to the client vpn
126
- [--stop=STOP] # cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn
127
- [--saml-arn=SAML_ARN] # IAM SAML idenditiy providor arn if using SAML federated authentication
128
- ```
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 identity provider arn if using SAML federated authentication
152
+ [--saml-self-service-arn=SAML_SELF_SERVICE_ARN] # IAM SAML identity provider arn for the self service portal
153
+ [--directory-id=DIRECTORY_ID] # AWS Directory Service directory id if using Active Directory authentication
154
+ [--slack-webhook-url=SLACK_WEBHOOK_URL] # slack webhook url to send notifications from the scheduler and route populator
155
+ [--auto-limit-increase], [--no-auto-limit-increase] # automatically request a AWS service quota increase if limits are hit for route entry and authorization rule limits
156
+ # Default: true
157
+ ```
data/docs/routes.md CHANGED
@@ -96,3 +96,51 @@ run the `modify` command and supply the yaml file to apply the changes
96
96
  ```sh
97
97
  cfn-vpn routes [name] --params-yaml cfnvpn.[name].yaml
98
98
  ```
99
+
100
+ ## Route Limits
101
+
102
+ Client VPN have a number of service limits associated with it some of which can be increased and may need to be increased by default.
103
+
104
+ | Name | Default | Adjustable |
105
+ | --- | --- | --- |
106
+ | Authorization rules per Client VPN endpoint | 50 | [Yes](https://console.aws.amazon.com/servicequotas/home/services/ec2/quotas/L-9A1BC94B) |
107
+ | Client VPN disconnect timeout | 24 hours | No |
108
+ | Client VPN endpoints per Region | 5 | [Yes](https://console.aws.amazon.com/servicequotas/home/services/ec2/quotas/L-8EA77D34) |
109
+ | Concurrent client connections per Client VPN endpoint | This value depends on the number of subnet associations per endpoint\. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/vpn/latest/clientvpn-admin/limits.html) | [Yes](https://console.aws.amazon.com/servicequotas/home/services/ec2/quotas/L-C4B238BF) |
110
+ | Concurrent operations per Client VPN endpoint † | 10 | No |
111
+ | Entries in a client certificate revocation list for Client VPN endpoints | 20,000 | No |
112
+ | Routes per Client VPN endpoint | 10 | [Yes](https://console.aws.amazon.com/servicequotas/home/services/ec2/quotas/L-401D78F7) |
113
+
114
+ † Operations include:
115
+ + Associate or disassociate subnets
116
+ + Create or delete routes
117
+ + Create or delete inbound and outbound rules
118
+ + Create or delete security groups
119
+
120
+ Check out the AWS [docs](https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/limits.html) for up to date details
121
+
122
+ ### Increasing Limits
123
+
124
+ **Automatic**
125
+
126
+ cfn-vpn supports automatically creating requests to increase the limits for `Routes per Client VPN endpoint` (by 10) and `Authorization rules per Client VPN endpoint` (by 20).
127
+
128
+ This functionality is enabled by default but can be disabled by modifying the vpn setting the `--no-auto-limit-increase` flag
129
+
130
+ ```sh
131
+ cfn-vpn modify [name] --no-auto-limit-increase
132
+ ```
133
+
134
+ **Manual**
135
+
136
+ `Routes per Client VPN endpoint`
137
+
138
+ ```sh
139
+ aws service-quotas request-service-quota-increase --service-code ec2 --quota-code L-401D78F7 --desired-value [value]
140
+ ```
141
+
142
+ `Authorization rules per Client VPN endpoint`
143
+
144
+ ```sh
145
+ aws service-quotas request-service-quota-increase --service-code ec2 --quota-code L-9A1BC94B --desired-value [value]
146
+ ```
@@ -0,0 +1,35 @@
1
+ # Slack Notifications
2
+
3
+ Slack notifications can be enabled for both the [dynamic route populator](routes.md#dynamic-dns-routes) and the [scheduler](scheduling.md) to show events.
4
+
5
+ ## Enable
6
+
7
+ Setup a Slack [incoming-webhook](https://api.slack.com/messaging/webhooks#getting_started) in your desired slack channel and grab the webhook url that'll look something like this:
8
+
9
+ ```
10
+ https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
11
+ ```
12
+
13
+ Next modify your VPN stack using the modify command and pass in url
14
+
15
+ ```sh
16
+ cfn-vpn modify [name] --slack-webhook-url "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
17
+ ```
18
+
19
+ ## Route Events
20
+
21
+ - `FAILED`: general failure
22
+ - `NEW_ROUTE`: new route added to route table
23
+ - `EXPIRED_ROUTE`: CIDR is no longer associated with DNS entry and is removed from the route table
24
+ - `ROUTE_LIMIT_EXCEEDED`: no new routes can be added to the route table due to AWS route table limit
25
+ - `AUTH_RULE_LIMIT_EXCEEDED`: no new authorization rules can be added to the rule list due to AWS auth rule limit
26
+ - `RESOLVE_FAILED`: failed to resolve the provided dns entry
27
+ - `SUBNET_NOT_ASSOCIATED`: no subnets are associated with the Client VPN
28
+ - `QUOTA_INCREASE_REQUEST`: automatic quota increase made
29
+
30
+ ## Scheduler Events
31
+
32
+ - `START_IN_PROGRESS`: associating subnets with the Client VPN
33
+ - `STOP_IN_PROGRESS`: disassociating subnets with the Client VPN
34
+ - `START_FAILED`: failed to associated subnets with the Client VPN
35
+ - `STOP_FAILED`: failed to disassociated subnets with the Client VPN
@@ -50,11 +50,10 @@ module CfnVpn::Actions
50
50
 
51
51
  def download_config
52
52
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
53
- @endpoint_id = vpn.get_endpoint_id()
54
- CfnVpn::Log.logger.debug "downloading client config for #{@endpoint_id}"
55
- @config = vpn.get_config(@endpoint_id)
53
+ CfnVpn::Log.logger.debug "downloading client config for #{vpn.endpoint_id}"
54
+ @config = vpn.get_config()
56
55
  string = (0...8).map { (65 + rand(26)).chr.downcase }.join
57
- @config.sub!(@endpoint_id, "#{string}.#{@endpoint_id}")
56
+ @config.sub!(vpn.endpoint_id, "#{string}.#{vpn.endpoint_id}")
58
57
  end
59
58
 
60
59
  def add_routes
@@ -35,9 +35,13 @@ module CfnVpn::Actions
35
35
  class_option :start, type: :string, desc: 'cloudwatch event cron schedule in UTC to associate subnets to the client vpn'
36
36
  class_option :stop, type: :string, desc: 'cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn'
37
37
 
38
- class_option :saml_arn, desc: 'IAM SAML idenditiy providor arn if using SAML federated authentication'
38
+ class_option :saml_arn, desc: 'IAM SAML identity provider arn if using SAML federated authentication'
39
+ class_option :saml_self_service_arn, desc: 'IAM SAML identity provider arn for the self service portal'
39
40
  class_option :directory_id, desc: 'AWS Directory Service directory id if using Active Directory authentication'
40
41
 
42
+ class_option :slack_webhook_url, type: :string, desc: 'slack webhook url to send notifications from the scheduler and route populator'
43
+ class_option :auto_limit_increase, type: :boolean, default: true, desc: 'automatically request a AWS service quota increase if limits are hit for route entry and authorization rule limits'
44
+
41
45
  def self.source_root
42
46
  File.dirname(__FILE__)
43
47
  end
@@ -64,7 +68,10 @@ module CfnVpn::Actions
64
68
  start: @options['start'],
65
69
  stop: @options['stop'],
66
70
  saml_arn: @options['saml_arn'],
71
+ saml_self_service_arn: @options['saml_self_service_arn'],
67
72
  directory_id: @options['directory_id'],
73
+ slack_webhook_url: @options['slack_webhook_url'],
74
+ auto_limit_increase: @options['auto_limit_increase'],
68
75
  routes: []
69
76
  }
70
77
  end
@@ -136,8 +143,7 @@ module CfnVpn::Actions
136
143
 
137
144
  def finish
138
145
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
139
- @endpoint_id = vpn.get_endpoint_id()
140
- CfnVpn::Log.logger.info "Client VPN #{@endpoint_id} created. Run `cfn-vpn config #{@name}` to setup the client config"
146
+ CfnVpn::Log.logger.info "Client VPN #{vpn.endpoint_id} created. Run `cfn-vpn config #{@name}` to setup the client config"
141
147
  end
142
148
 
143
149
  end
@@ -37,6 +37,9 @@ module CfnVpn::Actions
37
37
  class_option :start, type: :string, desc: 'cloudwatch event cron schedule in UTC to associate subnets to the client vpn'
38
38
  class_option :stop, type: :string, desc: 'cloudwatch event cron schedule in UTC to disassociate subnets to the client vpn'
39
39
 
40
+ class_option :slack_webhook_url, type: :string, desc: 'slack webhook url to send notifications from the scheduler and route populator'
41
+ class_option :auto_limit_increase, type: :boolean, desc: 'automatically request a AWS service quota increase if limits are hit for route entry and authorization rule limits'
42
+
40
43
  class_option :param_yaml, type: :string, desc: 'pass in cfnvpn params through YAML file'
41
44
 
42
45
  class_option :bucket, desc: 's3 bucket'
@@ -161,8 +164,7 @@ module CfnVpn::Actions
161
164
 
162
165
  def finish
163
166
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
164
- @endpoint_id = vpn.get_endpoint_id()
165
- CfnVpn::Log.logger.info "Client VPN #{@endpoint_id} modified."
167
+ CfnVpn::Log.logger.info "Client VPN #{vpn.endpoint_id} modified."
166
168
  end
167
169
 
168
170
  end
@@ -42,9 +42,8 @@ module CfnVpn::Actions
42
42
 
43
43
  def apply_rekocation_list
44
44
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
45
- endpoint_id = vpn.get_endpoint_id()
46
- vpn.put_revoke_list(endpoint_id,"#{@cert_dir}/crl.pem")
47
- CfnVpn::Log.logger.info("revoked client #{@options['client_cn']} from #{endpoint_id}")
45
+ vpn.put_revoke_list("#{@cert_dir}/crl.pem")
46
+ CfnVpn::Log.logger.info("revoked client #{@options['client_cn']} from #{vpn.endpoint_id}")
48
47
  end
49
48
 
50
49
  end
@@ -14,7 +14,7 @@ module CfnVpn::Actions
14
14
 
15
15
  class_option :cidr, desc: 'cidr range'
16
16
  class_option :dns, desc: 'dns record to auto lookup ip'
17
- class_option :subnet, desc: 'the target vpc subnet to route through, if none is supplied the default subnet is used'
17
+ class_option :subnets, type: :array, desc: 'target vpc subnets to route through, if none is supplied the default subnets are used'
18
18
  class_option :desc, desc: 'description of the route'
19
19
 
20
20
  class_option :groups, type: :array, desc: 'override all authorised groups on thr route'
@@ -83,15 +83,15 @@ module CfnVpn::Actions
83
83
  CfnVpn::Log.logger.warn "description for this route cannot be updated in place. To alter delete the route and add with the new description"
84
84
  end
85
85
 
86
- if @options[:subnet]
87
- CfnVpn::Log.logger.warn "the target subnet for this route cannot be updated in place. To alter delete the route and add with the new target subnet"
86
+ if @options[:subnets]
87
+ CfnVpn::Log.logger.warn "the target subnets for this route cannot be updated in place. To alter delete the route and add with the new target subnet"
88
88
  end
89
89
  elsif !@route && @options[:cidr]
90
90
  CfnVpn::Log.logger.info "adding new route for #{@options[:cidr]}"
91
91
  @config[:routes] << {
92
92
  cidr: @options[:cidr],
93
93
  desc: @options.fetch(:desc, ""),
94
- subnet: @options.fetch(:subnet, @config[:subnet_ids].first),
94
+ subnets: @options.fetch(:subnets, @config[:subnet_ids]),
95
95
  groups: @options.fetch(:groups, []) + @options.fetch(:add_groups, [])
96
96
  }
97
97
  elsif !@route && @options[:dns]
@@ -99,7 +99,7 @@ module CfnVpn::Actions
99
99
  @config[:routes] << {
100
100
  dns: @options[:dns],
101
101
  desc: @options.fetch(:desc, ""),
102
- subnet: @options.fetch(:subnet, @config[:subnet_ids].first),
102
+ subnets: @options.fetch(:subnets, @config[:subnet_ids]),
103
103
  groups: @options.fetch(:groups, []) + @options.fetch(:add_groups, [])
104
104
  }
105
105
  else
@@ -163,27 +163,31 @@ module CfnVpn::Actions
163
163
  end
164
164
  end
165
165
 
166
+ def get_routes
167
+ @vpn = CfnVpn::ClientVpn.new(@name, @options['region'])
168
+ end
169
+
166
170
  def cleanup_dns_routes
167
- @vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
168
171
  unless @dns_route_cleanup.nil?
169
- routes = @vpn.get_routes()
170
172
  CfnVpn::Log.logger.info("Cleaning up expired routes for #{@dns_route_cleanup}")
171
- expired_routes = routes.select {|route| route.description.include?(@dns_route_cleanup) }
173
+ expired_routes = @vpn.get_routes(@dns_route_cleanup)
172
174
  expired_routes.each do |route|
175
+ CfnVpn::Log.logger.info("Removing expired route #{route.destination_cidr} for target subnet #{route.target_subnet}")
173
176
  @vpn.delete_route(route.destination_cidr, route.target_subnet)
174
- @vpn.revoke_auth(route.destination_cidr)
175
177
  end
176
- end
177
- end
178
178
 
179
- def get_routes
180
- @endpoint = @vpn.get_endpoint_id()
181
- @routes = @vpn.get_routes()
179
+ expired_rules = @vpn.get_auth_rules(@dns_route_cleanup)
180
+ expired_rules.each do |rule|
181
+ CfnVpn::Log.logger.info("Removing expired auth rule for route #{route.destination_cidr}")
182
+ @vpn.revoke_auth(rule.destination_cidr)
183
+ end
184
+ end
182
185
  end
183
186
 
184
187
  def display_routes
185
- rows = @routes.collect do |s|
186
- groups = @vpn.get_groups_for_route(@endpoint, s.destination_cidr)
188
+ routes = @vpn.get_routes()
189
+ rows = routes.collect do |s|
190
+ groups = @vpn.get_groups_for_route(s.destination_cidr)
187
191
  [ s.destination_cidr, s.description, s.status.code, s.target_subnet, s.type, s.origin, (!groups.join("").empty? ? groups.join(' ') : 'AllowAll') ]
188
192
  end
189
193
  table = Terminal::Table.new(
@@ -29,20 +29,19 @@ module CfnVpn::Actions
29
29
  @build_dir = "#{CfnVpn.cfnvpn_path}/#{@name}"
30
30
  end
31
31
 
32
- def get_endpoint
32
+ def setup
33
33
  @vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
34
- @endpoint_id = @vpn.get_endpoint_id()
35
34
  end
36
35
 
37
36
  def kill_session
38
37
  if !@options['kill'].nil?
39
- sessions = @vpn.get_sessions(@endpoint_id)
38
+ sessions = @vpn.get_sessions()
40
39
  session = sessions.select { |s| s if s.connection_id == @options['kill'] }.first
41
40
  if session.any? && session.status.code == "active"
42
41
  terminate = yes? "Terminate connection #{@options['kill']} for #{session.common_name}?", :yellow
43
42
  if terminate
44
43
  CfnVpn::Log.logger.info "Terminating connection #{@options['kill']} for #{session.common_name}"
45
- @vpn.kill_session(@endpoint_id,@options['kill'])
44
+ @vpn.kill_session(@options['kill'])
46
45
  end
47
46
  else
48
47
  CfnVpn::Log.logger.error "Connection id #{@options['kill']} doesn't exist or is not active"
@@ -51,7 +50,7 @@ module CfnVpn::Actions
51
50
  end
52
51
 
53
52
  def display_sessions
54
- sessions = @vpn.get_sessions(@endpoint_id)
53
+ sessions = @vpn.get_sessions()
55
54
  rows = sessions.collect do |s|
56
55
  [ s.common_name, s.connection_established_time, s.status.code, s.client_ip, s.connection_id, s.ingress_bytes, s.egress_bytes ]
57
56
  end
@@ -26,11 +26,10 @@ module CfnVpn::Actions
26
26
 
27
27
  def copy_config_to_s3
28
28
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
29
- @endpoint_id = vpn.get_endpoint_id()
30
- CfnVpn::Log.logger.debug "downloading client config for #{@endpoint_id}"
31
- @config = vpn.get_config(@endpoint_id)
29
+ CfnVpn::Log.logger.debug "downloading client config for #{vpn.endpoint_id}"
30
+ @config = vpn.get_config()
32
31
  string = (0...8).map { (65 + rand(26)).chr.downcase }.join
33
- @config.sub!(@endpoint_id, "#{string}.#{@endpoint_id}")
32
+ @config.sub!(vpn.endpoint_id, "#{string}.#{vpn.endpoint_id}")
34
33
  end
35
34
 
36
35
  def add_routes
@@ -61,13 +61,9 @@ module CfnVpn::Actions
61
61
  end
62
62
  end
63
63
 
64
- def get_endpoint
65
- @vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
66
- @endpoint_id = @vpn.get_endpoint_id()
67
- end
68
-
69
64
  def associations
70
- associations = @vpn.get_associations(@endpoint_id)
65
+ vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
66
+ associations = vpn.get_associations()
71
67
  table = Terminal::Table.new(
72
68
  :headings => ['ID', 'Subnet', 'Status', 'CIDR', 'AZ', 'Groups'],
73
69
  :rows => associations.map {|ass| ass.values})
@@ -5,6 +5,7 @@ require 'netaddr'
5
5
  module CfnVpn
6
6
  class ClientVpn
7
7
 
8
+ attr_reader :endpoint_id
8
9
 
9
10
  def initialize(name,region)
10
11
  @client = Aws::EC2::Client.new(region: region)
@@ -31,56 +32,71 @@ module CfnVpn
31
32
  return get_endpoint().dns_servers
32
33
  end
33
34
 
34
- def get_config(endpoint_id)
35
+ def get_config()
35
36
  resp = @client.export_client_vpn_client_configuration({
36
- client_vpn_endpoint_id: endpoint_id
37
+ client_vpn_endpoint_id: @endpoint_id
37
38
  })
38
39
  return resp.client_configuration
39
40
  end
40
41
 
41
- def get_rekove_list(endpoint_id)
42
+ def get_rekove_list()
42
43
  resp = @client.export_client_vpn_client_certificate_revocation_list({
43
- client_vpn_endpoint_id: endpoint_id
44
+ client_vpn_endpoint_id: @endpoint_id
44
45
  })
45
46
  return resp.certificate_revocation_list
46
47
  end
47
48
 
48
- def put_revoke_list(endpoint_id,revoke_list)
49
+ def put_revoke_list(revoke_list)
49
50
  list = File.read(revoke_list)
50
51
  @client.import_client_vpn_client_certificate_revocation_list({
51
- client_vpn_endpoint_id: endpoint_id,
52
+ client_vpn_endpoint_id: @endpoint_id,
52
53
  certificate_revocation_list: list
53
54
  })
54
55
  end
55
56
 
56
- def get_sessions(endpoint_id)
57
+ def get_sessions()
57
58
  params = {
58
- client_vpn_endpoint_id: endpoint_id,
59
+ client_vpn_endpoint_id: @endpoint_id,
59
60
  max_results: 20
60
61
  }
61
62
  resp = @client.describe_client_vpn_connections(params)
62
63
  return resp.connections
63
64
  end
64
65
 
65
- def kill_session(endpoint_id, connection_id)
66
+ def kill_session(connection_id)
66
67
  @client.terminate_client_vpn_connections({
67
- client_vpn_endpoint_id: endpoint_id,
68
+ client_vpn_endpoint_id: @endpoint_id,
68
69
  connection_id: connection_id
69
70
  })
70
71
  end
71
72
 
72
- def get_routes()
73
- endpoint_id = get_endpoint_id()
74
- resp = @client.describe_client_vpn_routes({
75
- client_vpn_endpoint_id: endpoint_id,
76
- max_results: 20
77
- })
78
- return resp.routes
73
+ def get_routes(dns_route=nil)
74
+ routes = []
75
+ @client.describe_client_vpn_routes({client_vpn_endpoint_id: @endpoint_id}).each do |resp|
76
+ if dns_route
77
+ routes.concat resp.routes.select {|route| route.description.include?(dns_route) }
78
+ else
79
+ routes.concat resp.routes
80
+ end
81
+ end
82
+ return routes
79
83
  end
80
84
 
81
- def get_groups_for_route(endpoint, cidr)
85
+ def get_auth_rules(dns_route=nil)
86
+ rules = []
87
+ @client.describe_client_vpn_authorization_rules({client_vpn_endpoint_id: @endpoint_id}) do |resp|
88
+ if dns_route
89
+ rules.concat resp.authorization_rules.select {|rule| rule.description.include?(dns_route) }
90
+ else
91
+ rules.concat resp.routes
92
+ end
93
+ end
94
+ return rules
95
+ end
96
+
97
+ def get_groups_for_route(cidr)
82
98
  auth_resp = @client.describe_client_vpn_authorization_rules({
83
- client_vpn_endpoint_id: endpoint,
99
+ client_vpn_endpoint_id: @endpoint_id,
84
100
  filters: [
85
101
  {
86
102
  name: 'destination-cidr',
@@ -91,10 +107,10 @@ module CfnVpn
91
107
  return auth_resp.authorization_rules.map {|rule| rule.group_id }
92
108
  end
93
109
 
94
- def get_associations(endpoint)
110
+ def get_associations()
95
111
  associations = []
96
112
  resp = @client.describe_client_vpn_target_networks({
97
- client_vpn_endpoint_id: endpoint
113
+ client_vpn_endpoint_id: @endpoint_id
98
114
  })
99
115
 
100
116
  resp.client_vpn_target_networks.each do |net|
@@ -102,7 +118,7 @@ module CfnVpn
102
118
  subnet_ids: [net.target_network_id]
103
119
  })
104
120
  subnet = subnet_resp.subnets.first
105
- groups = get_groups_for_route(endpoint, subnet.cidr_block)
121
+ groups = get_groups_for_route(subnet.cidr_block)
106
122
 
107
123
  associations.push({
108
124
  association_id: net.association_id,