This repository has been archived by the owner on Dec 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
setup.sh
executable file
·256 lines (205 loc) · 8.54 KB
/
setup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/bin/bash
echo -e "---------------------------- AWS Client VPN Helper ----------------------------\n"
# Load variables from Configuration file
. variables.cfg
# Check that all variables are available
REQUIRED_ARGUMENTS=("WORKDIR" "SERVERNAME" "CLIENTNAME" "VPNCIDRBLOCK" "OVPNCFGFILE")
for REQUIRED in ${REQUIRED_ARGUMENTS[@]}; do
if [ -z $(eval echo \$$REQUIRED) ]; then
echo -e " ERROR: Configuration is missing the argument $REQUIRED.\n \
Required variables are ${REQUIRED_ARGUMENTS[@]}."; exit 1
fi
done
# Make sure the working directory is present and has the setup script
if [ -f "$WORKDIR/`basename "$0"`" ]; then
cd $WORKDIR
else
echo " ERROR: The working directory doesn't look valid. \
Please make sure you update variables.cfg"; exit 1
fi
# Menu Functions
function select-vpc-cidr {
echo ""
PS3="Select a VPC to use: "
VPCNAMES=$(aws ec2 describe-vpcs \
--output=text \
--query='Vpcs[].Tags[?Key==`Name`].Value')
select option in $VPCNAMES; do
VPCDETAILS=$(aws ec2 describe-vpcs \
--output=text \
--filters="Name=tag:Name,Values=$option" \
--query='Vpcs[].[CidrBlock,VpcId]')
VPCCIDR=$(echo $VPCDETAILS | cut -d" " -f1)
VPCID=$(echo $VPCDETAILS | cut -d" " -f2)
break
done
}
function select-subnet-id {
echo ""
PS3="Select a Subnet to use: "
SUBNETNAMES=$(aws ec2 describe-subnets \
--output=text \
--filter="Name=vpc-id,Values=$1" \
--query='Subnets[].Tags[?Key==`Name`].Value')
select option in $SUBNETNAMES; do
SUBNETID=$(aws ec2 describe-subnets \
--output=text \
--filters="Name=tag:Name,Values=$option" \
--query='Subnets[].SubnetId') && break
done
}
# Operational Function
function create-keys {
echo "Creating Certificate and Keys"
# Install OpenVPN's Easy-RSA for generating keys
if [ ! -d $WORKDIR/easy-rsa ]; then
echo " - Downloading OpenVPN's Easy-RSA"
curl https://github.com/OpenVPN/easy-rsa/tarball/master -Lso easy-rsa.tgz
mkdir ./easy-rsa; tar -xf easy-rsa.tgz --strip 1 -C ./easy-rsa
rm easy-rsa.tgz
fi
echo " - Initialising and Building CA"
$EASYRSAPATH/easyrsa init-pki
$EASYRSAPATH/easyrsa build-ca nopass
echo " - Generating Server/Client Certificates"
$EASYRSAPATH/easyrsa build-server-full $SERVERNAME nopass
$EASYRSAPATH/easyrsa build-client-full $CLIENTNAME nopass
}
function collect-acm-arns {
QUERY="'CertificateSummaryList[?DomainName==\`$SERVERNAME\`].CertificateArn'"
SERVERCERTARN=$(eval aws acm list-certificates \
--output=text \
--query=$QUERY)
QUERY="'CertificateSummaryList[?DomainName==\`$CLIENTNAME\`].CertificateArn'"
CLIENTCERTARN=$(eval aws acm list-certificates \
--output=text \
--query=$QUERY)
}
function acm-import-keys {
echo "Importing RSA Keys into AWS ACM and SSM Parameter Store"
collect-acm-arns
if [ -n "$SERVERCERTARN" ] && [ -n "$CLIENTCERTARN" ]; then
echo " - Certificates already exists in AWS ACM"
else
if [ ! -e "./pki/issued/$SERVERNAME.crt" ]; then
create-keys
fi
echo " - Certificates are being imported into Certificate Manager"
aws acm import-certificate \
--certificate=fileb://./pki/issued/$SERVERNAME.crt \
--private-key=fileb://./pki/private/$SERVERNAME.key \
--certificate-chain=fileb://./pki/ca.crt > /dev/null
aws acm import-certificate \
--certificate=fileb://./pki/issued/$CLIENTNAME.crt \
--private-key=fileb://./pki/private/$CLIENTNAME.key \
--certificate-chain=fileb://./pki/ca.crt > /dev/null
echo " - Placing Client Certificate & Key into Parameter Store"
aws ssm put-parameter \
--name="/clientvpn/$CLIENTNAME.crt" \
--description="Compressed Client Certificate for AWS Client VPN" \
--value=file://./pki/issued/$CLIENTNAME.crt \
--type="SecureString" \
--tier="Advanced" \
--overwrite > /dev/null
aws ssm put-parameter \
--name="/clientvpn/$CLIENTNAME.key" \
--description="Compressed Client Key for AWS Client VPN" \
--value=file://./pki/private/$CLIENTNAME.key \
--type="SecureString" \
--tier="Advanced" \
--overwrite > /dev/null
fi
}
function create-client-vpn {
echo "Creating Client VPN in AWS"
# Make sure ACM ARNs are present and known
acm-import-keys
collect-acm-arns
# Gather Information about where to create the VPN
select-vpc-cidr
select-subnet-id $VPCID
echo -e "\nCreating the Client VPN witin the VPC and Subnet Selected\n"
aws logs create-log-group --log-group-name="/aws/clientvpn" 2>/dev/null
aws logs create-log-stream \
--log-group-name="/aws/clientvpn" \
--log-stream-name="$SERVERNAME" 2>/dev/null
aws ec2 create-client-vpn-endpoint \
--client-cidr-block="$VPNCIDRBLOCK" \
--server-certificate-arn="$SERVERCERTARN" \
--authentication-options="Type=certificate-authentication, \
MutualAuthentication={ClientRootCertificateChainArn=$CLIENTCERTARN}" \
--connection-log-options="Enabled=true,CloudwatchLogGroup=/aws/clientvpn, \
CloudwatchLogStream=$SERVERNAME" \
--tag-specifications="ResourceType=client-vpn-endpoint, \
Tags=[{Key=Name,Value=$SERVERNAME}]"
ENDPOINTID=$(aws ec2 describe-client-vpn-endpoints \
--output=text \
--filters="Name=tag:Name,Values=$SERVERNAME" \
--query='ClientVpnEndpoints[].ClientVpnEndpointId')
aws ec2 associate-client-vpn-target-network \
--client-vpn-endpoint-id="$ENDPOINTID" \
--subnet-id="$SUBNETID"
aws ec2 authorize-client-vpn-ingress \
--client-vpn-endpoint-id="$ENDPOINTID" \
--target-network-cidr="0.0.0.0/0" \
--authorize-all-groups
aws ec2 create-client-vpn-route \
--description="Internet Route" \
--client-vpn-endpoint-id=$ENDPOINTID \
--destination-cidr-block="0.0.0.0/0" \
--target-vpc-subnet-id="$SUBNETID"
echo -e "\nAWS Client VPN setup process complete"
}
function create-client-config {
echo "Creating the OpenVPN Client Configuration file"
: ${ENDPOINTID:=$(aws ec2 describe-client-vpn-endpoints \
--output=text \
--filters="Name=tag:Name,Values=$SERVERNAME"\
--query='ClientVpnEndpoints[].ClientVpnEndpointId')}
if [ -n "$ENDPOINTID" ]; then
aws ec2 export-client-vpn-client-configuration \
--client-vpn-endpoint-id $ENDPOINTID \
--output text > $OVPNCFGFILE
echo "cert $WORKDIR/pki/issued/$CLIENTNAME.crt" >> $OVPNCFGFILE
echo "key $WORKDIR/pki/private/$CLIENTNAME.key" >> $OVPNCFGFILE
else
echo " ERROR: No Client VPN Endpoint could be found."; exit 1
fi
}
function check-existing-vpn {
echo "Checking to see if a VPN for "$CLIENTNAME" already exists"
CURRENTENDPOINT=$(aws ec2 describe-client-vpn-endpoints \
--filter=Name=tag:Name,Values=$SERVERNAME \
--query='ClientVpnEndpoints[].Tags[?Key==`Name`].Value' \
--output=text 2>&1)
if [ "$CURRENTENDPOINT" == "$SERVERNAME" ]; then
echo " - VPN Exists. Downloading Certificate now."
if [ ! -e "./pki/issued/$CLIENTNAME.crt" ]; then
mkdir -p ./pki/issued
aws ssm get-parameter \
--name="/clientvpn/$CLIENTNAME.crt" \
--with-decryption \
--query="Parameter.Value" > ./pki/issued/$CLIENTNAME.crt
fi
if [ ! -e "./pki/private/$CLIENTNAME.key" ]; then
mkdir -p $WORKDIR/pki/private
aws ssm get-parameter \
--name="/clientvpn/$CLIENTNAME.key" \
--with-decryption \
--query="Parameter.Value" > ./pki/private/$CLIENTNAME.key
fi
elif [ "$CURRENTENDPOINT" == "" ]; then
read -p "Client VPN doesn't exist. Do you want one created? [y/n] " createopt
if [ "$createopt" == "y" ] || [ "$createopt" == "yes" ]; then
create-client-vpn
else
echo "Exiting"; exit
fi
else
echo $CURRENTENDPOINT; exit
fi
}
# Main Execution
check-existing-vpn
create-client-config
echo -e "\nPlease wait several minutes for new VPNs to complete the Association before use."