cfn-vpn 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87da472b980570d8b77eaab6e47aa173d9d0cbdbc04ff35a99aa94000949afa7
4
- data.tar.gz: ba179c5ecafe598cb2e706f295fb46a4f929424673cff094e76c701023a2381a
3
+ metadata.gz: fa61bd2028397a6a6becb482a6c8ec7a76122779672ea0b58c3f4b6d9fd50b03
4
+ data.tar.gz: 324fa44d60e5f92e1d2fc06dc008c6b1856ec289f09e9a935778bfb41a316b8d
5
5
  SHA512:
6
- metadata.gz: a2a230d146fe3f6f4226dd4aad4d5f40cc6322e75b84e5ca46b3fddeee5f728424e744357cbae0e1205a188d68d100a9b630cb3b028285d906d0e4be8ad91b77
7
- data.tar.gz: c6be3bf8d173086327c4024fe6fdcaa116be743ff15498a56f2a22209608880b8da6458a608235687eb236e356f9b8bf73d704baa137c653c7f81712f803bd6e
6
+ metadata.gz: c86170a4dc9643618677b3fcef80ebfb426d6c07fc0ecbc875fc1190c051b21eef7b6514824c0ac0afc89e2f05a1113942577752529c5397d3ed11d0d5dc5e61
7
+ data.tar.gz: 7f9061f8ffebbf703084b8100df2952a3d041525703b6ed9b6749d62d5ecf0332e06c3e9793486cd987614559b4c8207c63f9b2150b4cbee3c22e101309c333d
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
 
@@ -64,15 +64,15 @@ The following command and required option will launch a new federated based Clie
64
64
 
65
65
  ```sh
66
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]
67
+ --subnet-ids [list of subnets to associate with the vpn] \
68
+ --saml-arn [identity provider arn]
69
69
  ```
70
70
 
71
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
72
 
73
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.
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
76
  ```
77
77
 
78
78
  ```sh
@@ -104,16 +104,16 @@ The following command and required option will launch a new directory service ba
104
104
 
105
105
  ```sh
106
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]
107
+ --subnet-ids [list of subnets to associate with the vpn] \
108
+ --directory-id [aws directory service id]
109
109
  ```
110
110
 
111
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.
112
112
 
113
113
  ```sh
114
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] \
115
+ --subnet-ids [list of subnets to associate with the vpn] \
116
+ --directory-id [aws directory service id] \
117
117
  --default-groups [list of group ids]
118
118
  ```
119
119
 
@@ -128,27 +128,30 @@ When using a federated ClientVPN you can modify the default auth to only allow s
128
128
 
129
129
  ```
130
130
  Options:
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
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
154
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,10 +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'
39
- class_option :saml_self_service_arn, desc: 'IAM SAML idenditiy providor arn for the self service portal'
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'
40
40
  class_option :directory_id, desc: 'AWS Directory Service directory id if using Active Directory authentication'
41
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
+
42
45
  def self.source_root
43
46
  File.dirname(__FILE__)
44
47
  end
@@ -67,6 +70,8 @@ module CfnVpn::Actions
67
70
  saml_arn: @options['saml_arn'],
68
71
  saml_self_service_arn: @options['saml_self_service_arn'],
69
72
  directory_id: @options['directory_id'],
73
+ slack_webhook_url: @options['slack_webhook_url'],
74
+ auto_limit_increase: @options['auto_limit_increase'],
70
75
  routes: []
71
76
  }
72
77
  end
@@ -138,8 +143,7 @@ module CfnVpn::Actions
138
143
 
139
144
  def finish
140
145
  vpn = CfnVpn::ClientVpn.new(@name,@options['region'])
141
- @endpoint_id = vpn.get_endpoint_id()
142
- 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"
143
147
  end
144
148
 
145
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,