To secure your Amazon Web Services (AWS) environment, it is vital that access to sensitive data is carefully controlled. Direct connections from the internet to secure application network layers (private subnets) or resources such as databases should be restricted. Bots and hackers are constantly scanning the web for vulnerabilities and they pose a significant risk to your data, services and your entire AWS environment.
As an engineer, you may have a need to connect your remote computer to the private subnet layer to run queries on a database or test that the services running in your secure network are behaving as expected.
Historically, virtual private networks (VPNs) are a common solution, and there are many custom options that require considerable setup and management. Alternatively a bastion host can be used, but this often requires additional tools to be installed and adds another layer of complexity. Additionally, both of these solutions often become their own security concerns being both difficult to provision, manage and make reliable.
What is AWS Client VPN?
In recent years, AWS introduced Client VPN - a fully managed service offering secure connections into your Virtual Private Cloud (VPC) from any client device. AWS Client VPN is highly available, elastic and deeply integrates with existing AWS services.
Consider a simple web application stack consisting of a web server hosted on a single EC2 instance and an RDS database instance, both inside a private subnet. End-users connect to the service via an Application Load Balancer in a public subnet. AWS Client VPN provides engineers with an endpoint to connect to from their remote machines, and injects a network interface into your private subnet for secure connection to your database (or any other resources in the subnet).
Why use AWS Client VPN with Google Workspace for authentication?
Many start-ups and smaller companies (as well as some large ones!) use Google Workspace (formerly G Suite) as their identity provider. By leveraging Google Workspace to provide authentication for AWS Client VPN, you can ensure that only people with access to your Google organisation can access your AWS VPN.
As an added benefit, access to AWS Client VPN will be automatically granted/revoked as engineers are onboarded and offboarded in your Google Workspace organisation. There is no need to remember to revoke access or remove keys from a bastion host.
Solution Setup
Phase one: configure Google Workspace (G Suite) to act as an identity provider for AWS
A SAML application needs to be created via the Google Admin Console and provisioned to users so that permissions are granted to authenticate with AWS Client VPN.
Log in to your Google Admin Console, select Apps -> Overview, then click on the Web and mobile apps tile.
In the Web and mobile apps page, click on the Add app dropdown, and select Add custom SAML app.
Enter a suitable name for the app, and click CONTINUE twice to get to the Service Provider Details screen (DO NOT download the metadata as it will not work with AWS without customisation).
In the Service Provider Details screen, enter https://127.0.0.1:35000 for ACS URL (we will eventually change this to http://127.0.0.1:35001, which is required by AWS, but Google only allows the URL to start with https. We will fix this using a curl command soon), and urn:amazon:webservices:clientvpn for Entity ID. Check the Signed response checkbox, and click CONTINUE.
In the Attributes screen, set up the following three mappings, then click Finish.
Next, we need to use a browser (Firefox is used in the example) to get a valid POST request for an amendment to the SAML app and configure it to use local http instead of https. To do this, we use the Network tab of Developer Tools in a browser to get the payload.
Click on Service Provider Details of the SAML app in Google Admin Console and switch on Network recording in the browser developer tools. Edit the ACS url to be https://127.0.0.1:35001 (port 35001) and click SAVE. This should result in the page below.
Click on the first HTTP POST request named batchexecute, right click on it and select Copy as cURL. The copied string should look something like this (the cookies have been removed in the below):
curl 'https://admin.google.com/_/DasherSamlAdminConsoleUi/data/batchexecute?rpcids=DcqUrb&source-path=%2Fac%2Fapps%2Fsaml%2F635637890734%2Fsp&f.sid=3568075621442303950&bl=boq_dasher-unifiedapps-adminconsole-ui_20220306.16_p0&hl=en_GB&cid=019do8f3&_reqid=463957&rt=c' -X POST -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Referer: https://admin.google.com/' -H 'X-Same-Domain: 1' -H 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' -H 'Origin: https://admin.google.com' -H 'DNT: 1' -H 'Alt-Used: admin.google.com' -H 'Connection: keep-alive' -H 'Cookie: ...' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'TE: trailers' --data-raw 'f.req=...https%3A%2F%2F127.0.0.1%3A35001...'
Edit the https within the data-raw parameter to http, then run the curl command from a terminal.
Refresh the browser, you should see the value of the ACS URL field has change to http://127.0.0.1:35001 (http instead of https).
Go back to the main page of the application, and click on the User Access card (NOT View details) to grant users access:
Check the ON for everyone radio box, and click SAVE.
Note: This means ALL Google Workspace users will have access to the AWS Client VPN. If you wish to restrict this to particular Organizational Units or Groups this can be selected on the left instead.
Finally, back at the main page of the application, click DOWNLOAD METADATA to download the configuration to be used by AWS to configure user trust in subsequent steps.
Phase two: create required resources in AWS
In the AWS Identity and Access Management (IAM) Console, select Identity providers -> Add provider. Enter a suitable Provider name, upload the metadata downloaded from the previous step, and click Add provider.
From AWS Certificate Manager Console, create a certificate to be used by the VPN connection in the region that you need.
Next, we need to create the following resources in: a Client VPN Endpoint, a Client VPN Endpoint Security Group, and optionally, a CloudWatch Log Group (CloudWatch Log Group allows logging of all VPN access to your VPC and is highly recommended for all production use cases).
Start by creating the CloudWatch Log Group. From the CloudWatch Console, select Log Groups and then click Create log group. Enter a name for the log group, select a desired retention period for the logs, and click Create.
Next, create a security group for the Client VPN Endpoint. Start by identifying which VPCs and subnets need to be accessed from the VPN. Once these are identified, go to the VPC Console, Security → Security Groups → Create Security Group. Enter a name and description for the security group, and select the VPC required. Leave all other options as default, and click Create security group.
Next, create the Client VPN Endpoint. From the VPC Console, select Client VPN Endpoints and click Create Client VPN Endpoint. Enter a name and description for your Client VPN Endpoint, and choose a CIDR range where endpoint IPv4 addresses to be allocated from (allowable subnets are from /22 up to /18). Ensure the CIDR range you choose does not overlap with any resources that needs to be accessed via the Client VPN. Fill out the Server certificate ARN and Authentication Options sections with the certificate and SAML provider created in previous steps. Select Yes for Connection Logging, and select the CloudWatch Log Group created in the previous step from the dropdown list. Associate the VPC ID and security group created in the previous steps. Verify all the information provided, and click Create Client VPN Endpoint.
We must associate the traffic to the subnets in the VPC via the VPC Console → Client VPN Endpoints → Associations → Associate:
Each association has a cost so only create connections for subnets that have resources that you need to connect to. See the pricing here.
Next, we need to authorise the traffic via the Authorize tab. Click Authorize Ingress, fill in with the CIRD of each private subnet that the VPN requires access to, and wait for the state to become ‘Available’.
Alternative approach: provision via CloudFormation
An alternative method of creating all the AWS resources for the Client VPN is via CloudFormation. A sample template can be downloaded from our GitHub repository. It creates the log group, security group, Client VPN endpoint, and associates and authorises the endpoint to three private subnets.
Connect
To connect via the Client VPN, install the client and load in the metadata configuration file downloaded earlier. Connect and test.
Now, we have everything set up to allow anyone to securely access private resources in AWS using Client VPN, with authentication using their existing Google Workspace logins!
We have set up a secure and easy to use VPN that is low cost, low/zero maintenance and highly available. This means we can get back to concentrating on accelerating our business and delivery and forget about managing infrastructure components!
Innablr is a leading cloud engineering and next generation platform consultancy