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 +4 -4
- data/Gemfile.lock +21 -19
- data/cfn-vpn.gemspec +1 -0
- data/docs/README.md +2 -2
- data/docs/getting-started.md +84 -29
- data/docs/routes.md +34 -20
- data/lib/cfnvpn/actions/init.rb +28 -12
- data/lib/cfnvpn/actions/modify.rb +21 -1
- data/lib/cfnvpn/actions/routes.rb +60 -8
- data/lib/cfnvpn/clientvpn.rb +18 -0
- data/lib/cfnvpn/s3.rb +30 -0
- data/lib/cfnvpn/s3_bucket.rb +48 -0
- data/lib/cfnvpn/string.rb +4 -0
- data/lib/cfnvpn/templates/lambdas/auto_route_populator/app.py +175 -0
- data/lib/cfnvpn/templates/lambdas/scheduler/app.py +36 -0
- data/lib/cfnvpn/templates/lambdas.rb +35 -0
- data/lib/cfnvpn/templates/vpn.rb +198 -93
- data/lib/cfnvpn/version.rb +1 -1
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c46ffdf0579ffd7c1fd42efadc969bbd095f9f789dfcb5b9e3e2aef7f85e959c
|
4
|
+
data.tar.gz: 7a6e1a34fa32b2246a8998e8645381635e8c5adf7a6bf978c241ea4d7e4ee217
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
19
|
-
aws-partitions (1.
|
20
|
-
aws-sdk-acm (1.
|
21
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
24
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
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.
|
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.
|
35
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
38
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
42
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
45
|
+
aws-sigv4 (1.2.3)
|
45
46
|
aws-eventstream (~> 1, >= 1.0.2)
|
46
|
-
cfndsl (1.
|
47
|
+
cfndsl (1.3.1)
|
47
48
|
hana (~> 1.3)
|
48
|
-
hana (1.3.
|
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.
|
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
|
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)
|
data/docs/getting-started.md
CHANGED
@@ -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
|
-
|
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
|
-
|
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]
|
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
|
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
|
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
|
-
|
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
|
127
|
+
## Additional Initializing Options
|
75
128
|
|
76
129
|
```
|
77
130
|
Options:
|
78
|
-
r, [--region=REGION]
|
79
|
-
|
80
|
-
[--verbose], [--no-verbose]
|
81
|
-
--server-cn=SERVER_CN
|
82
|
-
[--client-cn=CLIENT_CN]
|
83
|
-
[--easyrsa-local], [--no-easyrsa-local]
|
84
|
-
[--bucket=BUCKET]
|
85
|
-
--subnet-ids=one two three
|
86
|
-
[--default-groups=one two three]
|
87
|
-
[--cidr=CIDR]
|
88
|
-
|
89
|
-
[--dns-servers=one two three]
|
90
|
-
[--split-tunnel], [--no-split-tunnel]
|
91
|
-
|
92
|
-
[--internet-route=INTERNET_ROUTE]
|
93
|
-
[--protocol=PROTOCOL]
|
94
|
-
|
95
|
-
|
96
|
-
[--start=START]
|
97
|
-
[--stop=STOP]
|
98
|
-
[--saml-arn=SAML_ARN]
|
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
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
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
|
-
|
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
|
data/lib/cfnvpn/actions/init.rb
CHANGED
@@ -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
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
76
|
-
if @
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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'],@
|
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
|
-
|
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
|
-
|
42
|
-
|
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 "
|
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
|
-
|
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, "
|
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(
|
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
|
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
|
data/lib/cfnvpn/clientvpn.rb
CHANGED
@@ -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
|