Source code: https://github.com/DevNgugi/vpn_automate.git
Many VPN providers support Two-Factor Authentication (2FA), often in the form of a TOTP (Time-Based One-Time Password) code. This is great for security but can be a hassle if you’re manually entering passwords and codes every time you connect.
This blog post walks you through a Bash script that automates the OpenVPN login process.
Prerequisites:
Step 1). Extract the TOTP Secret from the provided QR Code:
When enabling 2FA, your VPN provider often gives you a QR code to scan with an authenticator app (e.g., Google Authenticator, Authy). That QR code encodes the TOTP secret in a URL like:
otpauth://totp/YourVPN:username?secret=ABCDEF1234567890&issuer=YourVPN
Python script for extracting the url from the QR image:
from pyzbar.pyzbar import decode
from PIL import Image
data = decode(Image.open('qr_code.png'))
print(data[0].data.decode())
Step 2) Encrypt Secrets with GPG
cat <<EOF | gpg --symmetric --cipher-algo AES256 -o ~/.vpn_secrets.gpg
USERNAME=<username>
STATIC_PASSWORD=<password>
TOTP_SECRET=<From provider>
EOF
The script:
Copy the following bash script and adjust the .ovpn config path (You should have downloaded the config from your VPN Provider). You can also clone the script from https://github.com/DevNgugi/vpn_automate.git
#!/bin/bash
SECRETS_FILE="$HOME/.vpn_secrets.gpg"
AUTH_FILE="/tmp/ovpn_creds.txt"
OVPN_CONFIG="./config.ovpn" # <- replace with your actual .ovpn config path
# === Decrypt secrets (GPG will prompt for passphrase) ===
eval $(gpg --quiet --batch --decrypt "$SECRETS_FILE")
if [[ -z "$USERNAME" || -z "$STATIC_PASSWORD" || -z "$TOTP_SECRET" ]]; then
echo "Failed to load secrets. Exiting."
exit 1
fi
# === Generate TOTP ===
OTP_CODE=$(python3 -c "import pyotp; print(pyotp.TOTP('$TOTP_SECRET').now())")
FULL_PASSWORD="${STATIC_PASSWORD}${OTP_CODE}"
# === Write temporary auth file ===
echo -e "${USERNAME}\n${FULL_PASSWORD}" > "$AUTH_FILE"
# === Start OpenVPN ===
sudo openvpn --config "$OVPN_CONFIG" --auth-user-pass "$AUTH_FILE"
# === Clean up ===
rm -f "$AUTH_FILE"
Run the script:
Make sure you give execute permissions to the script file:
chmod +x vpn.sh
Then run the script:
./vpn.sh