Connect to AWS VPN from i3
Here's how to connect to the AWS VPN from i3, or other non-desktop Linux environments.
The Problem
AWS has a VPN client for connecting to AWS VPNs. And they have a build for Linux. ...Good. But it can only be run from a desktop environment, like Gnome. What's an i3 user to do?
One option: Patch a version of an OpenVPN client. Use a great little project with a script that'll associate an AWS VPN response to that client.
Patch OpenVPN Client
To prep for building the VPN client and then running our later script, you'll need some tools:
sudo apt install libssl-dev liblzo2-dev libpam0g-dev liblz4-dev dnsutils
Choose a compatible version of openvpn. The samm-git/aws-vpn-client repo has patches for 2.4.9 and 2.5.1. But I have also successfully used 2.5.5. And I've heard of someone using this patch in in the 2.6.x range.
Download and extract the openvpn source:
curl -O https://swupdate.openvpn.org/community/releases/openvpn-2.5.5.tar.gz
tar xvf openvpn-2.5.5.tar.gz
Clone the samm-git/aws-vpn-client repo:
git clone git@github.com:samm-git/aws-vpn-client.git
Now apply the patch:
# assuming openvpn dir at: ~/Downloads/openvpn-2.5.5
# assuming samm-git dir at: ~/dev/aws-vpn-client
cd ~/Downloads/openvpn-2.5.5
patch -p1 < ~/dev/aws-vpn-client/openvpn-v2.5.1-aws.patch && autoreconf -ivf && ./configure && make
(For the above, see also samm-git/aws-vpn-client#3.)
And move the patched version of openvpn to the aws-vpn-client directory:
cp openvpn ~/Downloads/aws-vpn-client
Get VPN Endpoint Config
Your particular AWS VPN endpoint will require a specific configuration. This is usually provided as an .ovpn
file. As an option for acquiring this file, AWS provides a self-service portal.
First log into AWS. By default, that's at https://self-service.clientvpn.amazonaws.com/endpoints. You may need your administrator to provide you with the specific endpoint ID, which you can enter at the URL above. Sometimes they'll give you a URL with the endpoint ID built in.
Once you have access to the self-service portal for your endpoint, download the cvpn-endpoint-[id].ovpn
file.
Modify the Script and Config
samm-git/aws-vpn-client provides the key script for connecting to the vpn. You'll need to update some values:
cd ~/Downloads/aws-vpn-client
nvim aws-connect.sh
# edit:
# - VPN_HOST - update the `[id]` portion, using id from the `cvpn-endpoint-[id].ovpn` file
# - PORT - update, as needed, to port 443 for HTTPS
And in the config:
nvim vpn.conf
# edit:
# - `<ca>` section - copy over the `<ca>` section from the `cvpn-endpoint-[id].ovpn` file
Also note that this vpn.conf
file doesn't have the non-openvpn-standard headers that Amazon uses, such as auth-user-pass
or auth-federate
.
Listen for a SAML Response
In the next step, when we run the connect script, it'll make a request to AWS for a connection on the VPN. This will produce a response, and we need to have a process to accept it, running at localhost:35001
, per the aws-connect.sh
script.
The included server is written in Go. Install Go (Use asdf, which is great for this).
Then run the server:
cd ~/Downloads/aws-vpn-client
go run server.go
Run the Script
In a separate terminal, run the connect script:
cd ~/Downloads/aws-vpn-client
./aws-connect.sh
Be prepared to enter your local superuser password to help the script complete.
You'll know it worked when you see the browser say it got a SAML response, that you can close it, and your aws-connect.sh
terminal has some output like this:
2024-03-13 10:13:59 [vpn.mydomain.com] Peer Connection Initiated with [AF_INET]54.130.227.72:443
...
2024-03-13 10:14:00 TUN/TAP device tun0 opened
...
2024-03-13 10:14:00 Initialization Sequence Completed
You should now be able to access VPN-only resources! And in i3. Happy day!
Optional: Troubleshoot the Script Run
Initially, I ran the script like this:
sh aws-connect.sh
And I got this error:
Getting SAML redirect URL from the AUTH_FAILED response (host: 35.183.98.133:443)
aws-connect.sh: 33: Syntax error: "(" unexpected
A friendly Daniel pointed out that when running scripts with sh
, it runs them as POSIX scripts and ignores the #!/bin/bash
directive. But this script uses bash, so run it like this to make it happy with the script syntax:
chmod +x aws-connect.sh
./aws-connect.sh
A small, separate bash tip: If you want to see more of what the script is doing, add this line to the top of the script to print out all commands for visibility:
set -x
Optional: Troubleshoot DNS
After I successfully connected to the VPN, I couldn't resolve DNS. I still can't. I'm dealing with some workarounds at them moment, eager to make them better. Here's what's working best so far:
Find the VPN network name with:
ifconfig
Mine's tun0
. Then set the DNS server for that network:
resolvectl dns tun0 10.100.0.2
Now lookup the IP of your favorite VPN-only resource:
dig some-name.com @10.100.0.2
In the ANSWER
section, there'll be something like this:
some-name.com. 21 IN A 10.210.23.28
Now modify your /etc/hosts
file to set your own DNS entry:
sudo $(which nvim) /etc/hosts
10.210.23.285 some-name.com
Now you should be able to browser to some-name.com
and have it resolve. Yay!
Other things that did not work so far:
- Trying to specify the DNS server for the connection:
cd ~/Downloads/aws-vpn-client
nvim vpn.conf
# add:
dhcp-option DNS 10.100.0.2
- Trying to find the DNS server:
netstat -netp
dig
ing without the DNS server:
dig some-name.com
If anyone has hot tips on getting DNS to work in this VPN environment, please send them my way.