Skip to content

Instantly share code, notes, and snippets.

@victorono
Forked from monkut/PrepareAWSClientVPN.md
Created August 8, 2024 21:23
Show Gist options
  • Save victorono/cceb417a4d0301f17a89a2523752c40d to your computer and use it in GitHub Desktop.
Save victorono/cceb417a4d0301f17a89a2523752c40d to your computer and use it in GitHub Desktop.
Prepare AWS Client VPN for connecting to a VPC without NAT/IGW

Prepare AWS Client VPN README

Prerequisites

  • AWS Account
  • Linux(like) System
  • awscli

Prepare OpenVPN certificates and Keys

  1. Create a working directory:

    mkdir ~/prepare-aws-vpn-client
  2. Get OpenVPN/easy-rsa:

    OpenVPN/easy-rsa provides simplified RSA key creation/management features

    cd ~/prepare-aws-vpn-client
    git clone https://github.com/OpenVPN/easy-rsa.git
  3. Create the Public Key Infrastructure (PKI)

    cd easy-rsa/easyrsa3
    
    # run `easyrsa init-pki` to build the PublicKeyInfrastructure (PKI)
    ./easyrsa init-pki
  4. Build the Certificate Authority (CA) for issuing the certificate(s) needed:

    ./easyrsa build-ca nopass
    
    # Enter, "rcs-vpn-ca" for Common Name.
    Common Name (eg: your user, host, or server name) [Easy-RSA CA]:rcs-vpn-ca
    
    CA creation complete and you may now import and sign cert requests.
    Your new CA certificate file for publishing is at:
    ~/prepare-aws-client-vpn/easy-rsa/easyrsa3/pki/ca.crt
  5. Create the Server and Client Certificates:

    # create server private key for signing and certificate
    ./easyrsa build-server-full server nopass
    
    # create client private key for signing and certificate
    ./easyrsa build-client-full client1.vpn.tld nopass
    
  6. Collect Server/Client certifications/keys for ease of use:

    mkdir /tmp/aws-vpn/
    
    # copy CA certificate
    cp pki/ca.crt /tmp/aws-vpn/
    
    # collect server cert/key
    cp pki/issued/server.crt /tmp/aws-vpn/
    cp pki/private/server.key /tmp/aws-vpn/
    
    # collect cliet cert/key
    cp pki/issued/client1.vpn.tld.crt /tmp/aws-vpn/
    cp pki/private/client1.vpn.tld.key /tmp/aws-vpn/
    
    # check certs/keys were successfully copied
    ls -lrt /tmp/aws-vpn/

Import Server/Client Certificates and Keys to AWS ACM:

  1. Set AWS_PROFILE:

    export AWS_PROFILE={YOUR APPROPRIATE AWS PROFILE}
  2. Import Server Certificate and Private Key into AWS ACM:

    aws acm import-certificate --certificate file:///tmp/aws-vpn/server.crt --private-key file:///tmp/aws-vpn/server.key --certificate-chain file:///tmp/aws-vpn/ca.crt
  3. Import Client Certificate and Private Key into AWS ACM:

    aws acm import-certificate --certificate file:///tmp/aws-vpn/client1.vpn.tld.crt --private-key file:///tmp/aws-vpn/client1.vpn.tld.key --certificate-chain file:///tmp/aws-vpn/ca.crt
  4. Confirm that server/client certificates and keys were properly imported:

    aws acm list-certificates
    # both server & client1.vpn.tld should be displayed in the output
  5. Create Cloudwatch LogGroup/LogStream for vpn connection logging:

    aws logs create-log-group --log-group-name vpn-client-logs
    aws logs create-log-stream --log-group-name vpn-client-logs --log-stream-name connections
  6. Create the client VPN endpoint:

    aws ec2 create-client-vpn-endpoint --client-cidr-block "10.0.208.0/22" \
        --server-certificate-arn $(aws acm list-certificates --query 'CertificateSummaryList[?DomainName==`server`].CertificateArn' --output text) \
        --authentication-options Type=certificate-authentication,MutualAuthentication={ClientRootCertificateChainArn=$(aws acm list-certificates --query 'CertificateSummaryList[?DomainName==`client1.vpn.tld`].CertificateArn' --output text)} \ 
        --connection-log-options Enabled=true,CloudwatchLogGroup=vpn-client-logs,CloudwatchLogStream=connections
  7. Associate created ClientVPN Endpoint with VPC:

    NOTE: This expects that at least 1 subnet in the given VPC is tagged 'public'. Assumes only 1 ClientVpnEndpoint exists!

    export RCS_VPCID={YOUR TARGET VPC}
    aws ec2 associate-client-vpn-target-network \
        --client-vpn-endpoint-id $(aws ec2 describe-client-vpn-endpoints --query 'ClientVpnEndpoints[0].ClientVpnEndpointId' --output text) \
        --subnet-id $(aws ec2 describe-subnets --query 'Subnets[?VpcId==`'$RCS_VPCID'` && Tags[?Value==`public`]].SubnetId | [0]' --output text)
  8. Authorize access to VPC for Client VPN endpoint connectionsfor the FULL VPC segment:

    NOTE: Defined CIDR here is specific to prepared VPC, may need to update in your case.

    aws ec2 authorize-client-vpn-ingress \
        --client-vpn-endpoint-id $(aws ec2 describe-client-vpn-endpoints --query 'ClientVpnEndpoints[0].ClientVpnEndpointId' --output text) \
        --target-network-cidr "10.0.0.0/16" \
        --authorize-all-groups
  9. Download the client connection configuration for the created Client VPN endpoint:

    NOTE: Assumes only a single ClientVPNEndpoint

    aws ec2 export-client-vpn-client-configuration --client-vpn-endpoint-id $(aws ec2 describe-client-vpn-endpoints --query 'ClientVpnEndpoints[0].ClientVpnEndpointId' --output text) \
        --query 'ClientConfiguration' --output text > ~/client-configuration.ovpn
    
  10. Add client certification/key information to *.ovpn configuration file:

    echo "cert /tmp/aws-vpn/client1.vpn.tld.crt" >> ~/client-configuration.ovpn
    echo "key /tmp/aws-vpn/client1.vpn.tld.key" >> ~/client-configuration.ovpn 

Connect via VPN

  1. Install openvpn (ubuntu:

    sudo apt install openvpn
  2. Connect to VPN using prepared client-configuration.ovpn:

    sudo openvpn --config ~/client-configuration.ovpn
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment