{"id":3787,"date":"2020-12-15T21:28:40","date_gmt":"2020-12-16T03:28:40","guid":{"rendered":"http:\/\/benincosa.com\/?p=3787"},"modified":"2020-12-17T15:40:48","modified_gmt":"2020-12-17T21:40:48","slug":"aws-client-vpn-saml-authentication-with-google-g-suite","status":"publish","type":"post","link":"https:\/\/benincosa.com\/?p=3787","title":{"rendered":"AWS Client VPN SAML authentication with Google G-Suite"},"content":{"rendered":"\n<p>Note: <a href=\"https:\/\/youtu.be\/kYJaHankFAg\">Video for this Blog Post is Here<\/a>.<\/p>\n\n\n\n<p>When dealing with cloud resources the two opposing needs are security and accessibility.  When we often deploy resources in a private network inside of an AWS VPC that are not accessible directly from the outside.  To access these resources, we can use a bastion server or VPN.  <\/p>\n\n\n\n<p>The bastion server is a server that is accessible on the public network but also has a connection into the private network.  The drawbacks of of a bastion server is that you would have to login to it to do your work.  Most of my development is on my laptop and I like using the tools on my laptop as opposed to some server that may not have the tools.  We can configure SSH tunnels, but this can also be a hassle.  <\/p>\n\n\n\n<p>AWS has a managed Client VPN service that allows us to access this remote network and internal resources pretty easily.  I&#8217;m usually not a fan of client VPNs as it reminds me of big corporation life.  But the fact that I can tweak it and manage it with split tunnel and authenticate with my company GMail account makes it a pretty cool option.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Google G Suite Setup<\/h2>\n\n\n\n<p>Special shout out to <a href=\"https:\/\/stackoverflow.com\/questions\/63151685\/aws-vpn-using-federated-login-with-google-idp-app-not-configured-for-user\/63590967#63590967\">Stack Overflow<\/a> for helping with this as it was the hardest part! <\/p>\n\n\n\n<ol><li>In your G Suite Admin account go to the <a href=\"https:\/\/admin.google.com\/?hl=en\">Admin Console<\/a>.  Select Apps.<\/li><li>Select SAML apps<\/li><li>Add custom SAML app<\/li><li>Give it a name like Castle Rock AWS<\/li><li>Under Service Provider details: <ol><li>ACS URL:  <code>https:\/\/127.0.0.1:35001<\/code><\/li><li>Entity ID: <code>urn:amazon:webservices:clientvpn<\/code><\/li><li>Check Signed Response<\/li><li>Name ID<ol><li>Name ID format: <code>UNSPECIFIED<\/code><\/li><li>Name ID: <code>Basic Information &gt; Primary email<\/code><\/li><\/ol><\/li><\/ol><\/li><\/ol>\n\n\n\n<p>You now need to add the mapping.  The <a href=\"https:\/\/docs.aws.amazon.com\/vpn\/latest\/clientvpn-admin\/client-authentication.html\">SAML docs tell you<\/a> how this should be: <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"2062\" height=\"1132\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image.png\" alt=\"\" class=\"wp-image-3788\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.1 Google Apps Correction<\/h3>\n\n\n\n<p>Google SAML requires that you use https but Amazon isn&#8217;t having any of that.  Amazon specifies it wants <code>http:\/\/127.0.0.1:35001<\/code>. In order to get around it, you have to hack Google.  Once your new SAML app is created, go to edit the Service Provider Details. Change the 127.0.0.1 to something like 127.0.1.1.  I do this in Google Chrome.  Then open the console and navigate to the <code>Network<\/code> tab.  Monitor the network and hit save. You should see some webpage load called <code>batchexecute<\/code>&#8230; <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"2698\" height=\"96\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-1.png\" alt=\"\" class=\"wp-image-3789\"\/><figcaption>the first part that loads<\/figcaption><\/figure>\n\n\n\n<p>Now, right click and copy as cURL<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1102\" height=\"580\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-2.png\" alt=\"\" class=\"wp-image-3790\"\/><\/figure>\n\n\n\n<p>Open up a terminal and paste all that madness in it.  (I saved my to <code>\/tmp\/foo<\/code>) Then find the 127 and change it to http as well as the 127.0.1.1 to 127.0.0.1<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1526\" height=\"138\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-3.png\" alt=\"\" class=\"wp-image-3791\"\/><\/figure>\n\n\n\n<p>Next, run that curl command: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bash \/tmp\/foo<\/code><\/pre>\n\n\n\n<p>That should then set you up.  Refreshing your G-Suite SAML apps dashboard, you should now see that it is set to <code>http:\/\/127.0.0.1<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.2 Create SAML in AWS<\/h3>\n\n\n\n<p>Download the Metadata XML file from Google.  Then go to your downloads folder and run: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws iam create-saml-provider --saml-metadata-document fileb:\/\/GoogleIDPMetadata.xml --name CastleRockSAML<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">1.3 Configure Users<\/h3>\n\n\n\n<p>You may have some users or all users you want to add into the VPN.  You can configure this now at the Service Status.  Make sure whoever you test with has access.  The most simple is to give all users with your domain access.  This works great for small companies. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"2624\" height=\"750\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-7.png\" alt=\"\" class=\"wp-image-3797\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">2. Client Certificate Setup<\/h2>\n\n\n\n<p>The next step is you need to generate a server certificate for the VPN connection. We can follow some of the <a href=\"https:\/\/docs.aws.amazon.com\/vpn\/latest\/clientvpn-admin\/client-authentication.html\">steps Amazon provides<\/a> to do this. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/OpenVPN\/easy-rsa.git\ncd easy-rsa\/easyrsa3\n.\/easyrsa init-pki\n.\/easyrsa build-ca nopass\n.\/easyrsa build-server-full server nopass<\/code><\/pre>\n\n\n\n<p>We need the <code>pki\/issued\/server.crt<\/code>, <code>pki\/private\/server.key<\/code>, and the <code>pki\/ca.crt<\/code>.  With those we run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws acm import-certificate --certificate fileb:\/\/server.crt --private-key fileb:\/\/server.key --certificate-chain fileb:\/\/ca.crt --region region<\/code><\/pre>\n\n\n\n<p>If you want to be able to authenticate without Google Mail for other users like contractors outside your company, you can generate the <a href=\"https:\/\/docs.aws.amazon.com\/vpn\/latest\/clientvpn-admin\/client-authentication.html\">build-client-full instructions like Amazon says as well<\/a>. <\/p>\n\n\n\n<p>At this point you should have the keys up in AWS Cert Manager.  You are almost there!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Set up Client VPN Endpoint<\/h2>\n\n\n\n<p>We fill the form out with the following values<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"899\" height=\"713\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-4.png\" alt=\"\" class=\"wp-image-3792\"\/><\/figure>\n\n\n\n<p>Our IPv4 CIDR should not overlap with any of the CIDRs in your VPC.  My VPC is all 10.21.0.0\/16 so 172.23.0.0\/22 works pretty well.  The netmask has to be between 16-22. We are using the self signed certificate we generated and the SAML provider we generated with the Google ID. The rest of the details you can leave as default or configure as you want.  Be sure to enable split tunnel or your users will hate you. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Configure VPN Connections<\/h2>\n\n\n\n<p>At this point all the hard work is done.  You now just need to associate the VPN with the VPC you want it to join and add the subnets you want it to be able to reach.  Set up routing and authorization as specified in <a href=\"https:\/\/docs.aws.amazon.com\/vpn\/latest\/clientvpn-admin\/cvpn-working.html\">the documentation<\/a>.  For my simple purposes I added the subnet to the VM I was looking to attach to.  If I had an EKS cluster I&#8217;d have put it in the same subnets to be able to access the control plane.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> 5. Connect with VPN Client<\/h2>\n\n\n\n<p>You can download the VPN configuration from the Client VPN dashboard.  <\/p>\n\n\n\n<p>The AWS OpenVPN client can be <a href=\"https:\/\/aws.amazon.com\/vpn\/client-vpn-download\/\">downloaded from here<\/a>.  Importing the configuration our users will be presented with their Google SSO page to access the VPN. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"318\" height=\"159\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-5.png\" alt=\"\" class=\"wp-image-3795\"\/><figcaption>VPN Client<\/figcaption><\/figure>\n\n\n\n<p>At this point, if we have configured the VPN to be able to access the subnet our VMs or resources we&#8217;re interested in are on, we are able to connect to them without a bastion server.  Connecting to Databases are simple as well and we do it in a secure way without exposing these services over the internet. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"600\" height=\"226\" src=\"https:\/\/benincosa.com\/wp-content\/uploads\/2020\/12\/image-6.png\" alt=\"\" class=\"wp-image-3796\"\/><\/figure>\n\n\n\n<p>Our SSH config file has the following entry: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Host vpntest\n  User ec2-user\n  Hostname 10.21.101.93\n  IdentityFile ~\/.ssh\/vallard01.pem<\/code><\/pre>\n\n\n\n<p>We simply connect with <code>ssh vpntest<\/code> and are immediately on the server.  So easy! &#8230;Well at least it was after we set it all up. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Note: Video for this Blog Post is Here. When dealing with cloud resources the two opposing needs are security and accessibility. When we often deploy resources in a private network inside of an AWS VPC that are not accessible directly from the outside. To access these resources, we can use a bastion server or VPN&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[744],"tags":[967,965,964,968,963,966],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3787"}],"collection":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3787"}],"version-history":[{"count":6,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3787\/revisions"}],"predecessor-version":[{"id":3801,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3787\/revisions\/3801"}],"wp:attachment":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3787"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3787"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3787"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}