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 +4 -4
- data/Gemfile.lock +2 -2
- data/docs/README.md +2 -1
- data/docs/certificate-users.md +1 -1
- data/docs/getting-started.md +56 -27
- data/docs/routes.md +48 -0
- data/docs/slack-notifications.md +35 -0
- data/lib/cfnvpn/actions/embedded.rb +3 -4
- data/lib/cfnvpn/actions/init.rb +9 -3
- data/lib/cfnvpn/actions/modify.rb +4 -2
- data/lib/cfnvpn/actions/revoke.rb +2 -3
- data/lib/cfnvpn/actions/routes.rb +20 -16
- data/lib/cfnvpn/actions/sessions.rb +4 -5
- data/lib/cfnvpn/actions/share.rb +3 -4
- data/lib/cfnvpn/actions/subnets.rb +2 -6
- data/lib/cfnvpn/clientvpn.rb +38 -22
- data/lib/cfnvpn/templates/lambdas/auto_route_populator/app.py +177 -92
- data/lib/cfnvpn/templates/lambdas/auto_route_populator/quotas.py +37 -0
- data/lib/cfnvpn/templates/lambdas/auto_route_populator/states.py +21 -0
- data/lib/cfnvpn/templates/lambdas/lib/slack.py +66 -0
- data/lib/cfnvpn/templates/lambdas/scheduler/app.py +42 -24
- data/lib/cfnvpn/templates/lambdas/scheduler/states.py +13 -0
- data/lib/cfnvpn/templates/lambdas.rb +10 -1
- data/lib/cfnvpn/templates/vpn.rb +86 -21
- data/lib/cfnvpn/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d057b56046024cd10c21a62c616fb41ef38be5443860e5b7c33593638c1e3e23
|
4
|
+
data.tar.gz: feec8bfb3aece7986731846dbcb7f7d9c165029cef2f3cd48677f07eafea992e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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)
|
data/docs/certificate-users.md
CHANGED
@@ -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
|
88
|
+
Open myvpn.config.ovpn with your favorite openvpn client.
|
89
89
|
```
|
data/docs/getting-started.md
CHANGED
@@ -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
|
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]
|
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]
|
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]
|
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]
|
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]
|
108
|
-
|
109
|
-
[--verbose], [--no-verbose]
|
110
|
-
--server-cn=SERVER_CN
|
111
|
-
[--client-cn=CLIENT_CN]
|
112
|
-
[--easyrsa-local], [--no-easyrsa-local]
|
113
|
-
[--bucket=BUCKET]
|
114
|
-
--subnet-ids=one two three
|
115
|
-
[--default-groups=one two three]
|
116
|
-
[--cidr=CIDR]
|
117
|
-
|
118
|
-
[--dns-servers=one two three]
|
119
|
-
[--split-tunnel], [--no-split-tunnel]
|
120
|
-
|
121
|
-
[--internet-route=INTERNET_ROUTE]
|
122
|
-
[--protocol=PROTOCOL]
|
123
|
-
|
124
|
-
|
125
|
-
[--start=START]
|
126
|
-
[--stop=STOP]
|
127
|
-
[--saml-arn=SAML_ARN]
|
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
|
-
|
54
|
-
|
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!(
|
56
|
+
@config.sub!(vpn.endpoint_id, "#{string}.#{vpn.endpoint_id}")
|
58
57
|
end
|
59
58
|
|
60
59
|
def add_routes
|
data/lib/cfnvpn/actions/init.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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
|
-
|
46
|
-
|
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 :
|
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[:
|
87
|
-
CfnVpn::Log.logger.warn "the target
|
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
|
-
|
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
|
-
|
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 =
|
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
|
-
|
180
|
-
|
181
|
-
|
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
|
-
|
186
|
-
|
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
|
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(
|
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(@
|
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(
|
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
|
data/lib/cfnvpn/actions/share.rb
CHANGED
@@ -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
|
-
|
30
|
-
|
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!(
|
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
|
-
|
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})
|
data/lib/cfnvpn/clientvpn.rb
CHANGED
@@ -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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
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:
|
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(
|
110
|
+
def get_associations()
|
95
111
|
associations = []
|
96
112
|
resp = @client.describe_client_vpn_target_networks({
|
97
|
-
client_vpn_endpoint_id:
|
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(
|
121
|
+
groups = get_groups_for_route(subnet.cidr_block)
|
106
122
|
|
107
123
|
associations.push({
|
108
124
|
association_id: net.association_id,
|